summaryrefslogtreecommitdiff
path: root/astroid
diff options
context:
space:
mode:
authorJacob Walls <jacobtylerwalls@gmail.com>2023-05-06 11:16:58 -0400
committerGitHub <noreply@github.com>2023-05-06 11:16:58 -0400
commit0740a0dd5e9cb48bb1a400aded498e4db1fcfca9 (patch)
treed5c9c22df809ed7d5e4bed8b8f3bd38193fa725a /astroid
parent06fafc4d023460c682494672b617d456037baf67 (diff)
downloadastroid-git-0740a0dd5e9cb48bb1a400aded498e4db1fcfca9.tar.gz
Complete cache key for inference tip (#2158)
The cache key was lacking the `context` arg. Co-authored-by: Sylvain Ackermann <sylvain.ackermann@gmail.com>
Diffstat (limited to 'astroid')
-rw-r--r--astroid/inference_tip.py30
1 files changed, 22 insertions, 8 deletions
diff --git a/astroid/inference_tip.py b/astroid/inference_tip.py
index 5b855c9e..92cb6b4f 100644
--- a/astroid/inference_tip.py
+++ b/astroid/inference_tip.py
@@ -9,6 +9,7 @@ from __future__ import annotations
import sys
from collections.abc import Callable, Iterator
+from astroid.context import InferenceContext
from astroid.exceptions import InferenceOverwriteError, UseInferenceDefault
from astroid.nodes import NodeNG
from astroid.typing import InferenceResult, InferFn
@@ -20,7 +21,11 @@ else:
_P = ParamSpec("_P")
-_cache: dict[tuple[InferFn, NodeNG], list[InferenceResult] | None] = {}
+_cache: dict[
+ tuple[InferFn, NodeNG, InferenceContext | None], list[InferenceResult]
+] = {}
+
+_CURRENTLY_INFERRING: set[tuple[InferFn, NodeNG]] = set()
def clear_inference_tip_cache() -> None:
@@ -35,16 +40,25 @@ def _inference_tip_cached(
def inner(*args: _P.args, **kwargs: _P.kwargs) -> Iterator[InferenceResult]:
node = args[0]
- try:
- result = _cache[func, node]
+ context = args[1]
+ partial_cache_key = (func, node)
+ if partial_cache_key in _CURRENTLY_INFERRING:
# If through recursion we end up trying to infer the same
# func + node we raise here.
- if result is None:
- raise UseInferenceDefault()
+ raise UseInferenceDefault
+ try:
+ return _cache[func, node, context]
except KeyError:
- _cache[func, node] = None
- result = _cache[func, node] = list(func(*args, **kwargs))
- assert result
+ # Recursion guard with a partial cache key.
+ # Using the full key causes a recursion error on PyPy.
+ # It's a pragmatic compromise to avoid so much recursive inference
+ # with slightly different contexts while still passing the simple
+ # test cases included with this commit.
+ _CURRENTLY_INFERRING.add(partial_cache_key)
+ result = _cache[func, node, context] = list(func(*args, **kwargs))
+ # Remove recursion guard.
+ _CURRENTLY_INFERRING.remove(partial_cache_key)
+
return iter(result)
return inner