summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorda-woods <dw-git@d-woods.co.uk>2022-08-02 21:03:59 +0100
committerda-woods <dw-git@d-woods.co.uk>2022-08-02 21:03:59 +0100
commit816612e35e05320bf510132c765dde7d4133b2ab (patch)
treeef4b449ec3c0f8b58124634793a224ac1a99f030
parent7034c959be052664f557128a9299f537b6632582 (diff)
downloadcython-816612e35e05320bf510132c765dde7d4133b2ab.tar.gz
Parsing function names/signatures, flag for in_pattern_node
-rw-r--r--Cython/Compiler/ParseTreeTransforms.py15
-rw-r--r--Cython/Compiler/Parsing.pxd4
-rw-r--r--Cython/Compiler/Parsing.py21
3 files changed, 22 insertions, 18 deletions
diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py
index a9a692cd3..6d362ae31 100644
--- a/Cython/Compiler/ParseTreeTransforms.py
+++ b/Cython/Compiler/ParseTreeTransforms.py
@@ -186,6 +186,8 @@ class PostParse(ScopeTrackingTransform):
- Some invalid uses of := assignment expressions are detected
"""
+ in_pattern_node = False
+
def __init__(self, context):
super(PostParse, self).__init__(context)
self.specialattribute_handlers = {
@@ -397,16 +399,15 @@ class PostParse(ScopeTrackingTransform):
self.visitchildren(node)
return node
- def visit_MatchValuePatternNode(self, node):
- if isinstance(node.value, ExprNodes.JoinedStrNode):
- error(node.value.pos, "f-strings are not accepted for pattern matching")
+ def visit_PatternNode(self, node):
+ in_pattern_node, self.in_pattern_node = self.in_pattern_node, True
self.visitchildren(node)
+ self.in_pattern_node = in_pattern_node
return node
- def visit_MatchMappingPatternNode(self, node):
- for key in node.keys:
- if isinstance(key, ExprNodes.JoinedStrNode):
- error(key.pos, "f-strings are not accepted for pattern matching")
+ def visit_JoinedStrNode(self, node):
+ if self.in_pattern_node:
+ error(node.pos, "f-strings are not accepted for pattern matching")
self.visitchildren(node)
return node
diff --git a/Cython/Compiler/Parsing.pxd b/Cython/Compiler/Parsing.pxd
index 1df8530cb..a25652e2c 100644
--- a/Cython/Compiler/Parsing.pxd
+++ b/Cython/Compiler/Parsing.pxd
@@ -64,8 +64,8 @@ cdef expect_ellipsis(PyrexScanner s)
cdef make_slice_nodes(pos, subscripts)
cpdef make_slice_node(pos, start, stop = *, step = *)
cdef p_atom(PyrexScanner s)
-cdef parse_atom_string(pos, PyrexScanner s)
-cdef parse_atom_ident_constants(pos, PyrexScanner s)
+cdef p_atom_string(PyrexScanner s)
+cdef p_atom_ident_constants(PyrexScanner s)
@cython.locals(value=unicode)
cdef p_int_literal(PyrexScanner s)
cdef p_name(PyrexScanner s, name)
diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py
index d93b4aa64..291e1ceea 100644
--- a/Cython/Compiler/Parsing.py
+++ b/Cython/Compiler/Parsing.py
@@ -735,18 +735,19 @@ def p_atom(s):
s.next()
return ExprNodes.ImagNode(pos, value = value)
elif sy == 'BEGIN_STRING':
- return parse_atom_string(pos, s)
+ return p_atom_string(s)
elif sy == 'IDENT':
- result = parse_atom_ident_constants(pos, s)
+ result = p_atom_ident_constants(s)
if result is None:
result = p_name(s, s.systring)
- s.next()
+ s.next()
return result
else:
s.error("Expected an identifier or literal")
-def parse_atom_string(pos, s):
+def p_atom_string(s):
+ pos = s.position()
kind, bytes_value, unicode_value = p_cat_string_literal(s)
if kind == 'c':
return ExprNodes.CharNode(pos, value=bytes_value)
@@ -762,11 +763,12 @@ def parse_atom_string(pos, s):
s.error("invalid string kind '%s'" % kind)
-def parse_atom_ident_constants(pos, s):
+def p_atom_ident_constants(s):
"""
Returns None if it isn't one special-cased named constants.
- Does not call s.next()
+ Only calls s.next() if it successfully matches a matches.
"""
+ pos = s.position()
name = s.systring
result = None
if name == "None":
@@ -777,6 +779,8 @@ def parse_atom_ident_constants(pos, s):
result = ExprNodes.BoolNode(pos, value=False)
elif name == "NULL" and not s.in_python_file:
result = ExprNodes.NullNode(pos)
+ if result:
+ s.next()
return result
@@ -4225,15 +4229,14 @@ def p_literal_pattern(s):
if next_must_be_a_number:
s.error("Expected a number")
if sy == 'BEGIN_STRING':
- res = parse_atom_string(pos, s)
+ res = p_atom_string(s)
# f-strings not being accepted is validated in PostParse
return MatchCaseNodes.MatchValuePatternNode(pos, value=res)
elif sy == 'IDENT':
# Note that p_atom_ident_constants includes NULL.
# This is a deliberate Cython addition to the pattern matching specification
- result = parse_atom_ident_constants(pos, s)
+ result = p_atom_ident_constants(s)
if result:
- s.next()
return MatchCaseNodes.MatchValuePatternNode(pos, value=result, is_is_check=True)
s.error("Failed to match literal")