diff --git a/ChangeLog b/ChangeLog index 118601d76..810798340 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). +* Astroid now correctly supports the ``exceptions`` attribute of ``ExceptionGroup``. + + 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..31b013e59 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,22 @@ from astroid.nodes import Expr, Raise, TryStar +@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( + """ + 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(