Skip to content

Commit f9de737

Browse files
committed
Added more type hinting
1 parent 6f06dd9 commit f9de737

File tree

1 file changed

+56
-64
lines changed

1 file changed

+56
-64
lines changed

cmd2/cmd2.py

Lines changed: 56 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,7 +1304,7 @@ def _display_matches_pyreadline(self, matches: List[str]) -> None: # pragma: no
13041304

13051305
# ----- Methods which override stuff in cmd -----
13061306

1307-
def complete(self, text, state):
1307+
def complete(self, text: str, state: int) -> Optional[str]:
13081308
"""Override of command method which returns the next possible completion for 'text'.
13091309
13101310
If a command has not been entered, then complete against command list.
@@ -1315,8 +1315,8 @@ def complete(self, text, state):
13151315
This completer function is called as complete(text, state), for state in 0, 1, 2, …, until it returns a
13161316
non-string value. It should return the next possible completion starting with text.
13171317
1318-
:param text: str - the current word that user is typing
1319-
:param state: int - non-negative integer
1318+
:param text: the current word that user is typing
1319+
:param state: non-negative integer
13201320
"""
13211321
import functools
13221322
if state == 0 and rl_type != RlType.NONE:
@@ -1532,16 +1532,12 @@ def _autocomplete_default(self, text: str, line: str, begidx: int, endidx: int,
15321532

15331533
return results
15341534

1535-
def get_all_commands(self):
1536-
"""
1537-
Returns a list of all commands
1538-
"""
1535+
def get_all_commands(self) -> List[str]:
1536+
"""Returns a list of all commands."""
15391537
return [cur_name[3:] for cur_name in self.get_names() if cur_name.startswith('do_')]
15401538

1541-
def get_visible_commands(self):
1542-
"""
1543-
Returns a list of commands that have not been hidden
1544-
"""
1539+
def get_visible_commands(self) -> List[str]:
1540+
"""Returns a list of commands that have not been hidden."""
15451541
commands = self.get_all_commands()
15461542

15471543
# Remove the hidden commands
@@ -1551,11 +1547,11 @@ def get_visible_commands(self):
15511547

15521548
return commands
15531549

1554-
def get_help_topics(self):
1550+
def get_help_topics(self) -> List[str]:
15551551
""" Returns a list of help topics """
15561552
return [name[5:] for name in self.get_names() if name.startswith('help_')]
15571553

1558-
def complete_help(self, text, line, begidx, endidx):
1554+
def complete_help(self, text: str, line: str, begidx: int, endidx: int) -> List[str]:
15591555
"""
15601556
Override of parent class method to handle tab completing subcommands and not showing hidden commands
15611557
Returns a list of possible tab completions
@@ -1599,12 +1595,12 @@ def complete_help(self, text, line, begidx, endidx):
15991595
return matches
16001596

16011597
# noinspection PyUnusedLocal
1602-
def sigint_handler(self, signum, frame):
1598+
def sigint_handler(self, signum: int, frame) -> None:
16031599
"""Signal handler for SIGINTs which typically come from Ctrl-C events.
16041600
16051601
If you need custom SIGINT behavior, then override this function.
16061602
1607-
:param signum: int - signal number
1603+
:param signum: signal number
16081604
:param frame
16091605
"""
16101606

@@ -1617,7 +1613,7 @@ def sigint_handler(self, signum, frame):
16171613
# Re-raise a KeyboardInterrupt so other parts of the code can catch it
16181614
raise KeyboardInterrupt("Got a keyboard interrupt")
16191615

1620-
def preloop(self):
1616+
def preloop(self) -> None:
16211617
""""Hook method executed once when the cmdloop() method is called."""
16221618
import signal
16231619
# Register a default SIGINT signal handler for Ctrl+C
@@ -1626,8 +1622,8 @@ def preloop(self):
16261622
def precmd(self, statement: Statement) -> Statement:
16271623
"""Hook method executed just before the command is processed by ``onecmd()`` and after adding it to the history.
16281624
1629-
:param statement: Statement - subclass of str which also contains the parsed input
1630-
:return: Statement - a potentially modified version of the input Statement object
1625+
:param statement: subclass of str which also contains the parsed input
1626+
:return: a potentially modified version of the input Statement object
16311627
"""
16321628
return statement
16331629

@@ -1637,8 +1633,8 @@ def precmd(self, statement: Statement) -> Statement:
16371633
def preparse(self, raw: str) -> str:
16381634
"""Hook method executed just before the command line is interpreted, but after the input prompt is generated.
16391635
1640-
:param raw: str - raw command line input
1641-
:return: str - potentially modified raw command line input
1636+
:param raw: raw command line input
1637+
:return: potentially modified raw command line input
16421638
"""
16431639
return raw
16441640

@@ -1679,25 +1675,24 @@ def postparsing_postcmd(self, stop: bool) -> bool:
16791675
proc.communicate()
16801676
return stop
16811677

1682-
def parseline(self, line):
1678+
def parseline(self, line: str) -> Tuple[str, str, str]:
16831679
"""Parse the line into a command name and a string containing the arguments.
16841680
16851681
NOTE: This is an override of a parent class method. It is only used by other parent class methods.
16861682
16871683
Different from the parent class method, this ignores self.identchars.
16881684
1689-
:param line: str - line read by readline
1690-
:return: (str, str, str) - tuple containing (command, args, line)
1685+
:param line: line read by readline
1686+
:return: tuple containing (command, args, line)
16911687
"""
1692-
16931688
statement = self.statement_parser.parse_command_only(line)
16941689
return statement.command, statement.args, statement.command_and_args
16951690

1696-
def onecmd_plus_hooks(self, line):
1691+
def onecmd_plus_hooks(self, line: str) -> bool:
16971692
"""Top-level function called by cmdloop() to handle parsing a line and running the command and all of its hooks.
16981693
1699-
:param line: str - line of text read from input
1700-
:return: bool - True if cmdloop() should exit, False otherwise
1694+
:param line: line of text read from input
1695+
:return: True if cmdloop() should exit, False otherwise
17011696
"""
17021697
import datetime
17031698
stop = False
@@ -1731,7 +1726,7 @@ def onecmd_plus_hooks(self, line):
17311726
finally:
17321727
return self.postparsing_postcmd(stop)
17331728

1734-
def runcmds_plus_hooks(self, cmds):
1729+
def runcmds_plus_hooks(self, cmds: List[str]) -> bool:
17351730
"""Convenience method to run multiple commands by onecmd_plus_hooks.
17361731
17371732
This method adds the given cmds to the command queue and processes the
@@ -1749,8 +1744,8 @@ def runcmds_plus_hooks(self, cmds):
17491744
17501745
Example: cmd_obj.runcmds_plus_hooks(['load myscript.txt'])
17511746
1752-
:param cmds: list - Command strings suitable for onecmd_plus_hooks.
1753-
:return: bool - True implies the entire application should exit.
1747+
:param cmds: command strings suitable for onecmd_plus_hooks.
1748+
:return: True implies the entire application should exit.
17541749
17551750
"""
17561751
stop = False
@@ -1773,7 +1768,7 @@ def runcmds_plus_hooks(self, cmds):
17731768
# necessary/desired here.
17741769
return stop
17751770

1776-
def _complete_statement(self, line):
1771+
def _complete_statement(self, line: str) -> Statement:
17771772
"""Keep accepting lines of input until the command is complete.
17781773
17791774
There is some pretty hacky code here to handle some quirks of
@@ -1814,10 +1809,10 @@ def _complete_statement(self, line):
18141809
raise EmptyStatement()
18151810
return statement
18161811

1817-
def _redirect_output(self, statement):
1812+
def _redirect_output(self, statement: Statement) -> None:
18181813
"""Handles output redirection for >, >>, and |.
18191814
1820-
:param statement: Statement - a parsed statement from the user
1815+
:param statement: a parsed statement from the user
18211816
"""
18221817
import io
18231818
import subprocess
@@ -1874,12 +1869,11 @@ def _redirect_output(self, statement):
18741869
if statement.output == constants.REDIRECTION_APPEND:
18751870
self.poutput(get_paste_buffer())
18761871

1877-
def _restore_output(self, statement):
1872+
def _restore_output(self, statement: Statement) -> None:
18781873
"""Handles restoring state after output redirection as well as
18791874
the actual pipe operation if present.
18801875
1881-
:param statement: Statement object which contains the parsed
1882-
input from the user
1876+
:param statement: Statement object which contains the parsed input from the user
18831877
"""
18841878
# If we have redirected output to a file or the clipboard or piped it to a shell command, then restore state
18851879
if self.kept_state is not None:
@@ -1910,25 +1904,25 @@ def _restore_output(self, statement):
19101904

19111905
self.redirecting = False
19121906

1913-
def _func_named(self, arg):
1907+
def _func_named(self, arg: str) -> str:
19141908
"""Gets the method name associated with a given command.
19151909
1916-
:param arg: str - command to look up method name which implements it
1917-
:return: str - method name which implements the given command
1910+
:param arg: command to look up method name which implements it
1911+
:return: method name which implements the given command
19181912
"""
19191913
result = None
19201914
target = 'do_' + arg
19211915
if target in dir(self):
19221916
result = target
19231917
return result
19241918

1925-
def onecmd(self, statement):
1919+
def onecmd(self, statement: Statement) -> Optional[bool]:
19261920
""" This executes the actual do_* method for a command.
19271921
19281922
If the command provided doesn't exist, then it executes _default() instead.
19291923
19301924
:param statement: Command - a parsed command from the input stream
1931-
:return: bool - a flag indicating whether the interpretation of commands should stop
1925+
:return: a flag indicating whether the interpretation of commands should stop
19321926
"""
19331927
funcname = self._func_named(statement.command)
19341928
if not funcname:
@@ -1946,11 +1940,10 @@ def onecmd(self, statement):
19461940
stop = func(statement)
19471941
return stop
19481942

1949-
def default(self, statement):
1943+
def default(self, statement: Statement) -> None:
19501944
"""Executed when the command given isn't a recognized command implemented by a do_* method.
19511945
19521946
:param statement: Statement object with parsed input
1953-
:return:
19541947
"""
19551948
arg = statement.raw
19561949
if self.default_to_shell:
@@ -1963,13 +1956,13 @@ def default(self, statement):
19631956
self.poutput('*** Unknown syntax: {}\n'.format(arg))
19641957

19651958
@staticmethod
1966-
def _surround_ansi_escapes(prompt, start="\x01", end="\x02"):
1959+
def _surround_ansi_escapes(prompt: str, start: str="\x01", end: str="\x02") -> str:
19671960
"""Overcome bug in GNU Readline in relation to calculation of prompt length in presence of ANSI escape codes.
19681961
1969-
:param prompt: str - original prompt
1970-
:param start: str - start code to tell GNU Readline about beginning of invisible characters
1971-
:param end: str - end code to tell GNU Readline about end of invisible characters
1972-
:return: str - prompt safe to pass to GNU Readline
1962+
:param prompt: original prompt
1963+
:param start: start code to tell GNU Readline about beginning of invisible characters
1964+
:param end: end code to tell GNU Readline about end of invisible characters
1965+
:return: prompt safe to pass to GNU Readline
19731966
"""
19741967
# Windows terminals don't use ANSI escape codes and Windows readline isn't based on GNU Readline
19751968
if sys.platform == "win32":
@@ -1990,9 +1983,8 @@ def _surround_ansi_escapes(prompt, start="\x01", end="\x02"):
19901983

19911984
return result
19921985

1993-
def pseudo_raw_input(self, prompt):
1994-
"""
1995-
began life as a copy of cmd's cmdloop; like raw_input but
1986+
def pseudo_raw_input(self, prompt: str) -> str:
1987+
"""Began life as a copy of cmd's cmdloop; like raw_input but
19961988
19971989
- accounts for changed stdin, stdout
19981990
- if input is a pipe (instead of a tty), look at self.echo
@@ -2033,14 +2025,14 @@ def pseudo_raw_input(self, prompt):
20332025
line = 'eof'
20342026
return line.strip()
20352027

2036-
def _cmdloop(self):
2028+
def _cmdloop(self) -> bool:
20372029
"""Repeatedly issue a prompt, accept input, parse an initial prefix
20382030
off the received input, and dispatch to action methods, passing them
20392031
the remainder of the line as argument.
20402032
20412033
This serves the same role as cmd.cmdloop().
20422034
2043-
:return: bool - True implies the entire application should exit.
2035+
:return: True implies the entire application should exit.
20442036
"""
20452037
# An almost perfect copy from Cmd; however, the pseudo_raw_input portion
20462038
# has been split out so that it can be called separately
@@ -2070,7 +2062,7 @@ def _cmdloop(self):
20702062
# Enable tab completion
20712063
readline.parse_and_bind(self.completekey + ": complete")
20722064

2073-
stop = None
2065+
stop = False
20742066
try:
20752067
while not stop:
20762068
if self.cmdqueue:
@@ -2111,7 +2103,7 @@ def _cmdloop(self):
21112103
return stop
21122104

21132105
@with_argument_list
2114-
def do_alias(self, arglist):
2106+
def do_alias(self, arglist: List[str]) -> None:
21152107
"""Define or display aliases
21162108
21172109
Usage: Usage: alias [name] | [<name> <value>]
@@ -2167,7 +2159,7 @@ def do_alias(self, arglist):
21672159
errmsg = "Aliases can not contain: {}".format(invalidchars)
21682160
self.perror(errmsg, traceback_war=False)
21692161

2170-
def complete_alias(self, text, line, begidx, endidx):
2162+
def complete_alias(self, text: str, line: str, begidx: int, endidx: int) -> List[str]:
21712163
""" Tab completion for alias """
21722164
alias_names = set(self.aliases.keys())
21732165
visible_commands = set(self.get_visible_commands())
@@ -2180,7 +2172,7 @@ def complete_alias(self, text, line, begidx, endidx):
21802172
return self.index_based_complete(text, line, begidx, endidx, index_dict, self.path_complete)
21812173

21822174
@with_argument_list
2183-
def do_unalias(self, arglist):
2175+
def do_unalias(self, arglist: List[str]) -> None:
21842176
"""Unsets aliases
21852177
21862178
Usage: Usage: unalias [-a] name [name ...]
@@ -2191,7 +2183,7 @@ def do_unalias(self, arglist):
21912183
-a remove all alias definitions
21922184
"""
21932185
if not arglist:
2194-
self.do_help('unalias')
2186+
self.do_help(['unalias'])
21952187

21962188
if '-a' in arglist:
21972189
self.aliases.clear()
@@ -2208,12 +2200,12 @@ def do_unalias(self, arglist):
22082200
else:
22092201
self.perror("Alias {!r} does not exist".format(cur_arg), traceback_war=False)
22102202

2211-
def complete_unalias(self, text, line, begidx, endidx):
2203+
def complete_unalias(self, text: str, line: str, begidx: int, endidx: int) -> List[str]:
22122204
""" Tab completion for unalias """
22132205
return self.basic_complete(text, line, begidx, endidx, self.aliases)
22142206

22152207
@with_argument_list
2216-
def do_help(self, arglist):
2208+
def do_help(self, arglist: List[str]) -> None:
22172209
"""List available commands with "help" or detailed help with "help cmd"."""
22182210
if not arglist or (len(arglist) == 1 and arglist[0] in ('--verbose', '-v')):
22192211
verbose = len(arglist) == 1 and arglist[0] in ('--verbose', '-v')
@@ -2240,7 +2232,7 @@ def do_help(self, arglist):
22402232
# This could be a help topic
22412233
cmd.Cmd.do_help(self, arglist[0])
22422234

2243-
def _help_menu(self, verbose=False):
2235+
def _help_menu(self, verbose: bool=False) -> None:
22442236
"""Show a list of commands which help can be displayed for.
22452237
"""
22462238
# Get a sorted list of help topics
@@ -2283,7 +2275,7 @@ def _help_menu(self, verbose=False):
22832275
self.print_topics(self.misc_header, help_topics, 15, 80)
22842276
self.print_topics(self.undoc_header, cmds_undoc, 15, 80)
22852277

2286-
def _print_topics(self, header, cmds, verbose):
2278+
def _print_topics(self, header: str, cmds: List[str], verbose: bool) -> None:
22872279
"""Customized version of print_topics that can switch between verbose or traditional output"""
22882280
import io
22892281

@@ -2354,7 +2346,7 @@ def _print_topics(self, header, cmds, verbose):
23542346
command = ''
23552347
self.stdout.write("\n")
23562348

2357-
def do_shortcuts(self, _):
2349+
def do_shortcuts(self, _: str) -> None:
23582350
"""Lists shortcuts (aliases) available."""
23592351
result = "\n".join('%s: %s' % (sc[0], sc[1]) for sc in sorted(self.shortcuts))
23602352
self.poutput("Shortcuts for other commands:\n{}\n".format(result))
@@ -2722,7 +2714,7 @@ def do_pyscript(self, arglist):
27222714
"""
27232715
if not arglist:
27242716
self.perror("pyscript command requires at least 1 argument ...", traceback_war=False)
2725-
self.do_help('pyscript')
2717+
self.do_help(['pyscript'])
27262718
return
27272719

27282720
# Get the absolute path of the script

0 commit comments

Comments
 (0)