From 8a1ce0faed1e8e15d2bb6a266c9f5fa71ed5e2d7 2020-02-27 17:53:21 From: Matthias Bussonnier Date: 2020-02-27 17:53:21 Subject: [PATCH] Merge pull request #12144 from meeseeksmachine/auto-backport-of-pr-12130-on-7.x Backport PR #12130 on branch 7.x (Ensure set_custom_completer is working. Fixes #11272) --- diff --git a/.travis.yml b/.travis.yml index a70f00a..9bb3a9b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -72,7 +72,7 @@ matrix: - arch: arm64 python: "3.7" dist: xenial - env: ARM64=True + env: ARM64=True IPYTHON_TESTING_TIMEOUT_SCALE=2 sudo: true - arch: amd64 python: "3.8-dev" diff --git a/IPython/core/completer.py b/IPython/core/completer.py index 0942798..9a81d63 100644 --- a/IPython/core/completer.py +++ b/IPython/core/completer.py @@ -626,6 +626,8 @@ class Completer(Configurable): else: self.global_namespace = global_namespace + self.custom_matchers = [] + super(Completer, self).__init__(**kwargs) def complete(self, text, state): @@ -1122,12 +1124,14 @@ class IPCompleter(Completer): if self.use_jedi: return [ + *self.custom_matchers, self.file_matches, self.magic_matches, self.dict_key_matches, ] else: return [ + *self.custom_matchers, self.python_matches, self.file_matches, self.magic_matches, diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index 4cbc885..848a14a 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -2218,7 +2218,7 @@ class InteractiveShell(SingletonConfigurable): list where you want the completer to be inserted.""" newcomp = types.MethodType(completer,self.Completer) - self.Completer.matchers.insert(pos,newcomp) + self.Completer.custom_matchers.insert(pos,newcomp) def set_completer_frame(self, frame=None): """Set the frame of the completer.""" diff --git a/IPython/core/tests/test_interactiveshell.py b/IPython/core/tests/test_interactiveshell.py index 578ef27..496e3bd 100644 --- a/IPython/core/tests/test_interactiveshell.py +++ b/IPython/core/tests/test_interactiveshell.py @@ -998,3 +998,21 @@ def test_should_run_async(): assert not ip.should_run_async("a = 5") assert ip.should_run_async("await x") assert ip.should_run_async("import asyncio; await asyncio.sleep(1)") + + +def test_set_custom_completer(): + num_completers = len(ip.Completer.matchers) + + def foo(*args, **kwargs): + return "I'm a completer!" + + ip.set_custom_completer(foo, 0) + + # check that we've really added a new completer + assert len(ip.Completer.matchers) == num_completers + 1 + + # check that the first completer is the function we defined + assert ip.Completer.matchers[0]() == "I'm a completer!" + + # clean up + ip.Completer.custom_matchers.pop()