From fd1955aaa9cffa6f0bb084973dc3fb2fce727791 Mon Sep 17 00:00:00 2001 From: Mark Byrne Date: Tue, 23 Sep 2025 16:17:17 +0200 Subject: [PATCH 1/4] Fix a false positive for ``not-an-iterable`` in an ``ExceptionGroup`` context. Closes pylint-dev/pylint#8985 Closes pylint-dev/pylint#10558 --- ChangeLog | 5 +++++ astroid/interpreter/objectmodel.py | 7 +++++++ tests/test_group_exceptions.py | 16 ++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/ChangeLog b/ChangeLog index 118601d76..089bec3e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -85,6 +85,11 @@ Release date: TBA * Improve ``as_string()`` representation for ``TypeVar``, ``ParamSpec`` and ``TypeVarTuple`` nodes, as well as type parameter in ``ClassDef``, ``FuncDef`` and ``TypeAlias`` nodes (PEP 695). +* Fix a false positive for ``not-an-iterable`` in an ``ExceptionGroup`` context. + + Closes pylint-dev/pylint#8985 + Closes pylint-dev/pylint#10558 + What's New in astroid 3.3.11? ============================= diff --git a/astroid/interpreter/objectmodel.py b/astroid/interpreter/objectmodel.py index 085bd2cc8..31ef12e41 100644 --- a/astroid/interpreter/objectmodel.py +++ b/astroid/interpreter/objectmodel.py @@ -770,6 +770,12 @@ def attr_text(self): return node_classes.Const("") +class GroupExceptionInstanceModel(ExceptionInstanceModel): + @property + def attr_exceptions(self) -> nodes.Tuple: + return node_classes.Tuple(parent=self._instance) + + class OSErrorInstanceModel(ExceptionInstanceModel): @property def attr_filename(self): @@ -804,6 +810,7 @@ def attr_object(self): BUILTIN_EXCEPTIONS = { "builtins.SyntaxError": SyntaxErrorInstanceModel, + "builtins.ExceptionGroup": GroupExceptionInstanceModel, "builtins.ImportError": ImportErrorInstanceModel, "builtins.UnicodeDecodeError": UnicodeDecodeErrorInstanceModel, # These are all similar to OSError in terms of attributes diff --git a/tests/test_group_exceptions.py b/tests/test_group_exceptions.py index b3808f3a7..6f4754990 100644 --- a/tests/test_group_exceptions.py +++ b/tests/test_group_exceptions.py @@ -12,6 +12,7 @@ List, Name, Try, + Tuple, Uninferable, bases, extract_node, @@ -21,6 +22,21 @@ from astroid.nodes import Expr, Raise, TryStar +@pytest.mark.skipif(not PY311_PLUS, reason="Requires Python 3.11 or higher") +def test_group_exceptions_exceptions() -> None: + node = extract_node( + textwrap.dedent( + """ + try: + raise ExceptionGroup('', [TypeError(), TypeError()]) + except ExceptionGroup as eg: + eg.exceptions #@""" + ) + ) + + inferred = node.inferred()[0] + assert isinstance(inferred, Tuple) + @pytest.mark.skipif(not PY311_PLUS, reason="Requires Python 3.11 or higher") def test_group_exceptions() -> None: node = extract_node( From f95c4e97474a299477818cee69fca5b9f7e9de2e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 23 Sep 2025 14:20:55 +0000 Subject: [PATCH 2/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/test_group_exceptions.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_group_exceptions.py b/tests/test_group_exceptions.py index 6f4754990..5222bdc41 100644 --- a/tests/test_group_exceptions.py +++ b/tests/test_group_exceptions.py @@ -37,6 +37,7 @@ def test_group_exceptions_exceptions() -> None: inferred = node.inferred()[0] assert isinstance(inferred, Tuple) + @pytest.mark.skipif(not PY311_PLUS, reason="Requires Python 3.11 or higher") def test_group_exceptions() -> None: node = extract_node( From fd64822bddf533a7e11f269ef279568ac224a5ce Mon Sep 17 00:00:00 2001 From: Mark Byrne <31762852+mbyrnepr2@users.noreply.github.com> Date: Tue, 23 Sep 2025 21:18:39 +0200 Subject: [PATCH 3/4] Update test_group_exceptions.py Co-authored-by: Pierre Sassoulas --- tests/test_group_exceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_group_exceptions.py b/tests/test_group_exceptions.py index 5222bdc41..31b013e59 100644 --- a/tests/test_group_exceptions.py +++ b/tests/test_group_exceptions.py @@ -22,7 +22,7 @@ from astroid.nodes import Expr, Raise, TryStar -@pytest.mark.skipif(not PY311_PLUS, reason="Requires Python 3.11 or higher") +@pytest.mark.skipif(not PY311_PLUS, reason="Exception group introduced in Python 3.11") def test_group_exceptions_exceptions() -> None: node = extract_node( textwrap.dedent( From 5a255674a070e968a6df900766f27f76ecb7d38f Mon Sep 17 00:00:00 2001 From: Mark Byrne Date: Fri, 26 Sep 2025 11:14:11 +0200 Subject: [PATCH 4/4] Improve Changelog entry wording. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mention what is newly supported in Astroid. Co-authored-by: Daniƫl van Noord <13665637+DanielNoord@users.noreply.github.com> --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 089bec3e2..810798340 100644 --- a/ChangeLog +++ b/ChangeLog @@ -85,7 +85,7 @@ Release date: TBA * Improve ``as_string()`` representation for ``TypeVar``, ``ParamSpec`` and ``TypeVarTuple`` nodes, as well as type parameter in ``ClassDef``, ``FuncDef`` and ``TypeAlias`` nodes (PEP 695). -* Fix a false positive for ``not-an-iterable`` in an ``ExceptionGroup`` context. +* Astroid now correctly supports the ``exceptions`` attribute of ``ExceptionGroup``. Closes pylint-dev/pylint#8985 Closes pylint-dev/pylint#10558