From 21f1467bc36d067eb813c96e216a4cdda2d047d5 2022-09-07 03:00:23 From: krassowski <5832902+krassowski@users.noreply.github.com> Date: 2022-09-07 03:00:23 Subject: [PATCH] Correct suppression defaults, add a test for #13735 --- diff --git a/IPython/core/completer.py b/IPython/core/completer.py index f15fabb..e00d81e 100644 --- a/IPython/core/completer.py +++ b/IPython/core/completer.py @@ -1337,7 +1337,8 @@ class IPCompleter(Completer): ) suppress_competing_matchers = UnionTrait( - [Bool(), DictTrait(Bool(None, allow_none=True))], + [Bool(allow_none=True), DictTrait(Bool(None, allow_none=True))], + default_value=None, help=""" Whether to suppress completions from other *Matchers*. @@ -2703,13 +2704,14 @@ class IPCompleter(Completer): if not suppressed_matchers: suppression_recommended = result.get("suppress", False) + suppression_config = ( + self.suppress_competing_matchers.get(matcher_id, None) + if isinstance(self.suppress_competing_matchers, dict) + else self.suppress_competing_matchers + ) should_suppress = ( - self.suppress_competing_matchers is True - or suppression_recommended - or ( - isinstance(self.suppress_competing_matchers, dict) - and self.suppress_competing_matchers[matcher_id] - ) + (suppression_config is True) + or (suppression_recommended and (suppression_config is not False)) ) and len(result["completions"]) if should_suppress: diff --git a/IPython/core/magics/config.py b/IPython/core/magics/config.py index f93561a..f442ba1 100644 --- a/IPython/core/magics/config.py +++ b/IPython/core/magics/config.py @@ -139,7 +139,7 @@ class ConfigMagics(Magics): ``IPCompleter.merge_completions`` and can be beneficial for performance, but will sometimes omit relevant candidates from matchers further down the priority list. - Current: False + Current: None IPCompleter.use_jedi= Experimental: Use Jedi to generate autocompletions. Default to True if jedi is installed. diff --git a/IPython/core/tests/test_completer.py b/IPython/core/tests/test_completer.py index e47cf1a..c675a9a 100644 --- a/IPython/core/tests/test_completer.py +++ b/IPython/core/tests/test_completer.py @@ -1295,6 +1295,36 @@ class TestCompleter(unittest.TestCase): for c in completions: self.assertEqual(c.text[0], "%") + def test_dict_key_restrict_to_dicts(self): + """Test that dict key suppresses non-dict completion items""" + ip = get_ipython() + c = ip.Completer + d = {"abc": None} + ip.user_ns["d"] = d + + text = 'd["a' + + def _(): + with provisionalcompleter(): + c.use_jedi = True + return [ + completion.text for completion in c.completions(text, len(text)) + ] + + completions = _() + self.assertEqual(completions, ["abc"]) + + # check that it can be disabled in granular manner: + cfg = Config() + cfg.IPCompleter.suppress_competing_matchers = { + "IPCompleter.dict_key_matcher": False + } + c.update_config(cfg) + + completions = _() + self.assertIn("abc", completions) + self.assertGreater(len(completions), 1) + def test_matcher_suppression(self): @completion_matcher(identifier="a_matcher") def a_matcher(text): @@ -1326,16 +1356,34 @@ class TestCompleter(unittest.TestCase): c = ip.Completer def _(text, expected): - with provisionalcompleter(): - c.use_jedi = False - s, matches = c.complete(text) - self.assertEqual(expected, matches) + c.use_jedi = False + s, matches = c.complete(text) + self.assertEqual(expected, matches) _("do not suppress", ["completion_a", "completion_b", "completion_c"]) _("suppress all", ["completion_b"]) _("suppress all but a", ["completion_a", "completion_b"]) _("suppress all but c", ["completion_b", "completion_c"]) + def configure(suppression_config): + cfg = Config() + cfg.IPCompleter.suppress_competing_matchers = suppression_config + c.update_config(cfg) + + # test that configuration takes priority over the run-time decisions + + configure(False) + _("suppress all", ["completion_a", "completion_b", "completion_c"]) + + configure({"b_matcher": False}) + _("suppress all", ["completion_a", "completion_b", "completion_c"]) + + configure({"a_matcher": False}) + _("suppress all", ["completion_b"]) + + configure({"b_matcher": True}) + _("do not suppress", ["completion_b"]) + def test_matcher_disabling(self): @completion_matcher(identifier="a_matcher") def a_matcher(text): @@ -1346,10 +1394,8 @@ class TestCompleter(unittest.TestCase): return ["completion_b"] def _(expected): - with provisionalcompleter(): - c.use_jedi = False - s, matches = c.complete("completion_") - self.assertEqual(expected, matches) + s, matches = c.complete("completion_") + self.assertEqual(expected, matches) with custom_matchers([a_matcher, b_matcher]): ip = get_ipython() @@ -1376,10 +1422,8 @@ class TestCompleter(unittest.TestCase): return {"completions": [SimpleCompletion("completion_b")], "suppress": True} def _(expected): - with provisionalcompleter(): - c.use_jedi = False - s, matches = c.complete("completion_") - self.assertEqual(expected, matches) + s, matches = c.complete("completion_") + self.assertEqual(expected, matches) with custom_matchers([a_matcher, b_matcher]): ip = get_ipython()