removed various invalid syntax combinations for the c(p)def statement (#280)
authorStefan Behnel <scoder@users.berlios.de>
Sun, 3 May 2009 18:38:21 +0000 (20:38 +0200)
committerStefan Behnel <scoder@users.berlios.de>
Sun, 3 May 2009 18:38:21 +0000 (20:38 +0200)
Cython/Compiler/Parsing.py
tests/errors/cdef_syntax.pyx [new file with mode: 0644]
tests/errors/cpdef_syntax.pyx [new file with mode: 0644]

index 8cc729977170f32c39cad02fc9890ca9320e29ae..ad2d2f77af7942f0defde1a3355d25e68d3add01 100644 (file)
@@ -1691,6 +1691,8 @@ def p_c_simple_base_type(s, self_flag, nonempty):
     longness = 0
     module_path = []
     pos = s.position()
+    if not s.sy == 'IDENT':
+        error(pos, "Expected an identifier, found '%s'" % s.sy)
     if looking_at_base_type(s):
         #print "p_c_simple_base_type: looking_at_base_type at", s.position()
         is_basic = 1
@@ -2068,31 +2070,30 @@ def p_cdef_statement(s, ctx):
     elif s.sy == 'import':
         s.next()
         return p_cdef_extern_block(s, pos, ctx)
-    if p_nogil(s):
+    elif p_nogil(s):
         ctx.nogil = 1
-    if s.sy == ':':
+        if ctx.overridable:
+            error(pos, "cdef blocks cannot be declared cpdef")
+        return p_cdef_block(s, ctx)
+    elif s.sy == ':':
+        if ctx.overridable:
+            error(pos, "cdef blocks cannot be declared cpdef")
         return p_cdef_block(s, ctx)
     elif s.sy == 'class':
         if ctx.level not in ('module', 'module_pxd'):
             error(pos, "Extension type definition not allowed here")
-        #if ctx.api:
-        #    error(pos, "'api' not allowed with extension class")
+        if ctx.overridable:
+            error(pos, "Extension types cannot be declared cpdef")
         return p_c_class_definition(s, pos, ctx)
     elif s.sy == 'IDENT' and s.systring in ("struct", "union", "enum", "packed"):
         if ctx.level not in ('module', 'module_pxd'):
             error(pos, "C struct/union/enum definition not allowed here")
-        #if ctx.visibility == 'public':
-        #    error(pos, "Public struct/union/enum definition not implemented")
-        #if ctx.api:
-        #    error(pos, "'api' not allowed with '%s'" % s.systring)
+        if ctx.overridable:
+            error(pos, "C struct/union/enum cannot be declared cpdef")
         if s.systring == "enum":
             return p_c_enum_definition(s, pos, ctx)
         else:
             return p_c_struct_or_union_definition(s, pos, ctx)
-    elif s.sy == 'pass':
-        node = p_pass_statement(s)
-        s.expect_newline('Expected a newline')
-        return node
     else:
         return p_c_func_or_var_declaration(s, pos, ctx)
 
@@ -2100,6 +2101,8 @@ def p_cdef_block(s, ctx):
     return p_suite(s, ctx(cdef_flag = 1))
 
 def p_cdef_extern_block(s, pos, ctx):
+    if ctx.overridable:
+        error(pos, "cdef extern blocks cannot be declared cpdef")
     include_file = None
     s.expect('from')
     if s.sy == '*':
diff --git a/tests/errors/cdef_syntax.pyx b/tests/errors/cdef_syntax.pyx
new file mode 100644 (file)
index 0000000..aad39b3
--- /dev/null
@@ -0,0 +1,10 @@
+
+cdef pass
+cdef void
+cdef nogil class test: pass
+
+_ERRORS = u"""
+ 2: 5: Expected an identifier, found 'pass'
+ 3: 9: Empty declarator
+ 4:11: Expected ':'
+"""
diff --git a/tests/errors/cpdef_syntax.pyx b/tests/errors/cpdef_syntax.pyx
new file mode 100644 (file)
index 0000000..f67cd1c
--- /dev/null
@@ -0,0 +1,9 @@
+
+cpdef nogil: pass
+cpdef nogil class test: pass
+
+_ERRORS = u"""
+ 2: 6: cdef blocks cannot be declared cpdef
+ 3: 6: cdef blocks cannot be declared cpdef
+ 3:12: Expected ':'
+"""