Skip to content

Commit 7402581

Browse files
committed
Set ruff target-version to the minimum supported version of Python
Ignore warning about adding import for future annotations. I tried it but it wreaked havoc due to how cmd2 actively validates type hints using inspect. If you use future annotations it delays evaluation until necessary, which benefits runtime performance but converts all type annotations to strings instead of types. Also, cleaned up how we specify ruff per-file ignores.
1 parent 28f226a commit 7402581

File tree

2 files changed

+23
-46
lines changed

2 files changed

+23
-46
lines changed

cmd2/cmd2.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3597,8 +3597,8 @@ def _macro_create(self, args: argparse.Namespace) -> None:
35973597
max_arg_num = 0
35983598
arg_nums = set()
35993599

3600-
while True:
3601-
try:
3600+
try:
3601+
while True:
36023602
cur_match = normal_matches.__next__()
36033603

36043604
# Get the number string between the braces
@@ -3612,9 +3612,8 @@ def _macro_create(self, args: argparse.Namespace) -> None:
36123612
max_arg_num = max(max_arg_num, cur_num)
36133613

36143614
arg_list.append(MacroArg(start_index=cur_match.start(), number_str=cur_num_str, is_escaped=False))
3615-
3616-
except StopIteration:
3617-
break
3615+
except StopIteration:
3616+
pass
36183617

36193618
# Make sure the argument numbers are continuous
36203619
if len(arg_nums) != max_arg_num:
@@ -3624,16 +3623,16 @@ def _macro_create(self, args: argparse.Namespace) -> None:
36243623
# Find all escaped arguments
36253624
escaped_matches = re.finditer(MacroArg.macro_escaped_arg_pattern, value)
36263625

3627-
while True:
3628-
try:
3626+
try:
3627+
while True:
36293628
cur_match = escaped_matches.__next__()
36303629

36313630
# Get the number string between the braces
36323631
cur_num_str = re.findall(MacroArg.digit_pattern, cur_match.group())[0]
36333632

36343633
arg_list.append(MacroArg(start_index=cur_match.start(), number_str=cur_num_str, is_escaped=True))
3635-
except StopIteration:
3636-
break
3634+
except StopIteration:
3635+
pass
36373636

36383637
# Set the macro
36393638
result = "overwritten" if args.name in self.macros else "created"

pyproject.toml

Lines changed: 15 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,7 @@ exclude = [
147147
# Same as Black.
148148
line-length = 127
149149
indent-width = 4
150-
151-
# Assume Python 3.13
152-
target-version = "py313"
150+
target-version = "py39" # Minimum supported version of Python
153151
output-format = "full"
154152

155153
[tool.ruff.lint]
@@ -235,6 +233,7 @@ ignore = [
235233
"E111", # Conflicts with ruff format
236234
"E114", # Conflicts with ruff format
237235
"E117", # Conflicts with ruff format
236+
"FA100", # Adding from __future__ import annotations screws up cmd2 because of how use inspect to validate type annotations at runtime
238237
"ISC002", # Conflicts with ruff format
239238
"Q000", # Conflicts with ruff format
240239
"Q001", # Conflicts with ruff format
@@ -258,56 +257,35 @@ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
258257

259258
mccabe.max-complexity = 49
260259

261-
per-file-ignores."cmd2/__init__.py" = [
262-
"E402", # Module level import not at top of file
263-
"F401", # Unused import
264-
]
260+
[tool.ruff.lint.per-file-ignores]
261+
# Module level import not at top of file and unused import
262+
"cmd2/__init__.py" = ["E402", "F401"]
265263

266-
per-file-ignores."cmd2/argparse_custom.py" = [
267-
"B010", # Do not call setattr with a constant attribute value
268-
]
264+
# Do not call setattr with constant attribute value
265+
"cmd2/argparse_custom.py" = ["B010"]
269266

270-
per-file-ignores."examples/*.py" = [
267+
# Ignore various varnings in examples/ directory
268+
"examples/*.py" = [
271269
"ANN", # Ignore all type annotation rules in examples folder
272270
"D", # Ignore all pydocstyle rules in examples folder
273271
"INP001", # Module is part of an implicit namespace
274272
"PLW2901", # loop variable overwritten inside loop
275273
"S", # Ignore all Security rules in examples folder
276274
]
275+
"examples/scripts/*.py" = ["F821"] # Undefined name `app`
276+
"plugins/*.py" = ["INP001"] # Module is part of an implicit namespace
277277

278-
per-file-ignores."examples/scripts/*.py" = [
279-
"F821", # Undefined name `app`
280-
]
281-
282-
per-file-ignores."plugins/*.py" = [
283-
"ANN", # Ignore all type annotation rules in test folders
284-
"D", # Ignore all pydocstyle rules in test folders
285-
"INP001", # Module is part of an implicit namespace
286-
"S", # Ignore all Security rules in test folders
287-
"SLF", # Ignore all warnings about private or protected member access in test folders
288-
]
289-
290-
per-file-ignores."tests/*.py" = [
278+
# Ingore various rulesets in test and plugins directories
279+
"{plugins,tests,tests_isolated}/*.py" = [
291280
"ANN", # Ignore all type annotation rules in test folders
292281
"ARG", # Ignore all unused argument warnings in test folders
293282
"D", # Ignore all pydocstyle rules in test folders
294283
"E501", # Line too long
295284
"S", # Ignore all Security rules in test folders
296285
"SLF", # Ignore all warnings about private or protected member access in test folders
297286
]
298-
299-
per-file-ignores."tests/pyscript/*.py" = [
300-
"F821", # Undefined name `app`
301-
"INP001", # Module is part of an implicit namespace
302-
]
303-
304-
per-file-ignores."tests_isolated/*.py" = [
305-
"ANN", # Ignore all type annotation rules in test folders
306-
"ARG", # Ignore all unused argument warnings in test folders
307-
"D", # Ignore all pydocstyle rules in test folders
308-
"S", # Ignore all Security rules in test folders
309-
"SLF", # Ignore all warnings about private or protected member access in test folders
310-
]
287+
# Undefined name `app` and module is part of an implicit namespace
288+
"tests/pyscript/*.py" = ["F821", "INP001"]
311289

312290
[tool.ruff.format]
313291
# Like Black, use double quotes for strings.

0 commit comments

Comments
 (0)