diff --git a/src/wormhole/_rlcompleter.py b/src/wormhole/_rlcompleter.py index 95288dc..c717ed1 100644 --- a/src/wormhole/_rlcompleter.py +++ b/src/wormhole/_rlcompleter.py @@ -134,11 +134,13 @@ class CodeInputter(object): raise AlreadyInputNameplateError("nameplate (%s-) already entered, cannot go back" % self._committed_nameplate) else: debug(" choose_nameplate(%s)" % nameplate) - self._input_helper.choose_nameplate(nameplate) + self.bcft(self._input_helper.choose_nameplate, nameplate) debug(" choose_words(%s)" % words) - self._input_helper.choose_words(words) + self.bcft(self._input_helper.choose_words, words) def _input_code_with_completion(prompt, input_helper, reactor): + # reminder: this all occurs in a separate thread. All calls to input_helper + # must go through blockingCallFromThread() c = CodeInputter(input_helper, reactor) if readline is not None: if readline.__doc__ and "libedit" in readline.__doc__: diff --git a/src/wormhole/test/test_rlcompleter.py b/src/wormhole/test/test_rlcompleter.py index f21e55f..41f0abf 100644 --- a/src/wormhole/test/test_rlcompleter.py +++ b/src/wormhole/test/test_rlcompleter.py @@ -147,11 +147,15 @@ def get_completions(c, prefix): return completions completions.append(text) +def fake_blockingCallFromThread(f, *a, **kw): + return f(*a, **kw) + class Completion(unittest.TestCase): def test_simple(self): # no actual completion helper = mock.Mock() c = CodeInputter(helper, "reactor") + c.bcft = fake_blockingCallFromThread c.finish("1-code-ghost") self.assertFalse(c.used_completion) self.assertEqual(helper.mock_calls, @@ -164,6 +168,7 @@ class Completion(unittest.TestCase): # check that it calls _commit_and_build_completions correctly helper = mock.Mock() c = CodeInputter(helper, "reactor") + c.bcft = fake_blockingCallFromThread # pretend nameplates: 1, 12, 34 @@ -304,12 +309,13 @@ class Completion(unittest.TestCase): self.assertEqual(gwc.mock_calls, [mock.call("and-b")]) gwc.reset_mock() - c.finish("12-and-bat") + yield deferToThread(c.finish, "12-and-bat") self.assertEqual(cw.mock_calls, [mock.call("and-bat")]) def test_incomplete_code(self): helper = mock.Mock() c = CodeInputter(helper, "reactor") + c.bcft = fake_blockingCallFromThread with self.assertRaises(KeyFormatError) as e: c.finish("1") self.assertEqual(str(e.exception), "incomplete wormhole code") @@ -349,7 +355,7 @@ class Completion(unittest.TestCase): self.assertEqual(matches, ["1-code", "1-court"]) helper.reset_mock() with self.assertRaises(AlreadyInputNameplateError) as e: - c.finish("2-code") + yield deferToThread(c.finish, "2-code") self.assertEqual(str(e.exception), "nameplate (1-) already entered, cannot go back") self.assertEqual(helper.mock_calls, [])