Skip to content

Commit

Permalink
Improve dictionary completion performance.
Browse files Browse the repository at this point in the history
This improves the performance for dictionary-like objects where iterating over
the keys is fast, but doing a lookup for the values is slow. This change
ensures we only do value lookups when really needed.
  • Loading branch information
jonathanslenders committed Jul 22, 2024
1 parent 79cb14b commit d001a37
Showing 1 changed file with 13 additions and 8 deletions.
21 changes: 13 additions & 8 deletions ptpython/completer.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,15 +476,20 @@ def _get_item_lookup_completions(
Complete dictionary keys.
"""

def meta_repr(value: object) -> Callable[[], str]:
def meta_repr(obj: object, key: object) -> Callable[[], str]:
"Abbreviate meta text, make sure it fits on one line."

# We return a function, so that it gets computed when it's needed.
# When there are many completions, that improves the performance
# quite a bit (for the multi-column completion menu, we only need
# to display one meta text).
def get_value_repr() -> str:
text = self._do_repr(value)
try:
value = obj[key]

text = self._do_repr(value)
except BaseException:
return "-"

# Take first line, if multiple lines.
if "\n" in text:
Expand All @@ -504,24 +509,24 @@ def get_value_repr() -> str:
# If this object is a dictionary, complete the keys.
if isinstance(result, (dict, collections_abc.Mapping)):
# Try to evaluate the key.
key_obj = key
key_obj_str = str(key)
for k in [key, key + '"', key + "'"]:
try:
key_obj = ast.literal_eval(k)
key_obj_str = str(ast.literal_eval(k))
except (SyntaxError, ValueError):
continue
else:
break

for k, v in result.items():
if str(k).startswith(str(key_obj)):
for k in result:
if str(k).startswith(key_obj_str):
try:
k_repr = self._do_repr(k)
yield Completion(
k_repr + "]",
-len(key),
display=f"[{k_repr}]",
display_meta=meta_repr(v),
display_meta=meta_repr(result, k),
)
except ReprFailedError:
pass
Expand All @@ -537,7 +542,7 @@ def get_value_repr() -> str:
k_repr + "]",
-len(key),
display=f"[{k_repr}]",
display_meta=meta_repr(result[k]),
display_meta=meta_repr(result, k),
)
except KeyError:
# `result[k]` lookup failed. Trying to complete
Expand Down

0 comments on commit d001a37

Please sign in to comment.