def dedent(self):
self.level -= 1
- self.klass.declare_var(pos=None, name=cname, cname=cname, type=type, is_cdef=True)
+
+ class ClosureTempAllocator(object):
+ def __init__(self, klass):
+ self.klass = klass
+ self.temps_allocated = {}
+ self.temps_free = {}
+ self.temps_count = 0
+
+ def reset(self):
+ for type, cnames in self.temps_allocated.items():
+ self.temps_free[type] = list(cnames)
+
+ def allocate_temp(self, type):
+ if not type in self.temps_allocated:
+ self.temps_allocated[type] = []
+ self.temps_free[type] = []
+ elif self.temps_free[type]:
+ return self.temps_free[type].pop(0)
+ cname = '%s%d' % (Naming.codewriter_temp_prefix, self.temps_count)
++ self.klass.declare_var(pos=None, name=cname, cname=cname, type=type,
++ visibility='private', is_cdef=True)
+ self.temps_allocated[type].append(cname)
+ self.temps_count += 1
+ return cname
if entry and entry.is_cfunction:
var_entry = entry.as_variable
if var_entry:
- if var_entry.is_builtin and Options.cache_builtins:
+ if var_entry.is_builtin and var_entry.is_const:
- var_entry = env.declare_builtin(var_entry.name, self.pos)
+ var_entry = env.declare_builtin(
+ name = var_entry.name, pos = self.pos)
node = NameNode(self.pos, name = self.name)
node.entry = var_entry
node.analyse_rvalue_entry(env)
f.close()
def generate_h_code(self, env, options, result):
- def h_entries(entries, pxd = 0):
+ def h_entries(entries, api=0, pxd=0):
return [entry for entry in entries
- if entry.c_visibility == 'public' or pxd and entry.defined_in_pxd]
- h_types = h_entries(env.type_entries)
- if ((entry.visibility == 'public') or
++ if ((entry.c_visibility == 'public') or
+ (api and entry.api) or
+ (pxd and entry.defined_in_pxd))]
+ h_types = h_entries(env.type_entries, api=1)
h_vars = h_entries(env.var_entries)
h_funcs = h_entries(env.cfunc_entries)
h_extension_types = h_entries(env.c_class_entries)
code.putln("")
name = entry.type.typeobj_cname
if name:
- if entry.visibility == 'extern' and not entry.in_cinclude:
+ if entry.c_visibility == 'extern' and not entry.in_cinclude:
- code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
+ code.putln("%s %s %s;" % (
Naming.extern_c_macro,
+ PyrexTypes.public_decl("PyTypeObject", "DL_IMPORT"),
name))
- elif entry.visibility == 'public':
+ elif entry.c_visibility == 'public':
- code.putln("%s DL_EXPORT(PyTypeObject) %s;" % (
+ code.putln("%s %s %s;" % (
Naming.extern_c_macro,
+ PyrexTypes.public_decl("PyTypeObject", "DL_EXPORT"),
name))
# ??? Do we really need the rest of this? ???
#else:
def generate_cfunction_predeclarations(self, env, code, definition):
for entry in env.cfunc_entries:
if entry.inline_func_in_pxd or (not entry.in_cinclude and (definition
- or entry.defined_in_pxd or entry.visibility == 'extern')):
- if entry.visibility == 'public':
+ or entry.defined_in_pxd or entry.c_visibility == 'extern')):
+ if entry.c_visibility in ('extern', 'public'):
+ storage_class = "%s " % Naming.extern_c_macro
dll_linkage = "DL_EXPORT"
+ elif entry.visibility == 'extern':
+ storage_class = "%s " % Naming.extern_c_macro
+ dll_linkage = "DL_IMPORT"
+ elif entry.visibility == 'private':
+ storage_class = "static "
+ dll_linkage = None
else:
+ storage_class = "static "
dll_linkage = None
type = entry.type
+
if not definition and entry.defined_in_pxd:
type = CPtrType(type)
header = type.declaration_code(entry.cname,
- dll_linkage = dll_linkage)
+ dll_linkage = dll_linkage)
+ if entry.c_visibility == 'private':
+ storage_class = "static "
+ elif entry.c_visibility == 'public':
+ storage_class = ""
+ else:
+ storage_class = "%s " % Naming.extern_c_macro
if entry.func_modifiers:
- modifiers = '%s ' % ' '.join([
- modifier.upper() for modifier in entry.func_modifiers])
+ modifiers = "%s " % ' '.join(entry.func_modifiers).upper()
else:
modifiers = ''
code.putln("%s%s%s; /*proto*/" % (
need_property = True
else:
need_property = False
- visibility = self.visibility
for declarator in self.declarators:
- name_declarator, type = declarator.analyse(base_type, env)
+ if isinstance(declarator, CFuncDeclaratorNode):
+ name_declarator, type = declarator.analyse(base_type, env, directive_locals=self.directive_locals)
+ else:
+ name_declarator, type = declarator.analyse(base_type, env)
if not type.is_complete():
- if not (self.visibility == 'extern' and type.is_array):
+ if not (self.c_visibility == 'extern' and type.is_array):
error(declarator.pos,
"Variable type '%s' is incomplete" % type)
- if self.visibility == 'extern' and type.is_pyobject:
+ if self.c_visibility == 'extern' and type.is_pyobject:
error(declarator.pos,
"Python object cannot be declared extern")
name = name_declarator.name
error(declarator.pos, "Missing name in declaration.")
return
if type.is_cfunction:
- entry = dest_scope.declare_cfunction(name, type, declarator.pos,
- cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
- api = self.api)
+ entry = dest_scope.declare_cfunction(
+ name = name, cname = cname, c_visibility = self.c_visibility, visibility = self.visibility, overridable = self.overridable, api = self.api, type = type, in_pxd = self.in_pxd,
+ pos = declarator.pos)
if entry is not None:
- entry.directive_locals = self.directive_locals
+ entry.directive_locals = copy.copy(self.directive_locals)
else:
if self.directive_locals:
error(self.pos, "Decorators can only be followed by functions")
class CStructOrUnionDefNode(StatNode):
- # name string
- # cname string or None
+ # name (same as Entry.name)
+ # cname (same as Entry.cname)
# kind "struct" or "union"
# typedef_flag boolean
- # visibility "public" or "private"
- # api boolean
+ # c_visibility (same as Entry.c_visibility)
+ # visibility (same as Entry.visibility)
++ # api (same as Entry.api)
# in_pxd boolean
# attributes [CVarDefNode] or None
# entry Entry
if self.attributes is not None:
scope = StructOrUnionScope(self.name)
self.entry = env.declare_struct_or_union(
- name = self.name, cname = self.cname, c_visibility = self.c_visibility, visibility = self.visibility, overridable = self.overridable, kind = self.kind, scope = scope,
- self.name, self.kind, scope, self.typedef_flag, self.pos,
- self.cname, visibility = self.visibility, api = self.api,
- packed = self.packed)
++ name = self.name, cname = self.cname, c_visibility = self.c_visibility, visibility = self.visibility, overridable = self.overridable, api = self.api, kind = self.kind, scope = scope,
+ typedef_flag = self.typedef_flag, packed = self.packed,
+ pos = self.pos)
if self.attributes is not None:
if self.in_pxd and not env.in_cinclude:
self.entry.defined_in_pxd = 1
attr.analyse_declarations(scope)
class CEnumDefNode(StatNode):
- # name string or None
- # cname string or None
+ # name (same as Entry.name)
+ # cname (same as Entry.cname)
# items [CEnumDefItemNode]
# typedef_flag boolean
- # visibility "public" or "private"
- # api boolean
+ # c_visibility (same as Entry.c_visibility)
+ # visibility (same as Entry.visibility)
++ # api (same as Entry.api)
# in_pxd boolean
# entry Entry
child_attrs = ["items"]
def analyse_declarations(self, env):
- self.entry = env.declare_enum(self.name, self.pos,
- cname = self.cname, typedef_flag = self.typedef_flag,
- visibility = self.visibility, api = self.api)
+ self.entry = env.declare_enum(
- name = self.name, cname = self.cname, c_visibility = self.c_visibility, visibility = self.visibility, typedef_flag = self.typedef_flag, pos = self.pos)
++ name = self.name, cname = self.cname, c_visibility = self.c_visibility, visibility = self.visibility, api = self.api, typedef_flag = self.typedef_flag, pos = self.pos)
if self.items is not None:
if self.in_pxd and not env.in_cinclude:
self.entry.defined_in_pxd = 1
pass
def generate_execution_code(self, code):
- if self.visibility == 'public':
+ if self.visibility == 'public' or self.api:
temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
for item in self.entry.enum_values:
+ if item.visibility == 'private':
+ continue
code.putln("%s = PyInt_FromLong(%s); %s" % (
temp,
item.cname,
if not self.value.type.is_int:
self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
self.value.analyse_const_expression(env)
- entry = env.declare_const(self.name, enum_entry.type,
- self.value, self.pos, cname = self.cname,
- visibility = enum_entry.visibility, api = enum_entry.api)
+ entry = env.declare_const(
+ name = self.name, cname = self.cname, c_visibility = self.c_visibility, visibility = self.visibility, type = enum_entry.type,
- value = self.value, pos = self.pos)
++ api = enum_entry.api, value = self.value, pos = self.pos)
enum_entry.enum_values.append(entry)
# base_type CBaseTypeNode
# declarator CDeclaratorNode
# visibility "public" or "private"
- # api boolean
++ # api (same as Entry.api)
# in_pxd boolean
child_attrs = ["base_type", "declarator"]
def analyse_declarations(self, env):
base = self.base_type.analyse(env)
name_declarator, type = self.declarator.analyse(base, env)
- name = name_declarator.name
- cname = name_declarator.cname
- entry = env.declare_typedef(name, type, self.pos,
- cname = cname, visibility = self.visibility, api = self.api)
+ entry = env.declare_typedef(
- name = name_declarator.name, cname = name_declarator.cname, c_visibility = self.c_visibility, visibility = self.visibility, base_type = type, pos = self.pos)
++ name = name_declarator.name, cname = name_declarator.cname, c_visibility = self.c_visibility, visibility = self.visibility, api = self.api, base_type = type, pos = self.pos)
if self.in_pxd and not env.in_cinclude:
entry.defined_in_pxd = 1
if cname is None:
cname = self.entry.func_cname
entity = type.function_header_code(cname, ', '.join(arg_decls))
- if self.entry.c_visibility == 'public':
- dll_linkage = "DL_EXPORT"
- if self.entry.visibility == 'private':
++ if self.entry.c_visibility == 'private':
+ storage_class = "static "
else:
- dll_linkage = None
- header = self.return_type.declaration_code(entity,
- dll_linkage = dll_linkage)
- if self.entry.c_visibility == 'extern':
- storage_class = "%s " % Naming.extern_c_macro
- elif self.entry.c_visibility == 'public':
storage_class = ""
- else:
- storage_class = "static "
+ dll_linkage = None
+ modifiers = ""
if 'inline' in self.modifiers:
self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
- code.putln("%s%s %s {" % (
- storage_class,
- ' '.join(self.modifiers).upper(), # macro forms
- header))
+ if self.modifiers:
+ modifiers = "%s " % ' '.join(self.modifiers).upper()
+
+ header = self.return_type.declaration_code(entity, dll_linkage=dll_linkage)
+ #print (storage_class, modifiers, header)
+ code.putln("%s%s%s {" % (storage_class, modifiers, header))
def generate_argument_declarations(self, env, code):
for arg in self.args:
entry.doc = None
def declare_lambda_function(self, env):
- name = self.name
- prefix = env.scope_prefix
- func_cname = \
- Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
- entry = env.declare_lambda_function(cname = func_cname, pos = self.pos)
- entry.pymethdef_cname = \
- Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
- entry.qualified_name = env.qualify_name(self.lambda_name)
- entry = env.declare_lambda_function(self.lambda_name, self.pos)
++ entry = env.declare_lambda_function(cname = self.lambda_name, pos = self.pos)
entry.doc = None
self.entry = entry
def caller_will_check_exceptions(self):
return 1
- entry = env.declare_var(prefix + name, py_object_type, self.pos, visibility='private')
+
+ class GeneratorDefNode(DefNode):
+ # Generator DefNode.
+ #
+ # gbody GeneratorBodyDefNode
+ #
+
+ is_generator = True
+ needs_closure = True
+
+ child_attrs = DefNode.child_attrs + ["gbody"]
+
+ def __init__(self, **kwargs):
+ # XXX: don't actually needs a body
+ kwargs['body'] = StatListNode(kwargs['pos'], stats=[])
+ super(GeneratorDefNode, self).__init__(**kwargs)
+
+ def analyse_declarations(self, env):
+ super(GeneratorDefNode, self).analyse_declarations(env)
+ self.gbody.local_scope = self.local_scope
+ self.gbody.analyse_declarations(env)
+
+ def generate_function_body(self, env, code):
+ body_cname = self.gbody.entry.func_cname
+ generator_cname = '%s->%s' % (Naming.cur_scope_cname, Naming.obj_base_cname)
+
+ code.putln('%s.resume_label = 0;' % generator_cname)
+ code.putln('%s.body = (__pyx_generator_body_t) %s;' % (generator_cname, body_cname))
+ code.put_giveref(Naming.cur_scope_cname)
+ code.put_finish_refcount_context()
+ code.putln("return (PyObject *) %s;" % Naming.cur_scope_cname);
+
+ def generate_function_definitions(self, env, code):
+ self.gbody.generate_function_header(code, proto=True)
+ super(GeneratorDefNode, self).generate_function_definitions(env, code)
+ self.gbody.generate_function_definitions(env, code)
+
+
+ class GeneratorBodyDefNode(DefNode):
+ # Generator body DefNode.
+ #
+
+ is_generator_body = True
+
+ def __init__(self, pos=None, name=None, body=None):
+ super(GeneratorBodyDefNode, self).__init__(pos=pos, body=body, name=name, doc=None,
+ args=[],
+ star_arg=None, starstar_arg=None)
+
+ def declare_generator_body(self, env):
+ prefix = env.next_id(env.scope_prefix)
+ name = env.next_id('generator')
++ entry = env.declare_var(
++ name=prefix + name, type=py_object_type, c_visibility='private',
++ visibility='public', pos=self.pos)
+ entry.func_cname = Naming.genbody_prefix + prefix + name
+ entry.qualified_name = EncodedString(self.name)
+ self.entry = entry
+
+ def analyse_declarations(self, env):
+ self.analyse_argument_types(env)
+ self.declare_generator_body(env)
+
+ def generate_function_header(self, code, proto=False):
+ header = "static PyObject *%s(%s, PyObject *%s)" % (
+ self.entry.func_cname,
+ self.local_scope.scope_class.type.declaration_code(Naming.cur_scope_cname),
+ Naming.sent_value_cname)
+ if proto:
+ code.putln('%s; /* proto */' % header)
+ else:
+ code.putln('%s /* generator body */\n{' % header);
+
+ def generate_function_definitions(self, env, code):
+ lenv = self.local_scope
+
+ # Generate closure function definitions
+ self.body.generate_function_definitions(lenv, code)
+
+ # Generate C code for header and body of function
+ code.enter_cfunc_scope()
+ code.return_from_error_cleanup_label = code.new_label()
+
+ # ----- Top-level constants used by this function
+ code.mark_pos(self.pos)
+ self.generate_cached_builtins_decls(lenv, code)
+ # ----- Function header
+ code.putln("")
+ self.generate_function_header(code)
+ # ----- Local variables
+ code.putln("PyObject *%s = NULL;" % Naming.retval_cname)
+ tempvardecl_code = code.insertion_point()
+ code.put_declare_refcount_context()
+ code.put_setup_refcount_context(self.entry.name)
+
+ # ----- Resume switch point.
+ code.funcstate.init_closure_temps(lenv.scope_class.type.scope)
+ resume_code = code.insertion_point()
+ first_run_label = code.new_label('first_run')
+ code.use_label(first_run_label)
+ code.put_label(first_run_label)
+ code.putln('%s' %
+ (code.error_goto_if_null(Naming.sent_value_cname, self.pos)))
+
+ # ----- Function body
+ self.generate_function_body(env, code)
+ code.putln('PyErr_SetNone(PyExc_StopIteration); %s' % code.error_goto(self.pos))
+ # ----- Error cleanup
+ if code.error_label in code.labels_used:
+ code.put_goto(code.return_label)
+ code.put_label(code.error_label)
+ for cname, type in code.funcstate.all_managed_temps():
+ code.put_xdecref(cname, type)
+ code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
+
+ # ----- Non-error return cleanup
+ code.put_label(code.return_label)
+ code.put_xdecref(Naming.retval_cname, py_object_type)
+ code.putln('%s->%s.resume_label = -1;' % (Naming.cur_scope_cname, Naming.obj_base_cname))
+ code.put_finish_refcount_context()
+ code.putln('return NULL;');
+ code.putln("}")
+
+ # ----- Go back and insert temp variable declarations
+ tempvardecl_code.put_temp_declarations(code.funcstate)
+ # ----- Generator resume code
+ resume_code.putln("switch (%s->%s.resume_label) {" % (Naming.cur_scope_cname, Naming.obj_base_cname));
+ resume_code.putln("case 0: goto %s;" % first_run_label)
+
+ from ParseTreeTransforms import YieldNodeCollector
+ collector = YieldNodeCollector()
+ collector.visitchildren(self)
+ for yield_expr in collector.yields:
+ resume_code.putln("case %d: goto %s;" % (yield_expr.label_num, yield_expr.label_name));
+ resume_code.putln("default: /* CPython raises the right error here */");
+ resume_code.put_finish_refcount_context()
+ resume_code.putln("return NULL;");
+ resume_code.putln("}");
+
+ code.exit_cfunc_scope()
+
+
class OverrideCheckNode(StatNode):
# A Node for dispatching to the def method if it
# is overriden.
def visit_CNameDeclaratorNode(self, node):
if node.name in self.seen_vars_stack[-1]:
entry = self.env_stack[-1].lookup(node.name)
- if entry is None or entry.c_visibility != 'extern':
- if (entry is None or entry.visibility != 'extern'
++ if (entry is None or entry.c_visibility != 'extern'
+ and not entry.scope.is_c_class_scope):
warning(node.pos, "cdef variable '%s' declared after it is used" % node.name, 2)
self.visitchildren(node)
return node
self.visitchildren(node)
return node
- def get_scope_use(self, node):
+ def create_generator_class(self, target_module_scope, pos):
+ if self.generator_class:
+ return self.generator_class
+ # XXX: make generator class creation cleaner
+ entry = target_module_scope.declare_c_class(name='__pyx_Generator',
+ objstruct_cname='__pyx_Generator_object',
+ typeobj_cname='__pyx_Generator_type',
+ pos=pos, defining=True, implementing=True)
+ klass = entry.type.scope
+ klass.is_internal = True
+ klass.directives = {'final': True}
+
+ body_type = PyrexTypes.create_typedef_type('generator_body',
+ PyrexTypes.c_void_ptr_type,
+ '__pyx_generator_body_t')
+ klass.declare_var(pos=pos, name='body', cname='body',
- type=body_type, is_cdef=True)
++ visibility='private', type=body_type, is_cdef=True)
+ klass.declare_var(pos=pos, name='is_running', cname='is_running', type=PyrexTypes.c_int_type,
+ is_cdef=True)
+ klass.declare_var(pos=pos, name='resume_label', cname='resume_label', type=PyrexTypes.c_int_type,
+ is_cdef=True)
+ klass.declare_var(pos=pos, name='exc_type', cname='exc_type',
+ type=PyrexTypes.py_object_type, is_cdef=True)
+ klass.declare_var(pos=pos, name='exc_value', cname='exc_value',
+ type=PyrexTypes.py_object_type, is_cdef=True)
+ klass.declare_var(pos=pos, name='exc_traceback', cname='exc_traceback',
+ type=PyrexTypes.py_object_type, is_cdef=True)
+
+ import TypeSlots
- e = klass.declare_pyfunction('send', pos)
++ e = klass.declare_pyfunction(name='send', pos=pos)
+ e.func_cname = '__Pyx_Generator_Send'
+ e.signature = TypeSlots.binaryfunc
+
- e = klass.declare_pyfunction('close', pos)
++ e = klass.declare_pyfunction(name='close', pos=pos)
+ e.func_cname = '__Pyx_Generator_Close'
+ e.signature = TypeSlots.unaryfunc
+
- e = klass.declare_pyfunction('throw', pos)
++ e = klass.declare_pyfunction(name='throw', pos=pos)
+ e.func_cname = '__Pyx_Generator_Throw'
+ e.signature = TypeSlots.pyfunction_signature
+
- e = klass.declare_var('__iter__', PyrexTypes.py_object_type, pos, visibility='public')
++ e = klass.declare_var(
++ name='__iter__', type=PyrexTypes.py_object_type,
++ c_visibility='public', pos=pos)
+ e.func_cname = 'PyObject_SelfIter'
+
- e = klass.declare_var('__next__', PyrexTypes.py_object_type, pos, visibility='public')
++ e = klass.declare_var(
++ name='__next__', type=PyrexTypes.py_object_type,
++ c_visibility='public', pos=pos)
+ e.func_cname = '__Pyx_Generator_Next'
+
+ self.generator_class = entry.type
+ return self.generator_class
+
+ def find_entries_used_in_closures(self, node):
from_closure = []
in_closure = []
for name, entry in node.local_scope.entries.items():
s.expect_dedent()
return Nodes.CEnumDefNode(
pos, name = name, cname = cname, items = items,
- typedef_flag = ctx.typedef_flag, visibility = ctx.visibility,
- api = ctx.api, in_pxd = ctx.level == 'module_pxd')
+ typedef_flag = ctx.typedef_flag, c_visibility = ctx.c_visibility,
- visibility = ctx.visibility, in_pxd = ctx.level == 'module_pxd')
++ visibility = ctx.visibility, api = ctx.api,
++ in_pxd = ctx.level == 'module_pxd')
def p_c_enum_line(s, ctx, items):
if s.sy != 'pass':
s.expect_dedent()
else:
s.expect_newline("Syntax error in struct or union definition")
-- return Nodes.CStructOrUnionDefNode(pos,
- name = name, cname = cname, kind = kind, attributes = attributes,
- typedef_flag = ctx.typedef_flag, visibility = ctx.visibility,
- api = ctx.api, in_pxd = ctx.level == 'module_pxd', packed = packed)
++ return Nodes.CStructOrUnionDefNode(pos = pos,
+ name = name,
+ cname = cname,
+ kind = kind,
+ attributes = attributes,
+ typedef_flag = ctx.typedef_flag,
+ cdef_flag = ctx.cdef_flag,
+ overridable = ctx.overridable,
+ c_visibility = ctx.c_visibility,
+ visibility = ctx.visibility,
++ api = ctx.api,
+ in_pxd = ctx.level == 'module_pxd',
+ packed = packed)
-def p_visibility(s, prev_visibility):
+def p_visibility(s, ctx):
pos = s.position()
- visibility = prev_visibility
if s.sy == 'IDENT' and s.systring in ('extern', 'public', 'readonly'):
visibility = s.systring
- if prev_visibility != 'private' and visibility != prev_visibility:
- s.error("Conflicting visibility options '%s' and '%s'"
- % (prev_visibility, visibility))
+ outer_scope = ctx.level in ('module', 'module_pxd')
+ if visibility == 'extern':
+ #if prev_visibility != 'private' and visibility != prev_visibility:
+ # s.error("Conflicting visibility options '%s' and '%s'"
+ # % (prev_visibility, visibility))
+ ctx.c_visibility = 'extern'
+ # Need to restore/set default value for Python visibility?
+ elif outer_scope and visibility not in ('readonly',):
+ ctx.c_visibility = visibility
+ else:
+ ctx.visibility = visibility
+ if ctx.visibility != 'private':
+ ctx.c_visibility = 'public'
s.next()
- return visibility
+ return ctx
def p_c_modifiers(s):
if s.sy == 'IDENT' and s.systring in ('inline',):
declarator = p_c_declarator(s, ctx, is_type = 1, nonempty = 1)
s.expect_newline("Syntax error in ctypedef statement")
return Nodes.CTypeDefNode(
- pos, base_type = base_type,
- declarator = declarator,
- visibility = visibility, api = api,
- in_pxd = ctx.level == 'module_pxd')
+ pos, base_type = base_type, declarator = declarator,
+ c_visibility = ctx.c_visibility, visibility = ctx.visibility,
- in_pxd = ctx.level == 'module_pxd')
++ api = ctx.api, in_pxd = ctx.level == 'module_pxd')
def p_decorators(s):
decorators = []
base_class_module = ".".join(base_class_path[:-1])
base_class_name = base_class_path[-1]
if s.sy == '[':
- if ctx.c_visibility not in ('extern', 'public'):
- error(s.position(), "Name options only allowed for 'public' or 'extern' C class")
- if ctx.visibility not in ('public', 'extern') and not ctx.api:
++ if ctx.c_visibility not in ('public', 'extern') and not ctx.api:
+ error(s.position(), "Name options only allowed for 'public', 'api', or 'extern' C class")
objstruct_name, typeobj_name = p_c_class_options(s)
if s.sy == ':':
if ctx.level == 'module_pxd':
error(pos, "Object struct name specification required for 'public' C class")
if not typeobj_name:
error(pos, "Type object name specification required for 'public' C class")
- elif ctx.visibility == 'private':
+ elif ctx.c_visibility == 'private':
if ctx.api:
- error(pos, "Only 'public' C class can be declared 'api'")
+ if not objstruct_name:
+ error(pos, "Object struct name specification required for 'api' C class")
+ if not typeobj_name:
+ error(pos, "Type object name specification required for 'api' C class")
else:
- error(pos, "Invalid class visibility '%s'" % ctx.visibility)
+ error(pos, "Invalid class visibility '%s'" % ctx.visibility_string())
return Nodes.CClassDefNode(pos,
+ c_visibility = ctx.c_visibility,
visibility = ctx.visibility,
typedef_flag = ctx.typedef_flag,
api = ctx.api,
code.putln("return NULL;")
code.putln("}")
-- # This is a bit of a hack, we need a forward declaration
-- # due to the way things are ordered in the module...
-- if self.forward_decl:
-- proto.putln(self.type.declaration_code('') + ';')
proto.putln(self.header + ";")
-
+
class CStructOrUnionType(CType):
# name string
self.to_py_function = None
self._convert_code = False
return False
- forward_decl = (self.entry.visibility != 'extern')
+ forward_decl = (self.entry.c_visibility != 'extern')
self._convert_code = StructUtilityCode(self, forward_decl)
-
+
env.use_utility_code(self._convert_code)
return True
-
+
def __repr__(self):
return "<CStructOrUnionType %s %s%s>" % (self.name, self.cname,
("", " typedef")[self.typedef_flag])
def qualify_name(self, name):
return EncodedString("%s.%s" % (self.qualified_name, name))
- def declare_const(self, name, type, value, pos, cname = None, visibility = 'private', api = 0):
+ def declare_const(self, name, cname = None, namespace = None, c_visibility = 'private', visibility = 'public', overridable = 0, api = 0, type = None, value = None, pos = None):
# Add an entry for a named constant.
if not cname:
- if self.in_cinclude or c_visibility == 'public':
- if self.in_cinclude or (visibility == 'public' or api):
++ if self.in_cinclude or c_visibility == 'public' or api:
cname = name
else:
cname = self.mangle(Naming.enum_prefix, name)
# Add an entry for a type definition.
if not cname:
cname = name
- entry = self.declare(name, cname, type, pos, visibility, shadow)
+ entry = self.declare(name = name, cname = cname, namespace = namespace, c_visibility = c_visibility, visibility = visibility, overridable = overridable, api = api, type = type, shadow = shadow, pos = pos)
entry.is_type = 1
+ entry.api = api
if defining:
self.type_entries.append(entry)
# here we would set as_variable to an object representing this type
return entry
- def declare_typedef(self, name, base_type, pos, cname = None,
- visibility = 'private', api = 0):
+ def declare_typedef(self, name, cname = None, namespace = None, c_visibility = 'private', visibility = 'public', overridable = 0, api = 0,
+ base_type = None, pos = None):
if not cname:
- if self.in_cinclude or c_visibility == 'public':
- if self.in_cinclude or (visibility == 'public' or api):
++ if self.in_cinclude or c_visibility == 'public' or api:
cname = name
else:
cname = self.mangle(Naming.type_prefix, name)
type.qualified_name = entry.qualified_name
return entry
- def declare_struct_or_union(self, name, kind, scope,
- typedef_flag, pos, cname = None,
- visibility = 'private', api = 0,
- packed = False):
+ def declare_struct_or_union(self, name, cname = None, namespace = None, c_visibility = 'private', visibility = 'public', overridable = 0, api = 0, kind = None, scope = None, typedef_flag=False,
+ packed=False, pos = None):
# Add an entry for a struct or union definition.
if not cname:
- if self.in_cinclude or c_visibility == 'public':
- if self.in_cinclude or (visibility == 'public' or api):
++ if self.in_cinclude or c_visibility == 'public' or api:
cname = name
else:
cname = self.mangle(Naming.type_prefix, name)
def check_previous_typedef_flag(self, entry, typedef_flag, pos):
if typedef_flag != entry.type.typedef_flag:
error(pos, "'%s' previously declared using '%s'" % (
- entry.name, ("cdef", "ctypedef")[entry.type.typedef_flag]))
-
- def check_previous_visibility(self, entry, visibility, pos):
- if entry.visibility != visibility:
- error(pos, "'%s' previously declared as '%s'" % (
- entry.name, entry.visibility))
-
- def declare_enum(self, name, pos, cname, typedef_flag,
- visibility = 'private', api = 0):
+ entry.name,
+ ("cdef", "ctypedef")[entry.type.typedef_flag]))
+
- def _check_previous_visibility(self, entry, c_visibility = 'private', visibility = 'public'):
++ def check_previous_visibility(self, entry, name, cname = None, namespace = None, c_visibility = 'private', visibility = 'public', overridable = 0, api = 0, type_name=None,
++ pos = None):
+ # Compare the visibility of `entry` with a second
+ # `visibility`. If there is a difference, return a string
+ # representing the conflicting `entry` visibility, otherwise
+ # return an empty string.
++
++ if not type_name:
++ type_name = type(entry)
+ if c_visibility != entry.c_visibility:
- return entry.c_visibility
++ error(pos, "%s '%s' C visibility changed from '%s' to '%s'" % (
++ type_name, entry.name, entry.c_visibility, c_visibility))
+ if visibility != entry.visibility:
- return entry.visibility
-
- def check_previous_visibility(self, entry, name, cname = None, namespace = None, c_visibility = 'private', visibility = 'public', overridable = 0, api = 0, type_name=None,
- pos = None):
++ error(pos, "%s '%s' Python visibility changed from '%s' to %s" % (
++ type_name, entry.name, entry.visibility, visibility))
+ # WTK: check api? Previous code seems to allow you to set the
+ # api flag anywhere.
- vis_diff = self._check_previous_visibility(entry, c_visibility = c_visibility, visibility = visibility)
- if vis_diff:
- if not type_name:
- type_name = type(entry)
- error(pos, "%s '%s' previously declared as '%s'" % (
- type_name, entry.name, vis_diff))
+
+ def declare_enum(self, name, cname = None, namespace = None, c_visibility = 'private', visibility = 'public', overridable = 0, api = 0, typedef_flag = None, pos = None):
if name:
if not cname:
- if self.in_cinclude or c_visibility == 'public':
- if self.in_cinclude or (visibility == 'public' or api):
++ if self.in_cinclude or c_visibility == 'public' or api:
cname = name
else:
cname = self.mangle(Naming.type_prefix, name)
constructor = type.scope.lookup(u'<init>')
if constructor is not None and PyrexTypes.best_match([], constructor.all_alternatives()) is None:
error(pos, "C++ class must have a default constructor to be stack allocated")
- entry = self.declare(name, cname, type, pos, visibility)
+ entry = self.declare(name = name, cname = cname, namespace = namespace, c_visibility = c_visibility, visibility = visibility, overridable = overridable, api = api, type = type, pos = pos)
entry.is_variable = 1
+ entry.api = api
self.control_flow.set_state((), (name, 'initialized'), False)
return entry
entry.is_anonymous = True
return entry
- def declare_lambda_function(self, lambda_name, pos):
+ def declare_lambda_function(self, name = None, cname = None, namespace = None, c_visibility = 'private', visibility = 'public', overridable = 0, api = 0, pos = None):
# Add an entry for an anonymous Python function.
- func_cname = self.mangle(Naming.lambda_func_prefix + u'funcdef_', lambda_name)
- pymethdef_cname = self.mangle(Naming.lambda_func_prefix + u'methdef_', lambda_name)
- qualified_name = self.qualify_name(lambda_name)
++ if not cname:
++ cname = self.mangle(Naming.lambda_func_prefix + u'funcdef_', cname)
++ pymethdef_cname = self.mangle(Naming.lambda_func_prefix + u'methdef_', cname)
++ qualified_name = self.qualify_name(cname)
+
- entry = self.declare(None, func_cname, py_object_type, pos, 'private')
- entry.name = lambda_name
+ entry = self.declare_var(name = name, cname = cname, namespace = namespace, c_visibility = c_visibility, visibility = visibility, overridable = overridable, api = api, type = py_object_type, pos = pos)
++
+ entry.name = EncodedString(cname)
+ entry.qualified_name = qualified_name
+ entry.pymethdef_cname = pymethdef_cname
- entry.func_cname = func_cname
+ entry.func_cname = cname
entry.signature = pyfunction_signature
entry.is_anonymous = True
return entry
cname = self.mangle(Naming.func_prefix, name)
entry = self.lookup_here(name)
if entry:
- vis_diff = self._check_previous_visibility(entry, c_visibility = c_visibility, visibility = visibility)
- if vis_diff:
- warning(pos, "Function '%s' previously declared as '%s'" % (
- name, vis_diff), 1)
- if visibility != 'private' and visibility != entry.visibility:
- warning(pos, "Function '%s' previously declared as '%s'" % (name, entry.visibility), 1)
++ self.check_previous_visibility(
++ entry, name = name, cname = cname, namespace = namespace,
++ c_visibility = c_visibility, visibility = visibility,
++ overridable = overridable, api = api, type_name = 'Function',
++ pos = pos)
if not entry.type.same_as(type):
- if visibility == 'extern' and entry.visibility == 'extern':
+ if c_visibility == 'extern' and entry.c_visibility == 'extern':
can_override = False
if self.is_cpp():
can_override = True
name = 'unicode'
return Scope.lookup(self, name)
- def declare_builtin(self, name, pos):
+ def declare_builtin(self, name, cname = None, namespace = None, c_visibility = 'private', visibility = 'public', overridable = 0, api = 0, pos = None):
if not hasattr(builtins, name):
if self.outer_scope is not None:
- return self.outer_scope.declare_builtin(name, pos)
+ return self.outer_scope.declare_builtin(name = name, cname = cname, namespace = namespace, c_visibility = c_visibility, visibility = visibility, overridable = overridable, api = api, pos = pos)
else:
- error(pos, "undeclared name not builtin: %s" % name)
+ if Options.error_on_unknown_names:
+ error(pos, "undeclared name not builtin: %s" % name)
+ else:
+ warning(pos, "undeclared name not builtin: %s" % name, 2)
- def declare_builtin_cfunction(self, name, type, cname, python_equiv = None,
- utility_code = None):
+ def declare_builtin_cfunction(self, name, cname = None, namespace = None, c_visibility = 'private', visibility = 'public', overridable = 0, api = 0, type = None, python_equiv = None,
+ utility_code = None):
# If python_equiv == "*", the Python equivalent has the same name
# as the entry, otherwise it has the name specified by python_equiv.
name = EncodedString(name)
return entry
return self.outer_scope.lookup(name, language_level = self.context.language_level)
- def declare_builtin(self, name, pos):
+ def declare_builtin(self, name, cname = None, namespace = None, c_visibility = 'private', visibility = 'public', overridable = 0, api = 0, pos = None):
- if (not hasattr(builtins, name)
- and name != 'xrange'):
- # 'xrange' is special cased in Code.py
+ if not hasattr(builtins, name) \
+ and name not in Code.non_portable_builtins_map \
+ and name not in Code.uncachable_builtins:
if self.has_import_star:
- entry = self.declare_var(name, py_object_type, pos)
+ entry = self.declare_var(name = name, cname = cname, namespace = namespace, c_visibility = c_visibility, visibility = visibility, overridable = overridable, api = api, type = py_object_type, pos = pos)
return entry
+ elif self.outer_scope is not None:
+ return self.outer_scope.declare_builtin(name = name, cname = cname, namespace = namespace, c_visibility = c_visibility, visibility = visibility, overridable = overridable, api = api, pos = pos)
else:
- error(pos, "undeclared name not builtin: %s"%name)
+ if Options.error_on_unknown_names:
+ error(pos, "undeclared name not builtin: %s" % name)
+ else:
+ warning(pos, "undeclared name not builtin: %s" % name, 2)
+ # unknown - assume it's builtin and look it up at runtime
+ entry = self.declare(name, None, py_object_type, pos, 'private')
+ entry.is_builtin = 1
+ return entry
if Options.cache_builtins:
for entry in self.cached_builtins:
if entry.name == name:
return entry
- entry = self.declare(None, None, py_object_type, pos, 'private')
+ entry = self.declare(type = py_object_type, pos = pos)
- if Options.cache_builtins:
+ if Options.cache_builtins and name not in Code.uncachable_builtins:
entry.is_builtin = 1
- entry.is_const = 1
+ entry.is_const = 1 # cached
entry.name = name
entry.cname = Naming.builtin_prefix + name
self.cached_builtins.append(entry)
self.undeclared_cached_builtins.append(entry)
else:
entry.is_builtin = 1
+ entry.name = name
return entry
- def find_module(self, module_name, pos):
+ def find_module(self, module_name, pos = None):
# Find a module in the import namespace, interpreting
# relative imports relative to this module's parent.
# Finds and parses the module's .pxd file if the module
# If this is a non-extern typedef class, expose the typedef, but use
# the non-typedef struct internally to avoid needing forward
# declarations for anonymous structs.
- if typedef_flag and visibility != 'extern':
- if not (visibility == 'public' or api):
+ if typedef_flag and c_visibility != 'extern':
- if c_visibility != 'public':
- warning(pos, "ctypedef only valid for public and extern classes", 2)
++ if not (c_visibility == 'public' or api):
+ warning(pos, "ctypedef only valid for 'extern' , 'public', and 'api'", 2)
objtypedef_cname = objstruct_cname
typedef_flag = 0
else:
self.genexp_prefix = "%s%d%s" % (Naming.pyrex_prefix, len(name), name)
def mangle(self, prefix, name):
- return '%s%s' % (self.genexp_prefix, self.parent_scope.mangle(self, prefix, name))
+ return '%s%s' % (self.genexp_prefix, self.parent_scope.mangle(prefix, name))
- def declare_var(self, name, type, pos,
- cname = None, visibility = 'private', api = 0, is_cdef = True):
+ def declare_var(self, name, cname = None, namespace = None, c_visibility = 'private', visibility = 'public', overridable = 0, api = 0, type = None, is_cdef = 0, pos = None):
if type is unspecified_type:
# if the outer scope defines a type for this variable, inherit it
outer_entry = self.outer_scope.lookup(name)
self.entries[name] = entry
return entry
- def declare_lambda_function(self, func_cname, pos):
- return self.outer_scope.declare_lambda_function(func_cname, pos)
++ def declare_lambda_function(self, name = None, cname = None, namespace = None, c_visibility = 'private', visibility = 'public', overridable = 0, api = 0, pos = None):
++ return self.outer_scope.declare_lambda_function(
++ name = name, cname = cname, namespace = namespace,
++ c_visibility = c_visibility, visibility = visibility,
++ overridable = overridable, api = api, pos = pos)
+
+ def add_lambda_def(self, def_node):
+ return self.outer_scope.add_lambda_def(def_node)
+
class ClosureScope(LocalScope):
if type is unspecified_type:
type = py_object_type
# Add an entry for a class attribute.
- entry = Scope.declare_var(self, name, type, pos,
- cname=cname, visibility=visibility, api=api, is_cdef=is_cdef)
+ entry = Scope.declare_var(
+ self, name, cname = None, namespace = None, c_visibility = 'private', visibility = 'public', overridable = 0, api = 0, type = type, is_cdef = is_cdef, pos = pos)
- entry.is_pyglobal = 1
+ entry.is_pyglobal = 1 # FIXME: WTF?
entry.is_pyclass_attr = 1
return entry
if name == "__new__":
error(pos, "__new__ method of extension type will change semantics "
"in a future version of Pyrex and Cython. Use __cinit__ instead.")
- if c_visibility != 'extern':
- error(pos, "C class pyfunctions may only be extern")
- entry = self.declare_var(name, py_object_type, pos,
- visibility='extern')
+ entry = self.declare_var(name = name, cname = cname, namespace = namespace, c_visibility = c_visibility, visibility = visibility, overridable = overridable, api = api, type = py_object_type, pos = pos)
special_sig = get_special_method_signature(name)
if special_sig:
# Special methods get put in the method table with a particular
self.run_doctests(self.module, result)
def run_doctests(self, module_name, result):
- if sys.version_info[0] >= 3 or not hasattr(os, 'fork') or not self.fork:
- doctest.DocTestSuite(module_name).run(result)
- gc.collect()
- return
-
- # fork to make sure we do not keep the tested module loaded
- result_handle, result_file = tempfile.mkstemp()
- os.close(result_handle)
- child_id = os.fork()
- if not child_id:
- result_code = 0
- try:
- try:
- tests = None
- try:
- partial_result = PartialTestResult(result)
- tests = doctest.DocTestSuite(module_name)
- tests.run(partial_result)
- gc.collect()
- except Exception:
- if tests is None:
- # importing failed, try to fake a test class
- tests = _FakeClass(
- failureException=sys.exc_info()[1],
- _shortDescription=self.shortDescription(),
- module_name=None)
- partial_result.addError(tests, sys.exc_info())
- result_code = 1
- output = open(result_file, 'wb')
- pickle.dump(partial_result.data(), output)
- except:
- traceback.print_exc()
- finally:
- try: output.close()
- except: pass
- os._exit(result_code)
+ def run_test(result):
+ tests = doctest.DocTestSuite(module_name)
+ tests.run(result)
+ run_forked_test(result, run_test, self.shortDescription(), self.fork)
+
+ def run_forked_test(result, run_func, test_name, fork=True):
+ if not fork or sys.version_info[0] >= 3 or not hasattr(os, 'fork'):
+ run_func(result)
+ gc.collect()
+ return
+
+ # fork to make sure we do not keep the tested module loaded
+ result_handle, result_file = tempfile.mkstemp()
+ os.close(result_handle)
+ child_id = os.fork()
+ if not child_id:
+ result_code = 0
try:
- cid, result_code = os.waitpid(child_id, 0)
- # os.waitpid returns the child's result code in the
- # upper byte of result_code, and the signal it was
- # killed by in the lower byte
- if result_code & 255:
- raise Exception("Tests in module '%s' were unexpectedly killed by signal %d"%
- (module_name, result_code & 255))
- result_code = result_code >> 8
- if result_code in (0,1):
- input = open(result_file, 'rb')
+ try:
+ tests = None
try:
- PartialTestResult.join_results(result, pickle.load(input))
- finally:
- input.close()
- if result_code:
- raise Exception("Tests in module '%s' exited with status %d" %
- (module_name, result_code))
+ partial_result = PartialTestResult(result)
+ run_func(partial_result)
+ gc.collect()
+ except Exception:
+ if tests is None:
+ # importing failed, try to fake a test class
+ tests = _FakeClass(
+ failureException=sys.exc_info()[1],
+ _shortDescription=test_name,
+ module_name=None)
+ partial_result.addError(tests, sys.exc_info())
+ result_code = 1
+ output = open(result_file, 'wb')
+ pickle.dump(partial_result.data(), output)
+ except:
+ traceback.print_exc()
finally:
- try: os.unlink(result_file)
+ try: output.close()
except: pass
- raise Exception("Tests in module '%s' were unexpectedly killed by signal %d"%
- (module_name, result_code & 255))
+ os._exit(result_code)
+
+ try:
+ cid, result_code = os.waitpid(child_id, 0)
+ # os.waitpid returns the child's result code in the
+ # upper byte of result_code, and the signal it was
+ # killed by in the lower byte
+ if result_code & 255:
- raise Exception("Tests in module '%s' exited with status %d" %
- (module_name, result_code))
++ raise Exception("Test '%s' was unexpectedly killed by signal %d"%
++ (test_name, result_code & 255))
+ result_code = result_code >> 8
+ if result_code in (0,1):
+ input = open(result_file, 'rb')
+ try:
+ PartialTestResult.join_results(result, pickle.load(input))
+ finally:
+ input.close()
+ if result_code:
++ raise Exception("Test '%s' exited with status %d" %
++ (test_name, result_code))
+ finally:
+ try: os.unlink(result_file)
+ except: pass
class PureDoctestTestCase(unittest.TestCase):
def __init__(self, module_name, module_path):
+ # mode: compile
+
cdef class A:
+ cdef public int i
+ cdef readonly int j
+ cdef void *ptr
+
cpdef a(self):
ma(self)
pass
_ERRORS = """
- 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
-5:5: inheritance from PyVarObject types like 'tuple' is not currently supported
-8:5: inheritance from PyVarObject types like 'bytes' is not currently supported
-11:5: inheritance from PyVarObject types like 'str' is not currently supported
++5:0: inheritance from PyVarObject types like 'tuple' is not currently supported
++8:0: inheritance from PyVarObject types like 'bytes' is not currently supported
++11:0: inheritance from PyVarObject types like 'str' is not currently supported
"""
pass
_ERRORS = u"""
- 5:24: C attribute of type 'VoidP' cannot be accessed from Python
- 5:24: Cannot convert 'VoidP' to Python object
- 6:24: C attribute of type 'VoidP' cannot be accessed from Python
- 6:24: Cannot convert 'VoidP' to Python object
- 6:24: Cannot convert Python object to 'VoidP'
- 14:22: Cannot convert Python object to 'Foo'
+ 8:24: C attribute of type 'VoidP' cannot be accessed from Python
+ 8:24: Cannot convert 'VoidP' to Python object
+ 9:24: C attribute of type 'VoidP' cannot be accessed from Python
+ 9:24: Cannot convert 'VoidP' to Python object
+ 9:24: Cannot convert Python object to 'VoidP'
-17:22: C attribute of type 'Foo' cannot be accessed from Python
+ 17:22: Cannot convert Python object to 'Foo'
"""
--- /dev/null
- 3:17: Syntax error in C variable declaration
++# mode: error
++
+# TODO: a way to keep going after parsing errors?
+
+cdef private int priv_global_variable
+
+cdef private priv_global_function(x):
+ return x*2
+
+
+cdef class bare_global_class:
+ cdef private int priv_attribute
+
+ def __cinit__(self):
+ self.priv_attribute = 1
+
+
+cdef class public pub_global_class:
+ cpdef cp_method(self, x):
+ return x*2
+
+
+cdef class private priv_global_class:
+ cpdef cp_method(self, x):
+ return x*2
+
+
+cdef class readonly ro_global_class:
+ cpdef cp_method(self, x):
+ return x*2
+
+
+cpdef class cp_global_class:
+ cpdef cp_method(self, x):
+ return x*2
+
+
+_ERRORS = u"""
++5:17: Syntax error in C variable declaration
+"""
pass
_ERRORS = u"""
- 3:4: Special methods must be declared with 'def', not 'cdef'
- 6:4: Special methods must be declared with 'def', not 'cdef'
-4:9: Special methods must be declared with 'def', not 'cdef'
-7:9: Special methods must be declared with 'def', not 'cdef'
++4:4: Special methods must be declared with 'def', not 'cdef'
++7:4: Special methods must be declared with 'def', not 'cdef'
"""
pass
_ERRORS = u"""
- 6: 4: Signature not compatible with previous declaration
- 2: 4: Previous declaration is here
-8: 9: Signature not compatible with previous declaration
-4: 9: Previous declaration is here
++8: 4: Signature not compatible with previous declaration
++4: 4: Previous declaration is here
"""
cpdef nogil class test: pass
_ERRORS = u"""
- 2: 0: cdef blocks cannot be declared cpdef
- 3: 0: cdef blocks cannot be declared cpdef
- 3:12: Expected ':', found 'class'
-3: 6: cdef blocks cannot be declared cpdef
-4: 6: cdef blocks cannot be declared cpdef
++3: 0: cdef blocks cannot be declared cpdef
++4: 0: cdef blocks cannot be declared cpdef
+ 4:12: Expected ':', found 'class'
"""
cdef enum ham:
pass
_ERRORS = u"""
- 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:0: Empty enum definition not allowed outside a 'cdef extern from' block
-3:5: Empty struct or union definition not allowed outside a 'cdef extern from' block
++3:0: Empty struct or union definition not allowed outside a 'cdef extern from' block
+ 6:0: Empty struct or union definition not allowed outside a 'cdef extern from' block
-9:5: Empty enum definition not allowed outside a 'cdef extern from' block
++9:0: Empty enum definition not allowed outside a 'cdef extern from' block
"""
cdef void f(self, int x):
pass
_ERRORS = u"""
- 6:1: Signature not compatible with previous declaration
- 2:1: Previous declaration is here
-8:6: Signature not compatible with previous declaration
-4:6: Previous declaration is here
++8:1: Signature not compatible with previous declaration
++4:1: Previous declaration is here
"""
cdef Blarg b
_ERRORS = u"""
- 3:0: 'Foo' previously declared using 'cdef'
- 9:0: 'Blarg' previously declared using 'ctypedef'
+ 5:0: 'Foo' previously declared using 'cdef'
-11:5: 'Blarg' previously declared using 'ctypedef'
++11:0: 'Blarg' previously declared using 'ctypedef'
"""
pass
_ERRORS = u"""
- 2:1: Signature not compatible with previous declaration
2:12: Previous declaration is here
-4: 6: Signature not compatible with previous declaration
++4: 1: Signature not compatible with previous declaration
"""
char a
_ERRORS = u"""
- 2:4: Cannot declare extern struct as 'packed'
-5:9: Cannot declare extern struct as 'packed'
++5:4: Cannot declare extern struct as 'packed'
"""
cdef class Spam
cdef extern class external.Eggs
_ERRORS = u"""
- 1:0: C class 'Spam' is declared but not defined
- 2:0: C class 'Eggs' is declared but not defined
-3:5: C class 'Spam' is declared but not defined
-4:5: C class 'Eggs' is declared but not defined
++3:0: C class 'Spam' is declared but not defined
++4:0: C class 'Eggs' is declared but not defined
"""
pass
_ERRORS = u"""
- 3:4: C method has no self argument
-5:10: C method has no self argument
++5:4: C method has no self argument
"""
pass
_ERRORS = u"""
- 3:4: Self argument (int) of C method 'a' does not match parent type (A)
-5:10: Self argument (int) of C method 'a' does not match parent type (A)
++5:4: Self argument (int) of C method 'a' does not match parent type (A)
"""
# except these: 29, 34, 44, 56, 58, 60, 62-64
_ERRORS = u"""
- 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: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
- 28:8: Discarding owned Python object not allowed without gil
- 28:16: Constructing complex number not allowed without gil
- 30:8: Backquote expression not allowed without gil
-3:5: Function with Python return type cannot be declared nogil
-6:5: Function declared nogil has Python locals or temporaries
++<<<<<<< HEAD
++3:0: Function with Python return type cannot be declared nogil
++6:0: Function declared nogil has Python locals or temporaries
+ 8:6: Assignment of Python object not allowed without gil
+ 11:5: Discarding owned Python object not allowed without gil
-13:5: Function with Python return type cannot be declared nogil
++13:0: Function with Python return type cannot be declared nogil
+ 17:5: Calling gil-requiring function not allowed without gil
+ 26:9: Calling gil-requiring function not allowed without gil
+ 28:12: Assignment of Python object not allowed without gil
30:8: Discarding owned Python object not allowed without gil
- 30:9: Operation not allowed without gil
- 31:15: Assignment of Python object not allowed without gil
- 31:15: Operation not allowed without gil
- 31:15: Python import not allowed without gil
- 32:8: Operation not allowed without gil
- 32:13: Python import not allowed without gil
- 32:25: Constructing Python list not allowed without gil
- 32:25: Operation not allowed without gil
- 33:17: Iterating over Python object not allowed without gil
- 35:11: Discarding owned Python object not allowed without gil
- 35:11: Indexing Python object not allowed without gil
- 36:11: Discarding owned Python object not allowed without gil
- 36:11: Slicing Python object not allowed without gil
- 37:11: Constructing Python slice object not allowed without gil
+ 30:16: Constructing complex number not allowed without gil
+ 32:8: Backquote expression not allowed without gil
+ 32:8: Discarding owned Python object not allowed without gil
+ 32:9: Operation not allowed without gil
+ 33:15: Assignment of Python object not allowed without gil
+ 33:15: Operation not allowed without gil
+ 33:15: Python import not allowed without gil
+ 34:8: Operation not allowed without gil
+ 34:13: Python import not allowed without gil
+ 34:25: Constructing Python list not allowed without gil
+ 34:25: Operation not allowed without gil
+ 35:17: Iterating over Python object not allowed without gil
37:11: Discarding owned Python object not allowed without gil
37:11: Indexing Python object not allowed without gil
- 37:13: Converting to Python object not allowed without gil
- 37:15: Converting to Python object not allowed without gil
- 37:17: Converting to Python object not allowed without gil
- 38:11: Accessing Python attribute not allowed without gil
38:11: Discarding owned Python object not allowed without gil
- 39:9: Constructing Python tuple not allowed without gil
- 39:9: Discarding owned Python object not allowed without gil
- 40:8: Constructing Python list not allowed without gil
- 40:8: Discarding owned Python object not allowed without gil
- 41:8: Constructing Python dict not allowed without gil
- 41:8: Discarding owned Python object not allowed without gil
- 42:12: Discarding owned Python object not allowed without gil
- 42:12: Truth-testing Python object not allowed without gil
- 43:13: Python type test not allowed without gil
- 45:10: Discarding owned Python object not allowed without gil
- 45:10: Operation not allowed without gil
- 46:8: Discarding owned Python object not allowed without gil
- 46:8: Operation not allowed without gil
- 47:10: Assignment of Python object not allowed without gil
- 47:14: Assignment of Python object not allowed without gil
- 48:9: Assignment of Python object not allowed without gil
- 48:13: Assignment of Python object not allowed without gil
- 48:16: Creating temporary Python reference not allowed without gil
- 48:19: Creating temporary Python reference not allowed without gil
- 49:11: Assignment of Python object not allowed without gil
- 49:11: Indexing Python object not allowed without gil
- 50:11: Accessing Python attribute not allowed without gil
- 50:11: Assignment of Python object not allowed without gil
- 51:8: Constructing Python tuple not allowed without gil
- 51:8: Python print statement not allowed without gil
- 52:8: Deleting Python object not allowed without gil
- 53:8: Returning Python object not allowed without gil
- 54:8: Raising exception not allowed without gil
- 55:14: Truth-testing Python object not allowed without gil
- 57:17: Truth-testing Python object not allowed without gil
- 59:8: For-loop using object bounds or target not allowed without gil
- 61:8: Try-except statement not allowed without gil
- 65:8: Try-finally statement not allowed without gil
- 82:8: For-loop using object bounds or target not allowed without gil
+ 38:11: Slicing Python object not allowed without gil
+ 39:11: Constructing Python slice object not allowed without gil
+ 39:11: Discarding owned Python object not allowed without gil
+ 39:11: Indexing Python object not allowed without gil
+ 39:13: Converting to Python object not allowed without gil
+ 39:15: Converting to Python object not allowed without gil
+ 39:17: Converting to Python object not allowed without gil
+ 40:11: Accessing Python attribute not allowed without gil
+ 40:11: Discarding owned Python object not allowed without gil
+ 41:9: Constructing Python tuple not allowed without gil
+ 41:9: Discarding owned Python object not allowed without gil
+ 42:8: Constructing Python list not allowed without gil
+ 42:8: Discarding owned Python object not allowed without gil
+ 43:8: Constructing Python dict not allowed without gil
+ 43:8: Discarding owned Python object not allowed without gil
+ 44:12: Discarding owned Python object not allowed without gil
+ 44:12: Truth-testing Python object not allowed without gil
+ 45:13: Python type test not allowed without gil
+ 47:10: Discarding owned Python object not allowed without gil
+ 47:10: Operation not allowed without gil
+ 48:8: Discarding owned Python object not allowed without gil
+ 48:8: Operation not allowed without gil
+ 49:10: Assignment of Python object not allowed without gil
+ 49:14: Assignment of Python object not allowed without gil
+ 50:9: Assignment of Python object not allowed without gil
+ 50:13: Assignment of Python object not allowed without gil
+ 50:16: Creating temporary Python reference not allowed without gil
+ 50:19: Creating temporary Python reference not allowed without gil
+ 51:11: Assignment of Python object not allowed without gil
+ 51:11: Indexing Python object not allowed without gil
+ 52:11: Accessing Python attribute not allowed without gil
+ 52:11: Assignment of Python object not allowed without gil
+ 53:8: Constructing Python tuple not allowed without gil
+ 53:8: Python print statement not allowed without gil
+ 54:8: Deleting Python object not allowed without gil
+ 55:8: Returning Python object not allowed without gil
+ 56:8: Raising exception not allowed without gil
+ 57:14: Truth-testing Python object not allowed without gil
+ 59:17: Truth-testing Python object not allowed without gil
+ 61:8: For-loop using object bounds or target not allowed without gil
+ 63:8: Try-except statement not allowed without gil
+ 67:8: Try-finally statement not allowed without gil
+ 84:8: For-loop using object bounds or target not allowed without gil
"""
pass
_ERRORS = u"""
- 2:4: Signature not compatible with previous declaration
2:15: Previous declaration is here
-4:9: Signature not compatible with previous declaration
++4:4: Signature not compatible with previous declaration
"""
pass
_ERRORS = """
- 8:0: Base class 'FinalClass' of type 'SubType' is final
-9:5: Base class 'FinalClass' of type 'SubType' is final
++9:0: Base class 'FinalClass' of type 'SubType' is final
"""