@@ -427,14 +427,14 @@ def __init__(self, completekey: str = 'tab', stdin=None, stdout=None, *,
427
427
self ._script_dir = []
428
428
429
429
# Context manager used to protect critical sections in the main thread from stopping due to a KeyboardInterrupt
430
- self ._sigint_protection = utils .ContextFlag ()
430
+ self .sigint_protection = utils .ContextFlag ()
431
431
432
432
# If the current command created a process to pipe to, then this will be a ProcReader object.
433
433
# Otherwise it will be None. Its used to know when a pipe process can be killed and/or waited upon.
434
434
self ._cur_pipe_proc_reader = None
435
435
436
436
# Used by complete() for readline tab completion
437
- self ._completion_matches = []
437
+ self .completion_matches = []
438
438
439
439
# Used to keep track of whether we are redirecting or piping output
440
440
self ._redirecting = False
@@ -537,7 +537,7 @@ def __init__(self, completekey: str = 'tab', stdin=None, stdout=None, *,
537
537
# This lock should be acquired before doing any asynchronous changes to the terminal to
538
538
# ensure the updates to the terminal don't interfere with the input being typed or output
539
539
# being printed by a command.
540
- self ._terminal_lock = threading .RLock ()
540
+ self .terminal_lock = threading .RLock ()
541
541
542
542
# Commands that have been disabled from use. This is to support commands that are only available
543
543
# during specific states of the application. This dictionary's keys are the command names and its
@@ -688,7 +688,7 @@ def ppaged(self, msg: str, end: str = '\n', chop: bool = False) -> None:
688
688
689
689
# Prevent KeyboardInterrupts while in the pager. The pager application will
690
690
# still receive the SIGINT since it is in the same process group as us.
691
- with self ._sigint_protection :
691
+ with self .sigint_protection :
692
692
pipe_proc = subprocess .Popen (pager , shell = True , stdin = subprocess .PIPE )
693
693
pipe_proc .communicate (msg_str .encode ('utf-8' , 'replace' ))
694
694
else :
@@ -1398,7 +1398,7 @@ def _complete_worker(self, text: str, state: int) -> Optional[str]:
1398
1398
# Check if we either had a parsing error or are trying to complete the command token
1399
1399
# The latter can happen if " or ' was entered as the command
1400
1400
if len (tokens ) <= 1 :
1401
- self ._completion_matches = []
1401
+ self .completion_matches = []
1402
1402
return None
1403
1403
1404
1404
# Text we need to remove from completions later
@@ -1456,28 +1456,28 @@ def _complete_worker(self, text: str, state: int) -> Optional[str]:
1456
1456
1457
1457
# Attempt tab completion for redirection first, and if that isn't occurring,
1458
1458
# call the completer function for the current command
1459
- self ._completion_matches = self ._redirect_complete (text , line , begidx , endidx , compfunc )
1459
+ self .completion_matches = self ._redirect_complete (text , line , begidx , endidx , compfunc )
1460
1460
1461
- if self ._completion_matches :
1461
+ if self .completion_matches :
1462
1462
1463
1463
# Eliminate duplicates
1464
- self ._completion_matches = utils .remove_duplicates (self ._completion_matches )
1464
+ self .completion_matches = utils .remove_duplicates (self .completion_matches )
1465
1465
self .display_matches = utils .remove_duplicates (self .display_matches )
1466
1466
1467
1467
if not self .display_matches :
1468
- # Since self.display_matches is empty, set it to self._completion_matches
1468
+ # Since self.display_matches is empty, set it to self.completion_matches
1469
1469
# before we alter them. That way the suggestions will reflect how we parsed
1470
1470
# the token being completed and not how readline did.
1471
1471
import copy
1472
- self .display_matches = copy .copy (self ._completion_matches )
1472
+ self .display_matches = copy .copy (self .completion_matches )
1473
1473
1474
1474
# Check if we need to add an opening quote
1475
1475
if not unclosed_quote :
1476
1476
1477
1477
add_quote = False
1478
1478
1479
1479
# This is the tab completion text that will appear on the command line.
1480
- common_prefix = os .path .commonprefix (self ._completion_matches )
1480
+ common_prefix = os .path .commonprefix (self .completion_matches )
1481
1481
1482
1482
if self .matches_delimited :
1483
1483
# Check if any portion of the display matches appears in the tab completion
@@ -1490,36 +1490,36 @@ def _complete_worker(self, text: str, state: int) -> Optional[str]:
1490
1490
add_quote = True
1491
1491
1492
1492
# If there is a tab completion and any match has a space, then add an opening quote
1493
- elif common_prefix and any (' ' in match for match in self ._completion_matches ):
1493
+ elif common_prefix and any (' ' in match for match in self .completion_matches ):
1494
1494
add_quote = True
1495
1495
1496
1496
if add_quote :
1497
1497
# Figure out what kind of quote to add and save it as the unclosed_quote
1498
- if any ('"' in match for match in self ._completion_matches ):
1498
+ if any ('"' in match for match in self .completion_matches ):
1499
1499
unclosed_quote = "'"
1500
1500
else :
1501
1501
unclosed_quote = '"'
1502
1502
1503
- self ._completion_matches = [unclosed_quote + match for match in self ._completion_matches ]
1503
+ self .completion_matches = [unclosed_quote + match for match in self .completion_matches ]
1504
1504
1505
1505
# Check if we need to remove text from the beginning of tab completions
1506
1506
elif text_to_remove :
1507
- self ._completion_matches = \
1508
- [match .replace (text_to_remove , '' , 1 ) for match in self ._completion_matches ]
1507
+ self .completion_matches = \
1508
+ [match .replace (text_to_remove , '' , 1 ) for match in self .completion_matches ]
1509
1509
1510
1510
# Check if we need to restore a shortcut in the tab completions
1511
1511
# so it doesn't get erased from the command line
1512
1512
if shortcut_to_restore :
1513
- self ._completion_matches = \
1514
- [shortcut_to_restore + match for match in self ._completion_matches ]
1513
+ self .completion_matches = \
1514
+ [shortcut_to_restore + match for match in self .completion_matches ]
1515
1515
1516
1516
else :
1517
1517
# Complete token against anything a user can run
1518
- self ._completion_matches = self .basic_complete (text , line , begidx , endidx ,
1519
- self ._get_commands_aliases_and_macros_for_completion ())
1518
+ self .completion_matches = self .basic_complete (text , line , begidx , endidx ,
1519
+ self ._get_commands_aliases_and_macros_for_completion ())
1520
1520
1521
1521
# Handle single result
1522
- if len (self ._completion_matches ) == 1 :
1522
+ if len (self .completion_matches ) == 1 :
1523
1523
str_to_append = ''
1524
1524
1525
1525
# Add a closing quote if needed and allowed
@@ -1530,16 +1530,16 @@ def _complete_worker(self, text: str, state: int) -> Optional[str]:
1530
1530
if self .allow_appended_space and endidx == len (line ):
1531
1531
str_to_append += ' '
1532
1532
1533
- self ._completion_matches [0 ] += str_to_append
1533
+ self .completion_matches [0 ] += str_to_append
1534
1534
1535
1535
# Sort matches if they haven't already been sorted
1536
1536
if not self .matches_sorted :
1537
- self ._completion_matches .sort (key = self .matches_sort_key )
1537
+ self .completion_matches .sort (key = self .matches_sort_key )
1538
1538
self .display_matches .sort (key = self .matches_sort_key )
1539
1539
self .matches_sorted = True
1540
1540
1541
1541
try :
1542
- return self ._completion_matches [state ]
1542
+ return self .completion_matches [state ]
1543
1543
except IndexError :
1544
1544
return None
1545
1545
@@ -1631,7 +1631,7 @@ def sigint_handler(self, signum: int, frame) -> None:
1631
1631
self ._cur_pipe_proc_reader .send_sigint ()
1632
1632
1633
1633
# Check if we are allowed to re-raise the KeyboardInterrupt
1634
- if not self ._sigint_protection :
1634
+ if not self .sigint_protection :
1635
1635
raise KeyboardInterrupt ("Got a keyboard interrupt" )
1636
1636
1637
1637
def precmd (self , statement : Statement ) -> Statement :
@@ -1700,7 +1700,7 @@ def onecmd_plus_hooks(self, line: str, pyscript_bridge_call: bool = False) -> bo
1700
1700
1701
1701
try :
1702
1702
# Get sigint protection while we set up redirection
1703
- with self ._sigint_protection :
1703
+ with self .sigint_protection :
1704
1704
if pyscript_bridge_call :
1705
1705
# Start saving command's stdout at this point
1706
1706
self .stdout .pause_storage = False
@@ -1743,7 +1743,7 @@ def onecmd_plus_hooks(self, line: str, pyscript_bridge_call: bool = False) -> bo
1743
1743
self .pfeedback ('Elapsed: {}' .format (datetime .datetime .now () - timestart ))
1744
1744
finally :
1745
1745
# Get sigint protection while we restore stuff
1746
- with self ._sigint_protection :
1746
+ with self .sigint_protection :
1747
1747
if saved_state is not None :
1748
1748
self ._restore_output (statement , saved_state )
1749
1749
@@ -1765,7 +1765,7 @@ def onecmd_plus_hooks(self, line: str, pyscript_bridge_call: bool = False) -> bo
1765
1765
def _run_cmdfinalization_hooks (self , stop : bool , statement : Optional [Statement ]) -> bool :
1766
1766
"""Run the command finalization hooks"""
1767
1767
1768
- with self ._sigint_protection :
1768
+ with self .sigint_protection :
1769
1769
if not sys .platform .startswith ('win' ) and self .stdout .isatty ():
1770
1770
# Before the next command runs, fix any terminal problems like those
1771
1771
# caused by certain binary characters having been printed to it.
@@ -2147,10 +2147,10 @@ def _pseudo_raw_input(self, prompt: str) -> str:
2147
2147
if self .use_rawinput :
2148
2148
try :
2149
2149
if sys .stdin .isatty ():
2150
- # Wrap in try since _terminal_lock may not be locked when this function is called from unit tests
2150
+ # Wrap in try since terminal_lock may not be locked when this function is called from unit tests
2151
2151
try :
2152
2152
# A prompt is about to be drawn. Allow asynchronous changes to the terminal.
2153
- self ._terminal_lock .release ()
2153
+ self .terminal_lock .release ()
2154
2154
except RuntimeError :
2155
2155
pass
2156
2156
@@ -2166,7 +2166,7 @@ def _pseudo_raw_input(self, prompt: str) -> str:
2166
2166
finally :
2167
2167
if sys .stdin .isatty ():
2168
2168
# The prompt is gone. Do not allow asynchronous changes to the terminal.
2169
- self ._terminal_lock .acquire ()
2169
+ self .terminal_lock .acquire ()
2170
2170
else :
2171
2171
if self .stdin .isatty ():
2172
2172
# on a tty, print the prompt first, then read the line
@@ -2970,7 +2970,7 @@ def do_shell(self, args: argparse.Namespace) -> None:
2970
2970
2971
2971
# Prevent KeyboardInterrupts while in the shell process. The shell process will
2972
2972
# still receive the SIGINT since it is in the same process group as us.
2973
- with self ._sigint_protection :
2973
+ with self .sigint_protection :
2974
2974
# For any stream that is a StdSim, we will use a pipe so we can capture its output
2975
2975
proc = subprocess .Popen (expanded_command ,
2976
2976
stdout = subprocess .PIPE if isinstance (self .stdout , utils .StdSim ) else self .stdout ,
@@ -3490,7 +3490,7 @@ def _generate_transcript(self, history: List[Union[HistoryItem, str]], transcrip
3490
3490
3491
3491
commands_run = 0
3492
3492
try :
3493
- with self ._sigint_protection :
3493
+ with self .sigint_protection :
3494
3494
# Disable echo while we manually redirect stdout to a StringIO buffer
3495
3495
saved_echo = self .echo
3496
3496
saved_stdout = self .stdout
@@ -3535,7 +3535,7 @@ def _generate_transcript(self, history: List[Union[HistoryItem, str]], transcrip
3535
3535
if stop :
3536
3536
break
3537
3537
finally :
3538
- with self ._sigint_protection :
3538
+ with self .sigint_protection :
3539
3539
# Restore altered attributes to their original state
3540
3540
self .echo = saved_echo
3541
3541
self .stdout = saved_stdout
@@ -3655,7 +3655,7 @@ def do_run_script(self, args: argparse.Namespace) -> Optional[bool]:
3655
3655
return self .runcmds_plus_hooks (script_commands )
3656
3656
3657
3657
finally :
3658
- with self ._sigint_protection :
3658
+ with self .sigint_protection :
3659
3659
# Check if a script dir was added before an exception occurred
3660
3660
if orig_script_dir_count != len (self ._script_dir ):
3661
3661
self ._script_dir .pop ()
@@ -3765,14 +3765,14 @@ def async_alert(self, alert_msg: str, new_prompt: Optional[str] = None) -> None:
3765
3765
To the user it appears as if an alert message is printed above the prompt and their current input
3766
3766
text and cursor location is left alone.
3767
3767
3768
- IMPORTANT: This function will not print an alert unless it can acquire self._terminal_lock to ensure
3768
+ IMPORTANT: This function will not print an alert unless it can acquire self.terminal_lock to ensure
3769
3769
a prompt is onscreen. Therefore it is best to acquire the lock before calling this function
3770
3770
to guarantee the alert prints.
3771
3771
3772
3772
:param alert_msg: the message to display to the user
3773
3773
:param new_prompt: if you also want to change the prompt that is displayed, then include it here
3774
3774
see async_update_prompt() docstring for guidance on updating a prompt
3775
- :raises RuntimeError if called while another thread holds _terminal_lock
3775
+ :raises RuntimeError if called while another thread holds terminal_lock
3776
3776
"""
3777
3777
if not (vt100_support and self .use_rawinput ):
3778
3778
return
@@ -3781,8 +3781,8 @@ def async_alert(self, alert_msg: str, new_prompt: Optional[str] = None) -> None:
3781
3781
import colorama .ansi as ansi
3782
3782
from colorama import Cursor
3783
3783
3784
- # Sanity check that can't fail if self._terminal_lock was acquired before calling this function
3785
- if self ._terminal_lock .acquire (blocking = False ):
3784
+ # Sanity check that can't fail if self.terminal_lock was acquired before calling this function
3785
+ if self .terminal_lock .acquire (blocking = False ):
3786
3786
3787
3787
# Figure out what prompt is displaying
3788
3788
current_prompt = self .continuation_prompt if self ._at_continuation_prompt else self .prompt
@@ -3857,10 +3857,10 @@ def async_alert(self, alert_msg: str, new_prompt: Optional[str] = None) -> None:
3857
3857
# Redraw the prompt and input lines
3858
3858
rl_force_redisplay ()
3859
3859
3860
- self ._terminal_lock .release ()
3860
+ self .terminal_lock .release ()
3861
3861
3862
3862
else :
3863
- raise RuntimeError ("another thread holds _terminal_lock " )
3863
+ raise RuntimeError ("another thread holds terminal_lock " )
3864
3864
3865
3865
def async_update_prompt (self , new_prompt : str ) -> None : # pragma: no cover
3866
3866
"""
@@ -3870,7 +3870,7 @@ def async_update_prompt(self, new_prompt: str) -> None: # pragma: no cover
3870
3870
it is best to keep the prompt the same width as what's on screen. Otherwise the user's input text will
3871
3871
be shifted and the update will not be seamless.
3872
3872
3873
- IMPORTANT: This function will not update the prompt unless it can acquire self._terminal_lock to ensure
3873
+ IMPORTANT: This function will not update the prompt unless it can acquire self.terminal_lock to ensure
3874
3874
a prompt is onscreen. Therefore it is best to acquire the lock before calling this function
3875
3875
to guarantee the prompt changes.
3876
3876
@@ -3879,37 +3879,37 @@ def async_update_prompt(self, new_prompt: str) -> None: # pragma: no cover
3879
3879
and display immediately after the multiline line command completes.
3880
3880
3881
3881
:param new_prompt: what to change the prompt to
3882
- :raises RuntimeError if called while another thread holds _terminal_lock
3882
+ :raises RuntimeError if called while another thread holds terminal_lock
3883
3883
"""
3884
3884
self .async_alert ('' , new_prompt )
3885
3885
3886
3886
def set_window_title (self , title : str ) -> None : # pragma: no cover
3887
3887
"""
3888
3888
Set the terminal window title
3889
3889
3890
- IMPORTANT: This function will not set the title unless it can acquire self._terminal_lock to avoid
3890
+ IMPORTANT: This function will not set the title unless it can acquire self.terminal_lock to avoid
3891
3891
writing to stderr while a command is running. Therefore it is best to acquire the lock
3892
3892
before calling this function to guarantee the title changes.
3893
3893
3894
3894
:param title: the new window title
3895
- :raises RuntimeError if called while another thread holds _terminal_lock
3895
+ :raises RuntimeError if called while another thread holds terminal_lock
3896
3896
"""
3897
3897
if not vt100_support :
3898
3898
return
3899
3899
3900
- # Sanity check that can't fail if self._terminal_lock was acquired before calling this function
3901
- if self ._terminal_lock .acquire (blocking = False ):
3900
+ # Sanity check that can't fail if self.terminal_lock was acquired before calling this function
3901
+ if self .terminal_lock .acquire (blocking = False ):
3902
3902
try :
3903
3903
import colorama .ansi as ansi
3904
3904
sys .stderr .write (ansi .set_title (title ))
3905
3905
except AttributeError :
3906
3906
# Debugging in Pycharm has issues with setting terminal title
3907
3907
pass
3908
3908
finally :
3909
- self ._terminal_lock .release ()
3909
+ self .terminal_lock .release ()
3910
3910
3911
3911
else :
3912
- raise RuntimeError ("another thread holds _terminal_lock " )
3912
+ raise RuntimeError ("another thread holds terminal_lock " )
3913
3913
3914
3914
def enable_command (self , command : str ) -> None :
3915
3915
"""
@@ -4027,7 +4027,7 @@ def cmdloop(self, intro: Optional[str] = None) -> int:
4027
4027
signal .signal (signal .SIGINT , self .sigint_handler )
4028
4028
4029
4029
# Grab terminal lock before the prompt has been drawn by readline
4030
- self ._terminal_lock .acquire ()
4030
+ self .terminal_lock .acquire ()
4031
4031
4032
4032
# Always run the preloop first
4033
4033
for func in self ._preloop_hooks :
@@ -4056,7 +4056,7 @@ def cmdloop(self, intro: Optional[str] = None) -> int:
4056
4056
4057
4057
# Release terminal lock now that postloop code should have stopped any terminal updater threads
4058
4058
# This will also zero the lock count in case cmdloop() is called again
4059
- self ._terminal_lock .release ()
4059
+ self .terminal_lock .release ()
4060
4060
4061
4061
# Restore the original signal handler
4062
4062
signal .signal (signal .SIGINT , original_sigint_handler )
0 commit comments