Skip to content

Commit cf8763a

Browse files
Use the inference cache when no context is provided (#2257)
1 parent 3f812fa commit cf8763a

File tree

3 files changed

+29
-13
lines changed

3 files changed

+29
-13
lines changed

ChangeLog

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ Release date: TBA
5151
Closes pylint-dev/pylint#7464
5252
Closes pylint-dev/pylint#8074
5353

54+
* Use the global inference cache when inferring, even without an explicit
55+
``InferenceContext``. This is a significant performance improvement given how
56+
often methods default to ``None`` for the context argument. (Linting ``astroid``
57+
itself now takes ~5% less time on Python 3.12; other projects requiring more
58+
complex inference calculations will see greater speedups.)
59+
60+
Refs #529
61+
5462
* Fix interrupted ``InferenceContext`` call chains, thereby addressing performance
5563
problems when linting ``sqlalchemy``.
5664

astroid/nodes/node_ng.py

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -138,18 +138,13 @@ def infer(
138138
:returns: The inferred values.
139139
:rtype: iterable
140140
"""
141-
if context is not None:
141+
if context is None:
142+
context = InferenceContext()
143+
else:
142144
context = context.extra_context.get(self, context)
143145
if self._explicit_inference is not None:
144146
# explicit_inference is not bound, give it self explicitly
145147
try:
146-
if context is None:
147-
yield from self._explicit_inference(
148-
self, # type: ignore[arg-type]
149-
context,
150-
**kwargs,
151-
)
152-
return
153148
for result in self._explicit_inference(
154149
self, # type: ignore[arg-type]
155150
context,
@@ -161,11 +156,6 @@ def infer(
161156
except UseInferenceDefault:
162157
pass
163158

164-
if not context:
165-
# nodes_inferred?
166-
yield from self._infer(context=context, **kwargs)
167-
return
168-
169159
key = (self, context.lookupname, context.callcontext, context.boundnode)
170160
if key in context.inferred:
171161
yield from context.inferred[key]

tests/test_inference.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6157,6 +6157,24 @@ class InferMeTwice:
61576157
assert util.Uninferable not in instance.igetattr("item", context_to_be_used_twice)
61586158

61596159

6160+
@patch("astroid.nodes.Call._infer")
6161+
def test_cache_usage_without_explicit_context(mock) -> None:
6162+
code = """
6163+
class InferMeTwice:
6164+
item = 10
6165+
6166+
InferMeTwice()
6167+
"""
6168+
call = extract_node(code)
6169+
mock.return_value = [Uninferable]
6170+
6171+
# no explicit InferenceContext
6172+
call.inferred()
6173+
call.inferred()
6174+
6175+
mock.assert_called_once()
6176+
6177+
61606178
def test_infer_context_manager_with_unknown_args() -> None:
61616179
code = """
61626180
class client_log(object):

0 commit comments

Comments
 (0)