Skip to content

Commit a56ebec

Browse files
authored
checkexpr: speedup argument count check (#12703)
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.
1 parent dd6d786 commit a56ebec

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

mypy/checkexpr.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,10 +1386,11 @@ def check_argument_count(self,
13861386

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

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

13941395
ok, is_unexpected_arg_error = self.check_for_extra_actual_arguments(
13951396
callee, actual_types, actual_kinds, actual_names, all_actuals, context)
@@ -1423,7 +1424,7 @@ def check_for_extra_actual_arguments(self,
14231424
actual_types: List[Type],
14241425
actual_kinds: List[ArgKind],
14251426
actual_names: Optional[Sequence[Optional[str]]],
1426-
all_actuals: List[int],
1427+
all_actuals: Dict[int, int],
14271428
context: Context) -> Tuple[bool, bool]:
14281429
"""Check for extra actual arguments.
14291430
@@ -1457,7 +1458,7 @@ def check_for_extra_actual_arguments(self,
14571458
or kind == nodes.ARG_STAR2):
14581459
actual_type = get_proper_type(actual_types[i])
14591460
if isinstance(actual_type, (TupleType, TypedDictType)):
1460-
if all_actuals.count(i) < len(actual_type.items):
1461+
if all_actuals.get(i, 0) < len(actual_type.items):
14611462
# Too many tuple/dict items as some did not match.
14621463
if (kind != nodes.ARG_STAR2
14631464
or not isinstance(actual_type, TypedDictType)):

0 commit comments

Comments
 (0)