Skip to content

Commit efa7548

Browse files
committed
Added exception handling to account for non-standard Python environments in which readline is not loaded dynamically from a shared library file
1 parent aeb517d commit efa7548

File tree

3 files changed

+28
-13
lines changed

3 files changed

+28
-13
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
## 0.9.21 (TBD, 2019)
22
* Bug Fixes
33
* Fixed bug where pipe processes were not being stopped by Ctrl-C
4+
* Added exception handling to account for non-standard Python environments in which readline is not loaded
5+
dynamically from a shared library file
6+
47
* Enhancements
58
* Added `read_input()` function that is used to read from stdin. Unlike the Python built-in `input()`, it also has
69
an argument to disable tab completion while input is being entered.

cmd2/cmd2.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,10 @@
5252
from .decorators import with_argparser
5353
from .history import History, HistoryItem
5454
from .parsing import StatementParser, Statement, Macro, MacroArg, shlex_split
55-
from .rl_utils import rl_type, RlType, rl_get_point, rl_set_prompt, vt100_support, rl_make_safe_prompt
55+
from .rl_utils import rl_type, RlType, rl_get_point, rl_set_prompt, vt100_support, rl_make_safe_prompt, rl_warning
5656

5757
# Set up readline
5858
if rl_type == RlType.NONE: # pragma: no cover
59-
rl_warning = ("Readline features including tab completion have been disabled since no\n"
60-
"supported version of readline was found. To resolve this, install pyreadline\n"
61-
"on Windows or gnureadline on Mac.\n\n")
6259
sys.stderr.write(ansi.style_warning(rl_warning))
6360
else:
6461
from .rl_utils import rl_force_redisplay, readline

cmd2/rl_utils.py

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ class RlType(Enum):
3232
# Tells if the terminal we are running in supports vt100 control characters
3333
vt100_support = False
3434

35+
# Explanation for why readline wasn't loaded
36+
_rl_warn_reason = ''
37+
3538
# The order of this check matters since importing pyreadline will also show readline in the modules list
3639
if 'pyreadline' in sys.modules:
3740
rl_type = RlType.PYREADLINE
@@ -113,15 +116,27 @@ def pyreadline_remove_history_item(pos: int) -> None:
113116
elif 'gnureadline' in sys.modules or 'readline' in sys.modules:
114117
# We don't support libedit
115118
if 'libedit' not in readline.__doc__:
116-
rl_type = RlType.GNU
117-
118-
# Load the readline lib so we can access members of it
119-
import ctypes
120-
readline_lib = ctypes.CDLL(readline.__file__)
121-
122-
# Check if we are running in a terminal
123-
if sys.stdout.isatty():
124-
vt100_support = True
119+
try:
120+
# Load the readline lib so we can access members of it
121+
import ctypes
122+
readline_lib = ctypes.CDLL(readline.__file__)
123+
except AttributeError:
124+
_rl_warn_reason = ("this application is running in a non-standard Python environment in\n"
125+
"which readline is not loaded dynamically from a shared library file")
126+
else:
127+
rl_type = RlType.GNU
128+
if sys.stdout.isatty():
129+
vt100_support = True
130+
131+
# Check if readline was loaded
132+
if rl_type == RlType.NONE:
133+
if not _rl_warn_reason:
134+
_rl_warn_reason = ("no supported version of readline was found. To resolve this, install\n"
135+
"pyreadline on Windows or gnureadline on Mac.")
136+
rl_warning = ("Readline features including tab completion have been disabled because\n" +
137+
_rl_warn_reason + '\n\n')
138+
else:
139+
rl_warning = ''
125140

126141

127142
# noinspection PyProtectedMember,PyUnresolvedReferences

0 commit comments

Comments
 (0)