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)
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)
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
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'):
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))
_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')
visibility = visibility,
base_type = base_type,
declarator = declarator,
+ decorators = decorators,
body = suite,
doc = doc,
modifiers = modifiers,
overridable = ctx.python_binding.overridable,
base_type = base_type,
declarators = declarators,
+ decorators = decorators,
in_pxd = ctx.level == 'module_pxd')
return result
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 = []
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)