Skip to content

Commit 3933fc9

Browse files
committed
Avoid filter_errors overhead on every function call
Move the filter_errors context manager behind a cheap pre-check so that only calls matching the shifted-argument pattern (all positional args, exactly one arg short) use it. This keeps the hot path for the vast majority of function calls completely unchanged. Made-with: Cursor
1 parent 1ff910c commit 3933fc9

File tree

1 file changed

+39
-11
lines changed

1 file changed

+39
-11
lines changed

mypy/checkexpr.py

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,8 +1792,45 @@ def check_callable_call(
17921792

17931793
arg_types = self.infer_arg_types_in_context(callee, args, arg_kinds, formal_to_actual)
17941794

1795-
with self.msg.filter_errors(save_filtered_errors=True) as w:
1796-
ok = self.check_argument_count(
1795+
# Cheap pre-check: only use filter_errors when this could be a shifted-argument
1796+
# pattern (all positional args, exactly one arg short). This avoids adding any
1797+
# overhead to the hot path for the vast majority of function calls.
1798+
might_have_shifted_args = (
1799+
not self.msg.prefer_simple_messages()
1800+
and all(k == ARG_POS for k in callee.arg_kinds)
1801+
and all(k == ARG_POS for k in arg_kinds)
1802+
and len(arg_kinds) == len(callee.arg_kinds) - 1
1803+
)
1804+
1805+
if might_have_shifted_args:
1806+
with self.msg.filter_errors(save_filtered_errors=True) as w:
1807+
ok = self.check_argument_count(
1808+
callee,
1809+
arg_types,
1810+
arg_kinds,
1811+
arg_names,
1812+
formal_to_actual,
1813+
context,
1814+
object_type,
1815+
callable_name,
1816+
)
1817+
if not ok and self._detect_missing_positional_arg(
1818+
callee, arg_types, arg_kinds, args, context
1819+
):
1820+
pass
1821+
else:
1822+
self.msg.add_errors(w.filtered_errors())
1823+
self.check_argument_types(
1824+
arg_types,
1825+
arg_kinds,
1826+
args,
1827+
callee,
1828+
formal_to_actual,
1829+
context,
1830+
object_type=object_type,
1831+
)
1832+
else:
1833+
self.check_argument_count(
17971834
callee,
17981835
arg_types,
17991836
arg_kinds,
@@ -1803,15 +1840,6 @@ def check_callable_call(
18031840
object_type,
18041841
callable_name,
18051842
)
1806-
1807-
if (
1808-
not ok
1809-
and not self.msg.prefer_simple_messages()
1810-
and self._detect_missing_positional_arg(callee, arg_types, arg_kinds, args, context)
1811-
):
1812-
pass
1813-
else:
1814-
self.msg.add_errors(w.filtered_errors())
18151843
self.check_argument_types(
18161844
arg_types,
18171845
arg_kinds,

0 commit comments

Comments
 (0)