Skip to content

Commit a56adc8

Browse files
authored
Optimize generic inference passes (#19501)
This gives around 5% perf boost for interpreted mypy (on self-check), but only 1.5-2% for compiled one. Note this is _not_ a no-op, this is a faster (and IMO actually more correct) inference passes logic. Btw, for more generics-rich code the savings may be bigger, e.g. `mypy -c "import colours"` becomes 30% faster (compiled).
1 parent 2e5d7ee commit a56adc8

File tree

1 file changed

+20
-21
lines changed

1 file changed

+20
-21
lines changed

mypy/checkexpr.py

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,14 +1755,6 @@ def check_callable_call(
17551755
return AnyType(TypeOfAny.from_error), callee
17561756
seen_unpack = True
17571757

1758-
formal_to_actual = map_actuals_to_formals(
1759-
arg_kinds,
1760-
arg_names,
1761-
callee.arg_kinds,
1762-
callee.arg_names,
1763-
lambda i: self.accept(args[i]),
1764-
)
1765-
17661758
# This is tricky: return type may contain its own type variables, like in
17671759
# def [S] (S) -> def [T] (T) -> tuple[S, T], so we need to update their ids
17681760
# to avoid possible id clashes if this call itself appears in a generic
@@ -1773,27 +1765,29 @@ def check_callable_call(
17731765
freeze_all_type_vars(fresh_ret_type)
17741766
callee = callee.copy_modified(ret_type=fresh_ret_type)
17751767

1768+
if callee.is_generic():
1769+
callee = freshen_function_type_vars(callee)
1770+
callee = self.infer_function_type_arguments_using_context(callee, context)
1771+
1772+
formal_to_actual = map_actuals_to_formals(
1773+
arg_kinds,
1774+
arg_names,
1775+
callee.arg_kinds,
1776+
callee.arg_names,
1777+
lambda i: self.accept(args[i]),
1778+
)
1779+
17761780
if callee.is_generic():
17771781
need_refresh = any(
17781782
isinstance(v, (ParamSpecType, TypeVarTupleType)) for v in callee.variables
17791783
)
1780-
callee = freshen_function_type_vars(callee)
1781-
callee = self.infer_function_type_arguments_using_context(callee, context)
1782-
if need_refresh:
1783-
# Argument kinds etc. may have changed due to
1784-
# ParamSpec or TypeVarTuple variables being replaced with an arbitrary
1785-
# number of arguments; recalculate actual-to-formal map
1786-
formal_to_actual = map_actuals_to_formals(
1787-
arg_kinds,
1788-
arg_names,
1789-
callee.arg_kinds,
1790-
callee.arg_names,
1791-
lambda i: self.accept(args[i]),
1792-
)
17931784
callee = self.infer_function_type_arguments(
17941785
callee, args, arg_kinds, arg_names, formal_to_actual, need_refresh, context
17951786
)
17961787
if need_refresh:
1788+
# Argument kinds etc. may have changed due to
1789+
# ParamSpec or TypeVarTuple variables being replaced with an arbitrary
1790+
# number of arguments; recalculate actual-to-formal map
17971791
formal_to_actual = map_actuals_to_formals(
17981792
arg_kinds,
17991793
arg_names,
@@ -2258,6 +2252,11 @@ def infer_function_type_arguments_pass2(
22582252
if isinstance(arg, (NoneType, UninhabitedType)) or has_erased_component(arg):
22592253
inferred_args[i] = None
22602254
callee_type = self.apply_generic_arguments(callee_type, inferred_args, context)
2255+
2256+
if not callee_type.is_generic():
2257+
# Fast path, second pass can't give new information.
2258+
return callee_type, []
2259+
22612260
if need_refresh:
22622261
formal_to_actual = map_actuals_to_formals(
22632262
arg_kinds,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy