Skip to content

Commit

Permalink
checkexpr: speedup argument count check (python#12703)
Browse files Browse the repository at this point in the history
Replace List with Dict to avoid O(n**2) behavior in `check_for_extra_actual_arguments`

This manifests for instance when initializing a set with `set([...])` instead of a set
literal `{...}`. For large sets of literals (~80k entries) this change bring the
typechecking of a single set initializer from over 1 min down to under 1s.
  • Loading branch information
huguesb committed May 1, 2022
1 parent dd6d786 commit a56ebec
Showing 1 changed file with 6 additions and 5 deletions.
11 changes: 6 additions & 5 deletions mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -1386,10 +1386,11 @@ def check_argument_count(self,

# TODO(jukka): We could return as soon as we find an error if messages is None.

# Collect list of all actual arguments matched to formal arguments.
all_actuals: List[int] = []
# Collect dict of all actual arguments matched to formal arguments, with occurrence count
all_actuals: Dict[int, int] = {}
for actuals in formal_to_actual:
all_actuals.extend(actuals)
for a in actuals:
all_actuals[a] = all_actuals.get(a, 0) + 1

ok, is_unexpected_arg_error = self.check_for_extra_actual_arguments(
callee, actual_types, actual_kinds, actual_names, all_actuals, context)
Expand Down Expand Up @@ -1423,7 +1424,7 @@ def check_for_extra_actual_arguments(self,
actual_types: List[Type],
actual_kinds: List[ArgKind],
actual_names: Optional[Sequence[Optional[str]]],
all_actuals: List[int],
all_actuals: Dict[int, int],
context: Context) -> Tuple[bool, bool]:
"""Check for extra actual arguments.
Expand Down Expand Up @@ -1457,7 +1458,7 @@ def check_for_extra_actual_arguments(self,
or kind == nodes.ARG_STAR2):
actual_type = get_proper_type(actual_types[i])
if isinstance(actual_type, (TupleType, TypedDictType)):
if all_actuals.count(i) < len(actual_type.items):
if all_actuals.get(i, 0) < len(actual_type.items):
# Too many tuple/dict items as some did not match.
if (kind != nodes.ARG_STAR2
or not isinstance(actual_type, TypedDictType)):
Expand Down

0 comments on commit a56ebec

Please sign in to comment.