Instagram / LibCST

A concrete syntax tree parser and serializer library for Python that preserves many aspects of Python's abstract syntax tree
https://libcst.readthedocs.io/
Other
1.56k stars 192 forks source link

Dangling `case` parenthesis result in `CSTValidationError` #1216

Open neob91-close opened 1 month ago

neob91-close commented 1 month ago

Libcst version

$ pip freeze | grep libcst
libcst==1.4.0

Reproduction

import libcst as cst
import libcst.matchers as m

source = """
def a():
    match b:
        case (
            c()
        ):
            pass
"""

tree = cst.parse_module(source)
m.findall(tree, m.ClassDef())  # errors with libcst._nodes.base.CSTValidationError: Cannot have left paren without right paren.

Exception

Traceback (most recent call last):
  File "/home/closeio/closeio/libcstbugrepro.py", line 14, in <module>
    m.findall(tree, m.ClassDef())  # errors with libcst._nodes.base.CSTValidationError: Cannot have left paren without right paren.
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/matchers/_matcher_base.py", line 1713, in findall
    nodes, _ = _find_or_extract_all(tree, matcher, metadata_resolver=metadata_resolver)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/matchers/_matcher_base.py", line 1680, in _find_or_extract_all
    tree.visit(finder)
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/module.py", line 89, in visit
    result = super(Module, self).visit(visitor)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/base.py", line 227, in visit
    _CSTNodeSelfT, self._visit_and_replace_children(visitor)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/module.py", line 74, in _visit_and_replace_children
    body=visit_body_sequence(self, "body", self.body, visitor),
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/internal.py", line 227, in visit_body_sequence
    return tuple(visit_body_iterable(parent, fieldname, children, visitor))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/internal.py", line 193, in visit_body_iterable
    new_child = child.visit(visitor)
                ^^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/base.py", line 227, in visit
    _CSTNodeSelfT, self._visit_and_replace_children(visitor)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/statement.py", line 1814, in _visit_and_replace_children
    body=visit_required(self, "body", self.body, visitor),
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/internal.py", line 81, in visit_required
    result = node.visit(visitor)
             ^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/base.py", line 227, in visit
    _CSTNodeSelfT, self._visit_and_replace_children(visitor)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/statement.py", line 698, in _visit_and_replace_children
    body=visit_body_sequence(self, "body", self.body, visitor),
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/internal.py", line 227, in visit_body_sequence
    return tuple(visit_body_iterable(parent, fieldname, children, visitor))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/internal.py", line 193, in visit_body_iterable
    new_child = child.visit(visitor)
                ^^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/base.py", line 227, in visit
    _CSTNodeSelfT, self._visit_and_replace_children(visitor)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/statement.py", line 2788, in _visit_and_replace_children
    cases=visit_sequence(self, "cases", self.cases, visitor),
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/internal.py", line 177, in visit_sequence
    return tuple(visit_iterable(parent, fieldname, children, visitor))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/internal.py", line 159, in visit_iterable
    new_child = child.visit(visitor)
                ^^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/base.py", line 227, in visit
    _CSTNodeSelfT, self._visit_and_replace_children(visitor)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/statement.py", line 2856, in _visit_and_replace_children
    pattern=visit_required(self, "pattern", self.pattern, visitor),
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/internal.py", line 81, in visit_required
    result = node.visit(visitor)
             ^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/base.py", line 227, in visit
    _CSTNodeSelfT, self._visit_and_replace_children(visitor)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/statement.py", line 3368, in _visit_and_replace_children
    return MatchClass(
           ^^^^^^^^^^^
  File "<string>", line 11, in __init__
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/base.py", line 117, in __post_init__
    self._validate()
  File "/home/closeio/venv/lib/python3.11/site-packages/libcst/_nodes/expression.py", line 231, in _validate
    raise CSTValidationError("Cannot have left paren without right paren.")
libcst._nodes.base.CSTValidationError: Cannot have left paren without right paren.