@@ -293,14 +293,10 @@ class Cmd(cmd.Cmd):
293293
294294 Line-oriented command interpreters are often useful for test harnesses, internal tools, and rapid prototypes.
295295 """
296- # Attributes used to configure the StatementParser, best not to change these at runtime
297- multiline_commands = []
298- shortcuts = {'?' : 'help' , '!' : 'shell' , '@' : 'load' , '@@' : '_relative_load' }
299- terminators = [constants .MULTILINE_TERMINATOR ]
296+ DEFAULT_SHORTCUTS = {'?' : 'help' , '!' : 'shell' , '@' : 'load' , '@@' : '_relative_load' }
300297
301298 # Attributes which are NOT dynamically settable at runtime
302299 allow_cli_args = True # Should arguments passed on the command-line be processed as commands?
303- allow_redirection = True # Should output redirection and pipes be allowed
304300 default_to_shell = False # Attempt to run unrecognized commands as shell commands
305301 quit_on_sigint = False # Quit the loop on interrupt instead of just resetting prompt
306302 reserved_words = []
@@ -338,7 +334,9 @@ class Cmd(cmd.Cmd):
338334
339335 def __init__ (self , completekey : str = 'tab' , stdin = None , stdout = None , persistent_history_file : str = '' ,
340336 persistent_history_length : int = 1000 , startup_script : Optional [str ] = None , use_ipython : bool = False ,
341- transcript_files : Optional [List [str ]] = None ) -> None :
337+ transcript_files : Optional [List [str ]] = None , allow_redirection : bool = True ,
338+ multiline_commands : Optional [List [str ]] = None , terminators : Optional [List [str ]] = None ,
339+ shortcuts : Optional [Dict [str , str ]] = None ) -> None :
342340 """An easy but powerful framework for writing line-oriented command interpreters, extends Python's cmd package.
343341
344342 :param completekey: (optional) readline name of a completion key, default to Tab
@@ -349,6 +347,9 @@ def __init__(self, completekey: str = 'tab', stdin=None, stdout=None, persistent
349347 :param startup_script: (optional) file path to a a script to load and execute at startup
350348 :param use_ipython: (optional) should the "ipy" command be included for an embedded IPython shell
351349 :param transcript_files: (optional) allows running transcript tests when allow_cli_args is False
350+ :param allow_redirection: (optional) should output redirection and pipes be allowed
351+ :param multiline_commands: (optional) list of commands allowed to accept multi-line input
352+ :param shortcuts: (optional) dictionary containing shortcuts for commands
352353 """
353354 # If use_ipython is False, make sure the do_ipy() method doesn't exit
354355 if not use_ipython :
@@ -377,21 +378,21 @@ def __init__(self, completekey: str = 'tab', stdin=None, stdout=None, persistent
377378 self .aliases = dict ()
378379 self .macros = dict ()
379380
380- self ._finalize_app_parameters ()
381-
382381 self .initial_stdout = sys .stdout
383382 self .history = History ()
384383 self .pystate = {}
385384 self .py_history = []
386385 self .pyscript_name = 'app'
387386 self .keywords = self .reserved_words + self .get_all_commands ()
388- self .statement_parser = StatementParser (
389- allow_redirection = self .allow_redirection ,
390- terminators = self .terminators ,
391- multiline_commands = self .multiline_commands ,
392- aliases = self .aliases ,
393- shortcuts = self .shortcuts ,
394- )
387+
388+ if shortcuts is None :
389+ shortcuts = self .DEFAULT_SHORTCUTS
390+ shortcuts = sorted (shortcuts .items (), reverse = True )
391+ self .statement_parser = StatementParser (allow_redirection = allow_redirection ,
392+ terminators = terminators ,
393+ multiline_commands = multiline_commands ,
394+ aliases = self .aliases ,
395+ shortcuts = shortcuts )
395396 self ._transcript_files = transcript_files
396397
397398 # Used to enable the ability for a Python script to quit the application
@@ -545,10 +546,15 @@ def visible_prompt(self) -> str:
545546 """
546547 return utils .strip_ansi (self .prompt )
547548
548- def _finalize_app_parameters (self ) -> None :
549- """Finalize the shortcuts"""
550- # noinspection PyUnresolvedReferences
551- self .shortcuts = sorted (self .shortcuts .items (), reverse = True )
549+ @property
550+ def allow_redirection (self ) -> bool :
551+ """Read-only property to get whether or not redirection of stdout is allowed."""
552+ return self .statement_parser .allow_redirection
553+
554+ @property
555+ def shortcuts (self ) -> List [Tuple [str , str ]]:
556+ """Read-only property to access the shortcuts stored in the StatementParser."""
557+ return self .statement_parser .shortcuts
552558
553559 def decolorized_write (self , fileobj : IO , msg : str ) -> None :
554560 """Write a string to a fileobject, stripping ANSI escape sequences if necessary
@@ -2792,7 +2798,8 @@ def cmdenvironment(self) -> str:
27922798 Commands may be terminated with: {}
27932799 Arguments at invocation allowed: {}
27942800 Output redirection and pipes allowed: {}"""
2795- return read_only_settings .format (str (self .terminators ), self .allow_cli_args , self .allow_redirection )
2801+ return read_only_settings .format (str (self .statement_parser .terminators ), self .allow_cli_args ,
2802+ self .allow_redirection )
27962803
27972804 def show (self , args : argparse .Namespace , parameter : str = '' ) -> None :
27982805 """Shows current settings of parameters.
0 commit comments