57
57
IO ,
58
58
TYPE_CHECKING ,
59
59
Any ,
60
+ ClassVar ,
60
61
Optional ,
61
62
TextIO ,
62
63
TypeVar ,
@@ -297,6 +298,9 @@ class Cmd(cmd.Cmd):
297
298
ALPHABETICAL_SORT_KEY = utils .norm_fold
298
299
NATURAL_SORT_KEY = utils .natural_keys
299
300
301
+ # List for storing transcript test file names
302
+ testfiles : ClassVar [list [str ]] = []
303
+
300
304
def __init__ (
301
305
self ,
302
306
completekey : str = 'tab' ,
@@ -373,9 +377,9 @@ def __init__(
373
377
"""
374
378
# Check if py or ipy need to be disabled in this instance
375
379
if not include_py :
376
- setattr (self , 'do_py' , None )
380
+ setattr (self , 'do_py' , None ) # noqa: B010
377
381
if not include_ipy :
378
- setattr (self , 'do_ipy' , None )
382
+ setattr (self , 'do_ipy' , None ) # noqa: B010
379
383
380
384
# initialize plugin system
381
385
# needs to be done before we call __init__(0)
@@ -401,7 +405,7 @@ def __init__(
401
405
# The maximum number of CompletionItems to display during tab completion. If the number of completion
402
406
# suggestions exceeds this number, they will be displayed in the typical columnized format and will
403
407
# not include the description value of the CompletionItems.
404
- self .max_completion_items = 50
408
+ self .max_completion_items : int = 50
405
409
406
410
# A dictionary mapping settable names to their Settable instance
407
411
self ._settables : dict [str , Settable ] = {}
@@ -414,7 +418,7 @@ def __init__(
414
418
self .build_settables ()
415
419
416
420
# Use as prompt for multiline commands on the 2nd+ line of input
417
- self .continuation_prompt = '> '
421
+ self .continuation_prompt : str = '> '
418
422
419
423
# Allow access to your application in embedded Python shells and scripts py via self
420
424
self .self_in_py = False
@@ -445,7 +449,7 @@ def __init__(
445
449
# True if running inside a Python shell or pyscript, False otherwise
446
450
self ._in_py = False
447
451
448
- self .statement_parser = StatementParser (
452
+ self .statement_parser : StatementParser = StatementParser (
449
453
terminators = terminators , multiline_commands = multiline_commands , shortcuts = shortcuts
450
454
)
451
455
@@ -456,7 +460,7 @@ def __init__(
456
460
self ._script_dir : list [str ] = []
457
461
458
462
# Context manager used to protect critical sections in the main thread from stopping due to a KeyboardInterrupt
459
- self .sigint_protection = utils .ContextFlag ()
463
+ self .sigint_protection : utils . ContextFlag = utils .ContextFlag ()
460
464
461
465
# If the current command created a process to pipe to, then this will be a ProcReader object.
462
466
# Otherwise it will be None. It's used to know when a pipe process can be killed and/or waited upon.
@@ -551,7 +555,7 @@ def __init__(
551
555
# command and category names
552
556
# alias, macro, settable, and shortcut names
553
557
# tab completion results when self.matches_sorted is False
554
- self .default_sort_key = Cmd .ALPHABETICAL_SORT_KEY
558
+ self .default_sort_key : Callable [[ str ], str ] = Cmd .ALPHABETICAL_SORT_KEY
555
559
556
560
############################################################################################################
557
561
# The following variables are used by tab completion functions. They are reset each time complete() is run
@@ -567,14 +571,14 @@ def __init__(
567
571
self .allow_closing_quote = True
568
572
569
573
# An optional hint which prints above tab completion suggestions
570
- self .completion_hint = ''
574
+ self .completion_hint : str = ''
571
575
572
576
# Normally cmd2 uses readline's formatter to columnize the list of completion suggestions.
573
577
# If a custom format is preferred, write the formatted completions to this string. cmd2 will
574
578
# then print it instead of the readline format. ANSI style sequences and newlines are supported
575
579
# when using this value. Even when using formatted_completions, the full matches must still be returned
576
580
# from your completer function. ArgparseCompleter writes its tab completion tables to this string.
577
- self .formatted_completions = ''
581
+ self .formatted_completions : str = ''
578
582
579
583
# Used by complete() for readline tab completion
580
584
self .completion_matches : list [str ] = []
@@ -594,10 +598,10 @@ def __init__(
594
598
# Set to True before returning matches to complete() in cases where matches have already been sorted.
595
599
# If False, then complete() will sort the matches using self.default_sort_key before they are displayed.
596
600
# This does not affect self.formatted_completions.
597
- self .matches_sorted = False
601
+ self .matches_sorted : bool = False
598
602
599
603
# Command parsers for this Cmd instance.
600
- self ._command_parsers = _CommandParsers (self )
604
+ self ._command_parsers : _CommandParsers = _CommandParsers (self )
601
605
602
606
# Add functions decorated to be subcommands
603
607
self ._register_subcommands (self )
@@ -915,7 +919,7 @@ def _register_subcommands(self, cmdset: Union[CommandSet, 'Cmd']) -> None:
915
919
)
916
920
917
921
# iterate through all matching methods
918
- for method_name , method in methods :
922
+ for _method_name , method in methods :
919
923
subcommand_name : str = getattr (method , constants .SUBCMD_ATTR_NAME )
920
924
full_command_name : str = getattr (method , constants .SUBCMD_ATTR_COMMAND )
921
925
subcmd_parser_builder = getattr (method , constants .CMD_ATTR_ARGPARSER )
@@ -952,7 +956,7 @@ def find_subcommand(action: argparse.ArgumentParser, subcmd_names: list[str]) ->
952
956
if choice_name == cur_subcmd :
953
957
return find_subcommand (choice , subcmd_names )
954
958
break
955
- raise CommandSetRegistrationError (f"Could not find subcommand '{ full_command_name } '" )
959
+ raise CommandSetRegistrationError (f"Could not find subcommand '{ action } '" )
956
960
957
961
target_parser = find_subcommand (command_parser , subcommand_names )
958
962
@@ -1021,7 +1025,7 @@ def _unregister_subcommands(self, cmdset: Union[CommandSet, 'Cmd']) -> None:
1021
1025
)
1022
1026
1023
1027
# iterate through all matching methods
1024
- for method_name , method in methods :
1028
+ for _method_name , method in methods :
1025
1029
subcommand_name = getattr (method , constants .SUBCMD_ATTR_NAME )
1026
1030
command_name = getattr (method , constants .SUBCMD_ATTR_COMMAND )
1027
1031
@@ -1105,8 +1109,8 @@ def remove_settable(self, name: str) -> None:
1105
1109
"""
1106
1110
try :
1107
1111
del self ._settables [name ]
1108
- except KeyError :
1109
- raise KeyError (name + " is not a settable parameter" )
1112
+ except KeyError as exc :
1113
+ raise KeyError (name + " is not a settable parameter" ) from exc
1110
1114
1111
1115
def build_settables (self ) -> None :
1112
1116
"""Create the dictionary of user-settable parameters."""
@@ -1119,11 +1123,11 @@ def allow_style_type(value: str) -> ansi.AllowStyle:
1119
1123
"""Converts a string value into an ansi.AllowStyle."""
1120
1124
try :
1121
1125
return ansi .AllowStyle [value .upper ()]
1122
- except KeyError :
1126
+ except KeyError as esc :
1123
1127
raise ValueError (
1124
1128
f"must be { ansi .AllowStyle .ALWAYS } , { ansi .AllowStyle .NEVER } , or "
1125
1129
f"{ ansi .AllowStyle .TERMINAL } (case-insensitive)"
1126
- )
1130
+ ) from esc
1127
1131
1128
1132
self .add_settable (
1129
1133
Settable (
@@ -2561,7 +2565,7 @@ def onecmd_plus_hooks(
2561
2565
self .exit_code = ex .code
2562
2566
stop = True
2563
2567
except PassThroughException as ex :
2564
- raise ex .wrapped_ex
2568
+ raise ex .wrapped_ex from None
2565
2569
except Exception as ex : # noqa: BLE001
2566
2570
self .pexcept (ex )
2567
2571
finally :
@@ -2575,7 +2579,7 @@ def onecmd_plus_hooks(
2575
2579
self .exit_code = ex .code
2576
2580
stop = True
2577
2581
except PassThroughException as ex :
2578
- raise ex .wrapped_ex
2582
+ raise ex .wrapped_ex from None
2579
2583
except Exception as ex : # noqa: BLE001
2580
2584
self .pexcept (ex )
2581
2585
@@ -2896,7 +2900,7 @@ def _redirect_output(self, statement: Statement) -> utils.RedirectionSavedState:
2896
2900
# Use line buffering
2897
2901
new_stdout = cast (TextIO , open (utils .strip_quotes (statement .output_to ), mode = mode , buffering = 1 )) # noqa: SIM115
2898
2902
except OSError as ex :
2899
- raise RedirectionError (f 'Failed to redirect because: { ex } ' )
2903
+ raise RedirectionError ('Failed to redirect output' ) from ex
2900
2904
2901
2905
redir_saved_state .redirecting = True
2902
2906
sys .stdout = self .stdout = new_stdout
@@ -4059,8 +4063,8 @@ def complete_set_value(
4059
4063
param = arg_tokens ['param' ][0 ]
4060
4064
try :
4061
4065
settable = self .settables [param ]
4062
- except KeyError :
4063
- raise CompletionError (param + " is not a settable parameter" )
4066
+ except KeyError as exc :
4067
+ raise CompletionError (param + " is not a settable parameter" ) from exc
4064
4068
4065
4069
# Create a parser with a value field based on this settable
4066
4070
settable_parser = argparse_custom .DEFAULT_ARGUMENT_PARSER (parents = [Cmd .set_parser_parent ])
@@ -4528,7 +4532,7 @@ def do_ipy(self, _: argparse.Namespace) -> Optional[bool]: # pragma: no cover
4528
4532
4529
4533
# Allow users to install ipython from a cmd2 prompt when needed and still have ipy command work
4530
4534
try :
4531
- start_ipython # noqa: F823
4535
+ _dummy = start_ipython # noqa: F823
4532
4536
except NameError :
4533
4537
from IPython import start_ipython # type: ignore[import]
4534
4538
@@ -5145,7 +5149,7 @@ class TestMyAppCase(Cmd2TestCase):
5145
5149
self .poutput (f'cmd2 app: { sys .argv [0 ]} ' )
5146
5150
self .poutput (ansi .style (f'collected { num_transcripts } transcript{ plural } ' , bold = True ))
5147
5151
5148
- setattr ( self .__class__ , ' testfiles' , transcripts_expanded )
5152
+ self .__class__ . testfiles = transcripts_expanded
5149
5153
sys .argv = [sys .argv [0 ]] # the --test argument upsets unittest.main()
5150
5154
testcase = TestMyAppCase ()
5151
5155
stream = cast (TextIO , utils .StdSim (sys .stderr ))
0 commit comments