Condense p_cdef_statement() into p_statement() to reduce parsing duplication.
authorW. Trevor King <wking@drexel.edu>
Tue, 22 Feb 2011 21:15:44 +0000 (16:15 -0500)
committerW. Trevor King <wking@drexel.edu>
Wed, 23 Feb 2011 14:53:38 +0000 (09:53 -0500)
19 files changed:
Cython/Compiler/Parsing.pxd
Cython/Compiler/Parsing.py
tests/errors/builtin_type_inheritance.pyx
tests/errors/cdefspecial.pyx
tests/errors/cmethbasematch.pyx
tests/errors/cpdef_syntax.pyx
tests/errors/e_cdefemptysue.pyx
tests/errors/e_cmethbasematch.pyx
tests/errors/e_ctypedefornot.pyx
tests/errors/e_func_in_pxd.pyx
tests/errors/e_nogilcmeth.pyx
tests/errors/e_packedstruct_T290.pyx
tests/errors/e_undefexttype.pyx
tests/errors/missing_self_in_cpdef_method_T156.pyx
tests/errors/missing_self_in_cpdef_method_T165.pyx
tests/errors/nogil.pyx
tests/errors/nogilcmeth.pyx
tests/errors/pxd_cdef_class_declaration_T286.pyx
tests/errors/subtyping_final_class.pyx

index 9fef7b87b260f7d6215e030742ec70734ccaabdb..98b83b3873aa4e7a3ba8f489e8c915d308058896 100644 (file)
@@ -151,7 +151,6 @@ cpdef p_c_arg_list(PyrexScanner s, ctx = *, bint in_pyfunc = *, bint cmethod_fla
 cdef p_optional_ellipsis(PyrexScanner s)
 cpdef p_c_arg_decl(PyrexScanner s, ctx, in_pyfunc, bint cmethod_flag = *, bint nonempty = *, bint kw_only = *, bint annotated = *)
 cdef p_api(PyrexScanner s)
-cdef p_cdef_statement(PyrexScanner s, ctx)
 cdef p_cdef_block(PyrexScanner s, ctx)
 cdef p_cdef_extern_block(PyrexScanner s, pos, ctx)
 cdef p_c_enum_definition(PyrexScanner s, pos, ctx)
@@ -161,14 +160,14 @@ cdef p_c_struct_or_union_definition(PyrexScanner s, pos, ctx)
 cdef p_visibility(PyrexScanner s, ctx)
 cdef p_c_modifiers(PyrexScanner s)
 cdef p_binding(PyrexScanner s, ctx)
-cdef p_c_func_or_var_declaration(PyrexScanner s, pos, ctx)
+cdef p_c_func_or_var_declaration(PyrexScanner s, pos, ctx, decorators = *)
 cdef p_ctypedef_statement(PyrexScanner s, pos, ctx)
 cdef p_decorators(PyrexScanner s)
 cdef p_def_statement(PyrexScanner s, list decorators = *)
 cpdef p_varargslist(PyrexScanner s, terminator=*, bint annotated = *)
 cpdef p_py_arg_decl(PyrexScanner s, bint annotated = *)
 cdef p_class_statement(PyrexScanner s, decorators)
-cdef p_c_class_definition(PyrexScanner s, pos,  ctx)
+cdef p_c_class_definition(PyrexScanner s, pos,  ctx, decorators = *)
 cdef p_c_class_options(PyrexScanner s)
 cdef p_property_decl(PyrexScanner s)
 cdef p_doc_string(PyrexScanner s)
index d25b0edad44a087491108a6f44ebb368ccbec7e9..29407a91aab39842dbe0924c324b0e8a65b53317 100644 (file)
@@ -1906,14 +1906,21 @@ def p_statement(s, ctx, first_statement = 0):
         if ctx.level not in ('module', 'module_pxd', 'function', 'c_class', 'c_class_pxd'):
             s.error('cdef statement not allowed here')
         s.level = ctx.level
-        node = p_cdef_statement(s, ctx)
-        if decorators is not None:
-            if not isinstance(node, (Nodes.CFuncDefNode, Nodes.CVarDefNode, Nodes.CClassDefNode)):
-                s.error("Decorators can only be followed by functions or classes")
-            node.decorators = decorators
-        return node
-    elif ctx.c_binding.api:
-        s.error("'api' not allowed with this statement")
+    if ctx.c_binding.api:
+        if ctx.c_source.cdef_flag:
+            if ctx.c_source.extern:
+                error(pos, "Cannot combine 'api' with 'extern'")
+        else:
+            s.error("'api' not allowed with this statement")
+    if ctx.c_source.cdef_flag and p_nogil(s):
+        ctx.nogil = 1
+        if ctx.python_binding.overridable:
+            error(pos, "cdef blocks cannot be declared cpdef")
+        return p_cdef_block(s, ctx)
+    elif s.sy == ':' and ctx.c_source.cdef_flag:
+        if ctx.python_binding.overridable:
+            error(pos, "cdef blocks cannot be declared cpdef")
+        return p_cdef_block(s, ctx)
     elif s.sy == 'def':
         # def statements aren't allowed in pxd files, except
         # as part of a cdef class
@@ -1922,15 +1929,42 @@ def p_statement(s, ctx, first_statement = 0):
         s.level = ctx.level
         return p_def_statement(s, decorators)
     elif s.sy == 'class':
-        if ctx.level not in ('module', 'function', 'class', 'other'):
-            s.error("class definition not allowed here")
+        if ctx.c_source.cdef_flag:
+            if ctx.level not in ('module', 'module_pxd'):
+                error(pos, "Extension type definition not allowed here")
+            if ctx.python_binding.overridable:
+                error(pos, "Extension types cannot be declared cpdef")
+            return p_c_class_definition(s, pos, ctx, decorators)
+        else:
+            if ctx.level not in ('module', 'function', 'class', 'other'):
+                s.error("class definition not allowed here")
         return p_class_statement(s, decorators)
+    elif s.sy == 'from' and ctx.c_source.extern:
+        return p_cdef_extern_block(s, pos, ctx)
+    elif s.sy == 'import' and ctx.c_source.cdef_flag:
+        s.next()
+        return p_cdef_extern_block(s, pos, ctx)
     elif s.sy == 'include':
         if ctx.level not in ('module', 'module_pxd'):
             s.error("include statement not allowed here")
         return p_include_statement(s, ctx)
     elif ctx.level == 'c_class' and s.sy == 'IDENT' and s.systring == 'property':
         return p_property_decl(s)
+    elif ctx.c_source.cdef_flag:
+        if s.sy == 'IDENT' and s.systring == 'cppclass':
+            if not ctx.c_source.extern:
+                error(pos, "C++ classes need to be declared extern")
+            return p_cpp_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.python_binding.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)
+        return p_c_func_or_var_declaration(s, pos, ctx, decorators)
     elif s.sy == 'pass' and ctx.level != 'property':
         return p_pass_statement(s, with_newline = 1)
     elif ctx.level in ('c_class_pxd', 'property'):
@@ -2553,47 +2587,6 @@ def p_api(s):
     else:
         return 0
 
-def p_cdef_statement(s, ctx):
-    pos = s.position()
-    if ctx.c_binding.api:
-        if ctx.c_source.extern:
-            error(pos, "Cannot combine 'api' with 'extern'")
-    if ctx.c_source.extern and s.sy == 'from':
-        return p_cdef_extern_block(s, pos, ctx)
-    elif s.sy == 'import':
-        s.next()
-        return p_cdef_extern_block(s, pos, ctx)
-    elif p_nogil(s):
-        ctx.nogil = 1
-        if ctx.python_binding.overridable:
-            error(pos, "cdef blocks cannot be declared cpdef")
-        return p_cdef_block(s, ctx)
-    elif s.sy == ':':
-        if ctx.python_binding.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.python_binding.overridable:
-            error(pos, "Extension types cannot be declared cpdef")
-        return p_c_class_definition(s, pos, ctx)
-    elif s.sy == 'IDENT' and s.systring == 'cppclass':
-        if not ctx.c_source.extern:
-            error(pos, "C++ classes need to be declared extern")
-        return p_cpp_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.python_binding.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)
-    else:
-        return p_c_func_or_var_declaration(s, pos, ctx)
-
 def p_cdef_block(s, ctx):
     return p_suite(s, ctx(cdef_flag = 1))
 
@@ -2801,7 +2794,7 @@ def p_binding(s, ctx):
     _LOG.info('  python binding overridable: %s' % new_ctx.python_binding.overridable)
     return new_ctx
 
-def p_c_func_or_var_declaration(s, pos, ctx):
+def p_c_func_or_var_declaration(s, pos, ctx, decorators=None):
     _LOG.debug('p_c_func_or_var_declaration(s=<s sy:%s systring:%s>)'
                % (s.sy, s.systring))
     cmethod_flag = ctx.level in ('c_class', 'c_class_pxd')
@@ -2825,6 +2818,7 @@ def p_c_func_or_var_declaration(s, pos, ctx):
             visibility = visibility,
             base_type = base_type,
             declarator = declarator,
+            decorators = decorators,
             body = suite,
             doc = doc,
             modifiers = modifiers,
@@ -2852,6 +2846,7 @@ def p_c_func_or_var_declaration(s, pos, ctx):
             overridable = ctx.python_binding.overridable,
             base_type = base_type,
             declarators = declarators,
+            decorators = decorators,
             in_pxd = ctx.level == 'module_pxd')
     return result
 
@@ -2983,7 +2978,7 @@ def p_class_statement(s, decorators):
         starstar_arg = starstar_arg,
         doc = doc, body = body, decorators = decorators)
 
-def p_c_class_definition(s, pos,  ctx):
+def p_c_class_definition(s, pos,  ctx, decorators=None):
     # s.sy == 'class'
     s.next()
     module_path = []
@@ -3059,6 +3054,7 @@ def p_c_class_definition(s, pos,  ctx):
         base_class_name = base_class_name,
         objstruct_name = objstruct_name,
         typeobj_name = typeobj_name,
+        decorators = decorators,
         in_pxd = ctx.level == 'module_pxd',
         doc = doc,
         body = body)
index 79ff24a53fadbe2b9ee88bde98f085a64fee759b..0d11207d7b8a3b07c6c5c50915aa733f307c4f99 100644 (file)
@@ -11,7 +11,7 @@ cdef class MyStr(str): # only in Py2, but can't know that during compilation
     pass
 
 _ERRORS = """
-4:5: inheritance from PyVarObject types like 'tuple' is not currently supported
-7:5: inheritance from PyVarObject types like 'bytes' is not currently supported
-10:5: inheritance from PyVarObject types like 'str' is not currently supported
+4:0: inheritance from PyVarObject types like 'tuple' is not currently supported
+7:0: inheritance from PyVarObject types like 'bytes' is not currently supported
+10:0: inheritance from PyVarObject types like 'str' is not currently supported
 """
index 53a484eaa01f2d2f2329e00f767807f4462b2f93..f942006c5ace63ba03023a983384130979418ba3 100644 (file)
@@ -7,6 +7,6 @@ cdef class Test:
         pass
 
 _ERRORS = u"""
-3:9: Special methods must be declared with 'def', not 'cdef'
-6:9: Special methods must be declared with 'def', not 'cdef'
+3:4: Special methods must be declared with 'def', not 'cdef'
+6:4: Special methods must be declared with 'def', not 'cdef'
 """
index b0b1222e3bb6d65e6ef2f5451c027c63def8ea19..fbbafe2dc1741fad74cfdff9a9b323cea711f4aa 100644 (file)
@@ -7,6 +7,6 @@ cdef class D(C):
         pass
 
 _ERRORS = u"""
-6: 9: Signature not compatible with previous declaration
-2: 9: Previous declaration is here
+6: 4: Signature not compatible with previous declaration
+2: 4: Previous declaration is here
 """
index 654a1fe09db92b8fb3d51f725f21d40e74be7907..569750d3d06e45c26459efb6ca1b8a7a173157e2 100644 (file)
@@ -3,7 +3,7 @@ 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
+ 2: 0: cdef blocks cannot be declared cpdef
+ 3: 0: cdef blocks cannot be declared cpdef
  3:12: Expected ':', found 'class'
 """
index d71a8ab3cfc9efd82ad2302730eedae20472e7a5..5ed134979da0717ffb5124a8559cf5b8742eb213 100644 (file)
@@ -7,7 +7,7 @@ ctypedef union eggs:
 cdef enum ham:
        pass
 _ERRORS = u"""
-1:5: Empty struct or union definition not allowed outside a 'cdef extern from' block
+1:0: Empty struct or union definition not allowed outside a 'cdef extern from' block
 4:0: Empty struct or union definition not allowed outside a 'cdef extern from' block
-7:5: Empty enum definition not allowed outside a 'cdef extern from' block
+7:0: Empty enum definition not allowed outside a 'cdef extern from' block
 """
index b434c82a3d35d610d31f6ecd9beeea5fa996867a..271421dc247a3d4d1c394302c65a3b099791f13c 100644 (file)
@@ -6,6 +6,6 @@ cdef class D(C):
        cdef void f(self, int x):
                pass
 _ERRORS = u"""
-6:6: Signature not compatible with previous declaration
-2:6: Previous declaration is here
+6:1: Signature not compatible with previous declaration
+2:1: Previous declaration is here
 """
index 632ba780dc5211020fa5ec5b82362543260e16b0..1d8396b4cb64bc838adfa8a5b153905eaf0dec6a 100644 (file)
@@ -13,5 +13,5 @@ cdef Blarg b
 
 _ERRORS = u"""
 3:0: 'Foo' previously declared using 'cdef'
-9:5: 'Blarg' previously declared using 'ctypedef'
+9:0: 'Blarg' previously declared using 'ctypedef'
 """
index 83dc574e87fc78decd748e6f8f5bb0553cde5e0a..10a882e13865d09cfda8ff0b8c0097b1a5c78fe0 100644 (file)
@@ -1,7 +1,7 @@
 cimport e_func_in_pxd_support
 
 _ERRORS = u"""
-1:5: function definition in pxd file must be declared 'cdef inline'
-4:12: inline function definition in pxd file cannot be 'public'
-7:9: inline function definition in pxd file cannot be 'api'
+1:0: function definition in pxd file must be declared 'cdef inline'
+4:0: inline function definition in pxd file cannot be 'public'
+7:0: inline function definition in pxd file cannot be 'api'
 """
index ec596524dd26cbb2329d65ac76b4f3d06753f2b7..6f4cb6ee7bb876c3dd361aa0b748230c5117003a 100644 (file)
@@ -3,6 +3,6 @@ cdef class C:
                pass
 
 _ERRORS = u"""
-2:6: Signature not compatible with previous declaration
+2:1: Signature not compatible with previous declaration
 2:12: Previous declaration is here
 """
index 408246c83f6160a61130106fc20cb2e8400a62de..8a3ef5e6f11963511172440e8a0b8d6ceadfec59 100644 (file)
@@ -3,5 +3,5 @@ cdef extern:
         char a
 
 _ERRORS = u"""
-2:9: Cannot declare extern struct as 'packed'
+2:4: Cannot declare extern struct as 'packed'
 """
index 232f4d739bf694950504174ae8f265a632e96ea6..0a9f6a9bdc964d192d0150eede5c8ca02d465de1 100644 (file)
@@ -1,6 +1,6 @@
 cdef class Spam
 cdef extern class external.Eggs
 _ERRORS = u"""
-1:5: C class 'Spam' is declared but not defined
-2:12: C class 'Eggs' is declared but not defined
+1:0: C class 'Spam' is declared but not defined
+2:0: C class 'Eggs' is declared but not defined
 """
index 7f060e49a7562cb52189e8982992d5d689d57801..3fbb7f6d039f33247c56fb40e38024f06caa03eb 100644 (file)
@@ -4,5 +4,5 @@ cdef class B:
         pass
 
 _ERRORS = u"""
-3:10: C method has no self argument
+3:4: C method has no self argument
 """
index 3b66bc72d123bdcc5a0357d870e85f57525ba096..89fc19475651f0266aa058b12b24e5385bef85b4 100644 (file)
@@ -4,5 +4,5 @@ cdef class A:
         pass
 
 _ERRORS = u"""
-3:10: Self argument (int) of C method 'a' does not match parent type (A)
+3:4: Self argument (int) of C method 'a' does not match parent type (A)
 """
index 623d1ff405b6884997496cbab1be33ba99d00d40..1e85d08d6283bef38455a6d5ae5ed5dc7c3a83f1 100644 (file)
@@ -90,11 +90,11 @@ def bare_pyvar_name(object x):
 # except these: 29, 34, 44, 56, 58, 60, 62-64
 
 _ERRORS = u"""
-1:5: Function with Python return type cannot be declared nogil
-4:5: Function declared nogil has Python locals or temporaries
+1:0: Function with Python return type cannot be declared nogil
+4:0: Function declared nogil has Python locals or temporaries
 6:6: Assignment of Python object not allowed without gil
 9:5: Discarding owned Python object not allowed without gil
-11:5: Function with Python return type cannot be declared nogil
+11:0: Function with Python return type cannot be declared nogil
 15:5: Calling gil-requiring function not allowed without gil
 24:9: Calling gil-requiring function not allowed without gil
 26:12: Assignment of Python object not allowed without gil
index c7b3ce382595532bb995bf1561a236d692c99f4f..77327b23552861ae973af7cd5cf64d6d359d24e9 100644 (file)
@@ -3,6 +3,6 @@ cdef class C:
         pass
 
 _ERRORS = u"""
-2:9: Signature not compatible with previous declaration
+2:4: Signature not compatible with previous declaration
 2:15: Previous declaration is here
 """
index 7114bf8f6d7d886d16b528f704dcd07222e4ae8c..e377f6a4bafdf5789209e668db8657ba62cd8941 100644 (file)
@@ -2,5 +2,5 @@ cdef class A:
     pass
 
 _ERRORS = u"""
-1:5: C class 'A' is declared but not defined
+1:0: C class 'A' is declared but not defined
 """
index 477669b1dd9bd1e5dac285f769a755250bf1da88..ac16fbe8f08fc1b0a14c4f2d4473a7a4197d9c8d 100644 (file)
@@ -9,5 +9,5 @@ cdef class SubType(FinalClass):
     pass
 
 _ERRORS = """
-8:5: Base class 'FinalClass' of type 'SubType' is final
+8:0: Base class 'FinalClass' of type 'SubType' is final
 """