summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Leonhardt <todd.leonhardt@gmail.com>2021-02-21 10:04:56 -0500
committerGitHub <noreply@github.com>2021-02-21 10:04:56 -0500
commit9c60ac6f3169f9df37e6c5166844fb9cf5f6766d (patch)
treef96381edfdb6a31585e7ab3e3e05ded9d41731ec
parenta7119e1b26a8bae531b118b7cb8c4b195f731df6 (diff)
parent811a7302eef99b9f67bfcdde3400322b7557dbab (diff)
downloadcmd2-git-9c60ac6f3169f9df37e6c5166844fb9cf5f6766d.tar.gz
Merge pull request #1059 from python-cmd2/deprecate_35
Deprecate support for Python 3.5
-rw-r--r--.github/CONTRIBUTING.md2
-rw-r--r--CHANGELOG.md1
-rwxr-xr-xREADME.md4
-rw-r--r--cmd2/argparse_completer.py2
-rw-r--r--cmd2/cmd2.py36
-rw-r--r--cmd2/command_definition.py2
-rw-r--r--cmd2/table_creator.py21
-rw-r--r--cmd2/utils.py7
-rw-r--r--docs/features/embedded_python_shells.rst7
-rw-r--r--docs/overview/installation.rst4
-rw-r--r--plugins/ext_test/build-pyenvs.sh2
-rw-r--r--plugins/ext_test/noxfile.py2
-rw-r--r--plugins/ext_test/setup.py5
-rw-r--r--plugins/template/README.md22
-rw-r--r--plugins/template/build-pyenvs.sh2
-rw-r--r--plugins/template/noxfile.py2
-rw-r--r--plugins/template/setup.py7
-rwxr-xr-xsetup.py9
-rwxr-xr-xtests/test_cmd2.py11
-rwxr-xr-xtests/test_completion.py9
-rwxr-xr-xtests/test_history.py16
-rw-r--r--tests/test_plugin.py11
-rw-r--r--tests/test_run_pyscript.py11
23 files changed, 72 insertions, 123 deletions
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 6e5e7b9b..0348621f 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -47,7 +47,7 @@ The tables below list all prerequisites along with the minimum required version
| Prerequisite | Minimum Version |
| --------------------------------------------------- | --------------- |
-| [python](https://www.python.org/downloads/) | `3.5` |
+| [python](https://www.python.org/downloads/) | `3.6` |
| [attrs](https://github.com/python-attrs/attrs) | `16.3` |
| [colorama](https://github.com/tartley/colorama) | `0.3.7` |
| [pyperclip](https://github.com/asweigart/pyperclip) | `1.6` |
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8fe609ed..911df477 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,6 @@
## 2.0.0 (TBD, 2021)
* Breaking changes
+ * `cmd2` 2.0 supports Python 3.6+ (removed support for Python 3.5)
* Argparse Completion / Settables
* Replaced `choices_function` / `choices_method` with `choices_provider`.
* Replaced `completer_function` / `completer_method` with `completer`.
diff --git a/README.md b/README.md
index 6dd4e81e..13ce9410 100755
--- a/README.md
+++ b/README.md
@@ -38,7 +38,7 @@ Main Features
- Unicode character support
- Good tab completion of commands, subcommands, file system paths, and shell commands
- Automatic tab completion of `argparse` flags when using one of the `cmd2` `argparse` decorators
-- Support for Python 3.5+ on Windows, macOS, and Linux
+- Support for Python 3.6+ on Windows, macOS, and Linux
- Trivial to provide built-in help for all commands
- Built-in regression testing framework for your applications (transcript-based testing)
- Transcripts for use with built-in regression can be automatically generated from `history -t` or `run_script -t`
@@ -63,7 +63,7 @@ On all operating systems, the latest stable version of `cmd2` can be installed u
pip install -U cmd2
```
-cmd2 works with Python 3.5+ on Windows, macOS, and Linux. It is pure Python code with few 3rd-party dependencies.
+cmd2 works with Python 3.6+ on Windows, macOS, and Linux. It is pure Python code with few 3rd-party dependencies.
For information on other installation options, see
[Installation Instructions](https://cmd2.readthedocs.io/en/latest/overview/installation.html) in the cmd2
diff --git a/cmd2/argparse_completer.py b/cmd2/argparse_completer.py
index f19e9e2c..fbaa6107 100644
--- a/cmd2/argparse_completer.py
+++ b/cmd2/argparse_completer.py
@@ -507,7 +507,7 @@ class ArgparseCompleter:
matches = self._cmd2_app.basic_complete(text, line, begidx, endidx, match_against)
# Build a dictionary linking actions with their matched flag names
- matched_actions = dict() # type: Dict[argparse.Action, List[str]]
+ matched_actions: Dict[argparse.Action, List[str]] = dict()
for flag in matches:
action = self._flag_to_action[flag]
matched_actions.setdefault(action, [])
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index fd757891..0b198111 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -307,7 +307,7 @@ class Cmd(cmd.Cmd):
self.max_completion_items = 50
# A dictionary mapping settable names to their Settable instance
- self.settables = dict() # type: Dict[str, Settable]
+ self.settables: Dict[str, Settable] = dict()
self.build_settables()
# Use as prompt for multiline commands on the 2nd+ line of input
@@ -327,7 +327,7 @@ class Cmd(cmd.Cmd):
self.exclude_from_history = ['eof', 'history']
# Dictionary of macro names and their values
- self.macros = dict() # type: Dict[str, Macro]
+ self.macros: Dict[str, Macro] = dict()
# Keeps track of typed command history in the Python shell
self._py_history = []
@@ -350,14 +350,14 @@ class Cmd(cmd.Cmd):
self.last_result = None
# Used by run_script command to store current script dir as a LIFO queue to support _relative_run_script command
- self._script_dir = [] # type: List[str]
+ self._script_dir: List[str] = []
# Context manager used to protect critical sections in the main thread from stopping due to a KeyboardInterrupt
self.sigint_protection = utils.ContextFlag()
# If the current command created a process to pipe to, then this will be a ProcReader object.
# Otherwise it will be None. It's used to know when a pipe process can be killed and/or waited upon.
- self._cur_pipe_proc_reader = None # type: Optional[utils.ProcReader]
+ self._cur_pipe_proc_reader: Optional[utils.ProcReader] = None
# Used to keep track of whether we are redirecting or piping output
self._redirecting = False
@@ -381,7 +381,7 @@ class Cmd(cmd.Cmd):
self.broken_pipe_warning = ''
# Commands that will run at the beginning of the command loop
- self._startup_commands = [] # type: List[str]
+ self._startup_commands: List[str] = []
# If a startup script is provided and exists, then execute it in the startup commands
if startup_script:
@@ -393,7 +393,7 @@ class Cmd(cmd.Cmd):
self._startup_commands.append(script_cmd)
# Transcript files to run instead of interactive command loop
- self._transcript_files = None # type: Optional[List[str]]
+ self._transcript_files: Optional[List[str]] = None
# Check for command line args
if allow_cli_args:
@@ -436,7 +436,7 @@ class Cmd(cmd.Cmd):
# Commands that have been disabled from use. This is to support commands that are only available
# during specific states of the application. This dictionary's keys are the command names and its
# values are DisabledCommand objects.
- self.disabled_commands = dict() # type: Dict[str, DisabledCommand]
+ self.disabled_commands: Dict[str, DisabledCommand] = dict()
# If any command has been categorized, then all other commands that haven't been categorized
# will display under this section in the help output.
@@ -494,8 +494,8 @@ class Cmd(cmd.Cmd):
# depends on them and it's possible a module's on_register() method may need to access some.
############################################################################################################
# Load modular commands
- self._installed_command_sets = [] # type: List[CommandSet]
- self._cmd_to_command_sets = {} # type: Dict[str, CommandSet]
+ self._installed_command_sets: List[CommandSet] = []
+ self._cmd_to_command_sets: Dict[str, CommandSet] = {}
if command_sets:
for command_set in command_sets:
self.register_command_set(command_set)
@@ -749,8 +749,8 @@ class Cmd(cmd.Cmd):
# iterate through all matching methods
for method_name, method in methods:
- subcommand_name = getattr(method, constants.SUBCMD_ATTR_NAME) # type: str
- full_command_name = getattr(method, constants.SUBCMD_ATTR_COMMAND) # type: str
+ subcommand_name: str = getattr(method, constants.SUBCMD_ATTR_NAME)
+ full_command_name: str = getattr(method, constants.SUBCMD_ATTR_COMMAND)
subcmd_parser = getattr(method, constants.CMD_ATTR_ARGPARSER)
subcommand_valid, errmsg = self.statement_parser.is_valid_command(subcommand_name, is_subcommand=True)
@@ -2200,7 +2200,7 @@ class Cmd(cmd.Cmd):
# we need to run the finalization hooks
raise EmptyStatement
- redir_saved_state = None # type: Optional[utils.RedirectionSavedState]
+ redir_saved_state: Optional[utils.RedirectionSavedState] = None
try:
# Get sigint protection while we set up redirection
@@ -2489,7 +2489,7 @@ class Cmd(cmd.Cmd):
redir_saved_state = utils.RedirectionSavedState(self.stdout, sys.stdout, self._cur_pipe_proc_reader, self._redirecting)
# The ProcReader for this command
- cmd_pipe_proc_reader = None # type: Optional[utils.ProcReader]
+ cmd_pipe_proc_reader: Optional[utils.ProcReader] = None
if not self.allow_redirection:
# Don't return since we set some state variables at the end of the function
@@ -2727,8 +2727,8 @@ class Cmd(cmd.Cmd):
:raises: any exceptions raised by input() and stdin.readline()
"""
readline_configured = False
- saved_completer = None # type: Optional[Callable]
- saved_history = None # type: Optional[List[str]]
+ saved_completer: Optional[Callable] = None
+ saved_history: Optional[List[str]] = None
def configure_readline():
"""Configure readline tab completion and history"""
@@ -3094,7 +3094,7 @@ class Cmd(cmd.Cmd):
else:
to_list = sorted(self.aliases, key=self.default_sort_key)
- not_found = [] # type: List[str]
+ not_found: List[str] = []
for name in to_list:
if name not in self.aliases:
not_found.append(name)
@@ -3320,7 +3320,7 @@ class Cmd(cmd.Cmd):
else:
to_list = sorted(self.macros, key=self.default_sort_key)
- not_found = [] # type: List[str]
+ not_found: List[str] = []
for name in to_list:
if name not in self.macros:
not_found.append(name)
@@ -5135,7 +5135,7 @@ class Cmd(cmd.Cmd):
else:
# Search all registered CommandSets
func_self = None
- candidate_sets = [] # type: List[CommandSet]
+ candidate_sets: List[CommandSet] = []
for installed_cmd_set in self._installed_command_sets:
if type(installed_cmd_set) == func_class:
# Case 2: CommandSet is an exact type match for the function's CommandSet
diff --git a/cmd2/command_definition.py b/cmd2/command_definition.py
index e319d7f3..654043c8 100644
--- a/cmd2/command_definition.py
+++ b/cmd2/command_definition.py
@@ -89,7 +89,7 @@ class CommandSet(object):
"""
def __init__(self):
- self._cmd = None # type: Optional[cmd2.Cmd]
+ self._cmd: Optional[cmd2.Cmd] = None
def on_register(self, cmd) -> None:
"""
diff --git a/cmd2/table_creator.py b/cmd2/table_creator.py
index 3a3892b8..8dcd80f0 100644
--- a/cmd2/table_creator.py
+++ b/cmd2/table_creator.py
@@ -16,6 +16,7 @@ from enum import (
)
from typing import (
Any,
+ Deque,
Optional,
Sequence,
Tuple,
@@ -32,26 +33,6 @@ from . import (
utils,
)
-# This is needed for compatibility with early versions of Python 3.5 prior to 3.5.4
-try:
- from typing import (
- Deque,
- )
-except ImportError: # pragma: no cover
- import typing
-
- # The following copied from the implementation of Deque in Python 3.5.4
- # noinspection PyProtectedMember, PyUnresolvedReferences
- class Deque(deque, typing.MutableSequence[typing.T]):
- __slots__ = ()
- __extra__ = deque
-
- def __new__(cls, *args, **kwds):
- if typing._geqv(cls, Deque):
- raise TypeError('Type Deque cannot be instantiated; use deque() instead')
- return typing._generic_new(deque, cls, *args, **kwds)
-
-
# Constants
EMPTY = ''
SPACE = ' '
diff --git a/cmd2/utils.py b/cmd2/utils.py
index 9920ad64..3f928e5f 100644
--- a/cmd2/utils.py
+++ b/cmd2/utils.py
@@ -1049,20 +1049,15 @@ def categorize(func: Union[Callable, Iterable[Callable]], category: str) -> None
setattr(func, constants.CMD_ATTR_HELP_CATEGORY, category)
-def get_defining_class(meth) -> Type:
+def get_defining_class(meth: Callable) -> Optional[Type]:
"""
Attempts to resolve the class that defined a method.
Inspired by implementation published here:
https://stackoverflow.com/a/25959545/1956611
- TODO: Python 3.5.2 is unable to handle the type hints Callable and Optional[Type].
- Restore proper type hints after we drop 3.5.2 support
-
:param meth: method to inspect
- :type meth: Callable
:return: class type in which the supplied method was defined. None if it couldn't be resolved.
- :rtype: Optional[Type]
"""
if isinstance(meth, functools.partial):
return get_defining_class(meth.func)
diff --git a/docs/features/embedded_python_shells.rst b/docs/features/embedded_python_shells.rst
index 70765b21..8ff65ffe 100644
--- a/docs/features/embedded_python_shells.rst
+++ b/docs/features/embedded_python_shells.rst
@@ -28,9 +28,12 @@ More Python examples:
(Cmd) py print("-".join("spelling"))
s-p-e-l-l-i-n-g
(Cmd) py
- Python 3.5.3 (default, Jan 19 2017, 14:11:04)
- [GCC 6.3.0 20170118] on linux
+ Python 3.9.0 (default, Nov 11 2020, 21:21:51)
+ [Clang 12.0.0 (clang-1200.0.32.21)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
+
+ End with `Ctrl-D` (Unix) / `Ctrl-Z` (Windows), `quit()`, `exit()`.
+ Non-Python commands can be issued with: app("your command")
(CmdLineApp)
End with `Ctrl-D` (Unix) / `Ctrl-Z` (Windows), `quit()`, `exit()`.
diff --git a/docs/overview/installation.rst b/docs/overview/installation.rst
index 6080fe90..a98fef52 100644
--- a/docs/overview/installation.rst
+++ b/docs/overview/installation.rst
@@ -7,7 +7,7 @@ Installation Instructions
.. _setuptools: https://pypi.org/project/setuptools
.. _PyPI: https://pypi.org
-``cmd2`` works on Linux, macOS, and Windows. It requires Python 3.5 or
+``cmd2`` works on Linux, macOS, and Windows. It requires Python 3.6 or
higher, pip_, and setuptools_. If you've got all that, then you can just:
.. code-block:: shell
@@ -30,7 +30,7 @@ higher, pip_, and setuptools_. If you've got all that, then you can just:
Prerequisites
-------------
-If you have Python 3 >=3.5 installed from `python.org
+If you have Python 3 >=3.6 installed from `python.org
<https://www.python.org>`_, you will already have pip_ and setuptools_, but may
need to upgrade to the latest versions:
diff --git a/plugins/ext_test/build-pyenvs.sh b/plugins/ext_test/build-pyenvs.sh
index 39c28aa1..d64e11bd 100644
--- a/plugins/ext_test/build-pyenvs.sh
+++ b/plugins/ext_test/build-pyenvs.sh
@@ -23,7 +23,7 @@
# virtualenvs will be added to '.python-version'. Feel free to modify
# this list, but note that this script intentionally won't install
# dev, rc, or beta python releases
-declare -a pythons=("3.7" "3.6" "3.5" "3.4")
+declare -a pythons=("3.7" "3.6" "3.8" "3.9")
# function to find the latest patch of a minor version of python
function find_latest_version {
diff --git a/plugins/ext_test/noxfile.py b/plugins/ext_test/noxfile.py
index 85411106..75eab841 100644
--- a/plugins/ext_test/noxfile.py
+++ b/plugins/ext_test/noxfile.py
@@ -1,7 +1,7 @@
import nox
-@nox.session(python=['3.5', '3.6', '3.7', '3.8', '3.9'])
+@nox.session(python=['3.6', '3.7', '3.8', '3.9'])
def tests(session):
session.install('invoke', './[test]')
session.run('invoke', 'pytest', '--junit', '--no-pty')
diff --git a/plugins/ext_test/setup.py b/plugins/ext_test/setup.py
index 7dc55f6a..cab366b8 100644
--- a/plugins/ext_test/setup.py
+++ b/plugins/ext_test/setup.py
@@ -33,7 +33,7 @@ setuptools.setup(
license='MIT',
package_data=PACKAGE_DATA,
packages=['cmd2_ext_test'],
- python_requires='>=3.5',
+ python_requires='>=3.6',
install_requires=['cmd2 >= 0.9.4, <=2'],
setup_requires=['setuptools >= 42', 'setuptools_scm >= 3.4'],
classifiers=[
@@ -43,12 +43,11 @@ setuptools.setup(
'Topic :: Software Development :: Libraries :: Python Modules',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
- 'Programming Language :: Python :: 3.4',
- 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
],
# dependencies for development and testing
# $ pip install -e .[dev]
diff --git a/plugins/template/README.md b/plugins/template/README.md
index 1944f1c7..904b0541 100644
--- a/plugins/template/README.md
+++ b/plugins/template/README.md
@@ -235,15 +235,15 @@ $ pyenv install 3.7.0
$ pyenv virtualenv -p python3.7 3.7.0 cmd2-3.7
$ pyenv install 3.6.5
$ pyenv virtualenv -p python3.6 3.6.5 cmd2-3.6
-$ pyenv install 3.5.5
-$ pyenv virtualenv -p python3.5 3.5.5 cmd2-3.5
-$ pyenv install 3.4.8
-$ pyenv virtualenv -p python3.4 3.4.8 cmd2-3.4
+$ pyenv install 3.8.5
+$ pyenv virtualenv -p python3.8 3.8.5 cmd2-3.8
+$ pyenv install 3.9.0
+$ pyenv virtualenv -p python3.9 3.9.0 cmd2-3.9
```
Now set pyenv to make all three of those available at the same time:
```
-$ pyenv local cmd2-3.7 cmd2-3.6 cmd2-3.5 cmd2-3.4
+$ pyenv local cmd2-3.7 cmd2-3.6 cmd2-3.8 cmd2-3.9
```
Whether you ran the script, or did it by hand, you now have isolated virtualenvs
@@ -257,14 +257,14 @@ utilize.
| `python3` | 3.7.0 | cmd2-3.6 |
| `python3.7` | 3.7.0 | cmd2-3.7 |
| `python3.6` | 3.6.5 | cmd2-3.6 |
-| `python3.5` | 3.5.5 | cmd2-3.5 |
-| `python3.4` | 3.4.8 | cmd2-3.4 |
+| `python3.8` | 3.8.5 | cmd2-3.8 |
+| `python3.9` | 3.9.0 | cmd2-3.9 |
| `pip` | 3.7.0 | cmd2-3.6 |
| `pip3` | 3.7.0 | cmd2-3.6 |
| `pip3.7` | 3.7.0 | cmd2-3.7 |
| `pip3.6` | 3.6.5 | cmd2-3.6 |
-| `pip3.5` | 3.5.5 | cmd2-3.5 |
-| `pip3.4` | 3.4.8 | cmd2-3.4 |
+| `pip3.8` | 3.8.5 | cmd2-3.8 |
+| `pip3.9` | 3.9.0 | cmd2-3.9 |
## Install Dependencies
@@ -298,8 +298,8 @@ unit tests found in the `tests` directory.
### Use nox to run unit tests in multiple versions of python
-The included `noxfile.py` is setup to run the unit tests in python 3.4, 3.5, 3.6,
-and 3.7. You can run your unit tests in all of these versions of python by:
+The included `noxfile.py` is setup to run the unit tests in python 3.6, 3.7, 3.8,
+and 3.9. You can run your unit tests in all of these versions of python by:
```
$ nox
```
diff --git a/plugins/template/build-pyenvs.sh b/plugins/template/build-pyenvs.sh
index 39c28aa1..d64e11bd 100644
--- a/plugins/template/build-pyenvs.sh
+++ b/plugins/template/build-pyenvs.sh
@@ -23,7 +23,7 @@
# virtualenvs will be added to '.python-version'. Feel free to modify
# this list, but note that this script intentionally won't install
# dev, rc, or beta python releases
-declare -a pythons=("3.7" "3.6" "3.5" "3.4")
+declare -a pythons=("3.7" "3.6" "3.8" "3.9")
# function to find the latest patch of a minor version of python
function find_latest_version {
diff --git a/plugins/template/noxfile.py b/plugins/template/noxfile.py
index 85411106..75eab841 100644
--- a/plugins/template/noxfile.py
+++ b/plugins/template/noxfile.py
@@ -1,7 +1,7 @@
import nox
-@nox.session(python=['3.5', '3.6', '3.7', '3.8', '3.9'])
+@nox.session(python=['3.6', '3.7', '3.8', '3.9'])
def tests(session):
session.install('invoke', './[test]')
session.run('invoke', 'pytest', '--junit', '--no-pty')
diff --git a/plugins/template/setup.py b/plugins/template/setup.py
index fa3f5135..eea51e1f 100644
--- a/plugins/template/setup.py
+++ b/plugins/template/setup.py
@@ -24,7 +24,7 @@ setuptools.setup(
url='https://github.com/python-cmd2/cmd2-plugin-template',
license='MIT',
packages=['cmd2_myplugin'],
- python_requires='>=3.4',
+ python_requires='>=3.6',
install_requires=['cmd2 >= 0.9.4, <=2'],
setup_requires=['setuptools_scm'],
classifiers=[
@@ -34,10 +34,11 @@ setuptools.setup(
'Topic :: Software Development :: Libraries :: Python Modules',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
- 'Programming Language :: Python :: 3.4',
- 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
],
# dependencies for development and testing
# $ pip install -e .[dev]
diff --git a/setup.py b/setup.py
index 9867b87b..c9a97077 100755
--- a/setup.py
+++ b/setup.py
@@ -28,11 +28,11 @@ Intended Audience :: System Administrators
License :: OSI Approved :: MIT License
Programming Language :: Python
Programming Language :: Python :: 3
-Programming Language :: Python :: 3.5
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
+Programming Language :: Python :: 3.10
Programming Language :: Python :: Implementation :: CPython
Topic :: Software Development :: Libraries :: Python Modules
""".splitlines(),
@@ -57,7 +57,6 @@ EXTRAS_REQUIRE = {
# Extra dependencies for running unit tests
'test': [
"gnureadline; sys_platform=='darwin'", # include gnureadline on macOS to ensure it is available in nox env
- "mock ; python_version<'3.6'", # for python 3.5 we need the third party mock module
'codecov',
'coverage',
'pytest>=4.6',
@@ -66,13 +65,11 @@ EXTRAS_REQUIRE = {
],
# development only dependencies: install with 'pip install -e .[dev]'
'dev': [
- "mock ; python_version<'3.6'", # for python 3.5 we need the third party mock module
"pytest>=4.6",
'codecov',
'pytest-cov',
'pytest-mock',
- "nox==2019.11.9 ; python_version=='3.5.2'",
- "nox ; python_version>'3.5.2'",
+ 'nox',
'flake8',
'sphinx',
'sphinx-rtd-theme',
@@ -102,7 +99,7 @@ setup(
package_data=PACKAGE_DATA,
packages=['cmd2'],
keywords='command prompt console cmd',
- python_requires='>=3.5',
+ python_requires='>=3.6',
setup_requires=SETUP_REQUIRES,
install_requires=INSTALL_REQUIRES,
extras_require=EXTRAS_REQUIRE,
diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py
index e719851e..0c3333c1 100755
--- a/tests/test_cmd2.py
+++ b/tests/test_cmd2.py
@@ -12,6 +12,9 @@ import tempfile
from code import (
InteractiveConsole,
)
+from unittest import (
+ mock,
+)
import pytest
@@ -38,14 +41,6 @@ from .conftest import (
verify_help_text,
)
-# Python 3.5 had some regressions in the unitest.mock module, so use 3rd party mock if available
-try:
- import mock
-except ImportError:
- from unittest import (
- mock,
- )
-
def CreateOutsimApp():
c = cmd2.Cmd()
diff --git a/tests/test_completion.py b/tests/test_completion.py
index 6a6e2eff..0635bb48 100755
--- a/tests/test_completion.py
+++ b/tests/test_completion.py
@@ -6,16 +6,13 @@ Unit/functional testing for readline tab completion functions in the cmd2.py mod
These are primarily tests related to readline completer functions which handle tab completion of cmd2/cmd commands,
file system paths, and shell commands.
"""
-# Python 3.5 had some regressions in the unitest.mock module, so use 3rd party mock if available
-try:
- import mock
-except ImportError:
- from unittest import mock
-
import argparse
import enum
import os
import sys
+from unittest import (
+ mock,
+)
import pytest
diff --git a/tests/test_history.py b/tests/test_history.py
index 6f1336a8..64ec4d28 100755
--- a/tests/test_history.py
+++ b/tests/test_history.py
@@ -5,30 +5,20 @@ Test history functions of cmd2
"""
import os
import tempfile
+from unittest import (
+ mock,
+)
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,
)
-try:
- import mock
-except ImportError:
- from unittest import (
- mock,
- )
-
#
# readline tests
diff --git a/tests/test_plugin.py b/tests/test_plugin.py
index cd1d9ab9..97c046a2 100644
--- a/tests/test_plugin.py
+++ b/tests/test_plugin.py
@@ -5,6 +5,9 @@ Test plugin infrastructure and hooks.
"""
import argparse
import sys
+from unittest import (
+ mock,
+)
import pytest
@@ -16,14 +19,6 @@ from cmd2 import (
with_argparser,
)
-# Python 3.5 had some regressions in the unitest.mock module, so use 3rd party mock if available
-try:
- import mock
-except ImportError:
- from unittest import (
- mock,
- )
-
class Plugin:
"""A mixin class for testing hook registration and calling"""
diff --git a/tests/test_run_pyscript.py b/tests/test_run_pyscript.py
index 2d74a5f0..b8daa24b 100644
--- a/tests/test_run_pyscript.py
+++ b/tests/test_run_pyscript.py
@@ -5,6 +5,9 @@ Unit/functional testing for run_pytest in cmd2
"""
import builtins
import os
+from unittest import (
+ mock,
+)
import pytest
@@ -18,14 +21,6 @@ from .conftest import (
run_cmd,
)
-# Python 3.5 had some regressions in the unitest.mock module, so use 3rd party mock if available
-try:
- import mock
-except ImportError:
- from unittest import (
- mock,
- )
-
HOOK_OUTPUT = "TEST_OUTPUT"