diff --git a/IPython/core/completer.py b/IPython/core/completer.py index e442cb2..dcee838 100644 --- a/IPython/core/completer.py +++ b/IPython/core/completer.py @@ -780,14 +780,20 @@ def match_dict_keys(keys: List[Union[str, bytes, Tuple[Union[str, bytes]]]], pre """ prefix_tuple = extra_prefix if extra_prefix else () Nprefix = len(prefix_tuple) - def filter_by_prefix_tuple(key): + def filter_prefix_tuple(key): + # Reject too short keys if len(key) <= Nprefix: return False + # Reject keys with non str/bytes in it + for k in key: + if not isinstance(k, (str, bytes)): + return False + # Reject keys that do not match the prefix for k, pt in zip(key, prefix_tuple): if k != pt: return False - else: - return True + # All checks passed! + return True filtered_keys:List[Union[str,bytes]] = [] def _add_to_filtered_keys(key): @@ -796,7 +802,7 @@ def match_dict_keys(keys: List[Union[str, bytes, Tuple[Union[str, bytes]]]], pre for k in keys: if isinstance(k, tuple): - if filter_by_prefix_tuple(k): + if filter_prefix_tuple(k): _add_to_filtered_keys(k[Nprefix]) else: _add_to_filtered_keys(k) diff --git a/IPython/core/tests/test_completer.py b/IPython/core/tests/test_completer.py index 45e85d4..e9d8b51 100644 --- a/IPython/core/tests/test_completer.py +++ b/IPython/core/tests/test_completer.py @@ -920,12 +920,16 @@ class TestCompleter(unittest.TestCase): "bad": None, object(): None, 5: None, + ("abe", None): None, + (None, "abf"): None } _, matches = complete(line_buffer="d['a") nt.assert_in("abc", matches) nt.assert_in("abd", matches) nt.assert_not_in("bad", matches) + nt.assert_not_in("abe", matches) + nt.assert_not_in("abf", matches) assert not any(m.endswith(("]", '"', "'")) for m in matches), matches # check escaping and whitespace