summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--astroid/__init__.py1
-rw-r--r--astroid/node_classes.py1
-rw-r--r--astroid/nodes/__init__.py2
-rw-r--r--astroid/nodes/as_string.py22
-rw-r--r--astroid/nodes/node_ng.py2
-rw-r--r--astroid/rebuilder.py6
-rw-r--r--doc/api/astroid.nodes.rst3
-rw-r--r--tests/test_group_exceptions.py8
9 files changed, 41 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 3ee8ee60..1bb82999 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,6 +12,10 @@ What's New in astroid 2.15.4?
=============================
Release date: TBA
+* Add visitor function for ``TryStar`` to ``AsStringVisitor`` and
+ add ``TryStar`` to ``astroid.nodes.ALL_NODE_CLASSES``.
+
+ Refs #2142
What's New in astroid 2.15.3?
diff --git a/astroid/__init__.py b/astroid/__init__.py
index 605a8b48..bcb0c2c2 100644
--- a/astroid/__init__.py
+++ b/astroid/__init__.py
@@ -165,6 +165,7 @@ from astroid.nodes import ( # pylint: disable=redefined-builtin (Ellipsis)
Subscript,
TryExcept,
TryFinally,
+ TryStar,
Tuple,
UnaryOp,
Unknown,
diff --git a/astroid/node_classes.py b/astroid/node_classes.py
index 9ea1e8d2..64709632 100644
--- a/astroid/node_classes.py
+++ b/astroid/node_classes.py
@@ -76,6 +76,7 @@ from astroid.nodes.node_classes import ( # pylint: disable=redefined-builtin (E
Subscript,
TryExcept,
TryFinally,
+ TryStar,
Tuple,
UnaryOp,
Unknown,
diff --git a/astroid/nodes/__init__.py b/astroid/nodes/__init__.py
index b527ff7c..157aa242 100644
--- a/astroid/nodes/__init__.py
+++ b/astroid/nodes/__init__.py
@@ -197,6 +197,7 @@ ALL_NODE_CLASSES = (
Subscript,
TryExcept,
TryFinally,
+ TryStar,
Tuple,
UnaryOp,
Unknown,
@@ -291,6 +292,7 @@ __all__ = (
"Subscript",
"TryExcept",
"TryFinally",
+ "TryStar",
"Tuple",
"UnaryOp",
"Unknown",
diff --git a/astroid/nodes/as_string.py b/astroid/nodes/as_string.py
index cbd5ee17..ae55ab8b 100644
--- a/astroid/nodes/as_string.py
+++ b/astroid/nodes/as_string.py
@@ -9,6 +9,8 @@ from __future__ import annotations
from collections.abc import Iterator
from typing import TYPE_CHECKING
+from astroid import nodes
+
if TYPE_CHECKING:
from astroid.nodes import Const
from astroid.nodes.node_classes import (
@@ -254,13 +256,16 @@ class AsStringVisitor:
return ""
def visit_excepthandler(self, node) -> str:
+ n = "except"
+ if isinstance(getattr(node, "parent", None), nodes.TryStar):
+ n = "except*"
if node.type:
if node.name:
- excs = f"except {node.type.accept(self)} as {node.name.accept(self)}"
+ excs = f"{n} {node.type.accept(self)} as {node.name.accept(self)}"
else:
- excs = f"except {node.type.accept(self)}"
+ excs = f"{n} {node.type.accept(self)}"
else:
- excs = "except"
+ excs = f"{n}"
return f"{excs}:\n{self._stmt_list(node.body)}"
def visit_empty(self, node) -> str:
@@ -495,6 +500,17 @@ class AsStringVisitor:
self._stmt_list(node.body), self._stmt_list(node.finalbody)
)
+ def visit_trystar(self, node) -> str:
+ """return an astroid.TryStar node as string"""
+ trys = [f"try:\n{self._stmt_list(node.body)}"]
+ for handler in node.handlers:
+ trys.append(handler.accept(self))
+ if node.orelse:
+ trys.append(f"else:\n{self._stmt_list(node.orelse)}")
+ if node.finalbody:
+ trys.append(f"finally:\n{self._stmt_list(node.finalbody)}")
+ return "\n".join(trys)
+
def visit_tuple(self, node) -> str:
"""return an astroid.Tuple node as string"""
if len(node.elts) == 1:
diff --git a/astroid/nodes/node_ng.py b/astroid/nodes/node_ng.py
index 617f8ba4..3f8222e2 100644
--- a/astroid/nodes/node_ng.py
+++ b/astroid/nodes/node_ng.py
@@ -590,7 +590,7 @@ class NodeNG:
yield from ()
def _infer_name(self, frame, name):
- # overridden for ImportFrom, Import, Global, TryExcept and Arguments
+ # overridden for ImportFrom, Import, Global, TryExcept, TryStar and Arguments
pass
def _infer(
diff --git a/astroid/rebuilder.py b/astroid/rebuilder.py
index 6e996def..0d409c49 100644
--- a/astroid/rebuilder.py
+++ b/astroid/rebuilder.py
@@ -507,6 +507,12 @@ class TreeRebuilder:
) -> nodes.TryExcept | nodes.TryFinally:
...
+ if sys.version_info >= (3, 11):
+
+ @overload
+ def visit(self, node: ast.TryStar, parent: NodeNG) -> nodes.TryStar:
+ ...
+
@overload
def visit(self, node: ast.Tuple, parent: NodeNG) -> nodes.Tuple:
...
diff --git a/doc/api/astroid.nodes.rst b/doc/api/astroid.nodes.rst
index 7372cdd5..3e99e93b 100644
--- a/doc/api/astroid.nodes.rst
+++ b/doc/api/astroid.nodes.rst
@@ -80,6 +80,7 @@ Nodes
astroid.nodes.Subscript
astroid.nodes.TryExcept
astroid.nodes.TryFinally
+ astroid.nodes.TryStar
astroid.nodes.Tuple
astroid.nodes.UnaryOp
astroid.nodes.Unknown
@@ -230,6 +231,8 @@ Nodes
.. autoclass:: astroid.nodes.TryFinally
+.. autoclass:: astroid.nodes.TryStar
+
.. autoclass:: astroid.nodes.Tuple
.. autoclass:: astroid.nodes.UnaryOp
diff --git a/tests/test_group_exceptions.py b/tests/test_group_exceptions.py
index 173c25ed..11065aa4 100644
--- a/tests/test_group_exceptions.py
+++ b/tests/test_group_exceptions.py
@@ -54,9 +54,8 @@ def test_group_exceptions() -> None:
@pytest.mark.skipif(not PY311_PLUS, reason="Requires Python 3.11 or higher")
def test_star_exceptions() -> None:
- node = extract_node(
- textwrap.dedent(
- """
+ code = textwrap.dedent(
+ """
try:
raise ExceptionGroup("group", [ValueError(654)])
except* ValueError:
@@ -67,9 +66,10 @@ def test_star_exceptions() -> None:
sys.exit(127)
finally:
sys.exit(0)"""
- )
)
+ node = extract_node(code)
assert isinstance(node, TryStar)
+ assert node.as_string() == code.replace('"', "'").strip()
assert isinstance(node.body[0], Raise)
assert node.block_range(1) == (1, 11)
assert node.block_range(2) == (2, 2)