Skip to content

Commit 7ba2349

Browse files
authored
Declare support for Python 3.11 and drop support for Python 3.7 (#275)
1 parent 6049784 commit 7ba2349

17 files changed

+43
-67
lines changed

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ arch:
44
sudo: false
55
language: python
66
python:
7-
- '3.7'
87
- '3.8'
98
- '3.9'
109
- '3.10'
10+
- '3.11'
1111
install: pip install tox-travis
1212
script: tox

azure-pipeline.yml

+4-5
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ jobs:
2020
name: 'pool-ubuntu-2004'
2121
strategy:
2222
matrix:
23-
Python37:
24-
python.version: '3.7'
25-
tox_env: 'py37'
2623
Python38:
2724
python.version: '3.8'
2825
tox_env: 'py38'
@@ -32,6 +29,9 @@ jobs:
3229
Python310:
3330
python.version: '3.10'
3431
tox_env: 'py310'
32+
Python311:
33+
python.version: '3.11'
34+
tox_env: 'py311'
3535
steps:
3636
- task: UsePythonVersion@0
3737
displayName: 'Use Python $(python.version)'
@@ -53,9 +53,8 @@ jobs:
5353
name: 'pool-ubuntu-2004'
5454
steps:
5555
- task: UsePythonVersion@0
56-
displayName: Use Python 3.10
5756
inputs:
58-
versionSpec: 3.10
57+
versionSpec: 3.11
5958
- bash: |
6059
set -ev
6160

knack/cli.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,15 @@ def __init__(self,
104104
def _should_show_version(args):
105105
return args and (args[0] == '--version' or args[0] == '-v')
106106

107-
def get_cli_version(self): # pylint: disable=no-self-use
107+
def get_cli_version(self):
108108
""" Get the CLI Version. Override this to define how to get the CLI version
109109
110110
:return: The CLI version
111111
:rtype: str
112112
"""
113113
return ''
114114

115-
def get_runtime_version(self): # pylint: disable=no-self-use
115+
def get_runtime_version(self):
116116
""" Get the runtime information.
117117
118118
:return: Runtime information
@@ -169,7 +169,7 @@ def raise_event(self, event_name, **kwargs):
169169
for func in handlers:
170170
func(self, **kwargs)
171171

172-
def exception_handler(self, ex): # pylint: disable=no-self-use
172+
def exception_handler(self, ex):
173173
""" The default exception handler """
174174
if isinstance(ex, CLIError):
175175
logger.error(ex)

knack/completion.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def __init__(self, cli_ctx=None):
3434
self.cli_ctx = cli_ctx
3535
self.cli_ctx.data['completer_active'] = ARGCOMPLETE_ENV_NAME in os.environ
3636

37-
def get_completion_args(self, is_completion=False, comp_line=None): # pylint: disable=no-self-use
37+
def get_completion_args(self, is_completion=False, comp_line=None):
3838
""" Get the args that will be used to tab completion if completion is active. """
3939
is_completion = is_completion or os.environ.get(ARGCOMPLETE_ENV_NAME)
4040
comp_line = comp_line or os.environ.get('COMP_LINE')

knack/deprecation.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,10 @@ def _default_get_message(self):
9494
message_func=message_func or _default_get_message
9595
)
9696

97-
# pylint: disable=no-self-use
9897
def _version_less_than_or_equal_to(self, v1, v2):
9998
""" Returns true if v1 <= v2. """
100-
# pylint: disable=no-name-in-module, import-error
101-
from distutils.version import LooseVersion
102-
return LooseVersion(v1) <= LooseVersion(v2)
99+
from packaging.version import parse
100+
return parse(v1) <= parse(v2)
103101

104102
def expired(self):
105103
if self.expiration:

knack/introspection.py

+6-28
Original file line numberDiff line numberDiff line change
@@ -67,45 +67,23 @@ def extract_args_from_signature(operation, excluded_params=None):
6767
""" Extracts basic argument data from an operation's signature and docstring
6868
excluded_params: List of params to ignore and not extract. By default we ignore ['self', 'kwargs'].
6969
"""
70-
args = []
71-
try:
72-
# only supported in python3 - falling back to argspec if not available
73-
sig = inspect.signature(operation)
74-
args = sig.parameters
75-
except AttributeError:
76-
sig = inspect.getargspec(operation) # pylint: disable=deprecated-method, useless-suppression
77-
args = sig.args
70+
sig = inspect.signature(operation)
71+
args = sig.parameters
7872

7973
arg_docstring_help = option_descriptions(operation)
8074
excluded_params = excluded_params or ['self', 'kwargs']
8175

8276
for arg_name in [a for a in args if a not in excluded_params]:
83-
try:
84-
# this works in python3
85-
default = args[arg_name].default
86-
required = default == inspect.Parameter.empty # pylint: disable=no-member, useless-suppression
87-
except TypeError:
88-
arg_defaults = (dict(zip(sig.args[-len(sig.defaults):], sig.defaults))
89-
if sig.defaults
90-
else {})
91-
default = arg_defaults.get(arg_name)
92-
required = arg_name not in arg_defaults
93-
77+
default = args[arg_name].default
78+
required = default == inspect.Parameter.empty
9479
action = 'store_' + str(not default).lower() if isinstance(default, bool) else None
95-
96-
try:
97-
default = (default
98-
if default != inspect._empty # pylint: disable=protected-access
99-
else None)
100-
except AttributeError:
101-
pass
102-
80+
command_argument_default = default if default != inspect.Parameter.empty else None
10381
options_list = ['--' + arg_name.replace('_', '-')]
10482
help_str = arg_docstring_help.get(arg_name)
10583

10684
yield (arg_name, CLICommandArgument(arg_name,
10785
options_list=options_list,
10886
required=required,
109-
default=default,
87+
default=command_argument_default,
11088
help=help_str,
11189
action=action))

knack/invocation.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def __init__(self,
5454
prog=self.cli_ctx.name, parents=[self._global_parser])
5555
self.commands_loader = commands_loader_cls(cli_ctx=self.cli_ctx)
5656

57-
def _filter_params(self, args): # pylint: disable=no-self-use
57+
def _filter_params(self, args):
5858
# Consider - we are using any args that start with an underscore (_) as 'private'
5959
# arguments and remove them from the arguments that we pass to the actual function.
6060
params = {key: value
@@ -88,15 +88,15 @@ def _find_args(args):
8888

8989
return ' '.join(nouns)
9090

91-
def _validate_cmd_level(self, ns, cmd_validator): # pylint: disable=no-self-use
91+
def _validate_cmd_level(self, ns, cmd_validator):
9292
if cmd_validator:
9393
cmd_validator(ns)
9494
try:
9595
delattr(ns, '_command_validator')
9696
except AttributeError:
9797
pass
9898

99-
def _validate_arg_level(self, ns, **_): # pylint: disable=no-self-use
99+
def _validate_arg_level(self, ns, **_):
100100
for validator in getattr(ns, '_argument_validators', []):
101101
validator(ns)
102102
try:

knack/log.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ def _is_file_log_enabled(cli_ctx):
180180

181181
@staticmethod
182182
def _get_log_dir(cli_ctx):
183-
default_dir = (os.path.join(cli_ctx.config.config_dir, 'logs'))
183+
default_dir = os.path.join(cli_ctx.config.config_dir, 'logs')
184184
return os.path.expanduser(cli_ctx.config.get('logging', 'log_dir', fallback=default_dir))
185185

186186
def _get_console_log_levels(self):

knack/output.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ def __init__(self, cli_ctx=None):
129129
self.cli_ctx.register_event(EVENT_PARSER_GLOBAL_CREATE, OutputProducer.on_global_arguments)
130130
self.cli_ctx.register_event(EVENT_INVOKER_POST_PARSE_ARGS, OutputProducer.handle_output_argument)
131131

132-
def out(self, obj, formatter=None, out_file=None): # pylint: disable=no-self-use
132+
def out(self, obj, formatter=None, out_file=None):
133133
""" Produces the output using the command result.
134134
The method does not return a result as the output is written straight to the output file.
135135
@@ -157,7 +157,7 @@ def out(self, obj, formatter=None, out_file=None): # pylint: disable=no-self-us
157157
print(output.encode('ascii', 'ignore').decode('utf-8', 'ignore'),
158158
file=out_file, end='')
159159

160-
def get_formatter(self, format_type): # pylint: disable=no-self-use
160+
def get_formatter(self, format_type):
161161
# remove color if stdout is not a tty
162162
if not self.cli_ctx.enable_color and format_type == 'jsonc':
163163
return OutputProducer._FORMAT_DICT['json']

knack/testsdk/base.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def __init__(self, cli, method_name):
3333
def cmd(self, command, checks=None, expect_failure=False):
3434
return ExecutionResult(self.cli, command, expect_failure=expect_failure).assert_with_checks(checks)
3535

36-
def create_random_name(self, prefix, length): # pylint: disable=no-self-use
36+
def create_random_name(self, prefix, length):
3737
return create_random_name(prefix=prefix, length=length)
3838

3939
def create_temp_file(self, size_kb, full_random=False):
@@ -117,7 +117,7 @@ def setUp(self):
117117

118118
# set up cassette
119119
cm = self.vcr.use_cassette(self.recording_file)
120-
self.cassette = cm.__enter__()
120+
self.cassette = cm.__enter__() # pylint: disable=unnecessary-dunder-call
121121
self.addCleanup(cm.__exit__)
122122

123123
if not self.in_recording:

knack/testsdk/patches.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ def _mock_in_unit_test(unit_test, target, replacement):
1818
if not isinstance(unit_test, unittest.TestCase):
1919
raise CliTestError('The patch can be only used in unit test')
2020
mp = mock.patch(target, replacement)
21-
mp.__enter__()
21+
mp.__enter__() # pylint: disable=unnecessary-dunder-call
2222
unit_test.addCleanup(mp.__exit__)

knack/testsdk/recording_processors.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55

66

77
class RecordingProcessor(object):
8-
def process_request(self, request): # pylint: disable=no-self-use
8+
def process_request(self, request):
99
return request
1010

11-
def process_response(self, response): # pylint: disable=no-self-use
11+
def process_response(self, response):
1212
return response
1313

1414
@classmethod

knack/util.py

-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ def __init__(self, cli_ctx, object_type, target, tag_func, message_func, color,
8686
self._get_tag = tag_func
8787
self._get_message = message_func
8888

89-
# pylint: disable=no-self-use
9089
def hidden(self):
9190
return False
9291

requirements.txt

+9-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
argcomplete==1.12.2
2-
flake8==4.0.1
3-
jmespath==0.10.0
4-
Pygments==2.8.1
5-
pylint==2.11.1
6-
pytest==6.2.5
1+
argcomplete==3.1.1
2+
flake8==6.0.0
3+
jmespath==1.0.1
4+
packaging==23.1
5+
Pygments==2.15.1
6+
pylint==2.17.4
7+
pytest==7.4.0
78
PyYAML
8-
tabulate==0.8.9
9-
vcrpy==4.1.1
9+
tabulate==0.9.0
10+
vcrpy==5.0.0

setup.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
DEPENDENCIES = [
1414
'argcomplete',
1515
'jmespath',
16+
'packaging',
1617
'pygments',
1718
'pyyaml',
1819
'tabulate'
@@ -37,10 +38,10 @@
3738
'Intended Audience :: System Administrators',
3839
'Programming Language :: Python',
3940
'Programming Language :: Python :: 3',
40-
'Programming Language :: Python :: 3.7',
4141
'Programming Language :: Python :: 3.8',
4242
'Programming Language :: Python :: 3.9',
4343
'Programming Language :: Python :: 3.10',
44+
'Programming Language :: Python :: 3.11',
4445
'License :: OSI Approved :: MIT License',
4546
],
4647
packages=['knack', 'knack.testsdk'],

tests/test_query.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ class TestQuery(unittest.TestCase):
3838
(We are not testing JMESPath itself here)
3939
'''
4040

41-
def test_query_valid_1(self): # pylint: disable=no-self-use
41+
def test_query_valid_1(self):
4242
query = 'length(@)'
4343
# Should not raise any exception as it is valid
4444
CLIQuery.jmespath_type(query)
4545

46-
def test_query_valid_2(self): # pylint: disable=no-self-use
46+
def test_query_valid_2(self):
4747
query = "[?propertyX.propertyY.propertyZ=='AValue'].[col1,col2]"
4848
# Should not raise any exception as it is valid
4949
CLIQuery.jmespath_type(query)

tox.ini

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
[tox]
2-
envlist = py36,py37,py38,py39,py310
2+
envlist = py38,py39,py310,py311
33
[testenv]
44
deps = -rrequirements.txt
55
commands=
66
python ./scripts/license_verify.py
77
flake8 --statistics --append-config=.flake8 knack
8-
pylint knack --rcfile=.pylintrc -r n -d I0013
8+
pylint knack --rcfile=.pylintrc --reports n --disable I0013
99
pytest
1010
python ./examples/test_exapp

0 commit comments

Comments
 (0)