From eef0fbb5edae99dd2221f595f67ebaacab8696e7 Mon Sep 17 00:00:00 2001 From: thereversiblewheel Date: Thu, 3 Jul 2025 15:01:54 +0000 Subject: [PATCH 1/9] rm: ci --- .github/workflows/ci.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5147f457..8389b608 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,11 +39,6 @@ jobs: run: uv sync --locked --dev - name: Native Parser Tests run: uv run poe test - - name: Pure Parser Tests - env: - COVERAGE_FILE: .coverage.pure - LIBCST_PARSER_TYPE: pure - run: uv run poe test - name: Coverage run: | uv run coverage combine .coverage.pure From 157fd0a32c0eddf0cbec9dc625ded93f915a1a0a Mon Sep 17 00:00:00 2001 From: thereversiblewheel Date: Thu, 3 Jul 2025 16:08:09 +0000 Subject: [PATCH 2/9] rm: entry point --- libcst/_parser/entrypoints.py | 70 +++++++---------------------------- 1 file changed, 13 insertions(+), 57 deletions(-) diff --git a/libcst/_parser/entrypoints.py b/libcst/_parser/entrypoints.py index d9cee5e9..74c8f9a0 100644 --- a/libcst/_parser/entrypoints.py +++ b/libcst/_parser/entrypoints.py @@ -9,7 +9,6 @@ information """ -import os from functools import partial from typing import Union @@ -17,18 +16,13 @@ from libcst._nodes.expression import BaseExpression from libcst._nodes.module import Module from libcst._nodes.statement import BaseCompoundStatement, SimpleStatementLine -from libcst._parser.detect_config import convert_to_utf8, detect_config -from libcst._parser.grammar import get_grammar, validate_grammar -from libcst._parser.python_parser import PythonCSTParser +from libcst._parser.detect_config import convert_to_utf8 from libcst._parser.types.config import PartialParserConfig _DEFAULT_PARTIAL_PARSER_CONFIG: PartialParserConfig = PartialParserConfig() -def is_native() -> bool: - typ = os.environ.get("LIBCST_PARSER_TYPE") - return typ != "pure" - +from libcst import native def _parse( entrypoint: str, @@ -38,57 +32,19 @@ def _parse( detect_trailing_newline: bool, detect_default_newline: bool, ) -> CSTNode: - if is_native(): - from libcst.native import parse_expression, parse_module, parse_statement - - encoding, source_str = convert_to_utf8(source, partial=config) - - if entrypoint == "file_input": - parse = partial(parse_module, encoding=encoding) - elif entrypoint == "stmt_input": - parse = parse_statement - elif entrypoint == "expression_input": - parse = parse_expression - else: - raise ValueError(f"Unknown parser entry point: {entrypoint}") - - return parse(source_str) - return _pure_python_parse( - entrypoint, - source, - config, - detect_trailing_newline=detect_trailing_newline, - detect_default_newline=detect_default_newline, - ) + encoding, source_str = convert_to_utf8(source, partial=config) -def _pure_python_parse( - entrypoint: str, - source: Union[str, bytes], - config: PartialParserConfig, - *, - detect_trailing_newline: bool, - detect_default_newline: bool, -) -> CSTNode: - detection_result = detect_config( - source, - partial=config, - detect_trailing_newline=detect_trailing_newline, - detect_default_newline=detect_default_newline, - ) - validate_grammar() - grammar = get_grammar(config.parsed_python_version, config.future_imports) - - parser = PythonCSTParser( - tokens=detection_result.tokens, - config=detection_result.config, - pgen_grammar=grammar, - start_nonterminal=entrypoint, - ) - # The parser has an Any return type, we can at least refine it to CSTNode here. - result = parser.parse() - assert isinstance(result, CSTNode) - return result + if entrypoint == "file_input": + parse = partial(native.parse_module, encoding=encoding) + elif entrypoint == "stmt_input": + parse = native.parse_statement + elif entrypoint == "expression_input": + parse = native.parse_expression + else: + raise ValueError(f"Unknown parser entry point: {entrypoint}") + + return parse(source_str) def parse_module( From 7be04ac305a85387ff79270c9e95e8ef1c7a784b Mon Sep 17 00:00:00 2001 From: thereversiblewheel Date: Thu, 3 Jul 2025 16:17:36 +0000 Subject: [PATCH 3/9] fix: tests --- libcst/_nodes/tests/test_atom.py | 3 +-- libcst/_nodes/tests/test_binary_op.py | 3 +-- libcst/_nodes/tests/test_classdef.py | 3 --- libcst/_nodes/tests/test_dict.py | 3 +-- libcst/_nodes/tests/test_funcdef.py | 11 +---------- libcst/_nodes/tests/test_list.py | 3 +-- libcst/_nodes/tests/test_match.py | 5 +---- libcst/_nodes/tests/test_matrix_multiply.py | 3 +-- libcst/_nodes/tests/test_module.py | 4 ++-- libcst/_nodes/tests/test_set.py | 3 +-- libcst/_nodes/tests/test_try.py | 6 ++---- libcst/_nodes/tests/test_tuple.py | 4 ++-- libcst/_nodes/tests/test_type_alias.py | 6 +----- libcst/_nodes/tests/test_with.py | 14 +++++++------- libcst/_nodes/tests/test_yield.py | 4 ++-- libcst/_parser/tests/test_parse_errors.py | 4 +--- libcst/codemod/tests/test_codemod_cli.py | 16 +++++----------- libcst/metadata/tests/test_scope_provider.py | 16 +--------------- libcst/tests/__main__.py | 5 +---- libcst/tests/test_roundtrip.py | 4 +--- 20 files changed, 33 insertions(+), 87 deletions(-) diff --git a/libcst/_nodes/tests/test_atom.py b/libcst/_nodes/tests/test_atom.py index 82f7ab99..a33732c2 100644 --- a/libcst/_nodes/tests/test_atom.py +++ b/libcst/_nodes/tests/test_atom.py @@ -9,7 +9,6 @@ import libcst as cst from libcst import parse_expression from libcst._nodes.tests.base import CSTNodeTest, parse_expression_as -from libcst._parser.entrypoints import is_native from libcst.metadata import CodeRange from libcst.testing.utils import data_provider @@ -1184,7 +1183,7 @@ def test_invalid(self, **kwargs: Any) -> None: ) ) def test_versions(self, **kwargs: Any) -> None: - if is_native() and not kwargs.get("expect_success", True): + if not kwargs.get("expect_success", True): self.skipTest("parse errors are disabled for native parser") self.assert_parses(**kwargs) diff --git a/libcst/_nodes/tests/test_binary_op.py b/libcst/_nodes/tests/test_binary_op.py index b86af9fe..fddc90e1 100644 --- a/libcst/_nodes/tests/test_binary_op.py +++ b/libcst/_nodes/tests/test_binary_op.py @@ -8,7 +8,6 @@ import libcst as cst from libcst import parse_expression from libcst._nodes.tests.base import CSTNodeTest -from libcst._parser.entrypoints import is_native from libcst.metadata import CodeRange from libcst.testing.utils import data_provider @@ -189,4 +188,4 @@ def test_invalid(self, **kwargs: Any) -> None: ) ) def test_parse_error(self, **kwargs: Any) -> None: - self.assert_parses(**kwargs, expect_success=not is_native()) + self.assert_parses(**kwargs, expect_success=False ) diff --git a/libcst/_nodes/tests/test_classdef.py b/libcst/_nodes/tests/test_classdef.py index cca36fbb..2e026a6c 100644 --- a/libcst/_nodes/tests/test_classdef.py +++ b/libcst/_nodes/tests/test_classdef.py @@ -8,7 +8,6 @@ import libcst as cst from libcst import parse_statement from libcst._nodes.tests.base import CSTNodeTest -from libcst._parser.entrypoints import is_native from libcst.metadata import CodeRange from libcst.testing.utils import data_provider @@ -210,8 +209,6 @@ def test_valid(self, **kwargs: Any) -> None: ) ) def test_valid_native(self, **kwargs: Any) -> None: - if not is_native(): - self.skipTest("Disabled for pure python parser") self.validate_node(**kwargs) @data_provider( diff --git a/libcst/_nodes/tests/test_dict.py b/libcst/_nodes/tests/test_dict.py index 1ee33332..47cb0663 100644 --- a/libcst/_nodes/tests/test_dict.py +++ b/libcst/_nodes/tests/test_dict.py @@ -8,7 +8,6 @@ import libcst as cst from libcst import parse_expression from libcst._nodes.tests.base import CSTNodeTest, parse_expression_as -from libcst._parser.entrypoints import is_native from libcst.metadata import CodeRange from libcst.testing.utils import data_provider @@ -188,6 +187,6 @@ def test_invalid(self, **kwargs: Any) -> None: ) ) def test_versions(self, **kwargs: Any) -> None: - if is_native() and not kwargs.get("expect_success", True): + if not kwargs.get("expect_success", True): self.skipTest("parse errors are disabled for native parser") self.assert_parses(**kwargs) diff --git a/libcst/_nodes/tests/test_funcdef.py b/libcst/_nodes/tests/test_funcdef.py index 65a0ff07..4ed7fcc3 100644 --- a/libcst/_nodes/tests/test_funcdef.py +++ b/libcst/_nodes/tests/test_funcdef.py @@ -8,7 +8,6 @@ import libcst as cst from libcst import parse_statement from libcst._nodes.tests.base import CSTNodeTest, DummyIndentedBlock, parse_statement_as -from libcst._parser.entrypoints import is_native from libcst.metadata import CodeRange from libcst.testing.utils import data_provider @@ -741,8 +740,6 @@ class FunctionDefCreationTest(CSTNodeTest): ) ) def test_valid(self, **kwargs: Any) -> None: - if not is_native() and kwargs.get("native_only", False): - self.skipTest("Disabled for native parser") if "native_only" in kwargs: kwargs.pop("native_only") self.validate_node(**kwargs) @@ -891,8 +888,6 @@ def test_valid(self, **kwargs: Any) -> None: ) ) def test_valid_native(self, **kwargs: Any) -> None: - if not is_native(): - self.skipTest("Disabled for pure python parser") self.validate_node(**kwargs) @data_provider( @@ -2223,8 +2218,6 @@ def test_valid(self, node: cst.CSTNode, code: str) -> None: ) ) def test_valid_38(self, node: cst.CSTNode, code: str, **kwargs: Any) -> None: - if not is_native() and kwargs.get("native_only", False): - self.skipTest("disabled for pure python parser") self.validate_node(node, code, _parse_statement_force_38) @data_provider( @@ -2252,7 +2245,7 @@ def test_valid_38(self, node: cst.CSTNode, code: str, **kwargs: Any) -> None: ) ) def test_versions(self, **kwargs: Any) -> None: - if is_native() and not kwargs.get("expect_success", True): + if not kwargs.get("expect_success", True): self.skipTest("parse errors are disabled for native parser") self.assert_parses(**kwargs) @@ -2271,6 +2264,4 @@ def test_versions(self, **kwargs: Any) -> None: ) ) def test_parse_error(self, **kwargs: Any) -> None: - if not is_native(): - self.skipTest("Skipped for non-native parser") self.assert_parses(**kwargs, expect_success=False, parser=parse_statement) diff --git a/libcst/_nodes/tests/test_list.py b/libcst/_nodes/tests/test_list.py index 43e22df7..2f96124c 100644 --- a/libcst/_nodes/tests/test_list.py +++ b/libcst/_nodes/tests/test_list.py @@ -8,7 +8,6 @@ import libcst as cst from libcst import parse_expression, parse_statement from libcst._nodes.tests.base import CSTNodeTest, parse_expression_as -from libcst._parser.entrypoints import is_native from libcst.metadata import CodeRange from libcst.testing.utils import data_provider @@ -126,6 +125,6 @@ def test_invalid( ) ) def test_versions(self, **kwargs: Any) -> None: - if is_native() and not kwargs.get("expect_success", True): + if not kwargs.get("expect_success", True): self.skipTest("parse errors are disabled for native parser") self.assert_parses(**kwargs) diff --git a/libcst/_nodes/tests/test_match.py b/libcst/_nodes/tests/test_match.py index 2f1e4193..a3940053 100644 --- a/libcst/_nodes/tests/test_match.py +++ b/libcst/_nodes/tests/test_match.py @@ -8,12 +8,9 @@ import libcst as cst from libcst import parse_statement from libcst._nodes.tests.base import CSTNodeTest -from libcst._parser.entrypoints import is_native from libcst.testing.utils import data_provider -parser: Optional[Callable[[str], cst.CSTNode]] = ( - parse_statement if is_native() else None -) +parser: Optional[Callable[[str], cst.CSTNode]] = parse_statement class MatchTest(CSTNodeTest): diff --git a/libcst/_nodes/tests/test_matrix_multiply.py b/libcst/_nodes/tests/test_matrix_multiply.py index 5b4b8668..500b7aab 100644 --- a/libcst/_nodes/tests/test_matrix_multiply.py +++ b/libcst/_nodes/tests/test_matrix_multiply.py @@ -11,7 +11,6 @@ parse_expression_as, parse_statement_as, ) -from libcst._parser.entrypoints import is_native from libcst.testing.utils import data_provider @@ -70,6 +69,6 @@ def test_valid(self, **kwargs: Any) -> None: ) ) def test_versions(self, **kwargs: Any) -> None: - if is_native() and not kwargs.get("expect_success", True): + if not kwargs.get("expect_success", True): self.skipTest("parse errors are disabled for native parser") self.assert_parses(**kwargs) diff --git a/libcst/_nodes/tests/test_module.py b/libcst/_nodes/tests/test_module.py index 5b33c6b7..40de8f8e 100644 --- a/libcst/_nodes/tests/test_module.py +++ b/libcst/_nodes/tests/test_module.py @@ -8,7 +8,7 @@ import libcst as cst from libcst import parse_module, parse_statement from libcst._nodes.tests.base import CSTNodeTest -from libcst._parser.entrypoints import is_native + from libcst.metadata import CodeRange, MetadataWrapper, PositionProvider from libcst.testing.utils import data_provider @@ -117,7 +117,7 @@ def test_code_for_node( def test_parser( self, *, code: str, expected: cst.Module, enabled_for_native: bool = True ) -> None: - if is_native() and not enabled_for_native: + if not enabled_for_native: self.skipTest("Disabled for native parser") self.assertEqual(parse_module(code), expected) diff --git a/libcst/_nodes/tests/test_set.py b/libcst/_nodes/tests/test_set.py index 335a4d3a..699b458a 100644 --- a/libcst/_nodes/tests/test_set.py +++ b/libcst/_nodes/tests/test_set.py @@ -8,7 +8,6 @@ import libcst as cst from libcst import parse_expression from libcst._nodes.tests.base import CSTNodeTest, parse_expression_as -from libcst._parser.entrypoints import is_native from libcst.testing.utils import data_provider @@ -133,6 +132,6 @@ def test_invalid( ) ) def test_versions(self, **kwargs: Any) -> None: - if is_native() and not kwargs.get("expect_success", True): + if not kwargs.get("expect_success", True): self.skipTest("parse errors are disabled for native parser") self.assert_parses(**kwargs) diff --git a/libcst/_nodes/tests/test_try.py b/libcst/_nodes/tests/test_try.py index a2e8a433..8aea3643 100644 --- a/libcst/_nodes/tests/test_try.py +++ b/libcst/_nodes/tests/test_try.py @@ -8,13 +8,11 @@ import libcst as cst from libcst import parse_statement from libcst._nodes.tests.base import CSTNodeTest, DummyIndentedBlock -from libcst._parser.entrypoints import is_native + from libcst.metadata import CodeRange from libcst.testing.utils import data_provider -native_parse_statement: Optional[Callable[[str], cst.CSTNode]] = ( - parse_statement if is_native() else None -) +native_parse_statement: Optional[Callable[[str], cst.CSTNode]] = parse_statement class TryTest(CSTNodeTest): diff --git a/libcst/_nodes/tests/test_tuple.py b/libcst/_nodes/tests/test_tuple.py index 0055055c..78d16b8c 100644 --- a/libcst/_nodes/tests/test_tuple.py +++ b/libcst/_nodes/tests/test_tuple.py @@ -8,7 +8,7 @@ import libcst as cst from libcst import parse_expression, parse_statement from libcst._nodes.tests.base import CSTNodeTest, parse_expression_as -from libcst._parser.entrypoints import is_native + from libcst.metadata import CodeRange from libcst.testing.utils import data_provider @@ -286,6 +286,6 @@ def test_invalid( ) ) def test_versions(self, **kwargs: Any) -> None: - if is_native() and not kwargs.get("expect_success", True): + if not kwargs.get("expect_success", True): self.skipTest("parse errors are disabled for native parser") self.assert_parses(**kwargs) diff --git a/libcst/_nodes/tests/test_type_alias.py b/libcst/_nodes/tests/test_type_alias.py index aa26103b..3dc0ca68 100644 --- a/libcst/_nodes/tests/test_type_alias.py +++ b/libcst/_nodes/tests/test_type_alias.py @@ -8,7 +8,7 @@ import libcst as cst from libcst import parse_statement from libcst._nodes.tests.base import CSTNodeTest -from libcst._parser.entrypoints import is_native + from libcst.metadata import CodeRange from libcst.testing.utils import data_provider @@ -132,8 +132,6 @@ class TypeAliasCreationTest(CSTNodeTest): ) ) def test_valid(self, **kwargs: Any) -> None: - if not is_native(): - self.skipTest("Disabled in the old parser") self.validate_node(**kwargs) @@ -252,6 +250,4 @@ class TypeAliasParserTest(CSTNodeTest): ) ) def test_valid(self, **kwargs: Any) -> None: - if not is_native(): - self.skipTest("Disabled in the old parser") self.validate_node(**kwargs) diff --git a/libcst/_nodes/tests/test_with.py b/libcst/_nodes/tests/test_with.py index 517ce357..e775ebad 100644 --- a/libcst/_nodes/tests/test_with.py +++ b/libcst/_nodes/tests/test_with.py @@ -9,7 +9,7 @@ from libcst import parse_statement, PartialParserConfig from libcst._maybe_sentinel import MaybeSentinel from libcst._nodes.tests.base import CSTNodeTest, DummyIndentedBlock, parse_statement_as -from libcst._parser.entrypoints import is_native + from libcst.metadata import CodeRange from libcst.testing.utils import data_provider @@ -187,14 +187,14 @@ class WithTest(CSTNodeTest): cst.WithItem( cst.Call( cst.Name("context_mgr"), - lpar=() if is_native() else (cst.LeftParen(),), - rpar=() if is_native() else (cst.RightParen(),), + lpar=(), + rpar=(), ) ), ), cst.SimpleStatementSuite((cst.Pass(),)), - lpar=(cst.LeftParen() if is_native() else MaybeSentinel.DEFAULT), - rpar=(cst.RightParen() if is_native() else MaybeSentinel.DEFAULT), + lpar=(cst.LeftParen()), + rpar=(cst.RightParen()), whitespace_after_with=cst.SimpleWhitespace(""), ), "code": "with(context_mgr()): pass\n", @@ -233,7 +233,7 @@ class WithTest(CSTNodeTest): rpar=cst.RightParen(whitespace_before=cst.SimpleWhitespace(" ")), ), "code": ("with ( foo(),\n" " bar(), ): pass\n"), # noqa - "parser": parse_statement if is_native() else None, + "parser": parse_statement, "expected_position": CodeRange((1, 0), (2, 21)), }, ) @@ -310,7 +310,7 @@ def test_invalid(self, **kwargs: Any) -> None: ) ) def test_versions(self, **kwargs: Any) -> None: - if is_native() and not kwargs.get("expect_success", True): + if not kwargs.get("expect_success", True): self.skipTest("parse errors are disabled for native parser") self.assert_parses(**kwargs) diff --git a/libcst/_nodes/tests/test_yield.py b/libcst/_nodes/tests/test_yield.py index 22a18872..aacb2da0 100644 --- a/libcst/_nodes/tests/test_yield.py +++ b/libcst/_nodes/tests/test_yield.py @@ -8,7 +8,7 @@ import libcst as cst from libcst import parse_statement from libcst._nodes.tests.base import CSTNodeTest, parse_statement_as -from libcst._parser.entrypoints import is_native + from libcst.helpers import ensure_type from libcst.metadata import CodeRange from libcst.testing.utils import data_provider @@ -241,6 +241,6 @@ def test_valid( ) ) def test_versions(self, **kwargs: Any) -> None: - if is_native() and not kwargs.get("expect_success", True): + if not kwargs.get("expect_success", True): self.skipTest("parse errors are disabled for native parser") self.assert_parses(**kwargs) diff --git a/libcst/_parser/tests/test_parse_errors.py b/libcst/_parser/tests/test_parse_errors.py index 0a058898..2af51db1 100644 --- a/libcst/_parser/tests/test_parse_errors.py +++ b/libcst/_parser/tests/test_parse_errors.py @@ -10,7 +10,7 @@ import libcst as cst from libcst._nodes.base import CSTValidationError -from libcst._parser.entrypoints import is_native + from libcst.testing.utils import data_provider, UnitTest @@ -174,8 +174,6 @@ def test_parser_syntax_error_str( parse_fn() # make sure str() doesn't blow up self.assertIn("Syntax Error", str(cm.exception)) - if not is_native(): - self.assertEqual(str(cm.exception), expected) def test_native_fallible_into_py(self) -> None: with patch("libcst._nodes.expression.Name._validate") as await_validate: diff --git a/libcst/codemod/tests/test_codemod_cli.py b/libcst/codemod/tests/test_codemod_cli.py index 18dab870..90291527 100644 --- a/libcst/codemod/tests/test_codemod_cli.py +++ b/libcst/codemod/tests/test_codemod_cli.py @@ -12,7 +12,7 @@ from pathlib import Path from unittest import skipIf -from libcst._parser.entrypoints import is_native + from libcst.codemod import CodemodTest from libcst.testing.utils import UnitTest @@ -37,16 +37,10 @@ def test_codemod_formatter_error_input(self) -> None: stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) - if not is_native(): - self.assertIn( - "ParserSyntaxError: Syntax Error @ 14:11.", - rlt.stderr.decode("utf-8"), - ) - else: - self.assertIn( - "error: cannot format -: Cannot parse for target version Python 3.6: 13:10: async with AsyncExitStack() as stack:", - rlt.stderr.decode("utf-8"), - ) + self.assertIn( + "error: cannot format -: Cannot parse for target version Python 3.6: 13:10: async with AsyncExitStack() as stack:", + rlt.stderr.decode("utf-8"), + ) def test_codemod_external(self) -> None: # Test running the NOOP command as an "external command" diff --git a/libcst/metadata/tests/test_scope_provider.py b/libcst/metadata/tests/test_scope_provider.py index fd23e993..9afa6cba 100644 --- a/libcst/metadata/tests/test_scope_provider.py +++ b/libcst/metadata/tests/test_scope_provider.py @@ -11,7 +11,7 @@ import libcst as cst from libcst import ensure_type -from libcst._parser.entrypoints import is_native + from libcst.metadata import MetadataWrapper from libcst.metadata.scope_provider import ( _gen_dotted_names, @@ -2029,8 +2029,6 @@ def something(): ) def test_type_alias_scope(self) -> None: - if not is_native(): - self.skipTest("type aliases are only supported in the native parser") m, scopes = get_scope_metadata_provider( """ type A = C @@ -2052,8 +2050,6 @@ def test_type_alias_scope(self) -> None: self.assertIsInstance(scopes[alias.value], AnnotationScope) def test_type_alias_param(self) -> None: - if not is_native(): - self.skipTest("type parameters are only supported in the native parser") m, scopes = get_scope_metadata_provider( """ B = int @@ -2084,8 +2080,6 @@ def test_type_alias_param(self) -> None: ) def test_type_alias_tuple_and_paramspec(self) -> None: - if not is_native(): - self.skipTest("type parameters are only supported in the native parser") m, scopes = get_scope_metadata_provider( """ type A[*T] = T @@ -2113,8 +2107,6 @@ def test_type_alias_tuple_and_paramspec(self) -> None: self.assertEqual(t_refs[0].node, alias_paramspec.value) def test_class_type_params(self) -> None: - if not is_native(): - self.skipTest("type parameters are only supported in the native parser") m, scopes = get_scope_metadata_provider( """ class W[T]: @@ -2149,8 +2141,6 @@ def g[T]() -> T: pass self.assertEqual(t_refs_in_g[0].node, g.returns.annotation) def test_nested_class_type_params(self) -> None: - if not is_native(): - self.skipTest("type parameters are only supported in the native parser") m, scopes = get_scope_metadata_provider( """ class Outer: @@ -2168,8 +2158,6 @@ class Nested[T: Outer]: pass ) def test_annotation_refers_to_nested_class(self) -> None: - if not is_native(): - self.skipTest("type parameters are only supported in the native parser") m, scopes = get_scope_metadata_provider( """ class Outer: @@ -2229,8 +2217,6 @@ def meth2[T](self, arg: Nested): pass ) def test_body_isnt_subject_to_special_annotation_rule(self) -> None: - if not is_native(): - self.skipTest("type parameters are only supported in the native parser") m, scopes = get_scope_metadata_provider( """ class Outer: diff --git a/libcst/tests/__main__.py b/libcst/tests/__main__.py index 44e6bbe0..4f91e998 100644 --- a/libcst/tests/__main__.py +++ b/libcst/tests/__main__.py @@ -5,11 +5,8 @@ from unittest import main -from libcst._parser.entrypoints import is_native if __name__ == "__main__": - parser_type = "native" if is_native() else "pure" - print(f"running tests with {parser_type!r} parser") - + print(f"running tests with native parser") main(module=None, verbosity=2) diff --git a/libcst/tests/test_roundtrip.py b/libcst/tests/test_roundtrip.py index d5da81f2..96d1e507 100644 --- a/libcst/tests/test_roundtrip.py +++ b/libcst/tests/test_roundtrip.py @@ -8,7 +8,7 @@ from unittest import TestCase from libcst import CSTTransformer, parse_module -from libcst._parser.entrypoints import is_native + fixtures: Path = Path(__file__).parent.parent.parent / "native/libcst/tests/fixtures" @@ -19,8 +19,6 @@ class NOOPTransformer(CSTTransformer): class RoundTripTests(TestCase): def _get_fixtures(self) -> list[Path]: - if not is_native(): - self.skipTest("pure python parser doesn't work with this") self.assertTrue(fixtures.exists(), f"{fixtures} should exist") files = list(fixtures.iterdir()) self.assertGreater(len(files), 0) From 2d043755958ea04b5dd655edf98c51eb612b2b7d Mon Sep 17 00:00:00 2001 From: thereversiblewheel Date: Thu, 3 Jul 2025 20:47:07 +0000 Subject: [PATCH 4/9] fix: remove combine step from ci --- .github/workflows/ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8389b608..4b0fa767 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,9 +40,7 @@ jobs: - name: Native Parser Tests run: uv run poe test - name: Coverage - run: | - uv run coverage combine .coverage.pure - uv run coverage report + run: uv run coverage report # Run linters lint: From 32628806bdf94c960d35d4e8b562b7a57f29636a Mon Sep 17 00:00:00 2001 From: thereversiblewheel Date: Wed, 9 Jul 2025 20:20:42 +0000 Subject: [PATCH 5/9] linter fixes --- libcst/_nodes/tests/test_binary_op.py | 2 +- libcst/_nodes/tests/test_with.py | 1 - libcst/_parser/entrypoints.py | 3 +-- libcst/codemod/tests/test_codemod_cli.py | 1 - libcst/tests/__main__.py | 2 -- 5 files changed, 2 insertions(+), 7 deletions(-) diff --git a/libcst/_nodes/tests/test_binary_op.py b/libcst/_nodes/tests/test_binary_op.py index fddc90e1..f6b40daf 100644 --- a/libcst/_nodes/tests/test_binary_op.py +++ b/libcst/_nodes/tests/test_binary_op.py @@ -188,4 +188,4 @@ def test_invalid(self, **kwargs: Any) -> None: ) ) def test_parse_error(self, **kwargs: Any) -> None: - self.assert_parses(**kwargs, expect_success=False ) + self.assert_parses(**kwargs, expect_success=False) diff --git a/libcst/_nodes/tests/test_with.py b/libcst/_nodes/tests/test_with.py index e775ebad..17082a6c 100644 --- a/libcst/_nodes/tests/test_with.py +++ b/libcst/_nodes/tests/test_with.py @@ -7,7 +7,6 @@ import libcst as cst from libcst import parse_statement, PartialParserConfig -from libcst._maybe_sentinel import MaybeSentinel from libcst._nodes.tests.base import CSTNodeTest, DummyIndentedBlock, parse_statement_as from libcst.metadata import CodeRange diff --git a/libcst/_parser/entrypoints.py b/libcst/_parser/entrypoints.py index 74c8f9a0..d034258c 100644 --- a/libcst/_parser/entrypoints.py +++ b/libcst/_parser/entrypoints.py @@ -12,6 +12,7 @@ from functools import partial from typing import Union +from libcst import native from libcst._nodes.base import CSTNode from libcst._nodes.expression import BaseExpression from libcst._nodes.module import Module @@ -22,8 +23,6 @@ _DEFAULT_PARTIAL_PARSER_CONFIG: PartialParserConfig = PartialParserConfig() -from libcst import native - def _parse( entrypoint: str, source: Union[str, bytes], diff --git a/libcst/codemod/tests/test_codemod_cli.py b/libcst/codemod/tests/test_codemod_cli.py index 90291527..9798b071 100644 --- a/libcst/codemod/tests/test_codemod_cli.py +++ b/libcst/codemod/tests/test_codemod_cli.py @@ -12,7 +12,6 @@ from pathlib import Path from unittest import skipIf - from libcst.codemod import CodemodTest from libcst.testing.utils import UnitTest diff --git a/libcst/tests/__main__.py b/libcst/tests/__main__.py index 4f91e998..df28d1a6 100644 --- a/libcst/tests/__main__.py +++ b/libcst/tests/__main__.py @@ -6,7 +6,5 @@ from unittest import main - if __name__ == "__main__": - print(f"running tests with native parser") main(module=None, verbosity=2) From a1493695276257879c31f7dcb11692ee3c076e7e Mon Sep 17 00:00:00 2001 From: thereversiblewheel Date: Wed, 9 Jul 2025 20:40:29 +0000 Subject: [PATCH 6/9] omit the _parser --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 3ebaaef1..394eca43 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,6 +66,7 @@ fail_under = 93 precision = 1 show_missing = true skip_covered = true +omit = ["*/_parser/*"] # temporary while I remove the parser [tool.uv] cache-keys = [ From 273e08dc62830e4f93442106b9b8a597a05bc959 Mon Sep 17 00:00:00 2001 From: thereversiblewheel Date: Thu, 10 Jul 2025 00:22:57 +0000 Subject: [PATCH 7/9] fix newlines --- libcst/_nodes/tests/test_try.py | 1 - libcst/_nodes/tests/test_tuple.py | 1 - libcst/_nodes/tests/test_type_alias.py | 1 - libcst/_nodes/tests/test_with.py | 1 - libcst/_nodes/tests/test_yield.py | 1 - libcst/_parser/tests/test_parse_errors.py | 1 - libcst/metadata/tests/test_scope_provider.py | 1 - 7 files changed, 7 deletions(-) diff --git a/libcst/_nodes/tests/test_try.py b/libcst/_nodes/tests/test_try.py index 8aea3643..1b3f8558 100644 --- a/libcst/_nodes/tests/test_try.py +++ b/libcst/_nodes/tests/test_try.py @@ -8,7 +8,6 @@ import libcst as cst from libcst import parse_statement from libcst._nodes.tests.base import CSTNodeTest, DummyIndentedBlock - from libcst.metadata import CodeRange from libcst.testing.utils import data_provider diff --git a/libcst/_nodes/tests/test_tuple.py b/libcst/_nodes/tests/test_tuple.py index 78d16b8c..aa3d68bb 100644 --- a/libcst/_nodes/tests/test_tuple.py +++ b/libcst/_nodes/tests/test_tuple.py @@ -8,7 +8,6 @@ import libcst as cst from libcst import parse_expression, parse_statement from libcst._nodes.tests.base import CSTNodeTest, parse_expression_as - from libcst.metadata import CodeRange from libcst.testing.utils import data_provider diff --git a/libcst/_nodes/tests/test_type_alias.py b/libcst/_nodes/tests/test_type_alias.py index 3dc0ca68..865135c1 100644 --- a/libcst/_nodes/tests/test_type_alias.py +++ b/libcst/_nodes/tests/test_type_alias.py @@ -8,7 +8,6 @@ import libcst as cst from libcst import parse_statement from libcst._nodes.tests.base import CSTNodeTest - from libcst.metadata import CodeRange from libcst.testing.utils import data_provider diff --git a/libcst/_nodes/tests/test_with.py b/libcst/_nodes/tests/test_with.py index 17082a6c..0b396619 100644 --- a/libcst/_nodes/tests/test_with.py +++ b/libcst/_nodes/tests/test_with.py @@ -8,7 +8,6 @@ import libcst as cst from libcst import parse_statement, PartialParserConfig from libcst._nodes.tests.base import CSTNodeTest, DummyIndentedBlock, parse_statement_as - from libcst.metadata import CodeRange from libcst.testing.utils import data_provider diff --git a/libcst/_nodes/tests/test_yield.py b/libcst/_nodes/tests/test_yield.py index aacb2da0..e5085b4d 100644 --- a/libcst/_nodes/tests/test_yield.py +++ b/libcst/_nodes/tests/test_yield.py @@ -8,7 +8,6 @@ import libcst as cst from libcst import parse_statement from libcst._nodes.tests.base import CSTNodeTest, parse_statement_as - from libcst.helpers import ensure_type from libcst.metadata import CodeRange from libcst.testing.utils import data_provider diff --git a/libcst/_parser/tests/test_parse_errors.py b/libcst/_parser/tests/test_parse_errors.py index 2af51db1..7697893d 100644 --- a/libcst/_parser/tests/test_parse_errors.py +++ b/libcst/_parser/tests/test_parse_errors.py @@ -10,7 +10,6 @@ import libcst as cst from libcst._nodes.base import CSTValidationError - from libcst.testing.utils import data_provider, UnitTest diff --git a/libcst/metadata/tests/test_scope_provider.py b/libcst/metadata/tests/test_scope_provider.py index 9afa6cba..a367de39 100644 --- a/libcst/metadata/tests/test_scope_provider.py +++ b/libcst/metadata/tests/test_scope_provider.py @@ -11,7 +11,6 @@ import libcst as cst from libcst import ensure_type - from libcst.metadata import MetadataWrapper from libcst.metadata.scope_provider import ( _gen_dotted_names, From 39763cc5a020d5bbd63d17c3cf9aaaef4b0dc515 Mon Sep 17 00:00:00 2001 From: Martin Li Date: Wed, 30 Jul 2025 15:52:44 +0000 Subject: [PATCH 8/9] fix: remove optional --- libcst/_nodes/tests/test_match.py | 2 +- libcst/_nodes/tests/test_try.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libcst/_nodes/tests/test_match.py b/libcst/_nodes/tests/test_match.py index a3940053..c4f308a0 100644 --- a/libcst/_nodes/tests/test_match.py +++ b/libcst/_nodes/tests/test_match.py @@ -10,7 +10,7 @@ from libcst._nodes.tests.base import CSTNodeTest from libcst.testing.utils import data_provider -parser: Optional[Callable[[str], cst.CSTNode]] = parse_statement +parser: Callable[[str], cst.CSTNode] = parse_statement class MatchTest(CSTNodeTest): diff --git a/libcst/_nodes/tests/test_try.py b/libcst/_nodes/tests/test_try.py index 1b3f8558..6dda288f 100644 --- a/libcst/_nodes/tests/test_try.py +++ b/libcst/_nodes/tests/test_try.py @@ -11,7 +11,7 @@ from libcst.metadata import CodeRange from libcst.testing.utils import data_provider -native_parse_statement: Optional[Callable[[str], cst.CSTNode]] = parse_statement +native_parse_statement: Callable[[str], cst.CSTNode] = parse_statement class TryTest(CSTNodeTest): From 8bf1dd1ca526f5b171e2843aa66e0e05c05ba03d Mon Sep 17 00:00:00 2001 From: Martin Li Date: Wed, 30 Jul 2025 16:02:49 +0000 Subject: [PATCH 9/9] fix: linter --- libcst/_nodes/tests/test_match.py | 2 +- libcst/_nodes/tests/test_try.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libcst/_nodes/tests/test_match.py b/libcst/_nodes/tests/test_match.py index c4f308a0..2335b7c3 100644 --- a/libcst/_nodes/tests/test_match.py +++ b/libcst/_nodes/tests/test_match.py @@ -3,7 +3,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -from typing import Any, Callable, Optional +from typing import Any, Callable import libcst as cst from libcst import parse_statement diff --git a/libcst/_nodes/tests/test_try.py b/libcst/_nodes/tests/test_try.py index 6dda288f..5704d098 100644 --- a/libcst/_nodes/tests/test_try.py +++ b/libcst/_nodes/tests/test_try.py @@ -3,7 +3,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -from typing import Any, Callable, Optional +from typing import Any, Callable import libcst as cst from libcst import parse_statement