diff options
author | da-woods <dw-git@d-woods.co.uk> | 2022-07-17 12:20:14 +0100 |
---|---|---|
committer | da-woods <dw-git@d-woods.co.uk> | 2022-07-17 18:55:30 +0100 |
commit | 7183d4896804bb7364e296d9146722a41a0a4d56 (patch) | |
tree | ecc9b07c72de805ce053717308875f87b378c322 | |
parent | 3a919f5cb689ac0e72d4431515ab27171f2e1d72 (diff) | |
download | cython-7183d4896804bb7364e296d9146722a41a0a4d56.tar.gz |
Change compile tests to use TreeFragment
and fix a few tests
-rw-r--r-- | Cython/Compiler/MatchCaseNodes.py | 2 | ||||
-rw-r--r-- | Cython/Compiler/Nodes.py | 2 | ||||
-rw-r--r-- | Cython/Compiler/Parsing.py | 13 | ||||
-rw-r--r-- | tests/run/test_patma.py | 67 |
4 files changed, 44 insertions, 40 deletions
diff --git a/Cython/Compiler/MatchCaseNodes.py b/Cython/Compiler/MatchCaseNodes.py index b4d39e318..99fa70ccd 100644 --- a/Cython/Compiler/MatchCaseNodes.py +++ b/Cython/Compiler/MatchCaseNodes.py @@ -213,7 +213,7 @@ class MatchMappingPatternNode(PatternNode): value_patterns = [] double_star_capture_target = None - child_atts = PatternNode.child_attrs + [ + child_attrs = PatternNode.child_attrs + [ "keys", "value_patterns", "double_star_capture_target", diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 27d8ce323..476b380a3 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -10126,7 +10126,7 @@ class ErrorNode(Node): what str """ - pass + child_attrs = [] #------------------------------------------------------------------------------------ diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index 4441e1ae3..bb89875c4 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -4313,11 +4313,11 @@ def p_mapping_pattern(s): double_star_capture_target = None items_patterns = [] - double_star_set_twice = None + double_star_is_not_final = None while True: + if double_star_capture_target and not double_star_is_not_final: + double_star_is_not_final = s.position() if s.sy == '**': - if double_star_capture_target: - double_star_set_twice = s.position() s.next() double_star_capture_target = p_pattern_capture_target(s) else: @@ -4339,8 +4339,11 @@ def p_mapping_pattern(s): break s.expect('}') - if double_star_set_twice is not None: - return Nodes.ErrorNode(double_star_set_twice, what = "Double star capture set twice") + if double_star_is_not_final is not None: + return Nodes.ErrorNode( + double_star_is_not_final, + what = "** pattern must be the final part of a mapping pattern." + ) return MatchCaseNodes.MatchMappingPatternNode( pos, keys = [kv[0] for kv in items_patterns], diff --git a/tests/run/test_patma.py b/tests/run/test_patma.py index 6956099e2..240dbf0d3 100644 --- a/tests/run/test_patma.py +++ b/tests/run/test_patma.py @@ -4,40 +4,34 @@ # new code import cython -from Cython.Compiler.Main import compile as cython_compile, CompileError -from Cython.Build.Inline import cython_inline -import contextlib -from tempfile import NamedTemporaryFile - -@contextlib.contextmanager -def hidden_stderr(): - try: - from StringIO import StringIO - except ImportError: - from io import StringIO - - old_stderr = sys.stderr - try: - sys.stderr = StringIO() - yield - finally: - sys.stderr = old_stderr +from Cython.Compiler.TreeFragment import TreeFragment, StringParseContext +from Cython.Compiler.Errors import local_errors, CompileError +from Cython.Compiler.ParseTreeTransforms import PostParse def _compile(code): - with NamedTemporaryFile(suffix='.py') as f: - f.write(code.encode('utf8')) - f.flush() + context = StringParseContext("test") + # all the errors we care about are in the parsing or postparse stage + try: + with local_errors() as errors: + result = TreeFragment(code, pipeline=[PostParse(context)]) + result = result.substitute() + if errors: + raise errors[0] # compile error, which should get caught + else: + return result + except CompileError as e: + raise SyntaxError(e.message_only) - with hidden_stderr(): - result = cython_compile(f.name, language_level=3) - return result if cython.compiled: def compile(code, name, what): assert what == 'exec' - result = _compile(code) - if not result.c_file: - raise SyntaxError('unexpected EOF') # compile is only used for testing errors + _compile(code) + + +def disable(func): + pass + ############## SLIGHTLY MODIFIED ORIGINAL CODE import array @@ -69,9 +63,9 @@ class TestTracing(unittest.TestCase): # Deeply nested patterns can cause exponential backtracking when parsing. # See CPython gh-93671 for more information. # - # DW Cython note - this doesn't break the parser but may cause a + # DW: Cython note - this doesn't break the parser but may cause a # RecursionError later in the code-generation. I don't believe that's - # easily avoidable + # easily avoidable with the way Cython visitors currently work levels = 100 @@ -84,10 +78,9 @@ class TestTracing(unittest.TestCase): for pattern in patterns: with self.subTest(pattern): code = inspect.cleandoc(""" - if 0: # disabled - FIXME remove once pattern matching is fully implemented! - match None: - case {}: - pass + match None: + case {}: + pass """.format(pattern)) compile(code, "<string>", "exec") @@ -3019,6 +3012,7 @@ class TestSyntaxErrors(unittest.TestCase): """) + @disable # validation will be added when class patterns are added def test_attribute_name_repeated_in_class_pattern(self): self.assert_syntax_error(""" match ...: @@ -3117,6 +3111,7 @@ class TestSyntaxErrors(unittest.TestCase): pass """) + @disable # will be implemented as part of sequence patterns def test_multiple_starred_names_in_sequence_pattern_0(self): self.assert_syntax_error(""" match ...: @@ -3124,6 +3119,7 @@ class TestSyntaxErrors(unittest.TestCase): pass """) + @disable # will be implemented as part of sequence patterns def test_multiple_starred_names_in_sequence_pattern_1(self): self.assert_syntax_error(""" match ...: @@ -3258,6 +3254,7 @@ class TestSyntaxErrors(unittest.TestCase): pass """) + @disable # validation will be added when class patterns are added def test_mapping_pattern_duplicate_key(self): self.assert_syntax_error(""" match ...: @@ -3265,6 +3262,7 @@ class TestSyntaxErrors(unittest.TestCase): pass """) + @disable # validation will be added when class patterns are added def test_mapping_pattern_duplicate_key_edge_case0(self): self.assert_syntax_error(""" match ...: @@ -3272,6 +3270,7 @@ class TestSyntaxErrors(unittest.TestCase): pass """) + @disable # validation will be added when class patterns are added def test_mapping_pattern_duplicate_key_edge_case1(self): self.assert_syntax_error(""" match ...: @@ -3279,6 +3278,7 @@ class TestSyntaxErrors(unittest.TestCase): pass """) + @disable # validation will be added when class patterns are added def test_mapping_pattern_duplicate_key_edge_case2(self): self.assert_syntax_error(""" match ...: @@ -3286,6 +3286,7 @@ class TestSyntaxErrors(unittest.TestCase): pass """) + @disable # validation will be added when class patterns are added def test_mapping_pattern_duplicate_key_edge_case3(self): self.assert_syntax_error(""" match ...: |