summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Van Brunt <kmvanbrunt@gmail.com>2021-01-22 14:53:33 -0500
committerKevin Van Brunt <kmvanbrunt@gmail.com>2021-01-22 14:53:33 -0500
commit45580056485328338899dd65607c6c57d3797f35 (patch)
tree4cb6a10485b440e0b23eb638764fc2ff14faa974
parent49fac04513727a67b0360a9e7560087c64dd557d (diff)
parenta3b1b6ddf81cdc0b253f15feeb167ff348afd14f (diff)
downloadcmd2-git-45580056485328338899dd65607c6c57d3797f35.tar.gz
Merge branch 'master' into 2.0
-rw-r--r--cmd2/ansi.py23
-rw-r--r--cmd2/argparse_completer.py30
-rw-r--r--cmd2/argparse_custom.py23
-rw-r--r--cmd2/clipboard.py4
-rw-r--r--cmd2/cmd2.py93
-rw-r--r--cmd2/command_definition.py16
-rw-r--r--cmd2/decorators.py30
-rw-r--r--cmd2/history.py13
-rwxr-xr-xcmd2/parsing.py18
-rw-r--r--cmd2/py_bridge.py16
-rw-r--r--cmd2/rl_utils.py6
-rw-r--r--cmd2/table_creator.py34
-rw-r--r--cmd2/transcript.py11
-rw-r--r--cmd2/utils.py70
-rw-r--r--docs/features/shortcuts_aliases_macros.rst2
-rw-r--r--examples/argparse_completion.py15
-rwxr-xr-xexamples/async_printing.py9
-rwxr-xr-xexamples/basic.py6
-rwxr-xr-xexamples/basic_completion.py4
-rwxr-xr-xexamples/colors.py14
-rw-r--r--examples/custom_parser.py6
-rwxr-xr-xexamples/decorator_example.py4
-rw-r--r--examples/default_categories.py5
-rwxr-xr-xexamples/dynamic_commands.py5
-rwxr-xr-xexamples/exit_code.py4
-rwxr-xr-xexamples/hello_cmd2.py4
-rwxr-xr-xexamples/help_categories.py4
-rwxr-xr-xexamples/hooks.py4
-rwxr-xr-xexamples/initialization.py6
-rw-r--r--examples/modular_commands/commandset_basic.py15
-rw-r--r--examples/modular_commands/commandset_complex.py4
-rw-r--r--examples/modular_commands/commandset_custominit.py7
-rw-r--r--examples/modular_commands_basic.py5
-rw-r--r--examples/modular_commands_dynamic.py8
-rw-r--r--examples/modular_commands_main.py26
-rw-r--r--examples/modular_subcommands.py8
-rwxr-xr-xexamples/override_parser.py4
-rwxr-xr-xexamples/paged_output.py4
-rwxr-xr-xexamples/pirate.py4
-rwxr-xr-xexamples/plumbum_colors.py9
-rwxr-xr-xexamples/python_scripting.py4
-rw-r--r--examples/scripts/save_help_text.py5
-rwxr-xr-xexamples/table_creation.py19
-rw-r--r--plugins/ext_test/cmd2_ext_test/__init__.py4
-rw-r--r--plugins/ext_test/cmd2_ext_test/cmd2_ext_test.py5
-rw-r--r--plugins/ext_test/setup.py17
-rw-r--r--plugins/ext_test/tests/test_ext_test.py5
-rw-r--r--plugins/tasks.py8
-rw-r--r--plugins/template/cmd2_myplugin/__init__.py5
-rw-r--r--plugins/template/cmd2_myplugin/myplugin.py5
-rw-r--r--plugins/template/tests/test_myplugin.py4
-rw-r--r--setup.cfg2
-rwxr-xr-xsetup.py4
-rw-r--r--tasks.py6
-rw-r--r--tests/conftest.py25
-rw-r--r--tests/test_argparse.py9
-rw-r--r--tests/test_argparse_completer.py21
-rw-r--r--tests/test_argparse_custom.py15
-rwxr-xr-xtests/test_cmd2.py15
-rwxr-xr-xtests/test_completion.py15
-rwxr-xr-xtests/test_history.py12
-rwxr-xr-xtests/test_parsing.py11
-rw-r--r--tests/test_plugin.py7
-rw-r--r--tests/test_run_pyscript.py12
-rw-r--r--tests/test_table_creator.py4
-rw-r--r--tests/test_transcript.py20
-rw-r--r--tests/test_utils.py68
-rw-r--r--tests_isolated/test_commandset/conftest.py29
-rw-r--r--tests_isolated/test_commandset/test_argparse_subcommands.py6
-rw-r--r--tests_isolated/test_commandset/test_categories.py9
-rw-r--r--tests_isolated/test_commandset/test_commandset.py18
71 files changed, 699 insertions, 263 deletions
diff --git a/cmd2/ansi.py b/cmd2/ansi.py
index afef06ce..2a3ed01e 100644
--- a/cmd2/ansi.py
+++ b/cmd2/ansi.py
@@ -3,14 +3,27 @@
Support for ANSI escape sequences which are used for things like applying style to text,
setting the window title, and asynchronous alerts.
"""
-import enum
import functools
import re
-from typing import IO, Any, List, Union
+from enum import (
+ Enum,
+)
+from typing import (
+ IO,
+ Any,
+ List,
+ Union,
+)
import colorama
-from colorama import Back, Fore, Style
-from wcwidth import wcswidth
+from colorama import (
+ Back,
+ Fore,
+ Style,
+)
+from wcwidth import (
+ wcswidth,
+)
# On Windows, filter ANSI escape codes out of text sent to stdout/stderr, and replace them with equivalent Win32 calls
colorama.init(strip=False)
@@ -49,7 +62,7 @@ The default is ``STYLE_TERMINAL``.
ANSI_STYLE_RE = re.compile(r'\x1b\[[^m]*m')
-class ColorBase(enum.Enum):
+class ColorBase(Enum):
"""
Base class used for defining color enums. See fg and bg classes for examples.
diff --git a/cmd2/argparse_completer.py b/cmd2/argparse_completer.py
index f42e2a88..daaebdff 100644
--- a/cmd2/argparse_completer.py
+++ b/cmd2/argparse_completer.py
@@ -10,10 +10,21 @@ import argparse
import inspect
import numbers
import shutil
-from collections import deque
-from typing import Dict, List, Optional, Union
+from collections import (
+ deque,
+)
+from typing import (
+ Dict,
+ List,
+ Optional,
+ Union,
+)
-from . import ansi, cmd2, constants
+from . import (
+ ansi,
+ cmd2,
+ constants,
+)
from .argparse_custom import (
ATTR_CHOICES_CALLABLE,
ATTR_DESCRIPTIVE_COMPLETION_HEADER,
@@ -23,9 +34,16 @@ from .argparse_custom import (
CompletionItem,
generate_range_error,
)
-from .command_definition import CommandSet
-from .exceptions import CompletionError
-from .table_creator import Column, SimpleTable
+from .command_definition import (
+ CommandSet,
+)
+from .exceptions import (
+ CompletionError,
+)
+from .table_creator import (
+ Column,
+ SimpleTable,
+)
# If no descriptive header is supplied, then this will be used instead
DEFAULT_DESCRIPTIVE_HEADER = 'Description'
diff --git a/cmd2/argparse_custom.py b/cmd2/argparse_custom.py
index 3cf4d1ab..39676764 100644
--- a/cmd2/argparse_custom.py
+++ b/cmd2/argparse_custom.py
@@ -193,10 +193,25 @@ import argparse
import re
import sys
# noinspection PyUnresolvedReferences,PyProtectedMember
-from argparse import ONE_OR_MORE, ZERO_OR_MORE, ArgumentError, _
-from typing import Any, Callable, Optional, Tuple, Type, Union
-
-from . import ansi, constants
+from argparse import (
+ ONE_OR_MORE,
+ ZERO_OR_MORE,
+ ArgumentError,
+ _,
+)
+from typing import (
+ Any,
+ Callable,
+ Optional,
+ Tuple,
+ Type,
+ Union,
+)
+
+from . import (
+ ansi,
+ constants,
+)
############################################################################################################
# The following are names of custom argparse argument attributes added by cmd2
diff --git a/cmd2/clipboard.py b/cmd2/clipboard.py
index deb2f5cc..c759d8da 100644
--- a/cmd2/clipboard.py
+++ b/cmd2/clipboard.py
@@ -4,7 +4,9 @@ This module provides basic ability to copy from and paste to the clipboard/paste
"""
import pyperclip
# noinspection PyProtectedMember
-from pyperclip import PyperclipException
+from pyperclip import (
+ PyperclipException,
+)
# Can we access the clipboard? Should always be true on Windows and Mac, but only sometimes on Linux
try:
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index 9fe31fd7..b6b63d42 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -39,30 +39,89 @@ import pydoc
import re
import sys
import threading
-from code import InteractiveConsole
-from collections import namedtuple
-from contextlib import redirect_stdout
-from typing import Any, Callable, Dict, Iterable, List, Mapping, Optional, Tuple, Type, Union
-
-from . import ansi, constants, plugin, utils
-from .argparse_custom import DEFAULT_ARGUMENT_PARSER, CompletionItem
-from .clipboard import can_clip, get_paste_buffer, write_to_paste_buffer
-from .command_definition import CommandSet
-from .constants import CLASS_ATTR_DEFAULT_HELP_CATEGORY, COMMAND_FUNC_PREFIX, COMPLETER_FUNC_PREFIX, HELP_FUNC_PREFIX
-from .decorators import with_argparser, as_subcommand_to
+from code import (
+ InteractiveConsole,
+)
+from collections import (
+ namedtuple,
+)
+from contextlib import (
+ redirect_stdout,
+)
+from typing import (
+ Any,
+ Callable,
+ Dict,
+ Iterable,
+ List,
+ Mapping,
+ Optional,
+ Tuple,
+ Type,
+ Union,
+)
+
+from . import (
+ ansi,
+ constants,
+ plugin,
+ utils,
+)
+from .argparse_custom import (
+ DEFAULT_ARGUMENT_PARSER,
+ CompletionItem,
+)
+from .clipboard import (
+ can_clip,
+ get_paste_buffer,
+ write_to_paste_buffer,
+)
+from .command_definition import (
+ CommandSet,
+)
+from .constants import (
+ CLASS_ATTR_DEFAULT_HELP_CATEGORY,
+ COMMAND_FUNC_PREFIX,
+ COMPLETER_FUNC_PREFIX,
+ HELP_FUNC_PREFIX,
+)
+from .decorators import (
+ as_subcommand_to,
+ with_argparser,
+)
from .exceptions import (
- CommandSetRegistrationError,
Cmd2ShlexError,
+ CommandSetRegistrationError,
CompletionError,
EmbeddedConsoleExit,
EmptyStatement,
RedirectionError,
- SkipPostcommandHooks
+ SkipPostcommandHooks,
+)
+from .history import (
+ History,
+ HistoryItem,
+)
+from .parsing import (
+ Macro,
+ MacroArg,
+ Statement,
+ StatementParser,
+ shlex_split,
+)
+from .rl_utils import (
+ RlType,
+ rl_get_point,
+ rl_make_safe_prompt,
+ rl_set_prompt,
+ rl_type,
+ rl_warning,
+ vt100_support,
+)
+from .utils import (
+ Settable,
+ get_defining_class,
)
-from .history import History, HistoryItem
-from .parsing import Macro, MacroArg, Statement, StatementParser, shlex_split
-from .rl_utils import RlType, rl_get_point, rl_make_safe_prompt, rl_set_prompt, rl_type, rl_warning, vt100_support
-from .utils import get_defining_class, Settable
# Set up readline
if rl_type == RlType.NONE: # pragma: no cover
diff --git a/cmd2/command_definition.py b/cmd2/command_definition.py
index 3f05792c..c85814d7 100644
--- a/cmd2/command_definition.py
+++ b/cmd2/command_definition.py
@@ -2,10 +2,18 @@
"""
Supports the definition of commands in separate classes to be composed into cmd2.Cmd
"""
-from typing import Optional, Type
-
-from .constants import CLASS_ATTR_DEFAULT_HELP_CATEGORY, COMMAND_FUNC_PREFIX
-from .exceptions import CommandSetRegistrationError
+from typing import (
+ Optional,
+ Type,
+)
+
+from .constants import (
+ CLASS_ATTR_DEFAULT_HELP_CATEGORY,
+ COMMAND_FUNC_PREFIX,
+)
+from .exceptions import (
+ CommandSetRegistrationError,
+)
# Allows IDEs to resolve types without impacting imports at runtime, breaking circular dependency issues
try: # pragma: no cover
diff --git a/cmd2/decorators.py b/cmd2/decorators.py
index 6bc57b90..6d99b848 100644
--- a/cmd2/decorators.py
+++ b/cmd2/decorators.py
@@ -1,12 +1,30 @@
# coding=utf-8
"""Decorators for ``cmd2`` commands"""
import argparse
-from typing import TYPE_CHECKING, Any, Callable, Dict, Iterable, List, Optional, Tuple, Union
-
-from . import constants
-from .argparse_custom import Cmd2AttributeWrapper
-from .exceptions import Cmd2ArgparseError
-from .parsing import Statement
+from typing import (
+ TYPE_CHECKING,
+ Any,
+ Callable,
+ Dict,
+ Iterable,
+ List,
+ Optional,
+ Tuple,
+ Union,
+)
+
+from . import (
+ constants,
+)
+from .argparse_custom import (
+ Cmd2AttributeWrapper,
+)
+from .exceptions import (
+ Cmd2ArgparseError,
+)
+from .parsing import (
+ Statement,
+)
if TYPE_CHECKING: # pragma: no cover
import cmd2
diff --git a/cmd2/history.py b/cmd2/history.py
index 60a071fb..fc1691b4 100644
--- a/cmd2/history.py
+++ b/cmd2/history.py
@@ -4,12 +4,19 @@ History management classes
"""
import re
-from typing import List, Union
+from typing import (
+ List,
+ Union,
+)
import attr
-from . import utils
-from .parsing import Statement
+from . import (
+ utils,
+)
+from .parsing import (
+ Statement,
+)
@attr.s(frozen=True)
diff --git a/cmd2/parsing.py b/cmd2/parsing.py
index c420e9aa..acf9b471 100755
--- a/cmd2/parsing.py
+++ b/cmd2/parsing.py
@@ -4,12 +4,24 @@
import re
import shlex
-from typing import Dict, Iterable, List, Optional, Tuple, Union
+from typing import (
+ Dict,
+ Iterable,
+ List,
+ Optional,
+ Tuple,
+ Union,
+)
import attr
-from . import constants, utils
-from .exceptions import Cmd2ShlexError
+from . import (
+ constants,
+ utils,
+)
+from .exceptions import (
+ Cmd2ShlexError,
+)
def shlex_split(str_to_split: str) -> List[str]:
diff --git a/cmd2/py_bridge.py b/cmd2/py_bridge.py
index 38fef142..a9b8641d 100644
--- a/cmd2/py_bridge.py
+++ b/cmd2/py_bridge.py
@@ -5,10 +5,18 @@ while maintaining a reasonable degree of isolation between the two.
"""
import sys
-from contextlib import redirect_stderr, redirect_stdout
-from typing import Optional
-
-from .utils import StdSim, namedtuple_with_defaults
+from contextlib import (
+ redirect_stderr,
+ redirect_stdout,
+)
+from typing import (
+ Optional,
+)
+
+from .utils import (
+ StdSim,
+ namedtuple_with_defaults,
+)
class CommandResult(namedtuple_with_defaults('CommandResult', ['stdout', 'stderr', 'stop', 'data'])):
diff --git a/cmd2/rl_utils.py b/cmd2/rl_utils.py
index 9163efd8..e435c3f5 100644
--- a/cmd2/rl_utils.py
+++ b/cmd2/rl_utils.py
@@ -2,8 +2,10 @@
"""
Imports the proper readline for the platform and provides utility functions for it
"""
-import enum
import sys
+from enum import (
+ Enum,
+)
# Prefer statically linked gnureadline if available (for macOS compatibility due to issues with libedit)
try:
@@ -19,7 +21,7 @@ except ImportError:
pass
-class RlType(enum.Enum):
+class RlType(Enum):
"""Readline library types we recognize"""
GNU = 1
PYREADLINE = 2
diff --git a/cmd2/table_creator.py b/cmd2/table_creator.py
index fc2398f2..419f12b4 100644
--- a/cmd2/table_creator.py
+++ b/cmd2/table_creator.py
@@ -6,15 +6,31 @@ The general use case is to inherit from TableCreator to create a table class wit
There are already implemented and ready-to-use examples of this below TableCreator's code.
"""
import copy
-import enum
import functools
import io
-from collections import deque
-from typing import Any, Optional, Sequence, Tuple, Union
-
-from wcwidth import wcwidth
-
-from . import ansi, constants, utils
+from collections import (
+ deque,
+)
+from enum import (
+ Enum,
+)
+from typing import (
+ Any,
+ Optional,
+ Sequence,
+ Tuple,
+ Union,
+)
+
+from wcwidth import (
+ wcwidth,
+)
+
+from . import (
+ ansi,
+ constants,
+ utils,
+)
# This is needed for compatibility with early versions of Python 3.5 prior to 3.5.4
try:
@@ -39,14 +55,14 @@ EMPTY = ''
SPACE = ' '
-class HorizontalAlignment(enum.Enum):
+class HorizontalAlignment(Enum):
"""Horizontal alignment of text in a cell"""
LEFT = 1
CENTER = 2
RIGHT = 3
-class VerticalAlignment(enum.Enum):
+class VerticalAlignment(Enum):
"""Vertical alignment of text in a cell"""
TOP = 1
MIDDLE = 2
diff --git a/cmd2/transcript.py b/cmd2/transcript.py
index 940c97db..0c65cb8a 100644
--- a/cmd2/transcript.py
+++ b/cmd2/transcript.py
@@ -11,9 +11,14 @@ class is used in cmd2.py::run_transcript_tests()
"""
import re
import unittest
-from typing import Tuple
-
-from . import ansi, utils
+from typing import (
+ Tuple,
+)
+
+from . import (
+ ansi,
+ utils,
+)
class Cmd2TestCase(unittest.TestCase):
diff --git a/cmd2/utils.py b/cmd2/utils.py
index ea1a08c5..1f5de366 100644
--- a/cmd2/utils.py
+++ b/cmd2/utils.py
@@ -4,7 +4,6 @@
import argparse
import collections
import collections.abc as collections_abc
-import enum
import functools
import glob
import inspect
@@ -14,11 +13,26 @@ import re
import subprocess
import sys
import threading
-
import unicodedata
-from typing import Any, Callable, Dict, IO, Iterable, List, Optional, TextIO, Type, Union
-
-from . import constants
+from enum import (
+ Enum,
+)
+from typing import (
+ IO,
+ Any,
+ Callable,
+ Dict,
+ Iterable,
+ List,
+ Optional,
+ TextIO,
+ Type,
+ Union,
+)
+
+from . import (
+ constants,
+)
def is_quoted(arg: str) -> bool:
@@ -320,32 +334,30 @@ def expand_user_in_tokens(tokens: List[str]) -> None:
tokens[index] = expand_user(tokens[index])
-def is_executable(path) -> bool:
- """Return True if specified path is executable file, otherwise False."""
- return os.path.isfile(path) and os.access(path, os.X_OK)
-
-
-def probe_editors() -> str:
- """Find a favor editor in system path."""
- editors = ['vim', 'vi', 'emacs', 'nano', 'pico', 'gedit', 'kate', 'subl', 'geany', 'atom']
- paths = [p for p in os.getenv('PATH').split(os.path.pathsep) if not os.path.islink(p)]
- for editor, path in itertools.product(editors, paths):
- editor_path = os.path.join(path, editor)
- if is_executable(editor_path):
- break
- else:
- editor_path = None
- return editor_path
-
-
-def find_editor() -> str:
- """Find a reasonable editor to use by default for the system that the cmd2 application is running on."""
+def find_editor() -> Optional[str]:
+ """
+ Used to set cmd2.Cmd.DEFAULT_EDITOR. If EDITOR env variable is set, that will be used.
+ Otherwise the function will look for a known editor in directories specified by PATH env variable.
+ :return: Default editor or None
+ """
editor = os.environ.get('EDITOR')
if not editor:
if sys.platform[:3] == 'win':
- editor = 'notepad'
+ editors = ['code.cmd', 'notepad++.exe', 'notepad.exe']
+ else:
+ editors = ['vim', 'vi', 'emacs', 'nano', 'pico', 'joe', 'code', 'subl', 'atom', 'gedit', 'geany', 'kate']
+
+ paths = [p for p in os.getenv('PATH').split(os.path.pathsep) if not os.path.islink(p)]
+ for editor, path in itertools.product(editors, paths):
+ editor_path = os.path.join(path, editor)
+ if os.path.isfile(editor_path) and os.access(editor_path, os.X_OK):
+ if sys.platform[:3] == 'win':
+ # Remove extension from Windows file names
+ editor = os.path.splitext(editor)[0]
+ break
else:
- editor = probe_editors()
+ editor = None
+
return editor
@@ -669,7 +681,7 @@ class RedirectionSavedState:
self.saved_redirecting = saved_redirecting
-class TextAlignment(enum.Enum):
+class TextAlignment(Enum):
"""Horizontal text alignment"""
LEFT = 1
CENTER = 2
@@ -1041,7 +1053,7 @@ def get_defining_class(meth) -> Type:
return getattr(meth, '__objclass__', None) # handle special descriptor objects
-class CompletionMode(enum.Enum):
+class CompletionMode(Enum):
"""Enum for what type of tab completion to perform in cmd2.Cmd.read_input()"""
# Tab completion will be disabled during read_input() call
# Use of custom up-arrow history supported
diff --git a/docs/features/shortcuts_aliases_macros.rst b/docs/features/shortcuts_aliases_macros.rst
index e5b4bf1d..58d6d83c 100644
--- a/docs/features/shortcuts_aliases_macros.rst
+++ b/docs/features/shortcuts_aliases_macros.rst
@@ -24,7 +24,7 @@ defined:
To define more shortcuts, update the dict ``App.shortcuts`` with the
{'shortcut': 'command_name'} (omit ``do_``)::
- class App(Cmd2):
+ class App(Cmd):
def __init__(self):
shortcuts = dict(cmd2.DEFAULT_SHORTCUTS)
shortcuts.update({'*': 'sneeze', '~': 'squirm'})
diff --git a/examples/argparse_completion.py b/examples/argparse_completion.py
index c2cb31f6..49a608a9 100644
--- a/examples/argparse_completion.py
+++ b/examples/argparse_completion.py
@@ -4,9 +4,18 @@
A simple example demonstrating how to integrate tab completion with argparse-based commands.
"""
import argparse
-from typing import Dict, List
-
-from cmd2 import Cmd, Cmd2ArgumentParser, CompletionError, CompletionItem, with_argparser
+from typing import (
+ Dict,
+ List,
+)
+
+from cmd2 import (
+ Cmd,
+ Cmd2ArgumentParser,
+ CompletionError,
+ CompletionItem,
+ with_argparser,
+)
# Data source for argparse.choices
food_item_strs = ['Pizza', 'Ham', 'Ham Sandwich', 'Potato']
diff --git a/examples/async_printing.py b/examples/async_printing.py
index 29af2d64..e0442f1f 100755
--- a/examples/async_printing.py
+++ b/examples/async_printing.py
@@ -7,10 +7,15 @@ and changes the window title
import random
import threading
import time
-from typing import List
+from typing import (
+ List,
+)
import cmd2
-from cmd2 import fg, style
+from cmd2 import (
+ fg,
+ style,
+)
ALERTS = ["Watch as this application prints alerts and updates the prompt",
"This will only happen when the prompt is present",
diff --git a/examples/basic.py b/examples/basic.py
index 2a1e9a12..800a0946 100755
--- a/examples/basic.py
+++ b/examples/basic.py
@@ -9,7 +9,11 @@
6) Shell-like capabilities
"""
import cmd2
-from cmd2 import bg, fg, style
+from cmd2 import (
+ bg,
+ fg,
+ style,
+)
class BasicApp(cmd2.Cmd):
diff --git a/examples/basic_completion.py b/examples/basic_completion.py
index f33029c9..83e71a50 100755
--- a/examples/basic_completion.py
+++ b/examples/basic_completion.py
@@ -13,7 +13,9 @@ familiar with argparse. The recommended approach for tab completing positional t
argparse-based completion. For an example integrating tab completion with argparse, see argparse_completion.py
"""
import functools
-from typing import List
+from typing import (
+ List,
+)
import cmd2
diff --git a/examples/colors.py b/examples/colors.py
index 8f8e3c6e..dc5bdb99 100755
--- a/examples/colors.py
+++ b/examples/colors.py
@@ -24,12 +24,20 @@ Always
regardless of the output destination
"""
import argparse
-from typing import Any
+from typing import (
+ Any,
+)
-from colorama import Back, Fore, Style
+from colorama import (
+ Back,
+ Fore,
+ Style,
+)
import cmd2
-from cmd2 import ansi
+from cmd2 import (
+ ansi,
+)
class CmdLineApp(cmd2.Cmd):
diff --git a/examples/custom_parser.py b/examples/custom_parser.py
index 34c7bee2..194b47b8 100644
--- a/examples/custom_parser.py
+++ b/examples/custom_parser.py
@@ -4,7 +4,11 @@ Defines the CustomParser used with override_parser.py example
"""
import sys
-from cmd2 import Cmd2ArgumentParser, ansi, set_default_argument_parser
+from cmd2 import (
+ Cmd2ArgumentParser,
+ ansi,
+ set_default_argument_parser,
+)
# First define the parser
diff --git a/examples/decorator_example.py b/examples/decorator_example.py
index 1b6d7570..29fcbd9e 100755
--- a/examples/decorator_example.py
+++ b/examples/decorator_example.py
@@ -11,7 +11,9 @@ all the commands in the transcript against decorator_example.py,
verifying that the output produced matches the transcript.
"""
import argparse
-from typing import List
+from typing import (
+ List,
+)
import cmd2
diff --git a/examples/default_categories.py b/examples/default_categories.py
index 19699513..efa6729d 100644
--- a/examples/default_categories.py
+++ b/examples/default_categories.py
@@ -5,7 +5,10 @@ Simple example demonstrating basic CommandSet usage.
"""
import cmd2
-from cmd2 import CommandSet, with_default_category
+from cmd2 import (
+ CommandSet,
+ with_default_category,
+)
@with_default_category('Default Category')
diff --git a/examples/dynamic_commands.py b/examples/dynamic_commands.py
index 620acb7f..35c2cd42 100755
--- a/examples/dynamic_commands.py
+++ b/examples/dynamic_commands.py
@@ -5,7 +5,10 @@
import functools
import cmd2
-from cmd2.constants import COMMAND_FUNC_PREFIX, HELP_FUNC_PREFIX
+from cmd2.constants import (
+ COMMAND_FUNC_PREFIX,
+ HELP_FUNC_PREFIX,
+)
COMMAND_LIST = ['foo', 'bar']
CATEGORY = 'Dynamic Commands'
diff --git a/examples/exit_code.py b/examples/exit_code.py
index 89ed86cd..062ee12d 100755
--- a/examples/exit_code.py
+++ b/examples/exit_code.py
@@ -2,7 +2,9 @@
# coding=utf-8
"""A simple example demonstrating the following how to emit a non-zero exit code in your cmd2 application.
"""
-from typing import List
+from typing import (
+ List,
+)
import cmd2
diff --git a/examples/hello_cmd2.py b/examples/hello_cmd2.py
index 94ec334f..06303722 100755
--- a/examples/hello_cmd2.py
+++ b/examples/hello_cmd2.py
@@ -3,7 +3,9 @@
"""
This is intended to be a completely bare-bones cmd2 application suitable for rapid testing and debugging.
"""
-from cmd2 import cmd2
+from cmd2 import (
+ cmd2,
+)
if __name__ == '__main__':
import sys
diff --git a/examples/help_categories.py b/examples/help_categories.py
index 7401bafe..0b25375a 100755
--- a/examples/help_categories.py
+++ b/examples/help_categories.py
@@ -8,7 +8,9 @@ It also demonstrates the effects of decorator order when it comes to argparse er
import functools
import cmd2
-from cmd2 import COMMAND_NAME
+from cmd2 import (
+ COMMAND_NAME,
+)
def my_decorator(f):
diff --git a/examples/hooks.py b/examples/hooks.py
index f8079e58..8acbf91b 100755
--- a/examples/hooks.py
+++ b/examples/hooks.py
@@ -10,7 +10,9 @@ follow a command without any intervening whitespace.
"""
import re
-from typing import List
+from typing import (
+ List,
+)
import cmd2
diff --git a/examples/initialization.py b/examples/initialization.py
index 50bb73aa..76a136dd 100755
--- a/examples/initialization.py
+++ b/examples/initialization.py
@@ -13,7 +13,11 @@
10) How to make custom attributes settable at runtime
"""
import cmd2
-from cmd2 import bg, fg, style
+from cmd2 import (
+ bg,
+ fg,
+ style,
+)
class BasicApp(cmd2.Cmd):
diff --git a/examples/modular_commands/commandset_basic.py b/examples/modular_commands/commandset_basic.py
index 9c94e01e..17b86186 100644
--- a/examples/modular_commands/commandset_basic.py
+++ b/examples/modular_commands/commandset_basic.py
@@ -2,9 +2,18 @@
"""
A simple example demonstrating a loadable command set
"""
-from typing import List
-
-from cmd2 import Cmd, CommandSet, CompletionError, Statement, with_category, with_default_category
+from typing import (
+ List,
+)
+
+from cmd2 import (
+ Cmd,
+ CommandSet,
+ CompletionError,
+ Statement,
+ with_category,
+ with_default_category,
+)
@with_default_category('Basic Completion')
diff --git a/examples/modular_commands/commandset_complex.py b/examples/modular_commands/commandset_complex.py
index 94f8b5f4..f8d9dca9 100644
--- a/examples/modular_commands/commandset_complex.py
+++ b/examples/modular_commands/commandset_complex.py
@@ -5,7 +5,9 @@ Test CommandSet
"""
import argparse
-from typing import List
+from typing import (
+ List,
+)
import cmd2
diff --git a/examples/modular_commands/commandset_custominit.py b/examples/modular_commands/commandset_custominit.py
index 2ef94a75..e24ac291 100644
--- a/examples/modular_commands/commandset_custominit.py
+++ b/examples/modular_commands/commandset_custominit.py
@@ -2,7 +2,12 @@
"""
A simple example demonstrating a loadable command set
"""
-from cmd2 import Cmd, CommandSet, Statement, with_default_category
+from cmd2 import (
+ Cmd,
+ CommandSet,
+ Statement,
+ with_default_category,
+)
@with_default_category('Custom Init')
diff --git a/examples/modular_commands_basic.py b/examples/modular_commands_basic.py
index b9d4c4a2..4d5f83ce 100644
--- a/examples/modular_commands_basic.py
+++ b/examples/modular_commands_basic.py
@@ -5,7 +5,10 @@ Simple example demonstrating basic CommandSet usage.
"""
import cmd2
-from cmd2 import CommandSet, with_default_category
+from cmd2 import (
+ CommandSet,
+ with_default_category,
+)
@with_default_category('My Category')
diff --git a/examples/modular_commands_dynamic.py b/examples/modular_commands_dynamic.py
index b2be5dd1..8264c068 100644
--- a/examples/modular_commands_dynamic.py
+++ b/examples/modular_commands_dynamic.py
@@ -10,8 +10,14 @@ on which CommandSets are loaded
"""
import argparse
+
import cmd2
-from cmd2 import CommandSet, with_argparser, with_category, with_default_category
+from cmd2 import (
+ CommandSet,
+ with_argparser,
+ with_category,
+ with_default_category,
+)
@with_default_category('Fruits')
diff --git a/examples/modular_commands_main.py b/examples/modular_commands_main.py
index 1b0ec64d..2559544a 100644
--- a/examples/modular_commands_main.py
+++ b/examples/modular_commands_main.py
@@ -5,13 +5,27 @@ A complex example demonstrating a variety of methods to load CommandSets using a
with examples of how to integrate tab completion with argparse-based commands.
"""
import argparse
-from typing import Iterable, List, Optional
+from typing import (
+ Iterable,
+ List,
+ Optional,
+)
-from modular_commands.commandset_basic import BasicCompletionCommandSet # noqa: F401
-from modular_commands.commandset_complex import CommandSetA # noqa: F401
-from modular_commands.commandset_custominit import CustomInitCommandSet # noqa: F401
-
-from cmd2 import Cmd, Cmd2ArgumentParser, CommandSet, with_argparser
+from cmd2 import (
+ Cmd,
+ Cmd2ArgumentParser,
+ CommandSet,
+ with_argparser,
+)
+from modular_commands.commandset_basic import ( # noqa: F401
+ BasicCompletionCommandSet,
+)
+from modular_commands.commandset_complex import ( # noqa: F401
+ CommandSetA,
+)
+from modular_commands.commandset_custominit import (
+ CustomInitCommandSet, # noqa: F401
+)
class WithCommandSets(Cmd):
diff --git a/examples/modular_subcommands.py b/examples/modular_subcommands.py
index c1d499f0..082903fb 100644
--- a/examples/modular_subcommands.py
+++ b/examples/modular_subcommands.py
@@ -11,8 +11,14 @@ The `load` and `unload` command will load and unload the CommandSets. The availa
subcommands to the `cut` command will change depending on which CommandSets are loaded.
"""
import argparse
+
import cmd2
-from cmd2 import CommandSet, with_argparser, with_category, with_default_category
+from cmd2 import (
+ CommandSet,
+ with_argparser,
+ with_category,
+ with_default_category,
+)
@with_default_category('Fruits')
diff --git a/examples/override_parser.py b/examples/override_parser.py
index b6548388..b723f6d7 100755
--- a/examples/override_parser.py
+++ b/examples/override_parser.py
@@ -13,7 +13,9 @@ import argparse
# Next import stuff from cmd2. It will import your module just before the cmd2.Cmd class file is imported
# and therefore override the parser class it uses on its commands.
-from cmd2 import cmd2
+from cmd2 import (
+ cmd2,
+)
argparse.cmd2_parser_module = 'examples.custom_parser'
diff --git a/examples/paged_output.py b/examples/paged_output.py
index cba5c7c5..191fdd7f 100755
--- a/examples/paged_output.py
+++ b/examples/paged_output.py
@@ -3,7 +3,9 @@
"""A simple example demonstrating the using paged output via the ppaged() method.
"""
import os
-from typing import List
+from typing import (
+ List,
+)
import cmd2
diff --git a/examples/pirate.py b/examples/pirate.py
index a50f9a51..ab2403be 100755
--- a/examples/pirate.py
+++ b/examples/pirate.py
@@ -10,7 +10,9 @@ import argparse
import cmd2
import cmd2.ansi
-from cmd2.constants import MULTILINE_TERMINATOR
+from cmd2.constants import (
+ MULTILINE_TERMINATOR,
+)
class Pirate(cmd2.Cmd):
diff --git a/examples/plumbum_colors.py b/examples/plumbum_colors.py
index a30e4c70..ec138e89 100755
--- a/examples/plumbum_colors.py
+++ b/examples/plumbum_colors.py
@@ -28,8 +28,13 @@ WARNING: This example requires the plumbum package, which isn't normally require
import argparse
import cmd2
-from cmd2 import ansi
-from plumbum.colors import bg, fg
+from cmd2 import (
+ ansi,
+)
+from plumbum.colors import (
+ bg,
+ fg,
+)
class FgColors(ansi.ColorBase):
diff --git a/examples/python_scripting.py b/examples/python_scripting.py
index 6e4295d4..5d3f43b3 100755
--- a/examples/python_scripting.py
+++ b/examples/python_scripting.py
@@ -24,7 +24,9 @@ import argparse
import os
import cmd2
-from cmd2 import ansi
+from cmd2 import (
+ ansi,
+)
class CmdLineApp(cmd2.Cmd):
diff --git a/examples/scripts/save_help_text.py b/examples/scripts/save_help_text.py
index cc4cfcc7..ad028395 100644
--- a/examples/scripts/save_help_text.py
+++ b/examples/scripts/save_help_text.py
@@ -8,7 +8,10 @@ This is meant to be run within a cmd2 session using run_pyscript.
import argparse
import os
import sys
-from typing import List, TextIO
+from typing import (
+ List,
+ TextIO,
+)
ASTERISKS = "********************************************************"
diff --git a/examples/table_creation.py b/examples/table_creation.py
index 6325b200..a290f5df 100755
--- a/examples/table_creation.py
+++ b/examples/table_creation.py
@@ -3,10 +3,21 @@
"""Examples of using the cmd2 table creation API"""
import functools
import sys
-from typing import Any, List
-
-from cmd2 import ansi
-from cmd2.table_creator import AlternatingTable, BorderedTable, Column, HorizontalAlignment, SimpleTable
+from typing import (
+ Any,
+ List,
+)
+
+from cmd2 import (
+ ansi,
+)
+from cmd2.table_creator import (
+ AlternatingTable,
+ BorderedTable,
+ Column,
+ HorizontalAlignment,
+ SimpleTable,
+)
class DollarFormatter:
diff --git a/plugins/ext_test/cmd2_ext_test/__init__.py b/plugins/ext_test/cmd2_ext_test/__init__.py
index 21fd000b..ded8612c 100644
--- a/plugins/ext_test/cmd2_ext_test/__init__.py
+++ b/plugins/ext_test/cmd2_ext_test/__init__.py
@@ -17,7 +17,9 @@ except importlib_metadata.PackageNotFoundError: # pragma: no cover
# package is not installed
__version__ = 'unknown'
-from .cmd2_ext_test import ExternalTestMixin
+from .cmd2_ext_test import (
+ ExternalTestMixin,
+)
__all__ = [
'ExternalTestMixin'
diff --git a/plugins/ext_test/cmd2_ext_test/cmd2_ext_test.py b/plugins/ext_test/cmd2_ext_test/cmd2_ext_test.py
index b1827f02..c176bb78 100644
--- a/plugins/ext_test/cmd2_ext_test/cmd2_ext_test.py
+++ b/plugins/ext_test/cmd2_ext_test/cmd2_ext_test.py
@@ -2,7 +2,10 @@
# coding=utf-8
"""External test interface plugin"""
-from typing import TYPE_CHECKING, Optional
+from typing import (
+ TYPE_CHECKING,
+ Optional,
+)
import cmd2
diff --git a/plugins/ext_test/setup.py b/plugins/ext_test/setup.py
index 3384527c..70b264b5 100644
--- a/plugins/ext_test/setup.py
+++ b/plugins/ext_test/setup.py
@@ -11,15 +11,14 @@ here = os.path.abspath(os.path.dirname(__file__))
with open(os.path.join(here, 'README.md'), encoding='utf-8') as f:
long_description = f.read()
+scm_version = {
+ 'root': '../..',
+ 'git_describe_command': 'git describe --dirty --tags --long --match "plugin-ext-test*"',
+}
+
setuptools.setup(
name='cmd2-ext-test',
- version='0.2.0',
- # TODO: Figure out why this doesn't work on CI Server
- # use_scm_version={
- # 'root': '../..',
- # 'relative_to': __file__,
- # 'git_describe_command': 'git describe --dirty --tags --long --match plugin-ext-test*'
- # },
+ version=scm_version,
description='External test plugin for cmd2. Allows for external invocation of commands as if from a cmd2 pyscript',
long_description=long_description,
@@ -35,7 +34,9 @@ setuptools.setup(
python_requires='>=3.5',
install_requires=['cmd2 >= 0.9.4, <=2'],
- setup_requires=['setuptools_scm >= 3.0'],
+ setup_requires=[
+ 'setuptools >= 42',
+ 'setuptools_scm >= 3.4'],
classifiers=[
'Development Status :: 5 - Production/Stable',
diff --git a/plugins/ext_test/tests/test_ext_test.py b/plugins/ext_test/tests/test_ext_test.py
index b1ba1b7d..d55911c3 100644
--- a/plugins/ext_test/tests/test_ext_test.py
+++ b/plugins/ext_test/tests/test_ext_test.py
@@ -4,7 +4,10 @@
import pytest
import cmd2_ext_test
-from cmd2 import CommandResult, cmd2
+from cmd2 import (
+ CommandResult,
+ cmd2,
+)
######
#
diff --git a/plugins/tasks.py b/plugins/tasks.py
index 1a70e4f2..f198c34e 100644
--- a/plugins/tasks.py
+++ b/plugins/tasks.py
@@ -10,8 +10,12 @@ Make sure you satisfy the following Python module requirements if you are trying
"""
import invoke
-from plugins.ext_test import tasks as ext_test_tasks
-from plugins.template import tasks as template_tasks
+from plugins.ext_test import (
+ tasks as ext_test_tasks,
+)
+from plugins.template import (
+ tasks as template_tasks,
+)
# create namespaces
namespace = invoke.Collection(ext_test=ext_test_tasks,
diff --git a/plugins/template/cmd2_myplugin/__init__.py b/plugins/template/cmd2_myplugin/__init__.py
index 838d828a..daa20e71 100644
--- a/plugins/template/cmd2_myplugin/__init__.py
+++ b/plugins/template/cmd2_myplugin/__init__.py
@@ -5,7 +5,10 @@
An overview of what myplugin does.
"""
-from .myplugin import MyPluginMixin, empty_decorator # noqa: F401
+from .myplugin import ( # noqa: F401
+ MyPluginMixin,
+ empty_decorator,
+)
try:
# For python 3.8 and later
diff --git a/plugins/template/cmd2_myplugin/myplugin.py b/plugins/template/cmd2_myplugin/myplugin.py
index 816198b0..c0467366 100644
--- a/plugins/template/cmd2_myplugin/myplugin.py
+++ b/plugins/template/cmd2_myplugin/myplugin.py
@@ -3,7 +3,10 @@
"""An example cmd2 plugin"""
import functools
-from typing import TYPE_CHECKING, Callable
+from typing import (
+ TYPE_CHECKING,
+ Callable,
+)
import cmd2
diff --git a/plugins/template/tests/test_myplugin.py b/plugins/template/tests/test_myplugin.py
index d61181a6..a61490ca 100644
--- a/plugins/template/tests/test_myplugin.py
+++ b/plugins/template/tests/test_myplugin.py
@@ -2,7 +2,9 @@
# coding=utf-8
import cmd2_myplugin
-from cmd2 import cmd2
+from cmd2 import (
+ cmd2,
+)
######
#
diff --git a/setup.cfg b/setup.cfg
index a2b178bd..39e6ab81 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -8,7 +8,7 @@ max-line-length = 127
max-complexity = 26
[isort]
-line_length=127
+line_length=1
skip=cmd2/__init__.py
multi_line_output = 3
include_trailing_comma = true
diff --git a/setup.py b/setup.py
index 123a045f..46a2ad05 100755
--- a/setup.py
+++ b/setup.py
@@ -5,7 +5,9 @@ Setuptools setup file, used to install or test 'cmd2'
"""
import codecs
-from setuptools import setup
+from setuptools import (
+ setup,
+)
DESCRIPTION = "cmd2 - quickly build feature-rich and user-friendly interactive command line applications in Python"
diff --git a/tasks.py b/tasks.py
index 2bc7f7fb..4bc4540e 100644
--- a/tasks.py
+++ b/tasks.py
@@ -16,7 +16,9 @@ import sys
import invoke
-from plugins import tasks as plugin_tasks
+from plugins import (
+ tasks as plugin_tasks,
+)
TASK_ROOT = pathlib.Path(__file__).resolve().parent
TASK_ROOT_STR = str(TASK_ROOT)
@@ -96,7 +98,7 @@ namespace_clean.add_task(pytest_clean, 'pytest')
def mypy(context):
"""Run mypy optional static type checker"""
with context.cd(TASK_ROOT_STR):
- context.run("mypy main.py")
+ context.run("mypy cmd2")
namespace.add_task(mypy)
diff --git a/tests/conftest.py b/tests/conftest.py
index 73080b5c..c0b9e385 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -3,14 +3,27 @@
Cmd2 unit/functional testing
"""
import sys
-from contextlib import redirect_stderr, redirect_stdout
-from typing import List, Optional, Union
-from unittest import mock
-
-from pytest import fixture
+from contextlib import (
+ redirect_stderr,
+ redirect_stdout,
+)
+from typing import (
+ List,
+ Optional,
+ Union,
+)
+from unittest import (
+ mock,
+)
+
+from pytest import (
+ fixture,
+)
import cmd2
-from cmd2.utils import StdSim
+from cmd2.utils import (
+ StdSim,
+)
# Prefer statically linked gnureadline if available (for macOS compatibility due to issues with libedit)
try:
diff --git a/tests/test_argparse.py b/tests/test_argparse.py
index 7059e9d3..e7806056 100644
--- a/tests/test_argparse.py
+++ b/tests/test_argparse.py
@@ -4,13 +4,17 @@
Cmd2 testing for argument parsing
"""
import argparse
-from typing import Optional
+from typing import (
+ Optional,
+)
import pytest
import cmd2
-from .conftest import run_cmd
+from .conftest import (
+ run_cmd,
+)
# Prefer statically linked gnureadline if available (for macOS compatibility due to issues with libedit)
try:
@@ -457,4 +461,3 @@ def test_pytest_mock_invalid(mocker):
def test_pytest_mock_valid(mocker, spec_param):
mocker.patch.object(ArgparseApp, 'namespace_provider', **spec_param)
app = ArgparseApp()
-
diff --git a/tests/test_argparse_completer.py b/tests/test_argparse_completer.py
index 5c579b5c..25c7a03a 100644
--- a/tests/test_argparse_completer.py
+++ b/tests/test_argparse_completer.py
@@ -5,14 +5,27 @@ Unit/functional testing for argparse completer in cmd2
"""
import argparse
import numbers
-from typing import List
+from typing import (
+ List,
+)
import pytest
import cmd2
-from cmd2 import Cmd2ArgumentParser, CompletionError, CompletionItem, with_argparser
-from cmd2.utils import StdSim
-from .conftest import complete_tester, run_cmd
+from cmd2 import (
+ Cmd2ArgumentParser,
+ CompletionError,
+ CompletionItem,
+ with_argparser,
+)
+from cmd2.utils import (
+ StdSim,
+)
+
+from .conftest import (
+ complete_tester,
+ run_cmd,
+)
# Data and functions for testing standalone choice_provider and completer
standalone_choices = ['standalone', 'provider']
diff --git a/tests/test_argparse_custom.py b/tests/test_argparse_custom.py
index 3d41fffd..0820f215 100644
--- a/tests/test_argparse_custom.py
+++ b/tests/test_argparse_custom.py
@@ -7,10 +7,17 @@ import argparse
import pytest
import cmd2
-from cmd2 import Cmd2ArgumentParser, constants
-from cmd2.argparse_custom import generate_range_error
-
-from .conftest import run_cmd
+from cmd2 import (
+ Cmd2ArgumentParser,
+ constants,
+)
+from cmd2.argparse_custom import (
+ generate_range_error,
+)
+
+from .conftest import (
+ run_cmd,
+)
class ApCustomTestApp(cmd2.Cmd):
diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py
index 97e10f52..f9109a23 100755
--- a/tests/test_cmd2.py
+++ b/tests/test_cmd2.py
@@ -9,12 +9,22 @@ import io
import os
import sys
import tempfile
-from code import InteractiveConsole
+from code import (
+ InteractiveConsole,
+)
import pytest
import cmd2
-from cmd2 import COMMAND_NAME, ansi, clipboard, constants, exceptions, plugin, utils
+from cmd2 import (
+ COMMAND_NAME,
+ ansi,
+ clipboard,
+ constants,
+ exceptions,
+ plugin,
+ utils,
+)
from .conftest import (
HELP_HISTORY,
@@ -47,6 +57,7 @@ def outsim_app():
def test_version(base_app):
assert cmd2.__version__
+@pytest.mark.skipif(sys.version_info >= (3, 8), reason="failing in CI systems for Python 3.8 and 3.9")
def test_not_in_main_thread(base_app, capsys):
import threading
cli_thread = threading.Thread(name='cli_thread', target=base_app.cmdloop)
diff --git a/tests/test_completion.py b/tests/test_completion.py
index a9f2a51b..2f4e34c3 100755
--- a/tests/test_completion.py
+++ b/tests/test_completion.py
@@ -20,9 +20,18 @@ import sys
import pytest
import cmd2
-from cmd2 import utils
-from examples.subcommands import SubcommandsExample
-from .conftest import complete_tester, normalize, run_cmd
+from cmd2 import (
+ utils,
+)
+from examples.subcommands import (
+ SubcommandsExample,
+)
+
+from .conftest import (
+ complete_tester,
+ normalize,
+ run_cmd,
+)
# List of strings used with completion functions
food_item_strs = ['Pizza', 'Ham', 'Ham Sandwich', 'Potato', 'Cheese "Pizza"']
diff --git a/tests/test_history.py b/tests/test_history.py
index 86c52592..29ca020a 100755
--- a/tests/test_history.py
+++ b/tests/test_history.py
@@ -11,9 +11,15 @@ import pytest
import cmd2
# Python 3.5 had some regressions in the unitest.mock module, so use
# 3rd party mock if available
-from cmd2.parsing import StatementParser
-
-from .conftest import HELP_HISTORY, normalize, run_cmd
+from cmd2.parsing import (
+ StatementParser,
+)
+
+from .conftest import (
+ HELP_HISTORY,
+ normalize,
+ run_cmd,
+)
try:
import mock
diff --git a/tests/test_parsing.py b/tests/test_parsing.py
index 2eccec7c..abf8b9fd 100755
--- a/tests/test_parsing.py
+++ b/tests/test_parsing.py
@@ -7,8 +7,15 @@ import attr
import pytest
import cmd2
-from cmd2 import constants, exceptions, utils
-from cmd2.parsing import StatementParser, shlex_split
+from cmd2 import (
+ constants,
+ exceptions,
+ utils,
+)
+from cmd2.parsing import (
+ StatementParser,
+ shlex_split,
+)
@pytest.fixture
diff --git a/tests/test_plugin.py b/tests/test_plugin.py
index 279f2f79..4a019b15 100644
--- a/tests/test_plugin.py
+++ b/tests/test_plugin.py
@@ -9,7 +9,12 @@ import sys
import pytest
import cmd2
-from cmd2 import Cmd2ArgumentParser, exceptions, plugin, with_argparser
+from cmd2 import (
+ Cmd2ArgumentParser,
+ exceptions,
+ plugin,
+ with_argparser,
+)
# Python 3.5 had some regressions in the unitest.mock module, so use 3rd party mock if available
try:
diff --git a/tests/test_run_pyscript.py b/tests/test_run_pyscript.py
index 8cfd8578..a46a3ca3 100644
--- a/tests/test_run_pyscript.py
+++ b/tests/test_run_pyscript.py
@@ -8,9 +8,15 @@ import os
import pytest
-from cmd2 import plugin, utils
-
-from .conftest import odd_file_names, run_cmd
+from cmd2 import (
+ plugin,
+ utils,
+)
+
+from .conftest import (
+ odd_file_names,
+ run_cmd,
+)
# Python 3.5 had some regressions in the unitest.mock module, so use 3rd party mock if available
try:
diff --git a/tests/test_table_creator.py b/tests/test_table_creator.py
index 0d2edfb2..58dd6fdf 100644
--- a/tests/test_table_creator.py
+++ b/tests/test_table_creator.py
@@ -5,7 +5,9 @@ Unit testing for cmd2/table_creator.py module
"""
import pytest
-from cmd2 import ansi
+from cmd2 import (
+ ansi,
+)
from cmd2.table_creator import (
AlternatingTable,
BorderedTable,
diff --git a/tests/test_transcript.py b/tests/test_transcript.py
index 55d60e18..1b9c71fe 100644
--- a/tests/test_transcript.py
+++ b/tests/test_transcript.py
@@ -9,15 +9,25 @@ import random
import re
import sys
import tempfile
-from unittest import mock
+from unittest import (
+ mock,
+)
import pytest
import cmd2
-from cmd2 import transcript
-from cmd2.utils import Settable, StdSim
-
-from .conftest import run_cmd, verify_help_text
+from cmd2 import (
+ transcript,
+)
+from cmd2.utils import (
+ Settable,
+ StdSim,
+)
+
+from .conftest import (
+ run_cmd,
+ verify_help_text,
+)
class CmdLineApp(cmd2.Cmd):
diff --git a/tests/test_utils.py b/tests/test_utils.py
index ab3647e4..e6853570 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -10,13 +10,16 @@ import time
import pytest
+import cmd2.utils as cu
+from cmd2.constants import (
+ HORIZONTAL_ELLIPSIS,
+)
+
try:
import mock
except ImportError:
from unittest import mock
-import cmd2.utils as cu
-from cmd2.constants import HORIZONTAL_ELLIPSIS
HELLO_WORLD = 'Hello, world!'
@@ -641,55 +644,18 @@ def test_str_to_bool_bad_input():
with pytest.raises(ValueError):
cu.str_to_bool(1)
-@mock.patch('cmd2.utils.probe_editors')
-def test_find_editor_specified(mock_probe_editors):
- expected_editor = 'vim'
+def test_find_editor_specified():
+ expected_editor = os.path.join('fake_dir', 'editor')
with mock.patch.dict(os.environ, {'EDITOR': expected_editor}):
editor = cu.find_editor()
assert editor == expected_editor
- mock_probe_editors.assert_not_called()
-
-@pytest.mark.skipif(sys.platform.startswith('win'),
- reason="test 'find_editor' unix codepath")
-def test_find_editor_not_specified_unix():
- expected_editor = 'vim'
- with mock.patch.dict(os.environ, {'EDITOR': ''}):
- with mock.patch(
- 'cmd2.utils.probe_editors',
- return_value=expected_editor
- ) as mock_probe_editors:
- editor = cu.find_editor()
- assert editor == expected_editor
- mock_probe_editors.assert_called_once()
-
-@pytest.mark.skipif(not sys.platform.startswith('win'),
- reason="test 'find_editor' win codepath")
-def test_find_editor_not_specified_win():
- expected_editor = 'notepad'
- with mock.patch.dict(os.environ, {'EDITOR': ''}):
- with mock.patch('cmd2.utils.probe_editors') as mock_probe_editors:
- editor = cu.find_editor()
- assert editor == expected_editor
- mock_probe_editors.assert_not_called()
-
-@pytest.mark.skipif(sys.platform.startswith('win'),
- reason="test 'probe_editors' codepath")
-def test_probe_editors(tmpdir):
- path = tmpdir.mkdir('bin')
- vi_path = str(path.join('vi'))
- with mock.patch.dict(os.environ, {'PATH': str(path)}):
- editor = cu.probe_editors()
- assert not editor
-
- def mock_is_executable(p):
- print(p, vi_path)
- if p == vi_path:
- return True
-
- with mock.patch.dict(os.environ, {'PATH': str(path)}):
- with mock.patch(
- 'cmd2.utils.is_executable',
- mock_is_executable
- ):
- editor = cu.probe_editors()
- assert editor == vi_path
+
+def test_find_editor_not_specified():
+ # Use existing path env setting. Something in the editor list should be found.
+ editor = cu.find_editor()
+ assert editor
+
+ # Overwrite path env setting with invalid path, clear all other env vars so no editor should be found.
+ with mock.patch.dict(os.environ, {'PATH': 'fake_dir'}, clear=True):
+ editor = cu.find_editor()
+ assert editor is None
diff --git a/tests_isolated/test_commandset/conftest.py b/tests_isolated/test_commandset/conftest.py
index 037be199..e6050f8d 100644
--- a/tests_isolated/test_commandset/conftest.py
+++ b/tests_isolated/test_commandset/conftest.py
@@ -3,15 +3,30 @@
Cmd2 unit/functional testing
"""
import sys
-from contextlib import redirect_stderr, redirect_stdout
-from typing import List, Optional, Union
-from unittest import mock
-
-from pytest import fixture
+from contextlib import (
+ redirect_stderr,
+ redirect_stdout,
+)
+from typing import (
+ List,
+ Optional,
+ Union,
+)
+from unittest import (
+ mock,
+)
+
+from pytest import (
+ fixture,
+)
import cmd2
-from cmd2_ext_test import ExternalTestMixin
-from cmd2.utils import StdSim
+from cmd2.utils import (
+ StdSim,
+)
+from cmd2_ext_test import (
+ ExternalTestMixin,
+)
# Prefer statically linked gnureadline if available (for macOS compatibility due to issues with libedit)
try:
diff --git a/tests_isolated/test_commandset/test_argparse_subcommands.py b/tests_isolated/test_commandset/test_argparse_subcommands.py
index bd2bed42..9618a53a 100644
--- a/tests_isolated/test_commandset/test_argparse_subcommands.py
+++ b/tests_isolated/test_commandset/test_argparse_subcommands.py
@@ -9,7 +9,11 @@ import argparse
import pytest
import cmd2
-from .conftest import run_cmd, WithCommandSets
+
+from .conftest import (
+ WithCommandSets,
+ run_cmd,
+)
class SubcommandSet(cmd2.CommandSet):
diff --git a/tests_isolated/test_commandset/test_categories.py b/tests_isolated/test_commandset/test_categories.py
index c266e0d4..905d68a8 100644
--- a/tests_isolated/test_commandset/test_categories.py
+++ b/tests_isolated/test_commandset/test_categories.py
@@ -3,10 +3,15 @@
"""
Simple example demonstrating basic CommandSet usage.
"""
-from typing import Any
+from typing import (
+ Any,
+)
import cmd2
-from cmd2 import CommandSet, with_default_category
+from cmd2 import (
+ CommandSet,
+ with_default_category,
+)
@with_default_category('Default Category')
diff --git a/tests_isolated/test_commandset/test_commandset.py b/tests_isolated/test_commandset/test_commandset.py
index db1065b7..35b7069f 100644
--- a/tests_isolated/test_commandset/test_commandset.py
+++ b/tests_isolated/test_commandset/test_commandset.py
@@ -5,14 +5,24 @@ Test CommandSet
"""
import argparse
-from typing import List
+from typing import (
+ List,
+)
import pytest
import cmd2
-from cmd2 import utils
-from .conftest import complete_tester, WithCommandSets
-from cmd2.exceptions import CommandSetRegistrationError
+from cmd2 import (
+ utils,
+)
+from cmd2.exceptions import (
+ CommandSetRegistrationError,
+)
+
+from .conftest import (
+ WithCommandSets,
+ complete_tester,
+)
class CommandSetBase(cmd2.CommandSet):