Skip to content

Commit c5aaee5

Browse files
committed
Fixed AttributeError in rl_get_prompt() when prompt is None.
1 parent c7aae95 commit c5aaee5

3 files changed

Lines changed: 22 additions & 26 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 2.3.0 (TBD, 2021)
2+
* Bug Fixes
3+
* Fixed `AttributeError` in `rl_get_prompt()` when prompt is `None`.
4+
15
## 2.2.0 (September 14, 2021)
26
* Bug Fixes
37
* Fixed extra space appended to each alias by "alias list" command

cmd2/cmd2.py

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5011,15 +5011,14 @@ def async_alert(self, alert_msg: str, new_prompt: Optional[str] = None) -> None:
50115011
To the user it appears as if an alert message is printed above the prompt and their current input
50125012
text and cursor location is left alone.
50135013
5014-
Raises a `RuntimeError` if called while another thread holds `terminal_lock`.
5015-
50165014
IMPORTANT: This function will not print an alert unless it can acquire self.terminal_lock to ensure
50175015
a prompt is onscreen. Therefore it is best to acquire the lock before calling this function
50185016
to guarantee the alert prints and to avoid raising a RuntimeError.
50195017
50205018
:param alert_msg: the message to display to the user
50215019
:param new_prompt: If you also want to change the prompt that is displayed, then include it here.
50225020
See async_update_prompt() docstring for guidance on updating a prompt.
5021+
:raises RuntimeError: if called while another thread holds `terminal_lock`
50235022
"""
50245023
if not (vt100_support and self.use_rawinput):
50255024
return
@@ -5082,8 +5081,6 @@ def async_update_prompt(self, new_prompt: str) -> None: # pragma: no cover
50825081
prompt, it is best to keep the prompt the same width as what's on screen. Otherwise the user's input text will
50835082
be shifted and the update will not be seamless.
50845083
5085-
Raises a `RuntimeError` if called while another thread holds `terminal_lock`.
5086-
50875084
IMPORTANT: This function will not update the prompt unless it can acquire self.terminal_lock to ensure
50885085
a prompt is onscreen. Therefore it is best to acquire the lock before calling this function
50895086
to guarantee the prompt changes and to avoid raising a RuntimeError.
@@ -5093,36 +5090,29 @@ def async_update_prompt(self, new_prompt: str) -> None: # pragma: no cover
50935090
line command completes.
50945091
50955092
:param new_prompt: what to change the prompt to
5093+
:raises RuntimeError: if called while another thread holds `terminal_lock`
50965094
"""
50975095
self.async_alert('', new_prompt)
50985096

5099-
def set_window_title(self, title: str) -> None: # pragma: no cover
5100-
"""Set the terminal window title.
5101-
5102-
Raises a `RuntimeError` if called while another thread holds `terminal_lock`.
5097+
@staticmethod
5098+
def set_window_title(title: str) -> None: # pragma: no cover
5099+
"""
5100+
Set the terminal window title.
51035101
5104-
IMPORTANT: This function will not set the title unless it can acquire self.terminal_lock to avoid writing
5105-
to stderr while a command is running. Therefore it is best to acquire the lock before calling
5106-
this function to guarantee the title changes and to avoid raising a RuntimeError.
5102+
NOTE: This function writes to stderr. Therefore if you call this during a command run by a pyscript,
5103+
the string which updates the title will appear in that command's CommandResult.stderr data.
51075104
51085105
:param title: the new window title
51095106
"""
51105107
if not vt100_support:
51115108
return
51125109

5113-
# Sanity check that can't fail if self.terminal_lock was acquired before calling this function
5114-
if self.terminal_lock.acquire(blocking=False):
5115-
try:
5116-
sys.stderr.write(ansi.set_title_str(title))
5117-
sys.stderr.flush()
5118-
except AttributeError:
5119-
# Debugging in Pycharm has issues with setting terminal title
5120-
pass
5121-
finally:
5122-
self.terminal_lock.release()
5123-
5124-
else:
5125-
raise RuntimeError("another thread holds terminal_lock")
5110+
try:
5111+
sys.stderr.write(ansi.set_title_str(title))
5112+
sys.stderr.flush()
5113+
except AttributeError:
5114+
# Debugging in Pycharm has issues with setting terminal title
5115+
pass
51265116

51275117
def enable_command(self, command: str) -> None:
51285118
"""

cmd2/rl_utils.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
)
99
from typing import (
1010
Union,
11-
cast,
1211
)
1312

1413
# Prefer statically linked gnureadline if available (for macOS compatibility due to issues with libedit)
@@ -197,7 +196,10 @@ def rl_get_prompt() -> str: # pragma: no cover
197196
"""Gets Readline's current prompt"""
198197
if rl_type == RlType.GNU:
199198
encoded_prompt = ctypes.c_char_p.in_dll(readline_lib, "rl_prompt").value
200-
prompt = cast(bytes, encoded_prompt).decode(encoding='utf-8')
199+
if encoded_prompt is None:
200+
prompt = ''
201+
else:
202+
prompt = encoded_prompt.decode(encoding='utf-8')
201203

202204
elif rl_type == RlType.PYREADLINE:
203205
prompt_data: Union[str, bytes] = readline.rl.prompt

0 commit comments

Comments
 (0)