diff --git a/ChangeLog b/ChangeLog index f6cf04df14..7b49fdf5b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,6 +17,11 @@ What's New in astroid 3.0.2? ============================ Release date: TBA +* Avoid duplicate inference results for some uses of ``typing.X`` constructs like + ``Tuple[Optional[int], ...]``. This was causing pylint to occasionally omit + messages like ``deprecated-typing-alias``. + + Closes pylint-dev/pylint#9220 What's New in astroid 3.0.1? diff --git a/astroid/brain/brain_typing.py b/astroid/brain/brain_typing.py index d4b2ca0a5a..ea49644083 100644 --- a/astroid/brain/brain_typing.py +++ b/astroid/brain/brain_typing.py @@ -188,6 +188,8 @@ def infer_typing_attr( cache = node.parent.__cache # type: ignore[attr-defined] # Unrecognized getattr if cache.get(node.parent.slots) is not None: del cache[node.parent.slots] + # Avoid re-instantiating this class every time it's seen + node._explicit_inference = lambda node, context: iter([value]) return iter([value]) node = extract_node(TYPING_TYPE_TEMPLATE.format(value.qname().split(".")[-1])) @@ -393,6 +395,8 @@ def infer_special_alias( class_def.postinit(bases=[res], body=[], decorators=None) func_to_add = _extract_single_node(CLASS_GETITEM_TEMPLATE) class_def.locals["__class_getitem__"] = [func_to_add] + # Avoid re-instantiating this class every time it's seen + node._explicit_inference = lambda node, context: iter([class_def]) return iter([class_def]) diff --git a/tests/brain/test_brain.py b/tests/brain/test_brain.py index 12cdd5cf7d..aebf005889 100644 --- a/tests/brain/test_brain.py +++ b/tests/brain/test_brain.py @@ -668,6 +668,16 @@ def test_typing_no_duplicates(self): ) assert len(node.inferred()) == 1 + @test_utils.require_version(minver="3.9") + def test_typing_no_duplicates_2(self): + node = builder.extract_node( + """ + from typing import Optional, Tuple + Tuple[Optional[int], ...] + """ + ) + assert len(node.inferred()) == 1 + def test_collections_generic_alias_slots(self): """Test slots for a class which is a subclass of a generic alias type.""" node = builder.extract_node(