From e49f43395d8046aea712d7bd6cfdefd23c726703 Mon Sep 17 00:00:00 2001 From: Jacob Walls Date: Sun, 15 May 2022 17:11:02 -0400 Subject: [PATCH] Add a bound to the inference tips cache (#1565) --- ChangeLog | 4 ++++ astroid/inference_tip.py | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 06a7163ff6..22c6df4609 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24,6 +24,10 @@ Release date: TBA * Rename ``ModuleSpec`` -> ``module_type`` constructor parameter to match attribute name and improve typing. Use ``type`` instead. +* Add a bound to the inference tips cache. + + Closes #1150 + * Infer the return value of the ``.copy()`` method on ``dict``, ``list``, ``set``, and ``frozenset``. diff --git a/astroid/inference_tip.py b/astroid/inference_tip.py index 341efd631e..97e7ac525f 100644 --- a/astroid/inference_tip.py +++ b/astroid/inference_tip.py @@ -7,6 +7,7 @@ from __future__ import annotations import typing +from collections import OrderedDict from collections.abc import Iterator import wrapt @@ -20,7 +21,7 @@ NodeNG, bases.Instance, bases.UnboundMethod, typing.Type[util.Uninferable] ] -_cache: dict[tuple[InferFn, NodeNG], list[InferOptions] | None] = {} +_cache: OrderedDict[tuple[InferFn, NodeNG], list[InferOptions] | None] = OrderedDict() def clear_inference_tip_cache(): @@ -36,11 +37,14 @@ def _inference_tip_cached( node = args[0] try: result = _cache[func, node] + _cache.move_to_end((func, node)) # If through recursion we end up trying to infer the same # func + node we raise here. if result is None: raise UseInferenceDefault() except KeyError: + if len(_cache) > 127: + _cache.popitem(last=False) _cache[func, node] = None result = _cache[func, node] = list(func(*args, **kwargs)) assert result