Skip to content

Commit 55857ec

Browse files
committed
bug, refactor, test: make pragma history_length work interactively
history_length could be set interactively, but it was never used to set readline/pyreadline3's internal state. Using the pragma setting on the roundup-admin command line did set readline's state. Also refactored 2 calls to self.readline.get_current_history_length() into one call and storing in a variable. Also changed method for creating history strings for printing. Tests added for history_length pragma on cli and interactive use. Added test for exiting roundup-admin with EOF on input. Added test for 'readline nosuchdirective' error case. Added test to readline with a command directive to set an internal variable. This last one has no real test to see if it was successful because I can't emulate a real keyboard/tty which is needed to test.
1 parent c53b5cd commit 55857ec

File tree

3 files changed

+151
-5
lines changed

3 files changed

+151
-5
lines changed

CHANGES.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ Fixed:
2626
- cleaned up repo. Close obsolete branches and close a split head due
2727
to an identical merge intwo different workicng copies. (John
2828
Rouillard)
29+
- in roundup-admin, using 'pragma history_length interactively now
30+
sets readline history length. Using -P history_length=10 on the
31+
command line always worked. (John Rouillard)
2932

3033
Features:
3134

roundup/admin.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1821,6 +1821,11 @@ def do_pragma(self, args):
18211821
type(self.settings[setting]).__name__)
18221822
self.settings[setting] = value
18231823

1824+
# history_length has to be pushed to readline to have any effect.
1825+
if setting == "history_length":
1826+
self.readline.set_history_length(
1827+
self.settings['history_length'])
1828+
18241829
def do_readline(self, args):
18251830
''"""Usage: readline initrc_line | 'emacs' | 'history' | 'reload' | 'vi'
18261831
@@ -1881,13 +1886,12 @@ def do_readline(self, args):
18811886
self.readline.parse_and_bind("set editing-mode emacs")
18821887
print(_("Enabled emacs mode."))
18831888
elif args[0] == "history":
1884-
print("history size",
1885-
self.readline.get_current_history_length())
1889+
history_size = self.readline.get_current_history_length()
1890+
print("history size", history_size)
18861891
print('\n'.join([
1887-
str("%3d " % (i + 1) +
1892+
"%3d %s" % ((i + 1),
18881893
self.readline.get_history_item(i + 1))
1889-
for i in range(
1890-
self.readline.get_current_history_length())
1894+
for i in range(history_size)
18911895
]))
18921896
elif args[0] == "reload":
18931897
try:

test/test_admin.py

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,31 @@ def testBasicInteractive(self):
184184

185185
AdminTool.my_input = orig_input
186186

187+
# test EOF exit
188+
inputs = ["help"]
189+
190+
self._monkeypatch.setattr(
191+
'sys.stdin',
192+
io.StringIO("\n".join(inputs)))
193+
194+
# preserve directory self.install_init()
195+
self.admin=AdminTool()
196+
197+
# disable all features
198+
self.admin.settings['history_features'] = 7
199+
sys.argv=['main', '-i', self.dirname]
200+
201+
with captured_output() as (out, err):
202+
ret = self.admin.main()
203+
out = out.getvalue().strip().split('\n')
204+
205+
print(ret)
206+
self.assertTrue(ret == 0)
207+
208+
# 4 includes 2 commands in saved history
209+
expected = 'roundup> exit...'
210+
self.assertIn(expected, out)
211+
187212
def testGet(self):
188213
''' Note the tests will fail if you run this under pdb.
189214
the context managers capture the pdb prompts and this screws
@@ -1947,6 +1972,120 @@ def testReadline(self):
19471972

19481973
self.assertIn(expected, out)
19491974

1975+
# --- test 3,4 - make sure readline gets history_length pragma.
1976+
# test CLI and interactive.
1977+
1978+
inputs = ["pragma list", "q"]
1979+
1980+
self._monkeypatch.setattr(
1981+
'sys.stdin',
1982+
io.StringIO("\n".join(inputs)))
1983+
1984+
self.install_init()
1985+
self.admin=AdminTool()
1986+
1987+
# disable all config/history
1988+
self.admin.settings['history_features'] = 7
1989+
sys.argv=['main', '-i', self.dirname, '-P', 'history_length=11']
1990+
1991+
with captured_output() as (out, err):
1992+
ret = self.admin.main()
1993+
out = out.getvalue().strip().split('\n')
1994+
1995+
print(ret)
1996+
self.assertTrue(ret == 0)
1997+
self.assertEqual(self.admin.readline.get_history_length(),
1998+
11)
1999+
2000+
# 4
2001+
inputs = ["pragma history_length=17", "q"]
2002+
2003+
self._monkeypatch.setattr(
2004+
'sys.stdin',
2005+
io.StringIO("\n".join(inputs)))
2006+
2007+
self.install_init()
2008+
self.admin=AdminTool()
2009+
2010+
# disable all config/history
2011+
self.admin.settings['history_features'] = 7
2012+
# keep pragma in CLI. Make sure it's overridden by interactive
2013+
sys.argv=['main', '-i', self.dirname, '-P', 'history_length=11']
2014+
2015+
with captured_output() as (out, err):
2016+
ret = self.admin.main()
2017+
out = out.getvalue().strip().split('\n')
2018+
2019+
print(ret)
2020+
self.assertTrue(ret == 0)
2021+
# should not be 11.
2022+
self.assertEqual(self.admin.readline.get_history_length(),
2023+
17)
2024+
2025+
# --- test 5 invalid single word parameter
2026+
2027+
inputs = ["readline nosuchdirective", "q"]
2028+
2029+
self._monkeypatch.setattr(
2030+
'sys.stdin',
2031+
io.StringIO("\n".join(inputs)))
2032+
2033+
self.install_init()
2034+
self.admin=AdminTool()
2035+
2036+
# disable loading and saving history
2037+
self.admin.settings['history_features'] = 3
2038+
sys.argv=['main', '-i', self.dirname]
2039+
2040+
with captured_output() as (out, err):
2041+
ret = self.admin.main()
2042+
out = out.getvalue().strip().split('\n')
2043+
2044+
print(ret)
2045+
self.assertTrue(ret == 0)
2046+
2047+
expected = ('roundup> Unknown readline parameter nosuchdirective')
2048+
2049+
self.assertIn(expected, out)
2050+
2051+
# --- test 6 set keystroke command.
2052+
# FIXME: unable to test key binding/setting actually works.
2053+
#
2054+
# No errors seem to come back from readline or
2055+
# pyreadline3 even when the keybinding makes no
2056+
# sense. Errors are only reported when reading
2057+
# from init file. Using "set answer 42" does print
2058+
# 'readline: answer: unknown variable name' when
2059+
# attached to tty/pty and interactive, but not
2060+
# inside test case. Pyreadline3 doesn't
2061+
# report errors at all.
2062+
#
2063+
# Even if I set a keybidning, I can't invoke it
2064+
# because I am not running inside a pty, so
2065+
# editing is disabled and I have no way to
2066+
# simulate keyboard keystrokes for readline to act
2067+
# upon.
2068+
2069+
inputs = ['readline set meaning 42', "q"]
2070+
2071+
self._monkeypatch.setattr(
2072+
'sys.stdin',
2073+
io.StringIO("\n".join(inputs)))
2074+
2075+
self.install_init()
2076+
self.admin=AdminTool()
2077+
2078+
# disable loading and saving history
2079+
self.admin.settings['history_features'] = 3
2080+
sys.argv=['main', '-i', self.dirname]
2081+
2082+
with captured_output() as (out, err):
2083+
ret = self.admin.main()
2084+
out = out.getvalue().strip().split('\n')
2085+
2086+
print(ret)
2087+
self.assertTrue(ret == 0)
2088+
19502089
# === cleanup
19512090
if original_home:
19522091
os.environ['HOME'] = original_home

0 commit comments

Comments
 (0)