Commit a8af26e0 authored by Stefan Behnel's avatar Stefan Behnel

Merge branch '0.24.x'

parents 9ef17d2e 642b09e7
...@@ -32,7 +32,7 @@ class DeclarationWriter(TreeVisitor): ...@@ -32,7 +32,7 @@ class DeclarationWriter(TreeVisitor):
indent_string = u" " indent_string = u" "
def __init__(self, result = None): def __init__(self, result=None):
super(DeclarationWriter, self).__init__() super(DeclarationWriter, self).__init__()
if result is None: if result is None:
result = LinesResult() result = LinesResult()
...@@ -51,7 +51,7 @@ class DeclarationWriter(TreeVisitor): ...@@ -51,7 +51,7 @@ class DeclarationWriter(TreeVisitor):
def dedent(self): def dedent(self):
self.numindents -= 1 self.numindents -= 1
def startline(self, s = u""): def startline(self, s=u""):
self.result.put(self.indent_string * self.numindents + s) self.result.put(self.indent_string * self.numindents + s)
def put(self, s): def put(self, s):
...@@ -60,7 +60,7 @@ class DeclarationWriter(TreeVisitor): ...@@ -60,7 +60,7 @@ class DeclarationWriter(TreeVisitor):
def putline(self, s): def putline(self, s):
self.result.putline(self.indent_string * self.numindents + s) self.result.putline(self.indent_string * self.numindents + s)
def endline(self, s = u""): def endline(self, s=u""):
self.result.putline(s) self.result.putline(s)
def line(self, s): def line(self, s):
......
...@@ -70,7 +70,7 @@ class EmbedSignature(CythonTransform): ...@@ -70,7 +70,7 @@ class EmbedSignature(CythonTransform):
except Exception: except Exception:
try: try:
return self._fmt_expr_node(default_val) return self._fmt_expr_node(default_val)
except AttributeError as e: except AttributeError:
return '<???>' return '<???>'
def _fmt_arg(self, arg): def _fmt_arg(self, arg):
...@@ -190,7 +190,7 @@ class EmbedSignature(CythonTransform): ...@@ -190,7 +190,7 @@ class EmbedSignature(CythonTransform):
old_doc = node.py_func.entry.doc old_doc = node.py_func.entry.doc
else: else:
old_doc = None old_doc = None
new_doc = self._embed_signature(signature, old_doc) new_doc = self._embed_signature(signature, old_doc)
doc_holder.doc = EncodedString(new_doc) doc_holder.doc = EncodedString(new_doc)
if not is_constructor and getattr(node, 'py_func', None) is not None: if not is_constructor and getattr(node, 'py_func', None) is not None:
node.py_func.entry.doc = EncodedString(new_doc) node.py_func.entry.doc = EncodedString(new_doc)
......
...@@ -40,7 +40,7 @@ try: ...@@ -40,7 +40,7 @@ try:
except ImportError: except ImportError:
from builtins import str as basestring from builtins import str as basestring
KEYWORDS_MUST_BE_BYTES = sys.version_info < (2,7) KEYWORDS_MUST_BE_BYTES = sys.version_info < (2, 7)
non_portable_builtins_map = { non_portable_builtins_map = {
...@@ -392,12 +392,12 @@ class UtilityCode(UtilityCodeBase): ...@@ -392,12 +392,12 @@ class UtilityCode(UtilityCodeBase):
requires = [r.specialize(data) for r in self.requires] requires = [r.specialize(data) for r in self.requires]
s = self._cache[key] = UtilityCode( s = self._cache[key] = UtilityCode(
self.none_or_sub(self.proto, data), self.none_or_sub(self.proto, data),
self.none_or_sub(self.impl, data), self.none_or_sub(self.impl, data),
self.none_or_sub(self.init, data), self.none_or_sub(self.init, data),
self.none_or_sub(self.cleanup, data), self.none_or_sub(self.cleanup, data),
requires, requires,
self.proto_block) self.proto_block)
self.specialize_list.append(s) self.specialize_list.append(s)
return s return s
...@@ -481,7 +481,7 @@ class UtilityCode(UtilityCodeBase): ...@@ -481,7 +481,7 @@ class UtilityCode(UtilityCodeBase):
is_specialised1, impl = self.inject_string_constants(impl, output) is_specialised1, impl = self.inject_string_constants(impl, output)
is_specialised2, impl = self.inject_unbound_methods(impl, output) is_specialised2, impl = self.inject_unbound_methods(impl, output)
writer = output['utility_code_def'] writer = output['utility_code_def']
writer.putln("/* %s */" % self.name); writer.putln("/* %s */" % self.name)
if not (is_specialised1 or is_specialised2): if not (is_specialised1 or is_specialised2):
# no module specific adaptations => can be reused # no module specific adaptations => can be reused
writer.put_or_include(impl, '%s_impl' % self.name) writer.put_or_include(impl, '%s_impl' % self.name)
...@@ -773,8 +773,8 @@ class FunctionState(object): ...@@ -773,8 +773,8 @@ class FunctionState(object):
"""Return a list of (cname, type) tuples of refcount-managed Python objects. """Return a list of (cname, type) tuples of refcount-managed Python objects.
""" """
return [(cname, type) return [(cname, type)
for cname, type, manage_ref, static in self.temps_allocated for cname, type, manage_ref, static in self.temps_allocated
if manage_ref] if manage_ref]
def all_free_managed_temps(self): def all_free_managed_temps(self):
"""Return a list of (cname, type) tuples of refcount-managed Python """Return a list of (cname, type) tuples of refcount-managed Python
...@@ -849,7 +849,7 @@ class StringConst(object): ...@@ -849,7 +849,7 @@ class StringConst(object):
def add_py_version(self, version): def add_py_version(self, version):
if not version: if not version:
self.py_versions = [2,3] self.py_versions = [2, 3]
elif version not in self.py_versions: elif version not in self.py_versions:
self.py_versions.append(version) self.py_versions.append(version)
...@@ -1280,8 +1280,8 @@ class GlobalState(object): ...@@ -1280,8 +1280,8 @@ class GlobalState(object):
self.generate_object_constant_decls() self.generate_object_constant_decls()
def generate_object_constant_decls(self): def generate_object_constant_decls(self):
consts = [ (len(c.cname), c.cname, c) consts = [(len(c.cname), c.cname, c)
for c in self.py_constants ] for c in self.py_constants]
consts.sort() consts.sort()
decls_writer = self.parts['decls'] decls_writer = self.parts['decls']
for _, cname, c in consts: for _, cname, c in consts:
...@@ -1345,12 +1345,11 @@ class GlobalState(object): ...@@ -1345,12 +1345,11 @@ class GlobalState(object):
py_strings.sort() py_strings.sort()
w = self.parts['pystring_table'] w = self.parts['pystring_table']
w.putln("") w.putln("")
w.putln("static __Pyx_StringTabEntry %s[] = {" % w.putln("static __Pyx_StringTabEntry %s[] = {" % Naming.stringtab_cname)
Naming.stringtab_cname)
for c_cname, _, py_string in py_strings: for c_cname, _, py_string in py_strings:
if not py_string.is_str or not py_string.encoding or \ if not py_string.is_str or not py_string.encoding or \
py_string.encoding in ('ASCII', 'USASCII', 'US-ASCII', py_string.encoding in ('ASCII', 'USASCII', 'US-ASCII',
'UTF8', 'UTF-8'): 'UTF8', 'UTF-8'):
encoding = '0' encoding = '0'
else: else:
encoding = '"%s"' % py_string.encoding.lower() encoding = '"%s"' % py_string.encoding.lower()
...@@ -1359,8 +1358,7 @@ class GlobalState(object): ...@@ -1359,8 +1358,7 @@ class GlobalState(object):
"static PyObject *%s;" % py_string.cname) "static PyObject *%s;" % py_string.cname)
if py_string.py3str_cstring: if py_string.py3str_cstring:
w.putln("#if PY_MAJOR_VERSION >= 3") w.putln("#if PY_MAJOR_VERSION >= 3")
w.putln( w.putln("{&%s, %s, sizeof(%s), %s, %d, %d, %d}," % (
"{&%s, %s, sizeof(%s), %s, %d, %d, %d}," % (
py_string.cname, py_string.cname,
py_string.py3str_cstring.cname, py_string.py3str_cstring.cname,
py_string.py3str_cstring.cname, py_string.py3str_cstring.cname,
...@@ -1368,8 +1366,7 @@ class GlobalState(object): ...@@ -1368,8 +1366,7 @@ class GlobalState(object):
py_string.intern py_string.intern
)) ))
w.putln("#else") w.putln("#else")
w.putln( w.putln("{&%s, %s, sizeof(%s), %s, %d, %d, %d}," % (
"{&%s, %s, sizeof(%s), %s, %d, %d, %d}," % (
py_string.cname, py_string.cname,
c_cname, c_cname,
c_cname, c_cname,
......
...@@ -30,27 +30,29 @@ from .Code import UtilityCode ...@@ -30,27 +30,29 @@ from .Code import UtilityCode
from .StringEncoding import EncodedString from .StringEncoding import EncodedString
def check_c_declarations_pxd(module_node): def check_c_declarations_pxd(module_node):
module_node.scope.check_c_classes_pxd() module_node.scope.check_c_classes_pxd()
return module_node return module_node
def check_c_declarations(module_node): def check_c_declarations(module_node):
module_node.scope.check_c_classes() module_node.scope.check_c_classes()
module_node.scope.check_c_functions() module_node.scope.check_c_functions()
return module_node return module_node
def generate_c_code_config(env, options): def generate_c_code_config(env, options):
if Options.annotate or options.annotate: if Options.annotate or options.annotate:
emit_linenums = False emit_linenums = False
else: else:
emit_linenums = options.emit_linenums emit_linenums = options.emit_linenums
rootwriter = Code.CCodeWriter()
return Code.CCodeConfig(emit_linenums=emit_linenums, return Code.CCodeConfig(
emit_linenums=emit_linenums,
emit_code_comments=env.directives['emit_code_comments'], emit_code_comments=env.directives['emit_code_comments'],
c_line_in_traceback=options.c_line_in_traceback) c_line_in_traceback=options.c_line_in_traceback)
class ModuleNode(Nodes.Node, Nodes.BlockNode): class ModuleNode(Nodes.Node, Nodes.BlockNode):
# doc string or None # doc string or None
# body StatListNode # body StatListNode
...@@ -147,7 +149,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -147,7 +149,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
h_vars = h_entries(env.var_entries) h_vars = h_entries(env.var_entries)
h_funcs = h_entries(env.cfunc_entries) h_funcs = h_entries(env.cfunc_entries)
h_extension_types = h_entries(env.c_class_entries) h_extension_types = h_entries(env.c_class_entries)
if (h_types or h_vars or h_funcs or h_extension_types): if h_types or h_vars or h_funcs or h_extension_types:
result.h_file = replace_suffix(result.c_file, ".h") result.h_file = replace_suffix(result.c_file, ".h")
h_code = Code.CCodeWriter() h_code = Code.CCodeWriter()
c_code_config = generate_c_code_config(env, options) c_code_config = generate_c_code_config(env, options)
...@@ -207,10 +209,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -207,10 +209,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
h_code.putln("%s %s;" % ( h_code.putln("%s %s;" % (
Naming.extern_c_macro, Naming.extern_c_macro,
entry.type.declaration_code( entry.type.declaration_code(
entry.cname, dll_linkage = "DL_IMPORT"))) entry.cname, dll_linkage="DL_IMPORT")))
if i_code: if i_code:
i_code.putln("cdef extern %s" % i_code.putln("cdef extern %s" % (
entry.type.declaration_code(entry.cname, pyrex = 1)) entry.type.declaration_code(entry.cname, pyrex=1)))
def api_name(self, env): def api_name(self, env):
return env.qualified_name.replace(".", "__") return env.qualified_name.replace(".", "__")
...@@ -311,8 +313,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -311,8 +313,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
var_entries = type.scope.var_entries var_entries = type.scope.var_entries
if var_entries: if var_entries:
for entry in var_entries: for entry in var_entries:
i_code.putln("cdef %s" % i_code.putln("cdef %s" % (
entry.type.declaration_code(entry.cname, pyrex = 1)) entry.type.declaration_code(entry.cname, pyrex=1)))
else: else:
i_code.putln("pass") i_code.putln("pass")
i_code.dedent() i_code.dedent()
...@@ -439,12 +441,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -439,12 +441,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
tb.start('LineNumberMapping') tb.start('LineNumberMapping')
for cython_lineno, c_linenos in sorted(d.items()): for cython_lineno, c_linenos in sorted(d.items()):
attrs = { attrs = {
'c_linenos': ' '.join(map(str, c_linenos)), 'c_linenos': ' '.join(map(str, c_linenos)),
'cython_lineno': str(cython_lineno), 'cython_lineno': str(cython_lineno),
} }
tb.start('LineNumber', attrs) tb.start('LineNumber', attrs)
tb.end('LineNumber') tb.end('LineNumber')
tb.end('LineNumberMapping') tb.end('LineNumberMapping')
tb.serialize() tb.serialize()
...@@ -602,8 +604,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -602,8 +604,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
for filename in env.python_include_files: for filename in env.python_include_files:
code.putln('#include "%s"' % filename) code.putln('#include "%s"' % filename)
code.putln("#ifndef Py_PYTHON_H") code.putln("#ifndef Py_PYTHON_H")
code.putln(" #error Python headers needed to compile C extensions, please install development version of Python.") code.putln(" #error Python headers needed to compile C extensions, "
code.putln("#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)") "please install development version of Python.")
code.putln("#elif PY_VERSION_HEX < 0x02060000 || "
"(0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)")
code.putln(" #error Cython requires Python 2.6+ or Python 3.2+.") code.putln(" #error Cython requires Python 2.6+ or Python 3.2+.")
code.putln("#else") code.putln("#else")
code.globalstate["end"].putln("#endif /* Py_PYTHON_H */") code.globalstate["end"].putln("#endif /* Py_PYTHON_H */")
...@@ -627,8 +631,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -627,8 +631,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
{ \\ { \\
%s = %s[f_index]; %s = lineno; %sgoto Ln_error; \\ %s = %s[f_index]; %s = lineno; %sgoto Ln_error; \\
} }
""" % (Naming.filename_cname, Naming.filetable_cname, Naming.lineno_cname, """ % (Naming.filename_cname, Naming.filetable_cname, Naming.lineno_cname, cinfo))
cinfo))
code.put(""" code.put("""
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
...@@ -734,7 +737,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -734,7 +737,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
full_module_path = path.join(*self.full_module_name.split('.')) full_module_path = path.join(*self.full_module_name.split('.'))
module_abspath = path.splitext(path.abspath( module_abspath = path.splitext(path.abspath(
self.compilation_source.source_desc.get_filenametable_entry() ))[0] self.compilation_source.source_desc.get_filenametable_entry()))[0]
root_path = module_abspath[:-len(full_module_path)] root_path = module_abspath[:-len(full_module_path)]
workdir = path.abspath(os.getcwd()) + os.sep workdir = path.abspath(os.getcwd()) + os.sep
if root_path.startswith(workdir): if root_path.startswith(workdir):
...@@ -831,7 +834,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -831,7 +834,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_struct_union_predeclaration(self, entry, code): def generate_struct_union_predeclaration(self, entry, code):
type = entry.type type = entry.type
if type.is_cpp_class and type.templates: if type.is_cpp_class and type.templates:
code.putln("template <typename %s>" % ", typename ".join([T.empty_declaration_code() for T in type.templates])) code.putln("template <typename %s>" % ", typename ".join(
[T.empty_declaration_code() for T in type.templates]))
code.putln(self.sue_predeclaration(type, type.kind, type.cname)) code.putln(self.sue_predeclaration(type, type.kind, type.cname))
def sue_header_footer(self, type, kind, name): def sue_header_footer(self, type, kind, name):
...@@ -860,13 +864,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -860,13 +864,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln(header) code.putln(header)
var_entries = scope.var_entries var_entries = scope.var_entries
if not var_entries: if not var_entries:
error(entry.pos, error(entry.pos, "Empty struct or union definition not allowed outside a 'cdef extern from' block")
"Empty struct or union definition not allowed outside a"
" 'cdef extern from' block")
for attr in var_entries: for attr in var_entries:
code.putln( code.putln(
"%s;" % "%s;" % attr.type.declaration_code(attr.cname))
attr.type.declaration_code(attr.cname))
code.putln(footer) code.putln(footer)
if packed: if packed:
code.putln("#if defined(__SUNPRO_C)") code.putln("#if defined(__SUNPRO_C)")
...@@ -881,7 +882,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -881,7 +882,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
scope = type.scope scope = type.scope
if scope: if scope:
if type.templates: if type.templates:
code.putln("template <class %s>" % ", class ".join([T.empty_declaration_code() for T in type.templates])) code.putln("template <class %s>" % ", class ".join(
[T.empty_declaration_code() for T in type.templates]))
# Just let everything be public. # Just let everything be public.
code.put("struct %s" % type.cname) code.put("struct %s" % type.cname)
if type.base_classes: if type.base_classes:
...@@ -899,9 +901,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -899,9 +901,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
has_virtual_methods = True has_virtual_methods = True
if attr.cname[0] == '~': if attr.cname[0] == '~':
has_destructor = True has_destructor = True
code.putln( code.putln("%s;" % attr.type.declaration_code(attr.cname))
"%s;" %
attr.type.declaration_code(attr.cname))
if has_virtual_methods and not has_destructor: if has_virtual_methods and not has_destructor:
code.put("virtual ~%s() { }" % type.cname) code.put("virtual ~%s() { }" % type.cname)
code.putln("};") code.putln("};")
...@@ -910,14 +910,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -910,14 +910,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.mark_pos(entry.pos) code.mark_pos(entry.pos)
type = entry.type type = entry.type
name = entry.cname or entry.name or "" name = entry.cname or entry.name or ""
header, footer = \ header, footer = self.sue_header_footer(type, "enum", name)
self.sue_header_footer(type, "enum", name)
code.putln(header) code.putln(header)
enum_values = entry.enum_values enum_values = entry.enum_values
if not enum_values: if not enum_values:
error(entry.pos, error(entry.pos, "Empty enum definition not allowed outside a 'cdef extern from' block")
"Empty enum definition not allowed outside a"
" 'cdef extern from' block")
else: else:
last_entry = enum_values[-1] last_entry = enum_values[-1]
# this does not really generate code, just builds the result value # this does not really generate code, just builds the result value
...@@ -971,19 +968,15 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -971,19 +968,15 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if type.vtabstruct_cname: if type.vtabstruct_cname:
code.putln("") code.putln("")
code.putln( code.putln("struct %s {" % type.vtabstruct_cname)
"struct %s {" %
type.vtabstruct_cname)
if type.base_type and type.base_type.vtabstruct_cname: if type.base_type and type.base_type.vtabstruct_cname:
code.putln("struct %s %s;" % ( code.putln("struct %s %s;" % (
type.base_type.vtabstruct_cname, type.base_type.vtabstruct_cname,
Naming.obj_base_cname)) Naming.obj_base_cname))
for method_entry in scope.cfunc_entries: for method_entry in scope.cfunc_entries:
if not method_entry.is_inherited: if not method_entry.is_inherited:
code.putln( code.putln("%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.cname))
"%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.cname)) code.putln("};")
code.putln(
"};")
def generate_exttype_vtabptr_declaration(self, entry, code): def generate_exttype_vtabptr_declaration(self, entry, code):
if not entry.used: if not entry.used:
...@@ -1050,8 +1043,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1050,8 +1043,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
else: else:
attr_type = attr.type attr_type = attr.type
code.putln( code.putln(
"%s;" % "%s;" % attr_type.declaration_code(attr.cname))
attr_type.declaration_code(attr.cname))
code.putln(footer) code.putln(footer)
if type.objtypedef_cname is not None: if type.objtypedef_cname is not None:
# Only for exposing public typedef name. # Only for exposing public typedef name.
...@@ -1060,21 +1052,19 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1060,21 +1052,19 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_c_class_declarations(self, env, code, definition): def generate_c_class_declarations(self, env, code, definition):
for entry in env.c_class_entries: for entry in env.c_class_entries:
if definition or entry.defined_in_pxd: if definition or entry.defined_in_pxd:
code.putln("static PyTypeObject *%s = 0;" % code.putln("static PyTypeObject *%s = 0;" % (
entry.type.typeptr_cname) entry.type.typeptr_cname))
def generate_cvariable_declarations(self, env, code, definition): def generate_cvariable_declarations(self, env, code, definition):
if env.is_cython_builtin: if env.is_cython_builtin:
return return
for entry in env.var_entries: for entry in env.var_entries:
if (entry.in_cinclude or entry.in_closure or if (entry.in_cinclude or entry.in_closure or
(entry.visibility == 'private' and (entry.visibility == 'private' and not (entry.defined_in_pxd or entry.used))):
not (entry.defined_in_pxd or entry.used))):
continue continue
storage_class = None storage_class = None
dll_linkage = None dll_linkage = None
cname = None
init = None init = None
if entry.visibility == 'extern': if entry.visibility == 'extern':
...@@ -1090,7 +1080,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1090,7 +1080,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
storage_class = "static" storage_class = "static"
dll_linkage = None dll_linkage = None
if entry.init is not None: if entry.init is not None:
init = entry.type.literal_code(entry.init) init = entry.type.literal_code(entry.init)
type = entry.type type = entry.type
cname = entry.cname cname = entry.cname
...@@ -1104,7 +1094,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1104,7 +1094,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if storage_class: if storage_class:
code.put("%s " % storage_class) code.put("%s " % storage_class)
code.put(type.declaration_code( code.put(type.declaration_code(
cname, dll_linkage = dll_linkage)) cname, dll_linkage=dll_linkage))
if init is not None: if init is not None:
code.put_safe(" = %s" % init) code.put_safe(" = %s" % init)
code.putln(";") code.putln(";")
...@@ -1118,11 +1108,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1118,11 +1108,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_variable_definitions(self, env, code): def generate_variable_definitions(self, env, code):
for entry in env.var_entries: for entry in env.var_entries:
if (not entry.in_cinclude and if not entry.in_cinclude and entry.visibility == "public":
entry.visibility == "public"):
code.put(entry.type.declaration_code(entry.cname)) code.put(entry.type.declaration_code(entry.cname))
if entry.init is not None: if entry.init is not None:
init = entry.type.literal_code(entry.init) init = entry.type.literal_code(entry.init)
code.put_safe(" = %s" % init) code.put_safe(" = %s" % init)
code.putln(";") code.putln(";")
...@@ -1147,13 +1136,15 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1147,13 +1136,15 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if scope.defines_any(["__setitem__", "__delitem__"]): if scope.defines_any(["__setitem__", "__delitem__"]):
self.generate_ass_subscript_function(scope, code) self.generate_ass_subscript_function(scope, code)
if scope.defines_any(["__getslice__", "__setslice__", "__delslice__"]): if scope.defines_any(["__getslice__", "__setslice__", "__delslice__"]):
warning(self.pos, "__getslice__, __setslice__, and __delslice__ are not supported by Python 3, use __getitem__, __setitem__, and __delitem__ instead", 1) warning(self.pos,
"__getslice__, __setslice__, and __delslice__ are not supported by Python 3, "
"use __getitem__, __setitem__, and __delitem__ instead", 1)
code.putln("#if PY_MAJOR_VERSION >= 3") code.putln("#if PY_MAJOR_VERSION >= 3")
code.putln("#error __getslice__, __setslice__, and __delslice__ not supported in Python 3.") code.putln("#error __getslice__, __setslice__, and __delslice__ not supported in Python 3.")
code.putln("#endif") code.putln("#endif")
if scope.defines_any(["__setslice__", "__delslice__"]): if scope.defines_any(["__setslice__", "__delslice__"]):
self.generate_ass_slice_function(scope, code) self.generate_ass_slice_function(scope, code)
if scope.defines_any(["__getattr__","__getattribute__"]): if scope.defines_any(["__getattr__", "__getattribute__"]):
self.generate_getattro_function(scope, code) self.generate_getattro_function(scope, code)
if scope.defines_any(["__setattr__", "__delattr__"]): if scope.defines_any(["__setattr__", "__delattr__"]):
self.generate_setattro_function(scope, code) self.generate_setattro_function(scope, code)
...@@ -1221,8 +1212,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1221,8 +1212,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("static int %s = 0;" % freecount_name) code.putln("static int %s = 0;" % freecount_name)
code.putln("") code.putln("")
code.putln( code.putln(
"static PyObject *%s(PyTypeObject *t, %sPyObject *a, %sPyObject *k) {" "static PyObject *%s(PyTypeObject *t, %sPyObject *a, %sPyObject *k) {" % (
% (slot_func, unused_marker, unused_marker)) slot_func, unused_marker, unused_marker))
need_self_cast = (type.vtabslot_cname or need_self_cast = (type.vtabslot_cname or
(py_buffers or memoryview_slices or py_attrs) or (py_buffers or memoryview_slices or py_attrs) or
...@@ -1244,8 +1235,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1244,8 +1235,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
else: else:
type_safety_check = ' & ((t->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)) == 0)' type_safety_check = ' & ((t->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)) == 0)'
obj_struct = type.declaration_code("", deref=True) obj_struct = type.declaration_code("", deref=True)
code.putln("if (CYTHON_COMPILING_IN_CPYTHON && likely((%s > 0) & (t->tp_basicsize == sizeof(%s))%s)) {" % ( code.putln(
freecount_name, obj_struct, type_safety_check)) "if (CYTHON_COMPILING_IN_CPYTHON && likely((%s > 0) & (t->tp_basicsize == sizeof(%s))%s)) {" % (
freecount_name, obj_struct, type_safety_check))
code.putln("o = (PyObject*)%s[--%s];" % ( code.putln("o = (PyObject*)%s[--%s];" % (
freelist_name, freecount_name)) freelist_name, freecount_name))
code.putln("memset(o, 0, sizeof(%s));" % obj_struct) code.putln("memset(o, 0, sizeof(%s));" % obj_struct)
...@@ -1302,8 +1294,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1302,8 +1294,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
else: else:
cinit_args = "o, a, k" cinit_args = "o, a, k"
code.putln( code.putln(
"if (unlikely(%s(%s) < 0)) {" % "if (unlikely(%s(%s) < 0)) {" % (
(new_func_entry.func_cname, cinit_args)) new_func_entry.func_cname, cinit_args))
code.put_decref_clear("o", py_object_type, nanny=False) code.put_decref_clear("o", py_object_type, nanny=False)
code.putln( code.putln(
"}") "}")
...@@ -1417,9 +1409,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1417,9 +1409,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
' & ((Py_TYPE(o)->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)) == 0)') ' & ((Py_TYPE(o)->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)) == 0)')
type = scope.parent_type type = scope.parent_type
code.putln("if (CYTHON_COMPILING_IN_CPYTHON && ((%s < %d) & (Py_TYPE(o)->tp_basicsize == sizeof(%s))%s)) {" % ( code.putln(
freecount_name, freelist_size, type.declaration_code("", deref=True), "if (CYTHON_COMPILING_IN_CPYTHON && ((%s < %d) & (Py_TYPE(o)->tp_basicsize == sizeof(%s))%s)) {" % (
type_safety_check)) freecount_name,
freelist_size,
type.declaration_code("", deref=True),
type_safety_check))
code.putln("%s[%s++] = %s;" % ( code.putln("%s[%s++] = %s;" % (
freelist_name, freecount_name, type.cast_code("o"))) freelist_name, freecount_name, type.cast_code("o")))
code.putln("} else {") code.putln("} else {")
...@@ -1448,11 +1443,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1448,11 +1443,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
slot_func = scope.mangle_internal("tp_traverse") slot_func = scope.mangle_internal("tp_traverse")
base_type = scope.parent_type.base_type base_type = scope.parent_type.base_type
if tp_slot.slot_code(scope) != slot_func: if tp_slot.slot_code(scope) != slot_func:
return # never used return # never used
code.putln("") code.putln("")
code.putln( code.putln(
"static int %s(PyObject *o, visitproc v, void *a) {" "static int %s(PyObject *o, visitproc v, void *a) {" % slot_func)
% slot_func)
have_entries, (py_attrs, py_buffers, memoryview_slices) = ( have_entries, (py_attrs, py_buffers, memoryview_slices) = (
scope.get_refcounted_entries(include_gc_simple=False)) scope.get_refcounted_entries(include_gc_simple=False))
...@@ -1478,23 +1472,20 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1478,23 +1472,20 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# the module cleanup, which may already have cleared it. # the module cleanup, which may already have cleared it.
# In that case, fall back to traversing the type hierarchy. # In that case, fall back to traversing the type hierarchy.
base_cname = base_type.typeptr_cname base_cname = base_type.typeptr_cname
code.putln("e = ((likely(%s)) ? ((%s->tp_traverse) ? %s->tp_traverse(o, v, a) : 0) : __Pyx_call_next_tp_traverse(o, v, a, %s)); if (e) return e;" % ( code.putln(
base_cname, base_cname, base_cname, slot_func)) "e = ((likely(%s)) ? ((%s->tp_traverse) ? %s->tp_traverse(o, v, a) : 0) : "
"__Pyx_call_next_tp_traverse(o, v, a, %s)); if (e) return e;" % (
base_cname, base_cname, base_cname, slot_func))
code.globalstate.use_utility_code( code.globalstate.use_utility_code(
UtilityCode.load_cached("CallNextTpTraverse", "ExtensionTypes.c")) UtilityCode.load_cached("CallNextTpTraverse", "ExtensionTypes.c"))
for entry in py_attrs: for entry in py_attrs:
var_code = "p->%s" % entry.cname var_code = "p->%s" % entry.cname
code.putln( code.putln("if (%s) {" % var_code)
"if (%s) {"
% var_code)
if entry.type.is_extension_type: if entry.type.is_extension_type:
var_code = "((PyObject*)%s)" % var_code var_code = "((PyObject*)%s)" % var_code
code.putln( code.putln("e = (*v)(%s, a); if (e) return e;" % var_code)
"e = (*v)(%s, a); if (e) return e;" code.putln("}")
% var_code)
code.putln(
"}")
# Traverse buffer exporting objects. # Traverse buffer exporting objects.
# Note: not traversing memoryview attributes of memoryview slices! # Note: not traversing memoryview attributes of memoryview slices!
...@@ -1503,13 +1494,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1503,13 +1494,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
for entry in py_buffers: for entry in py_buffers:
cname = entry.cname + ".obj" cname = entry.cname + ".obj"
code.putln("if (p->%s) {" % cname) code.putln("if (p->%s) {" % cname)
code.putln( "e = (*v)(p->%s, a); if (e) return e;" % cname) code.putln("e = (*v)(p->%s, a); if (e) return e;" % cname)
code.putln("}") code.putln("}")
code.putln( code.putln("return 0;")
"return 0;") code.putln("}")
code.putln(
"}")
def generate_clear_function(self, scope, code, cclass_entry): def generate_clear_function(self, scope, code, cclass_entry):
tp_slot = TypeSlots.GCDependentSlot("tp_clear") tp_slot = TypeSlots.GCDependentSlot("tp_clear")
...@@ -1550,8 +1539,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1550,8 +1539,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# the module cleanup, which may already have cleared it. # the module cleanup, which may already have cleared it.
# In that case, fall back to traversing the type hierarchy. # In that case, fall back to traversing the type hierarchy.
base_cname = base_type.typeptr_cname base_cname = base_type.typeptr_cname
code.putln("if (likely(%s)) { if (%s->tp_clear) %s->tp_clear(o); } else __Pyx_call_next_tp_clear(o, %s);" % ( code.putln(
base_cname, base_cname, base_cname, slot_func)) "if (likely(%s)) { if (%s->tp_clear) %s->tp_clear(o); } else __Pyx_call_next_tp_clear(o, %s);" % (
base_cname, base_cname, base_cname, slot_func))
code.globalstate.use_utility_code( code.globalstate.use_utility_code(
UtilityCode.load_cached("CallNextTpClear", "ExtensionTypes.c")) UtilityCode.load_cached("CallNextTpClear", "ExtensionTypes.c"))
...@@ -1575,28 +1565,26 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1575,28 +1565,26 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if cclass_entry.cname == '__pyx_memoryviewslice': if cclass_entry.cname == '__pyx_memoryviewslice':
code.putln("__PYX_XDEC_MEMVIEW(&p->from_slice, 1);") code.putln("__PYX_XDEC_MEMVIEW(&p->from_slice, 1);")
code.putln( code.putln("return 0;")
"return 0;") code.putln("}")
code.putln(
"}")
def generate_getitem_int_function(self, scope, code): def generate_getitem_int_function(self, scope, code):
# This function is put into the sq_item slot when # This function is put into the sq_item slot when
# a __getitem__ method is present. It converts its # a __getitem__ method is present. It converts its
# argument to a Python integer and calls mp_subscript. # argument to a Python integer and calls mp_subscript.
code.putln( code.putln(
"static PyObject *%s(PyObject *o, Py_ssize_t i) {" % "static PyObject *%s(PyObject *o, Py_ssize_t i) {" % (
scope.mangle_internal("sq_item")) scope.mangle_internal("sq_item")))
code.putln( code.putln(
"PyObject *r;") "PyObject *r;")
code.putln( code.putln(
"PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;") "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;")
code.putln( code.putln(
"r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);") "r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);")
code.putln( code.putln(
"Py_DECREF(x);") "Py_DECREF(x);")
code.putln( code.putln(
"return r;") "return r;")
code.putln( code.putln(
"}") "}")
...@@ -1609,42 +1597,40 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1609,42 +1597,40 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
del_entry = scope.lookup_here("__delitem__") del_entry = scope.lookup_here("__delitem__")
code.putln("") code.putln("")
code.putln( code.putln(
"static int %s(PyObject *o, PyObject *i, PyObject *v) {" % "static int %s(PyObject *o, PyObject *i, PyObject *v) {" % (
scope.mangle_internal("mp_ass_subscript")) scope.mangle_internal("mp_ass_subscript")))
code.putln( code.putln(
"if (v) {") "if (v) {")
if set_entry: if set_entry:
code.putln( code.putln("return %s(o, i, v);" % set_entry.func_cname)
"return %s(o, i, v);" %
set_entry.func_cname)
else: else:
self.generate_guarded_basetype_call( self.generate_guarded_basetype_call(
base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code) base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
code.putln( code.putln(
"PyErr_Format(PyExc_NotImplementedError,") "PyErr_Format(PyExc_NotImplementedError,")
code.putln( code.putln(
' "Subscript assignment not supported by %.200s", Py_TYPE(o)->tp_name);') ' "Subscript assignment not supported by %.200s", Py_TYPE(o)->tp_name);')
code.putln( code.putln(
"return -1;") "return -1;")
code.putln( code.putln(
"}") "}")
code.putln( code.putln(
"else {") "else {")
if del_entry: if del_entry:
code.putln( code.putln(
"return %s(o, i);" % "return %s(o, i);" % (
del_entry.func_cname) del_entry.func_cname))
else: else:
self.generate_guarded_basetype_call( self.generate_guarded_basetype_call(
base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code) base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
code.putln( code.putln(
"PyErr_Format(PyExc_NotImplementedError,") "PyErr_Format(PyExc_NotImplementedError,")
code.putln( code.putln(
' "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);') ' "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);')
code.putln( code.putln(
"return -1;") "return -1;")
code.putln( code.putln(
"}") "}")
code.putln( code.putln(
"}") "}")
...@@ -1676,42 +1662,42 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1676,42 +1662,42 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
del_entry = scope.lookup_here("__delslice__") del_entry = scope.lookup_here("__delslice__")
code.putln("") code.putln("")
code.putln( code.putln(
"static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" % "static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" % (
scope.mangle_internal("sq_ass_slice")) scope.mangle_internal("sq_ass_slice")))
code.putln( code.putln(
"if (v) {") "if (v) {")
if set_entry: if set_entry:
code.putln( code.putln(
"return %s(o, i, j, v);" % "return %s(o, i, j, v);" % (
set_entry.func_cname) set_entry.func_cname))
else: else:
self.generate_guarded_basetype_call( self.generate_guarded_basetype_call(
base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code) base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
code.putln( code.putln(
"PyErr_Format(PyExc_NotImplementedError,") "PyErr_Format(PyExc_NotImplementedError,")
code.putln( code.putln(
' "2-element slice assignment not supported by %.200s", Py_TYPE(o)->tp_name);') ' "2-element slice assignment not supported by %.200s", Py_TYPE(o)->tp_name);')
code.putln( code.putln(
"return -1;") "return -1;")
code.putln( code.putln(
"}") "}")
code.putln( code.putln(
"else {") "else {")
if del_entry: if del_entry:
code.putln( code.putln(
"return %s(o, i, j);" % "return %s(o, i, j);" % (
del_entry.func_cname) del_entry.func_cname))
else: else:
self.generate_guarded_basetype_call( self.generate_guarded_basetype_call(
base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code) base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
code.putln( code.putln(
"PyErr_Format(PyExc_NotImplementedError,") "PyErr_Format(PyExc_NotImplementedError,")
code.putln( code.putln(
' "2-element slice deletion not supported by %.200s", Py_TYPE(o)->tp_name);') ' "2-element slice deletion not supported by %.200s", Py_TYPE(o)->tp_name);')
code.putln( code.putln(
"return -1;") "return -1;")
code.putln( code.putln(
"}") "}")
code.putln( code.putln(
"}") "}")
...@@ -1722,26 +1708,26 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1722,26 +1708,26 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# If that raises an AttributeError, call the __getattr__ if defined. # If that raises an AttributeError, call the __getattr__ if defined.
# #
# In both cases, defined can be in this class, or any base class. # In both cases, defined can be in this class, or any base class.
def lookup_here_or_base(n,type=None): def lookup_here_or_base(n, type=None):
# Recursive lookup # Recursive lookup
if type is None: if type is None:
type = scope.parent_type type = scope.parent_type
r = type.scope.lookup_here(n) r = type.scope.lookup_here(n)
if r is None and \ if r is None and \
type.base_type is not None: type.base_type is not None:
return lookup_here_or_base(n,type.base_type) return lookup_here_or_base(n, type.base_type)
else: else:
return r return r
getattr_entry = lookup_here_or_base("__getattr__") getattr_entry = lookup_here_or_base("__getattr__")
getattribute_entry = lookup_here_or_base("__getattribute__") getattribute_entry = lookup_here_or_base("__getattribute__")
code.putln("") code.putln("")
code.putln( code.putln(
"static PyObject *%s(PyObject *o, PyObject *n) {" "static PyObject *%s(PyObject *o, PyObject *n) {" % (
% scope.mangle_internal("tp_getattro")) scope.mangle_internal("tp_getattro")))
if getattribute_entry is not None: if getattribute_entry is not None:
code.putln( code.putln(
"PyObject *v = %s(o, n);" % "PyObject *v = %s(o, n);" % (
getattribute_entry.func_cname) getattribute_entry.func_cname))
else: else:
code.putln( code.putln(
"PyObject *v = PyObject_GenericGetAttr(o, n);") "PyObject *v = PyObject_GenericGetAttr(o, n);")
...@@ -1751,8 +1737,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1751,8 +1737,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln( code.putln(
"PyErr_Clear();") "PyErr_Clear();")
code.putln( code.putln(
"v = %s(o, n);" % "v = %s(o, n);" % (
getattr_entry.func_cname) getattr_entry.func_cname))
code.putln( code.putln(
"}") "}")
code.putln( code.putln(
...@@ -1769,34 +1755,34 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1769,34 +1755,34 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
del_entry = scope.lookup_here("__delattr__") del_entry = scope.lookup_here("__delattr__")
code.putln("") code.putln("")
code.putln( code.putln(
"static int %s(PyObject *o, PyObject *n, PyObject *v) {" % "static int %s(PyObject *o, PyObject *n, PyObject *v) {" % (
scope.mangle_internal("tp_setattro")) scope.mangle_internal("tp_setattro")))
code.putln( code.putln(
"if (v) {") "if (v) {")
if set_entry: if set_entry:
code.putln( code.putln(
"return %s(o, n, v);" % "return %s(o, n, v);" % (
set_entry.func_cname) set_entry.func_cname))
else: else:
self.generate_guarded_basetype_call( self.generate_guarded_basetype_call(
base_type, None, "tp_setattro", "o, n, v", code) base_type, None, "tp_setattro", "o, n, v", code)
code.putln( code.putln(
"return PyObject_GenericSetAttr(o, n, v);") "return PyObject_GenericSetAttr(o, n, v);")
code.putln( code.putln(
"}") "}")
code.putln( code.putln(
"else {") "else {")
if del_entry: if del_entry:
code.putln( code.putln(
"return %s(o, n);" % "return %s(o, n);" % (
del_entry.func_cname) del_entry.func_cname))
else: else:
self.generate_guarded_basetype_call( self.generate_guarded_basetype_call(
base_type, None, "tp_setattro", "o, n, v", code) base_type, None, "tp_setattro", "o, n, v", code)
code.putln( code.putln(
"return PyObject_GenericSetAttr(o, n, 0);") "return PyObject_GenericSetAttr(o, n, 0);")
code.putln( code.putln(
"}") "}")
code.putln( code.putln(
"}") "}")
...@@ -1808,8 +1794,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1808,8 +1794,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
user_get_entry = scope.lookup_here("__get__") user_get_entry = scope.lookup_here("__get__")
code.putln("") code.putln("")
code.putln( code.putln(
"static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" % "static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" % (
scope.mangle_internal("tp_descr_get")) scope.mangle_internal("tp_descr_get")))
code.putln( code.putln(
"PyObject *r = 0;") "PyObject *r = 0;")
code.putln( code.putln(
...@@ -1819,8 +1805,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1819,8 +1805,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
#code.put_incref("i", py_object_type) #code.put_incref("i", py_object_type)
#code.put_incref("c", py_object_type) #code.put_incref("c", py_object_type)
code.putln( code.putln(
"r = %s(o, i, c);" % "r = %s(o, i, c);" % (
user_get_entry.func_cname) user_get_entry.func_cname))
#code.put_decref("i", py_object_type) #code.put_decref("i", py_object_type)
#code.put_decref("c", py_object_type) #code.put_decref("c", py_object_type)
code.putln( code.putln(
...@@ -1837,38 +1823,38 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1837,38 +1823,38 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
user_del_entry = scope.lookup_here("__delete__") user_del_entry = scope.lookup_here("__delete__")
code.putln("") code.putln("")
code.putln( code.putln(
"static int %s(PyObject *o, PyObject *i, PyObject *v) {" % "static int %s(PyObject *o, PyObject *i, PyObject *v) {" % (
scope.mangle_internal("tp_descr_set")) scope.mangle_internal("tp_descr_set")))
code.putln( code.putln(
"if (v) {") "if (v) {")
if user_set_entry: if user_set_entry:
code.putln( code.putln(
"return %s(o, i, v);" % "return %s(o, i, v);" % (
user_set_entry.func_cname) user_set_entry.func_cname))
else: else:
self.generate_guarded_basetype_call( self.generate_guarded_basetype_call(
base_type, None, "tp_descr_set", "o, i, v", code) base_type, None, "tp_descr_set", "o, i, v", code)
code.putln( code.putln(
'PyErr_SetString(PyExc_NotImplementedError, "__set__");') 'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
code.putln( code.putln(
"return -1;") "return -1;")
code.putln( code.putln(
"}") "}")
code.putln( code.putln(
"else {") "else {")
if user_del_entry: if user_del_entry:
code.putln( code.putln(
"return %s(o, i);" % "return %s(o, i);" % (
user_del_entry.func_cname) user_del_entry.func_cname))
else: else:
self.generate_guarded_basetype_call( self.generate_guarded_basetype_call(
base_type, None, "tp_descr_set", "o, i, v", code) base_type, None, "tp_descr_set", "o, i, v", code)
code.putln( code.putln(
'PyErr_SetString(PyExc_NotImplementedError, "__delete__");') 'PyErr_SetString(PyExc_NotImplementedError, "__delete__");')
code.putln( code.putln(
"return -1;") "return -1;")
code.putln( code.putln(
"}") "}")
code.putln( code.putln(
"}") "}")
...@@ -1887,11 +1873,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1887,11 +1873,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
get_entry = property_scope.lookup_here("__get__") get_entry = property_scope.lookup_here("__get__")
code.putln("") code.putln("")
code.putln( code.putln(
"static PyObject *%s(PyObject *o, CYTHON_UNUSED void *x) {" % "static PyObject *%s(PyObject *o, CYTHON_UNUSED void *x) {" % (
property_entry.getter_cname) property_entry.getter_cname))
code.putln( code.putln(
"return %s(o);" % "return %s(o);" % (
get_entry.func_cname) get_entry.func_cname))
code.putln( code.putln(
"}") "}")
...@@ -1903,34 +1889,34 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1903,34 +1889,34 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
del_entry = property_scope.lookup_here("__del__") del_entry = property_scope.lookup_here("__del__")
code.putln("") code.putln("")
code.putln( code.putln(
"static int %s(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {" % "static int %s(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {" % (
property_entry.setter_cname) property_entry.setter_cname))
code.putln( code.putln(
"if (v) {") "if (v) {")
if set_entry: if set_entry:
code.putln( code.putln(
"return %s(o, v);" % "return %s(o, v);" % (
set_entry.func_cname) set_entry.func_cname))
else: else:
code.putln( code.putln(
'PyErr_SetString(PyExc_NotImplementedError, "__set__");') 'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
code.putln( code.putln(
"return -1;") "return -1;")
code.putln( code.putln(
"}") "}")
code.putln( code.putln(
"else {") "else {")
if del_entry: if del_entry:
code.putln( code.putln(
"return %s(o);" % "return %s(o);" % (
del_entry.func_cname) del_entry.func_cname))
else: else:
code.putln( code.putln(
'PyErr_SetString(PyExc_NotImplementedError, "__del__");') 'PyErr_SetString(PyExc_NotImplementedError, "__del__");')
code.putln( code.putln(
"return -1;") "return -1;")
code.putln( code.putln(
"}") "}")
code.putln( code.putln(
"}") "}")
...@@ -1956,8 +1942,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1956,8 +1942,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
else: else:
objstruct = "struct %s" % type.objstruct_cname objstruct = "struct %s" % type.objstruct_cname
code.putln( code.putln(
"sizeof(%s), /*tp_basicsize*/" % "sizeof(%s), /*tp_basicsize*/" % objstruct)
objstruct)
code.putln( code.putln(
"0, /*tp_itemsize*/") "0, /*tp_itemsize*/")
for slot in TypeSlots.slot_table: for slot in TypeSlots.slot_table:
...@@ -1970,13 +1955,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1970,13 +1955,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
return return
code.putln("") code.putln("")
code.putln( code.putln(
"static PyMethodDef %s[] = {" % "static PyMethodDef %s[] = {" % (
env.method_table_cname) env.method_table_cname))
for entry in env.pyfunc_entries: for entry in env.pyfunc_entries:
if not entry.fused_cfunction: if not entry.fused_cfunction:
code.put_pymethoddef(entry, ",") code.put_pymethoddef(entry, ",")
code.putln( code.putln(
"{0, 0, 0, 0}") "{0, 0, 0, 0}")
code.putln( code.putln(
"};") "};")
...@@ -2142,7 +2127,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -2142,7 +2127,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("/*--- Initialize various global constants etc. ---*/") code.putln("/*--- Initialize various global constants etc. ---*/")
code.put_error_if_neg(self.pos, "__Pyx_InitGlobals()") code.put_error_if_neg(self.pos, "__Pyx_InitGlobals()")
code.putln("#if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)") code.putln("#if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || "
"__PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)")
code.put_error_if_neg(self.pos, "__Pyx_init_sys_getdefaultencoding_params()") code.put_error_if_neg(self.pos, "__Pyx_init_sys_getdefaultencoding_params()")
code.putln("#endif") code.putln("#endif")
...@@ -2501,8 +2487,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -2501,8 +2487,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
entries = [] entries = []
for entry in env.var_entries: for entry in env.var_entries:
if (entry.api if (entry.api
or entry.defined_in_pxd or entry.defined_in_pxd
or (Options.cimport_from_pyx and not entry.visibility == 'extern')): or (Options.cimport_from_pyx and not entry.visibility == 'extern')):
entries.append(entry) entries.append(entry)
if entries: if entries:
env.use_utility_code(UtilityCode.load_cached("VoidPtrExport", "ImportExport.c")) env.use_utility_code(UtilityCode.load_cached("VoidPtrExport", "ImportExport.c"))
...@@ -2518,8 +2504,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -2518,8 +2504,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
entries = [] entries = []
for entry in env.cfunc_entries: for entry in env.cfunc_entries:
if (entry.api if (entry.api
or entry.defined_in_pxd or entry.defined_in_pxd
or (Options.cimport_from_pyx and not entry.visibility == 'extern')): or (Options.cimport_from_pyx and not entry.visibility == 'extern')):
entries.append(entry) entries.append(entry)
if entries: if entries:
env.use_utility_code( env.use_utility_code(
...@@ -2625,7 +2611,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -2625,7 +2611,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_base_type_import_code(self, env, entry, code): def generate_base_type_import_code(self, env, entry, code):
base_type = entry.type.base_type base_type = entry.type.base_type
if (base_type and base_type.module_name != env.qualified_name and not if (base_type and base_type.module_name != env.qualified_name and not
base_type.is_builtin_type and not entry.utility_code_definition): base_type.is_builtin_type and not entry.utility_code_definition):
self.generate_type_import_code(env, base_type, self.pos, code) self.generate_type_import_code(env, base_type, self.pos, code)
def generate_type_import_code(self, env, type, pos, code): def generate_type_import_code(self, env, type, pos, code):
...@@ -2717,8 +2703,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -2717,8 +2703,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# unless we let PyType_Ready create the slot wrappers we have # unless we let PyType_Ready create the slot wrappers we have
# a significant performance hit. (See trac #561.) # a significant performance hit. (See trac #561.)
for func in entry.type.scope.pyfunc_entries: for func in entry.type.scope.pyfunc_entries:
is_buffer = func.name in ('__getbuffer__', is_buffer = func.name in ('__getbuffer__', '__releasebuffer__')
'__releasebuffer__')
if (func.is_special and Options.docstrings and if (func.is_special and Options.docstrings and
func.wrapperbase_cname and not is_buffer): func.wrapperbase_cname and not is_buffer):
slot = TypeSlots.method_name_to_slot[func.name] slot = TypeSlots.method_name_to_slot[func.name]
...@@ -2799,7 +2784,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -2799,7 +2784,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
c_method_entries = [ c_method_entries = [
entry for entry in type.scope.cfunc_entries entry for entry in type.scope.cfunc_entries
if entry.func_cname ] if entry.func_cname]
if c_method_entries: if c_method_entries:
for meth_entry in c_method_entries: for meth_entry in c_method_entries:
cast = meth_entry.type.signature_cast_string() cast = meth_entry.type.signature_cast_string()
...@@ -2821,8 +2806,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -2821,8 +2806,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_cfunction_declaration(entry, env, code, definition): def generate_cfunction_declaration(entry, env, code, definition):
from_cy_utility = entry.used and entry.utility_code_definition from_cy_utility = entry.used and entry.utility_code_definition
if entry.used and entry.inline_func_in_pxd or (not entry.in_cinclude and (definition if entry.used and entry.inline_func_in_pxd or (not entry.in_cinclude and (
or entry.defined_in_pxd or entry.visibility == 'extern' or from_cy_utility)): definition or entry.defined_in_pxd or entry.visibility == 'extern' or from_cy_utility)):
if entry.visibility == 'extern': if entry.visibility == 'extern':
storage_class = Naming.extern_c_macro storage_class = Naming.extern_c_macro
dll_linkage = "DL_IMPORT" dll_linkage = "DL_IMPORT"
...@@ -2843,7 +2828,7 @@ def generate_cfunction_declaration(entry, env, code, definition): ...@@ -2843,7 +2828,7 @@ def generate_cfunction_declaration(entry, env, code, definition):
type = CPtrType(type) type = CPtrType(type)
header = type.declaration_code( header = type.declaration_code(
entry.cname, dll_linkage = dll_linkage) entry.cname, dll_linkage=dll_linkage)
modifiers = code.build_function_modifiers(entry.func_modifiers) modifiers = code.build_function_modifiers(entry.func_modifiers)
code.putln("%s %s%s; /*proto*/" % ( code.putln("%s %s%s; /*proto*/" % (
storage_class, storage_class,
......
...@@ -15,11 +15,6 @@ cython.declare(sys=object, os=object, copy=object, ...@@ -15,11 +15,6 @@ cython.declare(sys=object, os=object, copy=object,
import sys, os, copy import sys, os, copy
from itertools import chain from itertools import chain
if sys.version_info[0] >= 3:
_py_int_types = int
else:
_py_int_types = (int, long)
from . import Builtin from . import Builtin
from .Errors import error, warning, InternalError, CompileError from .Errors import error, warning, InternalError, CompileError
from . import Naming from . import Naming
...@@ -27,7 +22,7 @@ from . import PyrexTypes ...@@ -27,7 +22,7 @@ from . import PyrexTypes
from . import TypeSlots from . import TypeSlots
from .PyrexTypes import py_object_type, error_type from .PyrexTypes import py_object_type, error_type
from .Symtab import (ModuleScope, LocalScope, ClosureScope, from .Symtab import (ModuleScope, LocalScope, ClosureScope,
StructOrUnionScope, PyClassScope, CppClassScope, TemplateScope) StructOrUnionScope, PyClassScope, CppClassScope, TemplateScope)
from .Code import UtilityCode from .Code import UtilityCode
from .StringEncoding import EncodedString from .StringEncoding import EncodedString
from . import Future from . import Future
...@@ -37,6 +32,11 @@ from ..Utils import add_metaclass ...@@ -37,6 +32,11 @@ from ..Utils import add_metaclass
absolute_path_length = 0 absolute_path_length = 0
if sys.version_info[0] >= 3:
_py_int_types = int
else:
_py_int_types = (int, long)
def relative_position(pos): def relative_position(pos):
""" """
...@@ -55,7 +55,7 @@ def relative_position(pos): ...@@ -55,7 +55,7 @@ def relative_position(pos):
AUTHOR: William Stein AUTHOR: William Stein
""" """
global absolute_path_length global absolute_path_length
if absolute_path_length==0: if absolute_path_length == 0:
absolute_path_length = len(os.path.abspath(os.getcwd())) absolute_path_length = len(os.path.abspath(os.getcwd()))
return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1]) return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
...@@ -342,10 +342,9 @@ class Node(object): ...@@ -342,10 +342,9 @@ class Node(object):
if not self.pos: if not self.pos:
return u'' return u''
source_desc, line, col = self.pos source_desc, line, col = self.pos
contents = source_desc.get_lines(encoding='ASCII', contents = source_desc.get_lines(encoding='ASCII', error_handling='ignore')
error_handling='ignore')
# line numbers start at 1 # line numbers start at 1
lines = contents[max(0,line-3):line] lines = contents[max(0, line-3):line]
current = lines[-1] current = lines[-1]
if mark_column: if mark_column:
current = current[:col] + marker + current[col:] current = current[:col] + marker + current[col:]
...@@ -426,8 +425,8 @@ class StatListNode(Node): ...@@ -426,8 +425,8 @@ class StatListNode(Node):
def analyse_expressions(self, env): def analyse_expressions(self, env):
#print "StatListNode.analyse_expressions" ### #print "StatListNode.analyse_expressions" ###
self.stats = [ stat.analyse_expressions(env) self.stats = [stat.analyse_expressions(env)
for stat in self.stats ] for stat in self.stats]
return self return self
def generate_function_definitions(self, env, code): def generate_function_definitions(self, env, code):
...@@ -512,6 +511,7 @@ class CDeclaratorNode(Node): ...@@ -512,6 +511,7 @@ class CDeclaratorNode(Node):
# Only C++ functions have templates. # Only C++ functions have templates.
return None return None
class CNameDeclaratorNode(CDeclaratorNode): class CNameDeclaratorNode(CDeclaratorNode):
# name string The Cython name being declared # name string The Cython name being declared
# cname string or None C name, if specified # cname string or None C name, if specified
...@@ -521,7 +521,7 @@ class CNameDeclaratorNode(CDeclaratorNode): ...@@ -521,7 +521,7 @@ class CNameDeclaratorNode(CDeclaratorNode):
default = None default = None
def analyse(self, base_type, env, nonempty = 0): def analyse(self, base_type, env, nonempty=0):
if nonempty and self.name == '': if nonempty and self.name == '':
# May have mistaken the name for the type. # May have mistaken the name for the type.
if base_type.is_ptr or base_type.is_array or base_type.is_buffer: if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
...@@ -538,29 +538,30 @@ class CNameDeclaratorNode(CDeclaratorNode): ...@@ -538,29 +538,30 @@ class CNameDeclaratorNode(CDeclaratorNode):
self.type = base_type self.type = base_type
return self, base_type return self, base_type
class CPtrDeclaratorNode(CDeclaratorNode): class CPtrDeclaratorNode(CDeclaratorNode):
# base CDeclaratorNode # base CDeclaratorNode
child_attrs = ["base"] child_attrs = ["base"]
def analyse(self, base_type, env, nonempty = 0): def analyse(self, base_type, env, nonempty=0):
if base_type.is_pyobject: if base_type.is_pyobject:
error(self.pos, error(self.pos, "Pointer base type cannot be a Python object")
"Pointer base type cannot be a Python object")
ptr_type = PyrexTypes.c_ptr_type(base_type) ptr_type = PyrexTypes.c_ptr_type(base_type)
return self.base.analyse(ptr_type, env, nonempty = nonempty) return self.base.analyse(ptr_type, env, nonempty=nonempty)
class CReferenceDeclaratorNode(CDeclaratorNode): class CReferenceDeclaratorNode(CDeclaratorNode):
# base CDeclaratorNode # base CDeclaratorNode
child_attrs = ["base"] child_attrs = ["base"]
def analyse(self, base_type, env, nonempty = 0): def analyse(self, base_type, env, nonempty=0):
if base_type.is_pyobject: if base_type.is_pyobject:
error(self.pos, error(self.pos, "Reference base type cannot be a Python object")
"Reference base type cannot be a Python object")
ref_type = PyrexTypes.c_ref_type(base_type) ref_type = PyrexTypes.c_ref_type(base_type)
return self.base.analyse(ref_type, env, nonempty = nonempty) return self.base.analyse(ref_type, env, nonempty=nonempty)
class CArrayDeclaratorNode(CDeclaratorNode): class CArrayDeclaratorNode(CDeclaratorNode):
# base CDeclaratorNode # base CDeclaratorNode
...@@ -568,7 +569,7 @@ class CArrayDeclaratorNode(CDeclaratorNode): ...@@ -568,7 +569,7 @@ class CArrayDeclaratorNode(CDeclaratorNode):
child_attrs = ["base", "dimension"] child_attrs = ["base", "dimension"]
def analyse(self, base_type, env, nonempty = 0): def analyse(self, base_type, env, nonempty=0):
if (base_type.is_cpp_class and base_type.is_template_type()) or base_type.is_cfunction: if (base_type.is_cpp_class and base_type.is_template_type()) or base_type.is_cfunction:
from .ExprNodes import TupleNode from .ExprNodes import TupleNode
if isinstance(self.dimension, TupleNode): if isinstance(self.dimension, TupleNode):
...@@ -582,7 +583,7 @@ class CArrayDeclaratorNode(CDeclaratorNode): ...@@ -582,7 +583,7 @@ class CArrayDeclaratorNode(CDeclaratorNode):
base_type = error_type base_type = error_type
else: else:
base_type = base_type.specialize_here(self.pos, values) base_type = base_type.specialize_here(self.pos, values)
return self.base.analyse(base_type, env, nonempty = nonempty) return self.base.analyse(base_type, env, nonempty=nonempty)
if self.dimension: if self.dimension:
self.dimension = self.dimension.analyse_const_expression(env) self.dimension = self.dimension.analyse_const_expression(env)
if not self.dimension.type.is_int: if not self.dimension.type.is_int:
...@@ -597,16 +598,13 @@ class CArrayDeclaratorNode(CDeclaratorNode): ...@@ -597,16 +598,13 @@ class CArrayDeclaratorNode(CDeclaratorNode):
else: else:
size = None size = None
if not base_type.is_complete(): if not base_type.is_complete():
error(self.pos, error(self.pos, "Array element type '%s' is incomplete" % base_type)
"Array element type '%s' is incomplete" % base_type)
if base_type.is_pyobject: if base_type.is_pyobject:
error(self.pos, error(self.pos, "Array element cannot be a Python object")
"Array element cannot be a Python object")
if base_type.is_cfunction: if base_type.is_cfunction:
error(self.pos, error(self.pos, "Array element cannot be a function")
"Array element cannot be a function")
array_type = PyrexTypes.c_array_type(base_type, size) array_type = PyrexTypes.c_array_type(base_type, size)
return self.base.analyse(array_type, env, nonempty = nonempty) return self.base.analyse(array_type, env, nonempty=nonempty)
class CFuncDeclaratorNode(CDeclaratorNode): class CFuncDeclaratorNode(CDeclaratorNode):
...@@ -657,7 +655,8 @@ class CFuncDeclaratorNode(CDeclaratorNode): ...@@ -657,7 +655,8 @@ class CFuncDeclaratorNode(CDeclaratorNode):
func_type_args = [] func_type_args = []
for i, arg_node in enumerate(self.args): for i, arg_node in enumerate(self.args):
name_declarator, type = arg_node.analyse( name_declarator, type = arg_node.analyse(
env, nonempty=nonempty, is_self_arg=(i == 0 and env.is_c_class_scope and 'staticmethod' not in env.directives)) env, nonempty=nonempty,
is_self_arg=(i == 0 and env.is_c_class_scope and 'staticmethod' not in env.directives))
name = name_declarator.name name = name_declarator.name
if name in directive_locals: if name in directive_locals:
type_node = directive_locals[name] type_node = directive_locals[name]
...@@ -671,9 +670,8 @@ class CFuncDeclaratorNode(CDeclaratorNode): ...@@ -671,9 +670,8 @@ class CFuncDeclaratorNode(CDeclaratorNode):
else: else:
type = other_type type = other_type
if name_declarator.cname: if name_declarator.cname:
error(self.pos, error(self.pos, "Function argument cannot have C name specification")
"Function argument cannot have C name specification") if i == 0 and env.is_c_class_scope and type.is_unspecified:
if i==0 and env.is_c_class_scope and type.is_unspecified:
# fix the type of self # fix the type of self
type = env.parent_type type = env.parent_type
# Turn *[] argument into ** # Turn *[] argument into **
...@@ -699,8 +697,7 @@ class CFuncDeclaratorNode(CDeclaratorNode): ...@@ -699,8 +697,7 @@ class CFuncDeclaratorNode(CDeclaratorNode):
if (return_type.is_pyobject if (return_type.is_pyobject
and (self.exception_value or self.exception_check) and (self.exception_value or self.exception_check)
and self.exception_check != '+'): and self.exception_check != '+'):
error(self.pos, error(self.pos, "Exception clause not allowed for function returning Python object")
"Exception clause not allowed for function returning Python object")
else: else:
if self.exception_value: if self.exception_value:
self.exception_value = self.exception_value.analyse_const_expression(env) self.exception_value = self.exception_value.analyse_const_expression(env)
...@@ -727,16 +724,15 @@ class CFuncDeclaratorNode(CDeclaratorNode): ...@@ -727,16 +724,15 @@ class CFuncDeclaratorNode(CDeclaratorNode):
"Exception value incompatible with function return type") "Exception value incompatible with function return type")
exc_check = self.exception_check exc_check = self.exception_check
if return_type.is_cfunction: if return_type.is_cfunction:
error(self.pos, error(self.pos, "Function cannot return a function")
"Function cannot return a function")
func_type = PyrexTypes.CFuncType( func_type = PyrexTypes.CFuncType(
return_type, func_type_args, self.has_varargs, return_type, func_type_args, self.has_varargs,
optional_arg_count = self.optional_arg_count, optional_arg_count=self.optional_arg_count,
exception_value = exc_val, exception_check = exc_check, exception_value=exc_val, exception_check=exc_check,
calling_convention = self.base.calling_convention, calling_convention=self.base.calling_convention,
nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable, nogil=self.nogil, with_gil=self.with_gil, is_overridable=self.overridable,
is_const_method = self.is_const_method, is_const_method=self.is_const_method,
templates = self.templates) templates=self.templates)
if self.optional_arg_count: if self.optional_arg_count:
if func_type.is_fused: if func_type.is_fused:
...@@ -770,8 +766,8 @@ class CFuncDeclaratorNode(CDeclaratorNode): ...@@ -770,8 +766,8 @@ class CFuncDeclaratorNode(CDeclaratorNode):
arg_count_member = '%sn' % Naming.pyrex_prefix arg_count_member = '%sn' % Naming.pyrex_prefix
scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos) scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
for arg in func_type.args[len(func_type.args)-self.optional_arg_count:]: for arg in func_type.args[len(func_type.args) - self.optional_arg_count:]:
scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1) scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject=1)
struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name) struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
...@@ -779,12 +775,12 @@ class CFuncDeclaratorNode(CDeclaratorNode): ...@@ -779,12 +775,12 @@ class CFuncDeclaratorNode(CDeclaratorNode):
struct_cname = PyrexTypes.get_fused_cname(fused_cname, struct_cname) struct_cname = PyrexTypes.get_fused_cname(fused_cname, struct_cname)
op_args_struct = env.global_scope().declare_struct_or_union( op_args_struct = env.global_scope().declare_struct_or_union(
name = struct_cname, name=struct_cname,
kind = 'struct', kind='struct',
scope = scope, scope=scope,
typedef_flag = 0, typedef_flag=0,
pos = self.pos, pos=self.pos,
cname = struct_cname) cname=struct_cname)
op_args_struct.defined_in_pxd = 1 op_args_struct.defined_in_pxd = 1
op_args_struct.used = 1 op_args_struct.used = 1
...@@ -797,12 +793,12 @@ class CConstDeclaratorNode(CDeclaratorNode): ...@@ -797,12 +793,12 @@ class CConstDeclaratorNode(CDeclaratorNode):
child_attrs = ["base"] child_attrs = ["base"]
def analyse(self, base_type, env, nonempty = 0): def analyse(self, base_type, env, nonempty=0):
if base_type.is_pyobject: if base_type.is_pyobject:
error(self.pos, error(self.pos,
"Const base type cannot be a Python object") "Const base type cannot be a Python object")
const = PyrexTypes.c_const_type(base_type) const = PyrexTypes.c_const_type(base_type)
return self.base.analyse(const, env, nonempty = nonempty) return self.base.analyse(const, env, nonempty=nonempty)
class CArgDeclNode(Node): class CArgDeclNode(Node):
...@@ -835,7 +831,7 @@ class CArgDeclNode(Node): ...@@ -835,7 +831,7 @@ class CArgDeclNode(Node):
annotation = None annotation = None
is_dynamic = 0 is_dynamic = 0
def analyse(self, env, nonempty = 0, is_self_arg = False): def analyse(self, env, nonempty=0, is_self_arg=False):
if is_self_arg: if is_self_arg:
self.base_type.is_self_arg = self.is_self_arg = True self.base_type.is_self_arg = self.is_self_arg = True
if self.type is None: if self.type is None:
...@@ -936,7 +932,7 @@ class CAnalysedBaseTypeNode(Node): ...@@ -936,7 +932,7 @@ class CAnalysedBaseTypeNode(Node):
child_attrs = [] child_attrs = []
def analyse(self, env, could_be_name = False): def analyse(self, env, could_be_name=False):
return self.type return self.type
...@@ -956,7 +952,7 @@ class CSimpleBaseTypeNode(CBaseTypeNode): ...@@ -956,7 +952,7 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
is_basic_c_type = False is_basic_c_type = False
complex = False complex = False
def analyse(self, env, could_be_name = False): def analyse(self, env, could_be_name=False):
# Return type descriptor. # Return type descriptor.
#print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ### #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
type = None type = None
...@@ -1039,7 +1035,7 @@ class MemoryViewSliceTypeNode(CBaseTypeNode): ...@@ -1039,7 +1035,7 @@ class MemoryViewSliceTypeNode(CBaseTypeNode):
name = 'memoryview' name = 'memoryview'
child_attrs = ['base_type_node', 'axes'] child_attrs = ['base_type_node', 'axes']
def analyse(self, env, could_be_name = False): def analyse(self, env, could_be_name=False):
base_type = self.base_type_node.analyse(env) base_type = self.base_type_node.analyse(env)
if base_type.is_error: return base_type if base_type.is_error: return base_type
...@@ -1075,7 +1071,7 @@ class CNestedBaseTypeNode(CBaseTypeNode): ...@@ -1075,7 +1071,7 @@ class CNestedBaseTypeNode(CBaseTypeNode):
child_attrs = ['base_type'] child_attrs = ['base_type']
def analyse(self, env, could_be_name = None): def analyse(self, env, could_be_name=None):
base_type = self.base_type.analyse(env) base_type = self.base_type.analyse(env)
if base_type is PyrexTypes.error_type: if base_type is PyrexTypes.error_type:
return PyrexTypes.error_type return PyrexTypes.error_type
...@@ -1105,7 +1101,7 @@ class TemplatedTypeNode(CBaseTypeNode): ...@@ -1105,7 +1101,7 @@ class TemplatedTypeNode(CBaseTypeNode):
name = None name = None
def analyse(self, env, could_be_name = False, base_type = None): def analyse(self, env, could_be_name=False, base_type=None):
if base_type is None: if base_type is None:
base_type = self.base_type_node.analyse(env) base_type = self.base_type_node.analyse(env)
if base_type.is_error: return base_type if base_type.is_error: return base_type
...@@ -1138,8 +1134,8 @@ class TemplatedTypeNode(CBaseTypeNode): ...@@ -1138,8 +1134,8 @@ class TemplatedTypeNode(CBaseTypeNode):
if sys.version_info[0] < 3: if sys.version_info[0] < 3:
# Py 2.x enforces byte strings as keyword arguments ... # Py 2.x enforces byte strings as keyword arguments ...
options = dict([ (name.encode('ASCII'), value) options = dict([(name.encode('ASCII'), value)
for name, value in options.items() ]) for name, value in options.items()])
self.type = PyrexTypes.BufferType(base_type, **options) self.type = PyrexTypes.BufferType(base_type, **options)
...@@ -1156,9 +1152,10 @@ class TemplatedTypeNode(CBaseTypeNode): ...@@ -1156,9 +1152,10 @@ class TemplatedTypeNode(CBaseTypeNode):
dimension = None dimension = None
else: else:
dimension = self.positional_args[0] dimension = self.positional_args[0]
self.array_declarator = CArrayDeclaratorNode(self.pos, self.array_declarator = CArrayDeclaratorNode(
base = empty_declarator, self.pos,
dimension = dimension) base=empty_declarator,
dimension=dimension)
self.type = self.array_declarator.analyse(base_type, env)[1] self.type = self.array_declarator.analyse(base_type, env)[1]
if self.type.is_fused and env.fused_to_specific: if self.type.is_fused and env.fused_to_specific:
...@@ -1166,13 +1163,14 @@ class TemplatedTypeNode(CBaseTypeNode): ...@@ -1166,13 +1163,14 @@ class TemplatedTypeNode(CBaseTypeNode):
return self.type return self.type
class CComplexBaseTypeNode(CBaseTypeNode): class CComplexBaseTypeNode(CBaseTypeNode):
# base_type CBaseTypeNode # base_type CBaseTypeNode
# declarator CDeclaratorNode # declarator CDeclaratorNode
child_attrs = ["base_type", "declarator"] child_attrs = ["base_type", "declarator"]
def analyse(self, env, could_be_name = False): def analyse(self, env, could_be_name=False):
base = self.base_type.analyse(env, could_be_name) base = self.base_type.analyse(env, could_be_name)
_, type = self.declarator.analyse(base, env) _, type = self.declarator.analyse(base, env)
return type return type
...@@ -1215,7 +1213,7 @@ class FusedTypeNode(CBaseTypeNode): ...@@ -1215,7 +1213,7 @@ class FusedTypeNode(CBaseTypeNode):
# Omit the typedef declaration that self.declarator would produce # Omit the typedef declaration that self.declarator would produce
entry.in_cinclude = True entry.in_cinclude = True
def analyse(self, env, could_be_name = False): def analyse(self, env, could_be_name=False):
types = [] types = []
for type_node in self.types: for type_node in self.types:
type = type_node.analyse_as_type(env) type = type_node.analyse_as_type(env)
...@@ -1240,7 +1238,7 @@ class CConstTypeNode(CBaseTypeNode): ...@@ -1240,7 +1238,7 @@ class CConstTypeNode(CBaseTypeNode):
child_attrs = ["base_type"] child_attrs = ["base_type"]
def analyse(self, env, could_be_name = False): def analyse(self, env, could_be_name=False):
base = self.base_type.analyse(env, could_be_name) base = self.base_type.analyse(env, could_be_name)
if base.is_pyobject: if base.is_pyobject:
error(self.pos, error(self.pos,
...@@ -1267,7 +1265,7 @@ class CVarDefNode(StatNode): ...@@ -1267,7 +1265,7 @@ class CVarDefNode(StatNode):
decorators = None decorators = None
directive_locals = None directive_locals = None
def analyse_declarations(self, env, dest_scope = None): def analyse_declarations(self, env, dest_scope=None):
if self.directive_locals is None: if self.directive_locals is None:
self.directive_locals = {} self.directive_locals = {}
if not dest_scope: if not dest_scope:
...@@ -1301,15 +1299,16 @@ class CVarDefNode(StatNode): ...@@ -1301,15 +1299,16 @@ class CVarDefNode(StatNode):
for declarator in self.declarators: for declarator in self.declarators:
if (len(self.declarators) > 1 if (len(self.declarators) > 1
and not isinstance(declarator, CNameDeclaratorNode) and not isinstance(declarator, CNameDeclaratorNode)
and env.directives['warn.multiple_declarators']): and env.directives['warn.multiple_declarators']):
warning(declarator.pos, warning(
"Non-trivial type declarators in shared declaration (e.g. mix of pointers and values). " + declarator.pos,
"Non-trivial type declarators in shared declaration (e.g. mix of pointers and values). "
"Each pointer declaration should be on its own line.", 1) "Each pointer declaration should be on its own line.", 1)
create_extern_wrapper = (self.overridable create_extern_wrapper = (self.overridable
and self.visibility == 'extern' and self.visibility == 'extern'
and env.is_module_scope) and env.is_module_scope)
if create_extern_wrapper: if create_extern_wrapper:
declarator.overridable = False declarator.overridable = False
if isinstance(declarator, CFuncDeclaratorNode): if isinstance(declarator, CFuncDeclaratorNode):
...@@ -1318,11 +1317,9 @@ class CVarDefNode(StatNode): ...@@ -1318,11 +1317,9 @@ class CVarDefNode(StatNode):
name_declarator, type = declarator.analyse(base_type, env) name_declarator, type = declarator.analyse(base_type, env)
if not type.is_complete(): if not type.is_complete():
if not (self.visibility == 'extern' and type.is_array or type.is_memoryviewslice): if not (self.visibility == 'extern' and type.is_array or type.is_memoryviewslice):
error(declarator.pos, error(declarator.pos, "Variable type '%s' is incomplete" % type)
"Variable type '%s' is incomplete" % type)
if self.visibility == 'extern' and type.is_pyobject: if self.visibility == 'extern' and type.is_pyobject:
error(declarator.pos, error(declarator.pos, "Python object cannot be declared extern")
"Python object cannot be declared extern")
name = name_declarator.name name = name_declarator.name
cname = name_declarator.cname cname = name_declarator.cname
if name == '': if name == '':
...@@ -1331,7 +1328,8 @@ class CVarDefNode(StatNode): ...@@ -1331,7 +1328,8 @@ class CVarDefNode(StatNode):
if type.is_cfunction: if type.is_cfunction:
if 'staticmethod' in env.directives: if 'staticmethod' in env.directives:
type.is_static_method = True type.is_static_method = True
self.entry = dest_scope.declare_cfunction(name, type, declarator.pos, self.entry = dest_scope.declare_cfunction(
name, type, declarator.pos,
cname=cname, visibility=self.visibility, in_pxd=self.in_pxd, cname=cname, visibility=self.visibility, in_pxd=self.in_pxd,
api=self.api, modifiers=self.modifiers, overridable=self.overridable) api=self.api, modifiers=self.modifiers, overridable=self.overridable)
if self.entry is not None: if self.entry is not None:
...@@ -1342,9 +1340,10 @@ class CVarDefNode(StatNode): ...@@ -1342,9 +1340,10 @@ class CVarDefNode(StatNode):
else: else:
if self.directive_locals: if self.directive_locals:
error(self.pos, "Decorators can only be followed by functions") error(self.pos, "Decorators can only be followed by functions")
self.entry = dest_scope.declare_var(name, type, declarator.pos, self.entry = dest_scope.declare_var(
cname=cname, visibility=visibility, in_pxd=self.in_pxd, name, type, declarator.pos,
api=self.api, is_cdef=1) cname=cname, visibility=visibility, in_pxd=self.in_pxd,
api=self.api, is_cdef=1)
if Options.docstrings: if Options.docstrings:
self.entry.doc = embed_position(self.pos, self.doc) self.entry.doc = embed_position(self.pos, self.doc)
...@@ -1366,8 +1365,8 @@ class CStructOrUnionDefNode(StatNode): ...@@ -1366,8 +1365,8 @@ class CStructOrUnionDefNode(StatNode):
def declare(self, env, scope=None): def declare(self, env, scope=None):
self.entry = env.declare_struct_or_union( self.entry = env.declare_struct_or_union(
self.name, self.kind, scope, self.typedef_flag, self.pos, self.name, self.kind, scope, self.typedef_flag, self.pos,
self.cname, visibility = self.visibility, api = self.api, self.cname, visibility=self.visibility, api=self.api,
packed = self.packed) packed=self.packed)
def analyse_declarations(self, env): def analyse_declarations(self, env):
scope = None scope = None
...@@ -1418,8 +1417,8 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode): ...@@ -1418,8 +1417,8 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
if num_optional_templates and not all(required for _, required in self.templates[:-num_optional_templates]): if num_optional_templates and not all(required for _, required in self.templates[:-num_optional_templates]):
error(self.pos, "Required template parameters must precede optional template parameters.") error(self.pos, "Required template parameters must precede optional template parameters.")
self.entry = env.declare_cpp_class( self.entry = env.declare_cpp_class(
self.name, None, self.pos, self.name, None, self.pos, self.cname,
self.cname, base_classes = [], visibility = self.visibility, templates = template_types) base_classes=[], visibility=self.visibility, templates=template_types)
def analyse_declarations(self, env): def analyse_declarations(self, env):
if self.templates is None: if self.templates is None:
...@@ -1430,7 +1429,7 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode): ...@@ -1430,7 +1429,7 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
for template_name, required in self.templates] for template_name, required in self.templates]
scope = None scope = None
if self.attributes is not None: if self.attributes is not None:
scope = CppClassScope(self.name, env, templates = template_names) scope = CppClassScope(self.name, env, templates=template_names)
def base_ok(base_class): def base_ok(base_class):
if base_class.is_cpp_class or base_class.is_struct: if base_class.is_cpp_class or base_class.is_struct:
return True return True
...@@ -1439,7 +1438,7 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode): ...@@ -1439,7 +1438,7 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
base_class_types = filter(base_ok, [b.analyse(scope or env) for b in self.base_classes]) base_class_types = filter(base_ok, [b.analyse(scope or env) for b in self.base_classes])
self.entry = env.declare_cpp_class( self.entry = env.declare_cpp_class(
self.name, scope, self.pos, self.name, scope, self.pos,
self.cname, base_class_types, visibility = self.visibility, templates = template_types) self.cname, base_class_types, visibility=self.visibility, templates=template_types)
if self.entry is None: if self.entry is None:
return return
self.entry.is_cpp_class = 1 self.entry.is_cpp_class = 1
...@@ -1493,10 +1492,11 @@ class CEnumDefNode(StatNode): ...@@ -1493,10 +1492,11 @@ class CEnumDefNode(StatNode):
child_attrs = ["items"] child_attrs = ["items"]
def declare(self, env): def declare(self, env):
self.entry = env.declare_enum(self.name, self.pos, self.entry = env.declare_enum(
cname = self.cname, typedef_flag = self.typedef_flag, self.name, self.pos,
visibility = self.visibility, api = self.api, cname=self.cname, typedef_flag=self.typedef_flag,
create_wrapper = self.create_wrapper and self.name is None) visibility=self.visibility, api=self.api,
create_wrapper=self.create_wrapper and self.name is None)
def analyse_declarations(self, env): def analyse_declarations(self, env):
if self.items is not None: if self.items is not None:
...@@ -1505,15 +1505,14 @@ class CEnumDefNode(StatNode): ...@@ -1505,15 +1505,14 @@ class CEnumDefNode(StatNode):
for item in self.items: for item in self.items:
item.analyse_declarations(env, self.entry) item.analyse_declarations(env, self.entry)
if self.name is not None: if self.name is not None:
self.entry.type.values = set( self.entry.type.values = set(item.name for item in self.items)
(item.name) for item in self.items)
if self.create_wrapper and self.name is not None: if self.create_wrapper and self.name is not None:
from .UtilityCode import CythonUtilityCode from .UtilityCode import CythonUtilityCode
env.use_utility_code(CythonUtilityCode.load( env.use_utility_code(CythonUtilityCode.load(
"EnumType", "CpdefEnums.pyx", "EnumType", "CpdefEnums.pyx",
context={"name": self.name, context={"name": self.name,
"items": tuple(item.name for item in self.items)}, "items": tuple(item.name for item in self.items)},
outer_module_scope=env.global_scope())) outer_module_scope=env.global_scope()))
def analyse_expressions(self, env): def analyse_expressions(self, env):
return self return self
...@@ -1524,15 +1523,15 @@ class CEnumDefNode(StatNode): ...@@ -1524,15 +1523,15 @@ class CEnumDefNode(StatNode):
temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True) temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
for item in self.entry.enum_values: for item in self.entry.enum_values:
code.putln("%s = PyInt_FromLong(%s); %s" % ( code.putln("%s = PyInt_FromLong(%s); %s" % (
temp, temp,
item.cname, item.cname,
code.error_goto_if_null(temp, item.pos))) code.error_goto_if_null(temp, item.pos)))
code.put_gotref(temp) code.put_gotref(temp)
code.putln('if (PyDict_SetItemString(%s, "%s", %s) < 0) %s' % ( code.putln('if (PyDict_SetItemString(%s, "%s", %s) < 0) %s' % (
Naming.moddict_cname, Naming.moddict_cname,
item.name, item.name,
temp, temp,
code.error_goto(item.pos))) code.error_goto(item.pos)))
code.put_decref_clear(temp, PyrexTypes.py_object_type) code.put_decref_clear(temp, PyrexTypes.py_object_type)
code.funcstate.release_temp(temp) code.funcstate.release_temp(temp)
...@@ -1550,10 +1549,11 @@ class CEnumDefItemNode(StatNode): ...@@ -1550,10 +1549,11 @@ class CEnumDefItemNode(StatNode):
if not self.value.type.is_int: if not self.value.type.is_int:
self.value = self.value.coerce_to(PyrexTypes.c_int_type, env) self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
self.value = self.value.analyse_const_expression(env) self.value = self.value.analyse_const_expression(env)
entry = env.declare_const(self.name, enum_entry.type, entry = env.declare_const(
self.value, self.pos, cname = self.cname, self.name, enum_entry.type,
visibility = enum_entry.visibility, api = enum_entry.api, self.value, self.pos, cname=self.cname,
create_wrapper = enum_entry.create_wrapper and enum_entry.name is None) visibility=enum_entry.visibility, api=enum_entry.api,
create_wrapper=enum_entry.create_wrapper and enum_entry.name is None)
enum_entry.enum_values.append(entry) enum_entry.enum_values.append(entry)
if enum_entry.name: if enum_entry.name:
enum_entry.type.values.append(entry.cname) enum_entry.type.values.append(entry.cname)
...@@ -1574,8 +1574,9 @@ class CTypeDefNode(StatNode): ...@@ -1574,8 +1574,9 @@ class CTypeDefNode(StatNode):
name = name_declarator.name name = name_declarator.name
cname = name_declarator.cname cname = name_declarator.cname
entry = env.declare_typedef(name, type, self.pos, entry = env.declare_typedef(
cname = cname, visibility = self.visibility, api = self.api) name, type, self.pos,
cname=cname, visibility=self.visibility, api=self.api)
if type.is_fused: if type.is_fused:
entry.in_cinclude = True entry.in_cinclude = True
...@@ -1634,8 +1635,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1634,8 +1635,7 @@ class FuncDefNode(StatNode, BlockNode):
arg.default = arg.default.analyse_types(env) arg.default = arg.default.analyse_types(env)
arg.default = arg.default.coerce_to(arg.type, env) arg.default = arg.default.coerce_to(arg.type, env)
else: else:
error(arg.pos, error(arg.pos, "This argument cannot have a default value")
"This argument cannot have a default value")
arg.default = None arg.default = None
elif arg.kw_only: elif arg.kw_only:
default_seen = 1 default_seen = 1
...@@ -1663,8 +1663,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1663,8 +1663,7 @@ class FuncDefNode(StatNode, BlockNode):
return arg return arg
if other_type is None: if other_type is None:
error(type_node.pos, "Not a type") error(type_node.pos, "Not a type")
elif (orig_type is not PyrexTypes.py_object_type elif orig_type is not py_object_type and not orig_type.same_as(other_type):
and not orig_type.same_as(other_type)):
error(arg.base_type.pos, "Signature does not agree with previous declaration") error(arg.base_type.pos, "Signature does not agree with previous declaration")
error(type_node.pos, "Previous declaration here") error(type_node.pos, "Previous declaration here")
else: else:
...@@ -1680,8 +1679,8 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1680,8 +1679,8 @@ class FuncDefNode(StatNode, BlockNode):
genv = genv.outer_scope genv = genv.outer_scope
if self.needs_closure: if self.needs_closure:
lenv = ClosureScope(name=self.entry.name, lenv = ClosureScope(name=self.entry.name,
outer_scope = genv, outer_scope=genv,
parent_scope = env, parent_scope=env,
scope_name=self.entry.cname) scope_name=self.entry.cname)
else: else:
lenv = LocalScope(name=self.entry.name, lenv = LocalScope(name=self.entry.name,
...@@ -1749,11 +1748,9 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1749,11 +1748,9 @@ class FuncDefNode(StatNode, BlockNode):
with_pymethdef = (self.needs_assignment_synthesis(env, code) or with_pymethdef = (self.needs_assignment_synthesis(env, code) or
self.pymethdef_required) self.pymethdef_required)
if self.py_func: if self.py_func:
self.py_func.generate_function_header(code, self.py_func.generate_function_header(
with_pymethdef = with_pymethdef, code, with_pymethdef=with_pymethdef, proto_only=True)
proto_only=True) self.generate_function_header(code, with_pymethdef=with_pymethdef)
self.generate_function_header(code,
with_pymethdef = with_pymethdef)
# ----- Local variable declarations # ----- Local variable declarations
# Find function scope # Find function scope
cenv = env cenv = env
...@@ -1782,10 +1779,9 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1782,10 +1779,9 @@ class FuncDefNode(StatNode, BlockNode):
elif self.return_type.is_memoryviewslice: elif self.return_type.is_memoryviewslice:
init = ' = ' + MemoryView.memslice_entry_init init = ' = ' + MemoryView.memslice_entry_init
code.putln( code.putln("%s%s;" % (
"%s%s;" % self.return_type.declaration_code(Naming.retval_cname),
(self.return_type.declaration_code(Naming.retval_cname), init))
init))
tempvardecl_code = code.insertion_point() tempvardecl_code = code.insertion_point()
self.generate_keyword_list(code) self.generate_keyword_list(code)
...@@ -1810,12 +1806,12 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1810,12 +1806,12 @@ class FuncDefNode(StatNode, BlockNode):
used_buffer_entries = [entry for entry in lenv.buffer_entries if entry.used] used_buffer_entries = [entry for entry in lenv.buffer_entries if entry.used]
acquire_gil_for_var_decls_only = ( acquire_gil_for_var_decls_only = (
lenv.nogil and lenv.has_with_gil_block and lenv.nogil and lenv.has_with_gil_block and
(have_object_args or used_buffer_entries)) (have_object_args or used_buffer_entries))
acquire_gil_for_refnanny_only = ( acquire_gil_for_refnanny_only = (
lenv.nogil and lenv.has_with_gil_block and not lenv.nogil and lenv.has_with_gil_block and not
acquire_gil_for_var_decls_only) acquire_gil_for_var_decls_only)
use_refnanny = not lenv.nogil or lenv.has_with_gil_block use_refnanny = not lenv.nogil or lenv.has_with_gil_block
...@@ -2038,16 +2034,13 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -2038,16 +2034,13 @@ class FuncDefNode(StatNode, BlockNode):
# See if our return value is uninitialized on non-error return # See if our return value is uninitialized on non-error return
# from . import MemoryView # from . import MemoryView
# MemoryView.err_if_nogil_initialized_check(self.pos, env) # MemoryView.err_if_nogil_initialized_check(self.pos, env)
cond = code.unlikely(self.return_type.error_condition( cond = code.unlikely(self.return_type.error_condition(Naming.retval_cname))
Naming.retval_cname))
code.putln( code.putln(
'if (%s) {' % cond) 'if (%s) {' % cond)
if env.nogil: if env.nogil:
code.put_ensure_gil() code.put_ensure_gil()
code.putln( code.putln(
'PyErr_SetString(' 'PyErr_SetString(PyExc_TypeError, "Memoryview return value is not initialized");')
'PyExc_TypeError,'
'"Memoryview return value is not initialized");')
if env.nogil: if env.nogil:
code.put_release_ensured_gil() code.put_release_ensured_gil()
code.putln( code.putln(
...@@ -2061,8 +2054,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -2061,8 +2054,7 @@ class FuncDefNode(StatNode, BlockNode):
continue continue
if entry.type.is_memoryviewslice: if entry.type.is_memoryviewslice:
code.put_xdecref_memoryviewslice(entry.cname, code.put_xdecref_memoryviewslice(entry.cname, have_gil=not lenv.nogil)
have_gil=not lenv.nogil)
elif entry.type.is_pyobject: elif entry.type.is_pyobject:
if not entry.is_arg or len(entry.cf_assignments) > 1: if not entry.is_arg or len(entry.cf_assignments) > 1:
if entry.xdecref_cleanup: if entry.xdecref_cleanup:
...@@ -2073,8 +2065,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -2073,8 +2065,7 @@ class FuncDefNode(StatNode, BlockNode):
# Decref any increfed args # Decref any increfed args
for entry in lenv.arg_entries: for entry in lenv.arg_entries:
if entry.type.is_pyobject: if entry.type.is_pyobject:
if ((acquire_gil or len(entry.cf_assignments) > 1) and if (acquire_gil or len(entry.cf_assignments) > 1) and not entry.in_closure:
not entry.in_closure):
code.put_var_decref(entry) code.put_var_decref(entry)
elif (entry.type.is_memoryviewslice and elif (entry.type.is_memoryviewslice and
(not is_cdef or len(entry.cf_assignments) > 1)): (not is_cdef or len(entry.cf_assignments) > 1)):
...@@ -2099,7 +2090,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -2099,7 +2090,7 @@ class FuncDefNode(StatNode, BlockNode):
# Returning -1 for __hash__ is supposed to signal an error # Returning -1 for __hash__ is supposed to signal an error
# We do as Python instances and coerce -1 into -2. # We do as Python instances and coerce -1 into -2.
code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % ( code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
Naming.retval_cname, Naming.retval_cname)) Naming.retval_cname, Naming.retval_cname))
if profile or linetrace: if profile or linetrace:
code.funcstate.can_trace = False code.funcstate.can_trace = False
...@@ -2140,8 +2131,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -2140,8 +2131,7 @@ class FuncDefNode(StatNode, BlockNode):
if arg.type.is_void: if arg.type.is_void:
error(arg.pos, "Invalid use of 'void'") error(arg.pos, "Invalid use of 'void'")
elif not arg.type.is_complete() and not (arg.type.is_array or arg.type.is_memoryviewslice): elif not arg.type.is_complete() and not (arg.type.is_array or arg.type.is_memoryviewslice):
error(arg.pos, error(arg.pos, "Argument type '%s' is incomplete" % arg.type)
"Argument type '%s' is incomplete" % arg.type)
return env.declare_arg(arg.name, arg.type, arg.pos) return env.declare_arg(arg.name, arg.type, arg.pos)
def generate_arg_type_test(self, arg, code): def generate_arg_type_test(self, arg, code):
...@@ -2160,8 +2150,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -2160,8 +2150,7 @@ class FuncDefNode(StatNode, BlockNode):
arg.type.is_builtin_type, arg.type.is_builtin_type,
code.error_goto(arg.pos))) code.error_goto(arg.pos)))
else: else:
error(arg.pos, "Cannot test type of extern C class " error(arg.pos, "Cannot test type of extern C class without type object name specification")
"without type object name specification")
def generate_arg_none_check(self, arg, code): def generate_arg_none_check(self, arg, code):
# Generate None check for one argument. # Generate None check for one argument.
...@@ -2282,14 +2271,14 @@ class CFuncDefNode(FuncDefNode): ...@@ -2282,14 +2271,14 @@ class CFuncDefNode(FuncDefNode):
self.is_static_method = 'staticmethod' in env.directives and not env.lookup_here('staticmethod') self.is_static_method = 'staticmethod' in env.directives and not env.lookup_here('staticmethod')
# The 2 here is because we need both function and argument names. # The 2 here is because we need both function and argument names.
if isinstance(self.declarator, CFuncDeclaratorNode): if isinstance(self.declarator, CFuncDeclaratorNode):
name_declarator, type = self.declarator.analyse(base_type, env, name_declarator, type = self.declarator.analyse(
nonempty = 2 * (self.body is not None), base_type, env, nonempty=2 * (self.body is not None),
directive_locals = self.directive_locals) directive_locals=self.directive_locals)
else: else:
name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None)) name_declarator, type = self.declarator.analyse(
base_type, env, nonempty=2 * (self.body is not None))
if not type.is_cfunction: if not type.is_cfunction:
error(self.pos, error(self.pos, "Suite attached to non-function declaration")
"Suite attached to non-function declaration")
# Remember the actual type according to the function header # Remember the actual type according to the function header
# written here, because the type in the symbol table entry # written here, because the type in the symbol table entry
# may be different if we're overriding a C method inherited # may be different if we're overriding a C method inherited
...@@ -2306,10 +2295,9 @@ class CFuncDefNode(FuncDefNode): ...@@ -2306,10 +2295,9 @@ class CFuncDefNode(FuncDefNode):
opt_arg_count = self.cfunc_declarator.optional_arg_count opt_arg_count = self.cfunc_declarator.optional_arg_count
if (self.visibility == 'public' or self.api) and opt_arg_count: if (self.visibility == 'public' or self.api) and opt_arg_count:
error(self.cfunc_declarator.pos, error(self.cfunc_declarator.pos,
"Function with optional arguments may not be declared " "Function with optional arguments may not be declared public or api")
"public or api")
if (type.exception_check == '+' and self.visibility != 'extern'): if type.exception_check == '+' and self.visibility != 'extern':
warning(self.cfunc_declarator.pos, warning(self.cfunc_declarator.pos,
"Only extern functions can throw C++ exceptions.") "Only extern functions can throw C++ exceptions.")
...@@ -2330,8 +2318,7 @@ class CFuncDefNode(FuncDefNode): ...@@ -2330,8 +2318,7 @@ class CFuncDefNode(FuncDefNode):
if type_arg.type.is_buffer: if type_arg.type.is_buffer:
if self.type.nogil: if self.type.nogil:
error(formal_arg.pos, error(formal_arg.pos,
"Buffer may not be acquired without the GIL. " "Buffer may not be acquired without the GIL. Consider using memoryview slices instead.")
"Consider using memoryview slices instead.")
elif 'inline' in self.modifiers: elif 'inline' in self.modifiers:
warning(formal_arg.pos, "Buffer unpacking not optimized away.", 1) warning(formal_arg.pos, "Buffer unpacking not optimized away.", 1)
...@@ -2350,8 +2337,7 @@ class CFuncDefNode(FuncDefNode): ...@@ -2350,8 +2337,7 @@ class CFuncDefNode(FuncDefNode):
self.entry.inline_func_in_pxd = self.inline_in_pxd self.entry.inline_func_in_pxd = self.inline_in_pxd
self.return_type = type.return_type self.return_type = type.return_type
if self.return_type.is_array and self.visibility != 'extern': if self.return_type.is_array and self.visibility != 'extern':
error(self.pos, error(self.pos, "Function cannot return an array")
"Function cannot return an array")
if self.return_type.is_cpp_class: if self.return_type.is_cpp_class:
self.return_type.check_nullary_constructor(self.pos, "used as a return value") self.return_type.check_nullary_constructor(self.pos, "used as a return value")
...@@ -2369,33 +2355,33 @@ class CFuncDefNode(FuncDefNode): ...@@ -2369,33 +2355,33 @@ class CFuncDefNode(FuncDefNode):
# TODO(robertwb): Finish this up, perhaps via more function refactoring. # TODO(robertwb): Finish this up, perhaps via more function refactoring.
error(self.pos, "static cpdef methods not yet supported") error(self.pos, "static cpdef methods not yet supported")
name = self.entry.name name = self.entry.name
py_func_body = self.call_self_node(is_module_scope = env.is_module_scope) py_func_body = self.call_self_node(is_module_scope=env.is_module_scope)
if self.is_static_method: if self.is_static_method:
from .ExprNodes import NameNode from .ExprNodes import NameNode
decorators = [DecoratorNode(self.pos, decorator=NameNode(self.pos, name='staticmethod'))] decorators = [DecoratorNode(self.pos, decorator=NameNode(self.pos, name='staticmethod'))]
decorators[0].decorator.analyse_types(env) decorators[0].decorator.analyse_types(env)
else: else:
decorators = [] decorators = []
self.py_func = DefNode(pos = self.pos, self.py_func = DefNode(pos=self.pos,
name = self.entry.name, name=self.entry.name,
args = self.args, args=self.args,
star_arg = None, star_arg=None,
starstar_arg = None, starstar_arg=None,
doc = self.doc, doc=self.doc,
body = py_func_body, body=py_func_body,
decorators = decorators, decorators=decorators,
is_wrapper = 1) is_wrapper=1)
self.py_func.is_module_scope = env.is_module_scope self.py_func.is_module_scope = env.is_module_scope
self.py_func.analyse_declarations(env) self.py_func.analyse_declarations(env)
self.py_func_stat = StatListNode(pos = self.pos, stats = [self.py_func]) self.py_func_stat = StatListNode(self.pos, stats=[self.py_func])
self.py_func.type = PyrexTypes.py_object_type self.py_func.type = PyrexTypes.py_object_type
self.entry.as_variable = self.py_func.entry self.entry.as_variable = self.py_func.entry
self.entry.used = self.entry.as_variable.used = True self.entry.used = self.entry.as_variable.used = True
# Reset scope entry the above cfunction # Reset scope entry the above cfunction
env.entries[name] = self.entry env.entries[name] = self.entry
if (not self.entry.is_final_cmethod and if (not self.entry.is_final_cmethod and
(not env.is_module_scope or Options.lookup_module_cpdef)): (not env.is_module_scope or Options.lookup_module_cpdef)):
self.override = OverrideCheckNode(self.pos, py_func = self.py_func) self.override = OverrideCheckNode(self.pos, py_func=self.py_func)
self.body = StatListNode(self.pos, stats=[self.override, self.body]) self.body = StatListNode(self.pos, stats=[self.override, self.body])
def _validate_type_visibility(self, type, pos, env): def _validate_type_visibility(self, type, pos, env):
...@@ -2408,8 +2394,7 @@ class CFuncDefNode(FuncDefNode): ...@@ -2408,8 +2394,7 @@ class CFuncDefNode(FuncDefNode):
if public_or_api and entry and env.is_module_scope: if public_or_api and entry and env.is_module_scope:
if not (entry.visibility in ('public', 'extern') or if not (entry.visibility in ('public', 'extern') or
entry.api or entry.in_cinclude): entry.api or entry.in_cinclude):
error(pos, "Function declared public or api may not have " error(pos, "Function declared public or api may not have private types")
"private types")
def call_self_node(self, omit_optional_args=0, is_module_scope=0): def call_self_node(self, omit_optional_args=0, is_module_scope=0):
from . import ExprNodes from . import ExprNodes
...@@ -2476,7 +2461,7 @@ class CFuncDefNode(FuncDefNode): ...@@ -2476,7 +2461,7 @@ class CFuncDefNode(FuncDefNode):
def needs_assignment_synthesis(self, env, code=None): def needs_assignment_synthesis(self, env, code=None):
return False return False
def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None): def generate_function_header(self, code, with_pymethdef, with_opt_args=1, with_dispatch=1, cname=None):
scope = self.local_scope scope = self.local_scope
arg_decls = [] arg_decls = []
type = self.type type = self.type
...@@ -2517,7 +2502,8 @@ class CFuncDefNode(FuncDefNode): ...@@ -2517,7 +2502,8 @@ class CFuncDefNode(FuncDefNode):
code.globalstate.parts['module_declarations'].putln(self.template_declaration) code.globalstate.parts['module_declarations'].putln(self.template_declaration)
code.putln(self.template_declaration) code.putln(self.template_declaration)
if needs_proto: if needs_proto:
code.globalstate.parts['module_declarations'].putln("%s%s%s; /* proto*/" % (storage_class, modifiers, header)) code.globalstate.parts['module_declarations'].putln(
"%s%s%s; /* proto*/" % (storage_class, modifiers, header))
code.putln("%s%s%s {" % (storage_class, modifiers, header)) code.putln("%s%s%s {" % (storage_class, modifiers, header))
def generate_argument_declarations(self, env, code): def generate_argument_declarations(self, env, code):
...@@ -2606,11 +2592,11 @@ class CFuncDefNode(FuncDefNode): ...@@ -2606,11 +2592,11 @@ class CFuncDefNode(FuncDefNode):
entry = entry.prev_entry entry = entry.prev_entry
entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k) entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
code.putln() code.putln()
self.generate_function_header(code, self.generate_function_header(
0, code, 0,
with_dispatch = entry.type.is_overridable, with_dispatch=entry.type.is_overridable,
with_opt_args = entry.type.optional_arg_count, with_opt_args=entry.type.optional_arg_count,
cname = entry.func_cname) cname=entry.func_cname)
if not self.return_type.is_void: if not self.return_type.is_void:
code.put('return ') code.put('return ')
args = self.type.args args = self.type.args
...@@ -2641,6 +2627,7 @@ class PyArgDeclNode(Node): ...@@ -2641,6 +2627,7 @@ class PyArgDeclNode(Node):
def generate_function_definitions(self, env, code): def generate_function_definitions(self, env, code):
self.entry.generate_function_definitions(env, code) self.entry.generate_function_definitions(env, code)
class DecoratorNode(Node): class DecoratorNode(Node):
# A decorator # A decorator
# #
...@@ -2717,18 +2704,18 @@ class DefNode(FuncDefNode): ...@@ -2717,18 +2704,18 @@ class DefNode(FuncDefNode):
cfunc_args = [] cfunc_args = []
for formal_arg in self.args: for formal_arg in self.args:
name_declarator, type = formal_arg.analyse(scope, nonempty=1) name_declarator, type = formal_arg.analyse(scope, nonempty=1)
cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name, cfunc_args.append(PyrexTypes.CFuncTypeArg(name=name_declarator.name,
cname = None, cname=None,
type = py_object_type, type=py_object_type,
pos = formal_arg.pos)) pos=formal_arg.pos))
cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type, cfunc_type = PyrexTypes.CFuncType(return_type=py_object_type,
args = cfunc_args, args=cfunc_args,
has_varargs = False, has_varargs=False,
exception_value = None, exception_value=None,
exception_check = False, exception_check=False,
nogil = False, nogil=False,
with_gil = False, with_gil=False,
is_overridable = overridable) is_overridable=overridable)
cfunc = CVarDefNode(self.pos, type=cfunc_type) cfunc = CVarDefNode(self.pos, type=cfunc_type)
else: else:
if scope is None: if scope is None:
...@@ -2739,7 +2726,7 @@ class DefNode(FuncDefNode): ...@@ -2739,7 +2726,7 @@ class DefNode(FuncDefNode):
error(cfunc.pos, "previous declaration here") error(cfunc.pos, "previous declaration here")
for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)): for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
name_declarator, type = formal_arg.analyse(scope, nonempty=1, name_declarator, type = formal_arg.analyse(scope, nonempty=1,
is_self_arg = (i == 0 and scope.is_c_class_scope)) is_self_arg=(i == 0 and scope.is_c_class_scope))
if type is None or type is PyrexTypes.py_object_type: if type is None or type is PyrexTypes.py_object_type:
formal_arg.type = type_arg.type formal_arg.type = type_arg.type
formal_arg.name_declarator = name_declarator formal_arg.name_declarator = name_declarator
...@@ -2747,29 +2734,30 @@ class DefNode(FuncDefNode): ...@@ -2747,29 +2734,30 @@ class DefNode(FuncDefNode):
if cfunc_type.exception_value is None: if cfunc_type.exception_value is None:
exception_value = None exception_value = None
else: else:
exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type) exception_value = ExprNodes.ConstNode(
self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
declarator = CFuncDeclaratorNode(self.pos, declarator = CFuncDeclaratorNode(self.pos,
base = CNameDeclaratorNode(self.pos, name=self.name, cname=None), base=CNameDeclaratorNode(self.pos, name=self.name, cname=None),
args = self.args, args=self.args,
has_varargs = False, has_varargs=False,
exception_check = cfunc_type.exception_check, exception_check=cfunc_type.exception_check,
exception_value = exception_value, exception_value=exception_value,
with_gil = cfunc_type.with_gil, with_gil=cfunc_type.with_gil,
nogil = cfunc_type.nogil) nogil=cfunc_type.nogil)
return CFuncDefNode(self.pos, return CFuncDefNode(self.pos,
modifiers = modifiers or [], modifiers=modifiers or [],
base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type), base_type=CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
declarator = declarator, declarator=declarator,
body = self.body, body=self.body,
doc = self.doc, doc=self.doc,
overridable = cfunc_type.is_overridable, overridable=cfunc_type.is_overridable,
type = cfunc_type, type=cfunc_type,
with_gil = cfunc_type.with_gil, with_gil=cfunc_type.with_gil,
nogil = cfunc_type.nogil, nogil=cfunc_type.nogil,
visibility = 'private', visibility='private',
api = False, api=False,
directive_locals = getattr(cfunc, 'directive_locals', {}), directive_locals=getattr(cfunc, 'directive_locals', {}),
directive_returns = returns) directive_returns=returns)
def is_cdef_func_compatible(self): def is_cdef_func_compatible(self):
"""Determines if the function's signature is compatible with a """Determines if the function's signature is compatible with a
...@@ -2850,8 +2838,7 @@ class DefNode(FuncDefNode): ...@@ -2850,8 +2838,7 @@ class DefNode(FuncDefNode):
self.align_argument_type(env, arg) self.align_argument_type(env, arg)
if name_declarator and name_declarator.cname: if name_declarator and name_declarator.cname:
error(self.pos, error(self.pos, "Python function argument cannot have C name specification")
"Python function argument cannot have C name specification")
arg.type = arg.type.as_argument_type() arg.type = arg.type.as_argument_type()
arg.hdr_type = None arg.hdr_type = None
arg.needs_conversion = 0 arg.needs_conversion = 0
...@@ -2863,7 +2850,7 @@ class DefNode(FuncDefNode): ...@@ -2863,7 +2850,7 @@ class DefNode(FuncDefNode):
elif arg.not_none: elif arg.not_none:
arg.accept_none = False arg.accept_none = False
elif (arg.type.is_extension_type or arg.type.is_builtin_type elif (arg.type.is_extension_type or arg.type.is_builtin_type
or arg.type.is_buffer or arg.type.is_memoryviewslice): or arg.type.is_buffer or arg.type.is_memoryviewslice):
if arg.default and arg.default.constant_result is None: if arg.default and arg.default.constant_result is None:
# special case: def func(MyType obj = None) # special case: def func(MyType obj = None)
arg.accept_none = True arg.accept_none = True
...@@ -2903,8 +2890,8 @@ class DefNode(FuncDefNode): ...@@ -2903,8 +2890,8 @@ class DefNode(FuncDefNode):
sig = self.entry.signature sig = self.entry.signature
nfixed = sig.num_fixed_args() nfixed = sig.num_fixed_args()
if sig is TypeSlots.pymethod_signature and nfixed == 1 \ if (sig is TypeSlots.pymethod_signature and nfixed == 1
and len(self.args) == 0 and self.star_arg: and len(self.args) == 0 and self.star_arg):
# this is the only case where a diverging number of # this is the only case where a diverging number of
# arguments is not an error - when we have no explicit # arguments is not an error - when we have no explicit
# 'self' parameter as in method(*args) # 'self' parameter as in method(*args)
...@@ -2922,7 +2909,7 @@ class DefNode(FuncDefNode): ...@@ -2922,7 +2909,7 @@ class DefNode(FuncDefNode):
sig.has_generic_args = True sig.has_generic_args = True
if ((self.is_classmethod or self.is_staticmethod) and if ((self.is_classmethod or self.is_staticmethod) and
self.has_fused_arguments and env.is_c_class_scope): self.has_fused_arguments and env.is_c_class_scope):
del self.decorator_indirection.stats[:] del self.decorator_indirection.stats[:]
for i in range(min(nfixed, len(self.args))): for i in range(min(nfixed, len(self.args))):
...@@ -2955,8 +2942,7 @@ class DefNode(FuncDefNode): ...@@ -2955,8 +2942,7 @@ class DefNode(FuncDefNode):
if not sig.has_generic_args: if not sig.has_generic_args:
self.bad_signature() self.bad_signature()
for arg in self.args: for arg in self.args:
if arg.is_generic and \ if arg.is_generic and (arg.type.is_extension_type or arg.type.is_builtin_type):
(arg.type.is_extension_type or arg.type.is_builtin_type):
arg.needs_type_test = 1 arg.needs_type_test = 1
def bad_signature(self): def bad_signature(self):
...@@ -2969,10 +2955,8 @@ class DefNode(FuncDefNode): ...@@ -2969,10 +2955,8 @@ class DefNode(FuncDefNode):
desc = "Special method" desc = "Special method"
else: else:
desc = "Method" desc = "Method"
error(self.pos, error(self.pos, "%s %s has wrong number of arguments (%d declared, %s expected)" % (
"%s %s has wrong number of arguments " desc, self.name, len(self.args), expected_str))
"(%d declared, %s expected)" % (
desc, self.name, len(self.args), expected_str))
def declare_pyfunction(self, env): def declare_pyfunction(self, env):
#print "DefNode.declare_pyfunction:", self.name, "in", env ### #print "DefNode.declare_pyfunction:", self.name, "in", env ###
...@@ -2981,8 +2965,7 @@ class DefNode(FuncDefNode): ...@@ -2981,8 +2965,7 @@ class DefNode(FuncDefNode):
if entry: if entry:
if entry.is_final_cmethod and not env.parent_type.is_final_type: if entry.is_final_cmethod and not env.parent_type.is_final_type:
error(self.pos, "Only final types can have final Python (def/cpdef) methods") error(self.pos, "Only final types can have final Python (def/cpdef) methods")
if (entry.type.is_cfunction and not entry.is_builtin_cmethod if entry.type.is_cfunction and not entry.is_builtin_cmethod and not self.is_wrapper:
and not self.is_wrapper):
warning(self.pos, "Overriding cdef method with def method.", 5) warning(self.pos, "Overriding cdef method with def method.", 5)
entry = env.declare_pyfunction(name, self.pos, allow_redefine=not self.is_wrapper) entry = env.declare_pyfunction(name, self.pos, allow_redefine=not self.is_wrapper)
self.entry = entry self.entry = entry
...@@ -2992,7 +2975,8 @@ class DefNode(FuncDefNode): ...@@ -2992,7 +2975,8 @@ class DefNode(FuncDefNode):
entry.doc = embed_position(self.pos, self.doc) entry.doc = embed_position(self.pos, self.doc)
entry.doc_cname = Naming.funcdoc_prefix + prefix + name entry.doc_cname = Naming.funcdoc_prefix + prefix + name
if entry.is_special: if entry.is_special:
if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']): if entry.name in TypeSlots.invisible or not entry.doc or (
entry.name in '__getattr__' and env.directives['fast_getattr']):
entry.wrapperbase_cname = None entry.wrapperbase_cname = None
else: else:
entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
...@@ -3314,14 +3298,14 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3314,14 +3298,14 @@ class DefNodeWrapper(FuncDefNode):
arg_code_list.append("CYTHON_UNUSED PyObject *unused") arg_code_list.append("CYTHON_UNUSED PyObject *unused")
if sig.has_generic_args: if sig.has_generic_args:
arg_code_list.append( arg_code_list.append(
"PyObject *%s, PyObject *%s" "PyObject *%s, PyObject *%s" % (
% (Naming.args_cname, Naming.kwds_cname)) Naming.args_cname, Naming.kwds_cname))
arg_code = ", ".join(arg_code_list) arg_code = ", ".join(arg_code_list)
# Prevent warning: unused function '__pyx_pw_5numpy_7ndarray_1__getbuffer__' # Prevent warning: unused function '__pyx_pw_5numpy_7ndarray_1__getbuffer__'
mf = "" mf = ""
if (entry.name in ("__getbuffer__", "__releasebuffer__") if (entry.name in ("__getbuffer__", "__releasebuffer__")
and entry.scope.is_c_class_scope): and entry.scope.is_c_class_scope):
mf = "CYTHON_UNUSED " mf = "CYTHON_UNUSED "
with_pymethdef = False with_pymethdef = False
...@@ -3335,7 +3319,7 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3335,7 +3319,7 @@ class DefNodeWrapper(FuncDefNode):
# want the prototype for the "fused cpdef", in case we're # want the prototype for the "fused cpdef", in case we're
# checking to see if our method was overridden in Python # checking to see if our method was overridden in Python
self.target.fused_py_func.generate_function_header( self.target.fused_py_func.generate_function_header(
code, with_pymethdef, proto_only=True) code, with_pymethdef, proto_only=True)
return return
if (Options.docstrings and entry.doc and if (Options.docstrings and entry.doc and
...@@ -3361,8 +3345,7 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3361,8 +3345,7 @@ class DefNodeWrapper(FuncDefNode):
if with_pymethdef or self.target.fused_py_func: if with_pymethdef or self.target.fused_py_func:
code.put( code.put(
"static PyMethodDef %s = " % "static PyMethodDef %s = " % entry.pymethdef_cname)
entry.pymethdef_cname)
code.put_pymethoddef(self.target.entry, ";", allow_skip=False) code.put_pymethoddef(self.target.entry, ";", allow_skip=False)
code.putln("%s {" % header) code.putln("%s {" % header)
...@@ -3391,7 +3374,7 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3391,7 +3374,7 @@ class DefNodeWrapper(FuncDefNode):
for arg in self.args: for arg in self.args:
if not arg.type.is_pyobject: if not arg.type.is_pyobject:
if not arg.type.create_from_py_utility_code(env): if not arg.type.create_from_py_utility_code(env):
pass # will fail later pass # will fail later
if not self.signature_has_generic_args(): if not self.signature_has_generic_args():
if has_star_or_kw_args: if has_star_or_kw_args:
...@@ -3438,7 +3421,7 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3438,7 +3421,7 @@ class DefNodeWrapper(FuncDefNode):
code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" % code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
Naming.args_cname) Naming.args_cname)
code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % ( code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
self.name, Naming.args_cname, self.error_value())) self.name, Naming.args_cname, self.error_value()))
code.putln("}") code.putln("}")
if self.starstar_arg: if self.starstar_arg:
...@@ -3460,10 +3443,10 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3460,10 +3443,10 @@ class DefNodeWrapper(FuncDefNode):
if all(ref.node.allow_null for ref in self.starstar_arg.entry.cf_references): if all(ref.node.allow_null for ref in self.starstar_arg.entry.cf_references):
code.putln("if (%s) {" % kwarg_check) code.putln("if (%s) {" % kwarg_check)
code.putln("%s = PyDict_Copy(%s); if (unlikely(!%s)) return %s;" % ( code.putln("%s = PyDict_Copy(%s); if (unlikely(!%s)) return %s;" % (
self.starstar_arg.entry.cname, self.starstar_arg.entry.cname,
Naming.kwds_cname, Naming.kwds_cname,
self.starstar_arg.entry.cname, self.starstar_arg.entry.cname,
self.error_value())) self.error_value()))
code.put_gotref(self.starstar_arg.entry.cname) code.put_gotref(self.starstar_arg.entry.cname)
code.putln("} else {") code.putln("} else {")
code.putln("%s = NULL;" % (self.starstar_arg.entry.cname,)) code.putln("%s = NULL;" % (self.starstar_arg.entry.cname,))
...@@ -3471,20 +3454,20 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3471,20 +3454,20 @@ class DefNodeWrapper(FuncDefNode):
self.starstar_arg.entry.xdecref_cleanup = 1 self.starstar_arg.entry.xdecref_cleanup = 1
else: else:
code.put("%s = (%s) ? PyDict_Copy(%s) : PyDict_New(); " % ( code.put("%s = (%s) ? PyDict_Copy(%s) : PyDict_New(); " % (
self.starstar_arg.entry.cname, self.starstar_arg.entry.cname,
Naming.kwds_cname, Naming.kwds_cname,
Naming.kwds_cname)) Naming.kwds_cname))
code.putln("if (unlikely(!%s)) return %s;" % ( code.putln("if (unlikely(!%s)) return %s;" % (
self.starstar_arg.entry.cname, self.error_value())) self.starstar_arg.entry.cname, self.error_value()))
self.starstar_arg.entry.xdecref_cleanup = 0 self.starstar_arg.entry.xdecref_cleanup = 0
code.put_gotref(self.starstar_arg.entry.cname) code.put_gotref(self.starstar_arg.entry.cname)
if self.self_in_stararg and not self.target.is_staticmethod: if self.self_in_stararg and not self.target.is_staticmethod:
# need to create a new tuple with 'self' inserted as first item # need to create a new tuple with 'self' inserted as first item
code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % ( code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
self.star_arg.entry.cname, self.star_arg.entry.cname,
Naming.args_cname, Naming.args_cname,
self.star_arg.entry.cname)) self.star_arg.entry.cname))
if self.starstar_arg and self.starstar_arg.entry.cf_used: if self.starstar_arg and self.starstar_arg.entry.cf_used:
code.putln("{") code.putln("{")
code.put_xdecref_clear(self.starstar_arg.entry.cname, py_object_type) code.put_xdecref_clear(self.starstar_arg.entry.cname, py_object_type)
...@@ -3512,8 +3495,8 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3512,8 +3495,8 @@ class DefNodeWrapper(FuncDefNode):
elif self.star_arg: elif self.star_arg:
code.put_incref(Naming.args_cname, py_object_type) code.put_incref(Naming.args_cname, py_object_type)
code.putln("%s = %s;" % ( code.putln("%s = %s;" % (
self.star_arg.entry.cname, self.star_arg.entry.cname,
Naming.args_cname)) Naming.args_cname))
self.star_arg.entry.xdecref_cleanup = 0 self.star_arg.entry.xdecref_cleanup = 0
def generate_tuple_and_keyword_parsing_code(self, args, success_label, code): def generate_tuple_and_keyword_parsing_code(self, args, success_label, code):
...@@ -3558,8 +3541,8 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3558,8 +3541,8 @@ class DefNodeWrapper(FuncDefNode):
all_args = tuple(positional_args) + tuple(kw_only_args) all_args = tuple(positional_args) + tuple(kw_only_args)
code.putln("static PyObject **%s[] = {%s,0};" % ( code.putln("static PyObject **%s[] = {%s,0};" % (
Naming.pykwdlist_cname, Naming.pykwdlist_cname,
','.join([ '&%s' % code.intern_identifier(arg.name) ','.join(['&%s' % code.intern_identifier(arg.name)
for arg in all_args ]))) for arg in all_args])))
# Before being converted and assigned to the target variables, # Before being converted and assigned to the target variables,
# borrowed references to all unpacked argument values are # borrowed references to all unpacked argument values are
...@@ -3589,14 +3572,14 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3589,14 +3572,14 @@ class DefNodeWrapper(FuncDefNode):
else: else:
compare = '<' compare = '<'
code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % ( code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
Naming.args_cname, compare, min_positional_args)) Naming.args_cname, compare, min_positional_args))
code.put_goto(argtuple_error_label) code.put_goto(argtuple_error_label)
if self.num_required_kw_args: if self.num_required_kw_args:
# pure error case: keywords required but not passed # pure error case: keywords required but not passed
if max_positional_args > min_positional_args and not self.star_arg: if max_positional_args > min_positional_args and not self.star_arg:
code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % ( code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
Naming.args_cname, max_positional_args)) Naming.args_cname, max_positional_args))
code.put_goto(argtuple_error_label) code.put_goto(argtuple_error_label)
code.putln('} else {') code.putln('} else {')
for i, arg in enumerate(kw_only_args): for i, arg in enumerate(kw_only_args):
...@@ -3604,8 +3587,8 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3604,8 +3587,8 @@ class DefNodeWrapper(FuncDefNode):
pystring_cname = code.intern_identifier(arg.name) pystring_cname = code.intern_identifier(arg.name)
# required keyword-only argument missing # required keyword-only argument missing
code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % ( code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
self.name, self.name,
pystring_cname)) pystring_cname))
code.putln(code.error_goto(self.pos)) code.putln(code.error_goto(self.pos))
break break
...@@ -3657,9 +3640,9 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3657,9 +3640,9 @@ class DefNodeWrapper(FuncDefNode):
code.globalstate.use_utility_code( code.globalstate.use_utility_code(
UtilityCode.load_cached("RaiseArgTupleInvalid", "FunctionArguments.c")) UtilityCode.load_cached("RaiseArgTupleInvalid", "FunctionArguments.c"))
code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % ( code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
self.name, has_fixed_positional_count, self.name, has_fixed_positional_count,
min_positional_args, max_positional_args, min_positional_args, max_positional_args,
Naming.args_cname)) Naming.args_cname))
code.putln(code.error_goto(self.pos)) code.putln(code.error_goto(self.pos))
def generate_arg_assignment(self, arg, item, code): def generate_arg_assignment(self, arg, item, code):
...@@ -3684,10 +3667,9 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3684,10 +3667,9 @@ class DefNodeWrapper(FuncDefNode):
code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos))) code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
if arg.default: if arg.default:
code.putln('} else {') code.putln('} else {')
code.putln( code.putln("%s = %s;" % (
"%s = %s;" % ( arg.entry.cname,
arg.entry.cname, arg.calculate_default_value_code(code)))
arg.calculate_default_value_code(code)))
if arg.type.is_memoryviewslice: if arg.type.is_memoryviewslice:
code.put_incref_memoryviewslice(arg.entry.cname, code.put_incref_memoryviewslice(arg.entry.cname,
have_gil=True) have_gil=True)
...@@ -3699,18 +3681,18 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3699,18 +3681,18 @@ class DefNodeWrapper(FuncDefNode):
if self.starstar_arg: if self.starstar_arg:
self.starstar_arg.entry.xdecref_cleanup = 0 self.starstar_arg.entry.xdecref_cleanup = 0
code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % ( code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
self.starstar_arg.entry.cname, self.starstar_arg.entry.cname,
self.starstar_arg.entry.cname, self.starstar_arg.entry.cname,
self.error_value())) self.error_value()))
code.put_gotref(self.starstar_arg.entry.cname) code.put_gotref(self.starstar_arg.entry.cname)
if self.star_arg: if self.star_arg:
self.star_arg.entry.xdecref_cleanup = 0 self.star_arg.entry.xdecref_cleanup = 0
code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % ( code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
Naming.args_cname, Naming.args_cname,
max_positional_args)) max_positional_args))
code.putln('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s));' % ( code.putln('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s));' % (
self.star_arg.entry.cname, Naming.args_cname, self.star_arg.entry.cname, Naming.args_cname,
max_positional_args, Naming.args_cname)) max_positional_args, Naming.args_cname))
code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname) code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
if self.starstar_arg: if self.starstar_arg:
code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type) code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
...@@ -3754,7 +3736,7 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3754,7 +3736,7 @@ class DefNodeWrapper(FuncDefNode):
for i in range(max_positional_args-1, -1, -1): for i in range(max_positional_args-1, -1, -1):
code.put('case %2d: ' % (i+1)) code.put('case %2d: ' % (i+1))
code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % ( code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
i, Naming.args_cname, i)) i, Naming.args_cname, i))
code.putln('case 0: break;') code.putln('case 0: break;')
if not self.star_arg: if not self.star_arg:
code.put('default: ') # more arguments than allowed code.put('default: ') # more arguments than allowed
...@@ -3813,14 +3795,14 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3813,14 +3795,14 @@ class DefNodeWrapper(FuncDefNode):
code.globalstate.use_utility_code( code.globalstate.use_utility_code(
UtilityCode.load_cached("RaiseArgTupleInvalid", "FunctionArguments.c")) UtilityCode.load_cached("RaiseArgTupleInvalid", "FunctionArguments.c"))
code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % ( code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
self.name, has_fixed_positional_count, self.name, has_fixed_positional_count,
min_positional_args, max_positional_args, i)) min_positional_args, max_positional_args, i))
code.putln(code.error_goto(self.pos)) code.putln(code.error_goto(self.pos))
code.putln('}') code.putln('}')
elif arg.kw_only: elif arg.kw_only:
code.putln('else {') code.putln('else {')
code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %( code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
self.name, pystring_cname)) self.name, pystring_cname))
code.putln(code.error_goto(self.pos)) code.putln(code.error_goto(self.pos))
code.putln('}') code.putln('}')
if max_positional_args > 0: if max_positional_args > 0:
...@@ -3843,20 +3825,19 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3843,20 +3825,19 @@ class DefNodeWrapper(FuncDefNode):
pos_arg_count = "0" pos_arg_count = "0"
elif self.star_arg: elif self.star_arg:
code.putln("const Py_ssize_t used_pos_args = (pos_args < %d) ? pos_args : %d;" % ( code.putln("const Py_ssize_t used_pos_args = (pos_args < %d) ? pos_args : %d;" % (
max_positional_args, max_positional_args)) max_positional_args, max_positional_args))
pos_arg_count = "used_pos_args" pos_arg_count = "used_pos_args"
else: else:
pos_arg_count = "pos_args" pos_arg_count = "pos_args"
code.globalstate.use_utility_code( code.globalstate.use_utility_code(
UtilityCode.load_cached("ParseKeywords", "FunctionArguments.c")) UtilityCode.load_cached("ParseKeywords", "FunctionArguments.c"))
code.putln( code.putln('if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) %s' % (
'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) %s' % ( Naming.kwds_cname,
Naming.kwds_cname, Naming.pykwdlist_cname,
Naming.pykwdlist_cname, self.starstar_arg and self.starstar_arg.entry.cname or '0',
self.starstar_arg and self.starstar_arg.entry.cname or '0', pos_arg_count,
pos_arg_count, self.name,
self.name, code.error_goto(self.pos)))
code.error_goto(self.pos)))
code.putln('}') code.putln('}')
def generate_optional_kwonly_args_unpacking_code(self, all_args, code): def generate_optional_kwonly_args_unpacking_code(self, all_args, code):
...@@ -3913,12 +3894,9 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3913,12 +3894,9 @@ class DefNodeWrapper(FuncDefNode):
self.generate_arg_conversion_to_pyobject(arg, code) self.generate_arg_conversion_to_pyobject(arg, code)
else: else:
if new_type.assignable_from(old_type): if new_type.assignable_from(old_type):
code.putln( code.putln("%s = %s;" % (arg.entry.cname, arg.hdr_cname))
"%s = %s;" % (arg.entry.cname, arg.hdr_cname))
else: else:
error(arg.pos, error(arg.pos, "Cannot convert 1 argument from '%s' to '%s'" % (old_type, new_type))
"Cannot convert 1 argument from '%s' to '%s'" %
(old_type, new_type))
def generate_arg_conversion_from_pyobject(self, arg, code): def generate_arg_conversion_from_pyobject(self, arg, code):
new_type = arg.type new_type = arg.type
...@@ -3934,9 +3912,7 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3934,9 +3912,7 @@ class DefNodeWrapper(FuncDefNode):
rhs, rhs,
code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos))) code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
else: else:
error(arg.pos, error(arg.pos, "Cannot convert Python object argument to type '%s'" % new_type)
"Cannot convert Python object argument to type '%s'"
% new_type)
def generate_arg_conversion_to_pyobject(self, arg, code): def generate_arg_conversion_to_pyobject(self, arg, code):
old_type = arg.hdr_type old_type = arg.hdr_type
...@@ -3949,9 +3925,7 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3949,9 +3925,7 @@ class DefNodeWrapper(FuncDefNode):
code.error_goto_if_null(arg.entry.cname, arg.pos))) code.error_goto_if_null(arg.entry.cname, arg.pos)))
code.put_var_gotref(arg.entry) code.put_var_gotref(arg.entry)
else: else:
error(arg.pos, error(arg.pos, "Cannot convert argument of type '%s' to Python object" % old_type)
"Cannot convert argument of type '%s' to Python object"
% old_type)
def generate_argument_type_tests(self, code): def generate_argument_type_tests(self, code):
# Generate type tests for args whose signature # Generate type tests for args whose signature
...@@ -4199,12 +4173,12 @@ class OverrideCheckNode(StatNode): ...@@ -4199,12 +4173,12 @@ class OverrideCheckNode(StatNode):
self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type) self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
call_node = ExprNodes.SimpleCallNode( call_node = ExprNodes.SimpleCallNode(
self.pos, function=self.func_node, self.pos, function=self.func_node,
args=[ ExprNodes.NameNode(self.pos, name=arg.name) args=[ExprNodes.NameNode(self.pos, name=arg.name)
for arg in self.args[first_arg:] ]) for arg in self.args[first_arg:]])
if env.return_type.is_void or env.return_type.is_returncode: if env.return_type.is_void or env.return_type.is_returncode:
self.body = StatListNode(self.pos, stats=[ self.body = StatListNode(self.pos, stats=[
ExprStatNode(self.pos, expr=call_node), ExprStatNode(self.pos, expr=call_node),
ReturnStatNode(self.pos, value=None)]) ReturnStatNode(self.pos, value=None)])
else: else:
self.body = ReturnStatNode(self.pos, value=call_node) self.body = ReturnStatNode(self.pos, value=call_node)
self.body = self.body.analyse_expressions(env) self.body = self.body.analyse_expressions(env)
...@@ -4378,21 +4352,21 @@ class PyClassDefNode(ClassDefNode): ...@@ -4378,21 +4352,21 @@ class PyClassDefNode(ClassDefNode):
return None return None
return CClassDefNode(self.pos, return CClassDefNode(self.pos,
visibility = 'private', visibility='private',
module_name = None, module_name=None,
class_name = self.name, class_name=self.name,
base_class_module = base_class_module, base_class_module=base_class_module,
base_class_name = base_class_name, base_class_name=base_class_name,
decorators = self.decorators, decorators=self.decorators,
body = self.body, body=self.body,
in_pxd = False, in_pxd=False,
doc = self.doc) doc=self.doc)
def create_scope(self, env): def create_scope(self, env):
genv = env genv = env
while genv.is_py_class_scope or genv.is_c_class_scope: while genv.is_py_class_scope or genv.is_c_class_scope:
genv = genv.outer_scope genv = genv.outer_scope
cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv) cenv = self.scope = PyClassScope(name=self.name, outer_scope=genv)
return cenv return cenv
def analyse_declarations(self, env): def analyse_declarations(self, env):
...@@ -4402,8 +4376,8 @@ class PyClassDefNode(ClassDefNode): ...@@ -4402,8 +4376,8 @@ class PyClassDefNode(ClassDefNode):
for decorator in self.decorators[::-1]: for decorator in self.decorators[::-1]:
class_result = SimpleCallNode( class_result = SimpleCallNode(
decorator.pos, decorator.pos,
function = decorator.decorator, function=decorator.decorator,
args = [class_result]) args=[class_result])
self.decorators = None self.decorators = None
self.class_result = class_result self.class_result = class_result
self.class_result.analyse_declarations(env) self.class_result.analyse_declarations(env)
...@@ -4422,7 +4396,6 @@ class PyClassDefNode(ClassDefNode): ...@@ -4422,7 +4396,6 @@ class PyClassDefNode(ClassDefNode):
self.mkw = self.mkw.analyse_expressions(env) self.mkw = self.mkw.analyse_expressions(env)
self.dict = self.dict.analyse_expressions(env) self.dict = self.dict.analyse_expressions(env)
self.class_result = self.class_result.analyse_expressions(env) self.class_result = self.class_result.analyse_expressions(env)
genv = env.global_scope()
cenv = self.scope cenv = self.scope
self.body = self.body.analyse_expressions(cenv) self.body = self.body.analyse_expressions(cenv)
self.target.analyse_target_expression(env, self.classobj) self.target.analyse_target_expression(env, self.classobj)
...@@ -4520,19 +4493,19 @@ class CClassDefNode(ClassDefNode): ...@@ -4520,19 +4493,19 @@ class CClassDefNode(ClassDefNode):
home_scope = env home_scope = env
self.entry = home_scope.declare_c_class( self.entry = home_scope.declare_c_class(
name = self.class_name, name=self.class_name,
pos = self.pos, pos=self.pos,
defining = 0, defining=0,
implementing = 0, implementing=0,
module_name = self.module_name, module_name=self.module_name,
base_type = None, base_type=None,
objstruct_cname = self.objstruct_name, objstruct_cname=self.objstruct_name,
typeobj_cname = self.typeobj_name, typeobj_cname=self.typeobj_name,
visibility = self.visibility, visibility=self.visibility,
typedef_flag = self.typedef_flag, typedef_flag=self.typedef_flag,
api = self.api, api=self.api,
buffer_defaults = self.buffer_defaults(env), buffer_defaults=self.buffer_defaults(env),
shadow = self.shadow) shadow=self.shadow)
def analyse_declarations(self, env): def analyse_declarations(self, env):
#print "CClassDefNode.analyse_declarations:", self.class_name #print "CClassDefNode.analyse_declarations:", self.class_name
...@@ -4540,11 +4513,9 @@ class CClassDefNode(ClassDefNode): ...@@ -4540,11 +4513,9 @@ class CClassDefNode(ClassDefNode):
#print "...module_name =", self.module_name #print "...module_name =", self.module_name
if env.in_cinclude and not self.objstruct_name: if env.in_cinclude and not self.objstruct_name:
error(self.pos, "Object struct name specification required for " error(self.pos, "Object struct name specification required for C class defined in 'extern from' block")
"C class defined in 'extern from' block")
if self.decorators: if self.decorators:
error(self.pos, error(self.pos, "Decorators not allowed on cdef classes (used on type '%s')" % self.class_name)
"Decorators not allowed on cdef classes (used on type '%s')" % self.class_name)
self.base_type = None self.base_type = None
# Now that module imports are cached, we need to # Now that module imports are cached, we need to
# import the modules for extern classes. # import the modules for extern classes.
...@@ -4611,24 +4582,24 @@ class CClassDefNode(ClassDefNode): ...@@ -4611,24 +4582,24 @@ class CClassDefNode(ClassDefNode):
if self.visibility == 'extern': if self.visibility == 'extern':
if (self.module_name == '__builtin__' and if (self.module_name == '__builtin__' and
self.class_name in Builtin.builtin_types and self.class_name in Builtin.builtin_types and
env.qualified_name[:8] != 'cpython.'): # allow overloaded names for cimporting from cpython env.qualified_name[:8] != 'cpython.'): # allow overloaded names for cimporting from cpython
warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1) warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
self.entry = home_scope.declare_c_class( self.entry = home_scope.declare_c_class(
name = self.class_name, name=self.class_name,
pos = self.pos, pos=self.pos,
defining = has_body and self.in_pxd, defining=has_body and self.in_pxd,
implementing = has_body and not self.in_pxd, implementing=has_body and not self.in_pxd,
module_name = self.module_name, module_name=self.module_name,
base_type = self.base_type, base_type=self.base_type,
objstruct_cname = self.objstruct_name, objstruct_cname=self.objstruct_name,
typeobj_cname = self.typeobj_name, typeobj_cname=self.typeobj_name,
visibility = self.visibility, visibility=self.visibility,
typedef_flag = self.typedef_flag, typedef_flag=self.typedef_flag,
api = self.api, api=self.api,
buffer_defaults = self.buffer_defaults(env), buffer_defaults=self.buffer_defaults(env),
shadow = self.shadow) shadow=self.shadow)
if self.shadow: if self.shadow:
home_scope.lookup(self.class_name).as_variable = self.entry home_scope.lookup(self.class_name).as_variable = self.entry
...@@ -4760,11 +4731,11 @@ class ExprStatNode(StatNode): ...@@ -4760,11 +4731,11 @@ class ExprStatNode(StatNode):
if type is None: if type is None:
error(type_node.pos, "Unknown type") error(type_node.pos, "Unknown type")
else: else:
env.declare_var(var.value, type, var.pos, is_cdef = True) env.declare_var(var.value, type, var.pos, is_cdef=True)
self.__class__ = PassStatNode self.__class__ = PassStatNode
def analyse_expressions(self, env): def analyse_expressions(self, env):
self.expr.result_is_used = False # hint that .result() may safely be left empty self.expr.result_is_used = False # hint that .result() may safely be left empty
self.expr = self.expr.analyse_expressions(env) self.expr = self.expr.analyse_expressions(env)
return self return self
...@@ -5242,13 +5213,13 @@ class ParallelAssignmentNode(AssignmentNode): ...@@ -5242,13 +5213,13 @@ class ParallelAssignmentNode(AssignmentNode):
stat.analyse_declarations(env) stat.analyse_declarations(env)
def analyse_expressions(self, env): def analyse_expressions(self, env):
self.stats = [ stat.analyse_types(env, use_temp = 1) self.stats = [stat.analyse_types(env, use_temp=1)
for stat in self.stats ] for stat in self.stats]
return self return self
# def analyse_expressions(self, env): # def analyse_expressions(self, env):
# for stat in self.stats: # for stat in self.stats:
# stat.analyse_expressions_1(env, use_temp = 1) # stat.analyse_expressions_1(env, use_temp=1)
# for stat in self.stats: # for stat in self.stats:
# stat.analyse_expressions_2(env) # stat.analyse_expressions_2(env)
...@@ -5429,11 +5400,10 @@ class ExecStatNode(StatNode): ...@@ -5429,11 +5400,10 @@ class ExecStatNode(StatNode):
args = [] args = []
for arg in self.args: for arg in self.args:
arg.generate_evaluation_code(code) arg.generate_evaluation_code(code)
args.append( arg.py_result() ) args.append(arg.py_result())
args = tuple(args + ['0', '0'][:3-len(args)]) args = tuple(args + ['0', '0'][:3-len(args)])
temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True) temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
code.putln("%s = __Pyx_PyExec3(%s, %s, %s);" % ( code.putln("%s = __Pyx_PyExec3(%s, %s, %s);" % ((temp_result,) + args))
(temp_result,) + args))
for arg in self.args: for arg in self.args:
arg.generate_disposal_code(code) arg.generate_disposal_code(code)
arg.free_temps(code) arg.free_temps(code)
...@@ -5463,8 +5433,7 @@ class DelStatNode(StatNode): ...@@ -5463,8 +5433,7 @@ class DelStatNode(StatNode):
def analyse_expressions(self, env): def analyse_expressions(self, env):
for i, arg in enumerate(self.args): for i, arg in enumerate(self.args):
arg = self.args[i] = arg.analyse_target_expression(env, None) arg = self.args[i] = arg.analyse_target_expression(env, None)
if arg.type.is_pyobject or (arg.is_name and if arg.type.is_pyobject or (arg.is_name and arg.type.is_memoryviewslice):
arg.type.is_memoryviewslice):
if arg.is_name and arg.entry.is_cglobal: if arg.is_name and arg.entry.is_cglobal:
error(arg.pos, "Deletion of global C variable") error(arg.pos, "Deletion of global C variable")
elif arg.type.is_ptr and arg.type.base_type.is_cpp_class: elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
...@@ -5579,15 +5548,14 @@ class ReturnStatNode(StatNode): ...@@ -5579,15 +5548,14 @@ class ReturnStatNode(StatNode):
if self.value: if self.value:
self.value = self.value.analyse_types(env) self.value = self.value.analyse_types(env)
if return_type.is_void or return_type.is_returncode: if return_type.is_void or return_type.is_returncode:
error(self.value.pos, error(self.value.pos, "Return with value in void function")
"Return with value in void function")
else: else:
self.value = self.value.coerce_to(env.return_type, env) self.value = self.value.coerce_to(env.return_type, env)
else: else:
if (not return_type.is_void if (not return_type.is_void
and not return_type.is_pyobject and not return_type.is_pyobject
and not return_type.is_returncode): and not return_type.is_returncode):
error(self.pos, "Return value required") error(self.pos, "Return value required")
return self return self
def nogil_check(self, env): def nogil_check(self, env):
...@@ -5610,12 +5578,12 @@ class ReturnStatNode(StatNode): ...@@ -5610,12 +5578,12 @@ class ReturnStatNode(StatNode):
if self.return_type.is_memoryviewslice: if self.return_type.is_memoryviewslice:
from . import MemoryView from . import MemoryView
MemoryView.put_acquire_memoryviewslice( MemoryView.put_acquire_memoryviewslice(
lhs_cname=Naming.retval_cname, lhs_cname=Naming.retval_cname,
lhs_type=self.return_type, lhs_type=self.return_type,
lhs_pos=self.value.pos, lhs_pos=self.value.pos,
rhs=self.value, rhs=self.value,
code=code, code=code,
have_gil=self.in_nogil_context) have_gil=self.in_nogil_context)
elif self.in_generator: elif self.in_generator:
# return value == raise StopIteration(value), but uncatchable # return value == raise StopIteration(value), but uncatchable
code.globalstate.use_utility_code( code.globalstate.use_utility_code(
...@@ -5626,10 +5594,9 @@ class ReturnStatNode(StatNode): ...@@ -5626,10 +5594,9 @@ class ReturnStatNode(StatNode):
self.value.generate_disposal_code(code) self.value.generate_disposal_code(code)
else: else:
self.value.make_owned_reference(code) self.value.make_owned_reference(code)
code.putln( code.putln("%s = %s;" % (
"%s = %s;" % ( Naming.retval_cname,
Naming.retval_cname, self.value.result_as(self.return_type)))
self.value.result_as(self.return_type)))
self.value.generate_post_assignment_code(code) self.value.generate_post_assignment_code(code)
self.value.free_temps(code) self.value.free_temps(code)
else: else:
...@@ -5690,9 +5657,8 @@ class RaiseStatNode(StatNode): ...@@ -5690,9 +5657,8 @@ class RaiseStatNode(StatNode):
exc = self.exc_type exc = self.exc_type
from . import ExprNodes from . import ExprNodes
if (isinstance(exc, ExprNodes.SimpleCallNode) and if (isinstance(exc, ExprNodes.SimpleCallNode) and
not (exc.args or (exc.arg_tuple is not None and not (exc.args or (exc.arg_tuple is not None and exc.arg_tuple.args))):
exc.arg_tuple.args))): exc = exc.function # extract the exception type
exc = exc.function # extract the exception type
if exc.is_name and exc.entry.is_builtin: if exc.is_name and exc.entry.is_builtin:
self.builtin_exc_name = exc.name self.builtin_exc_name = exc.name
if self.builtin_exc_name == 'MemoryError': if self.builtin_exc_name == 'MemoryError':
...@@ -5823,20 +5789,18 @@ class AssertStatNode(StatNode): ...@@ -5823,20 +5789,18 @@ class AssertStatNode(StatNode):
code.mark_pos(self.pos) code.mark_pos(self.pos)
self.cond.generate_evaluation_code(code) self.cond.generate_evaluation_code(code)
code.putln( code.putln(
"if (unlikely(!%s)) {" % "if (unlikely(!%s)) {" % self.cond.result())
self.cond.result())
if self.value: if self.value:
self.value.generate_evaluation_code(code) self.value.generate_evaluation_code(code)
code.putln( code.putln(
"PyErr_SetObject(PyExc_AssertionError, %s);" % "PyErr_SetObject(PyExc_AssertionError, %s);" % self.value.py_result())
self.value.py_result())
self.value.generate_disposal_code(code) self.value.generate_disposal_code(code)
self.value.free_temps(code) self.value.free_temps(code)
else: else:
code.putln( code.putln(
"PyErr_SetNone(PyExc_AssertionError);") "PyErr_SetNone(PyExc_AssertionError);")
code.putln( code.putln(
code.error_goto(self.pos)) code.error_goto(self.pos))
code.putln( code.putln(
"}") "}")
self.cond.generate_disposal_code(code) self.cond.generate_disposal_code(code)
...@@ -6045,8 +6009,7 @@ class WhileStatNode(LoopNode, StatNode): ...@@ -6045,8 +6009,7 @@ class WhileStatNode(LoopNode, StatNode):
self.condition.generate_evaluation_code(code) self.condition.generate_evaluation_code(code)
self.condition.generate_disposal_code(code) self.condition.generate_disposal_code(code)
code.putln( code.putln(
"if (!%s) break;" % "if (!%s) break;" % self.condition.result())
self.condition.result())
self.condition.free_temps(code) self.condition.free_temps(code)
self.body.generate_execution_code(code) self.body.generate_execution_code(code)
code.put_label(code.continue_label) code.put_label(code.continue_label)
...@@ -6091,15 +6054,15 @@ class DictIterationNextNode(Node): ...@@ -6091,15 +6054,15 @@ class DictIterationNextNode(Node):
key_target, value_target, tuple_target, is_dict_flag): key_target, value_target, tuple_target, is_dict_flag):
Node.__init__( Node.__init__(
self, dict_obj.pos, self, dict_obj.pos,
dict_obj = dict_obj, dict_obj=dict_obj,
expected_size = expected_size, expected_size=expected_size,
pos_index_var = pos_index_var, pos_index_var=pos_index_var,
key_target = key_target, key_target=key_target,
value_target = value_target, value_target=value_target,
tuple_target = tuple_target, tuple_target=tuple_target,
is_dict_flag = is_dict_flag, is_dict_flag=is_dict_flag,
is_temp = True, is_temp=True,
type = PyrexTypes.c_bint_type) type=PyrexTypes.c_bint_type)
def analyse_expressions(self, env): def analyse_expressions(self, env):
from . import ExprNodes from . import ExprNodes
...@@ -6350,7 +6313,8 @@ class ForFromStatNode(LoopNode, StatNode): ...@@ -6350,7 +6313,8 @@ class ForFromStatNode(LoopNode, StatNode):
self.bound2 = self.bound2.analyse_types(env) self.bound2 = self.bound2.analyse_types(env)
if self.step is not None: if self.step is not None:
if isinstance(self.step, ExprNodes.UnaryMinusNode): if isinstance(self.step, ExprNodes.UnaryMinusNode):
warning(self.step.pos, "Probable infinite loop in for-from-by statement. Consider switching the directions of the relations.", 2) warning(self.step.pos, "Probable infinite loop in for-from-by statement. "
"Consider switching the directions of the relations.", 2)
self.step = self.step.analyse_types(env) self.step = self.step.analyse_types(env)
if self.target.type.is_numeric: if self.target.type.is_numeric:
...@@ -6374,8 +6338,7 @@ class ForFromStatNode(LoopNode, StatNode): ...@@ -6374,8 +6338,7 @@ class ForFromStatNode(LoopNode, StatNode):
target_type = self.target.type target_type = self.target.type
if not (target_type.is_pyobject or target_type.is_numeric): if not (target_type.is_pyobject or target_type.is_numeric):
error(self.target.pos, error(self.target.pos, "for-from loop variable must be c numeric type or Python object")
"for-from loop variable must be c numeric type or Python object")
if target_type.is_numeric: if target_type.is_numeric:
self.is_py_target = False self.is_py_target = False
if isinstance(self.target, ExprNodes.BufferIndexNode): if isinstance(self.target, ExprNodes.BufferIndexNode):
...@@ -6418,25 +6381,23 @@ class ForFromStatNode(LoopNode, StatNode): ...@@ -6418,25 +6381,23 @@ class ForFromStatNode(LoopNode, StatNode):
# is within step of 0. # is within step of 0.
if not self.step: if not self.step:
step = 1 step = 1
code.putln( code.putln("for (%s = %s%s + %s; %s %s %s + %s; ) { %s%s;" % (
"for (%s = %s%s + %s; %s %s %s + %s; ) { %s%s;" % ( loopvar_name,
loopvar_name, self.bound1.result(), offset, step,
self.bound1.result(), offset, step, loopvar_name, self.relation2, self.bound2.result(), step,
loopvar_name, self.relation2, self.bound2.result(), step, loopvar_name, incop))
loopvar_name, incop))
else: else:
code.putln( code.putln("for (%s = %s%s; %s %s %s; %s%s) {" % (
"for (%s = %s%s; %s %s %s; %s%s) {" % ( loopvar_name,
loopvar_name, self.bound1.result(), offset,
self.bound1.result(), offset, loopvar_name, self.relation2, self.bound2.result(),
loopvar_name, self.relation2, self.bound2.result(), loopvar_name, incop))
loopvar_name, incop))
if self.py_loopvar_node: if self.py_loopvar_node:
self.py_loopvar_node.generate_evaluation_code(code) self.py_loopvar_node.generate_evaluation_code(code)
self.target.generate_assignment_code(self.py_loopvar_node, code) self.target.generate_assignment_code(self.py_loopvar_node, code)
elif from_range: elif from_range:
code.putln("%s = %s;" % ( code.putln("%s = %s;" % (
self.target.result(), loopvar_name)) self.target.result(), loopvar_name))
self.body.generate_execution_code(code) self.body.generate_execution_code(code)
code.put_label(code.continue_label) code.put_label(code.continue_label)
if self.py_loopvar_node: if self.py_loopvar_node:
...@@ -6503,7 +6464,7 @@ class ForFromStatNode(LoopNode, StatNode): ...@@ -6503,7 +6464,7 @@ class ForFromStatNode(LoopNode, StatNode):
'<=': ("", "++"), '<=': ("", "++"),
'<' : ("+1", "++"), '<' : ("+1", "++"),
'>=': ("", "--"), '>=': ("", "--"),
'>' : ("-1", "--") '>' : ("-1", "--"),
} }
def generate_function_definitions(self, env, code): def generate_function_definitions(self, env, code):
...@@ -6912,8 +6873,8 @@ class ExceptClauseNode(Node): ...@@ -6912,8 +6873,8 @@ class ExceptClauseNode(Node):
# exception and stores it in the thread state. # exception and stores it in the thread state.
code.globalstate.use_utility_code(get_exception_utility_code) code.globalstate.use_utility_code(get_exception_utility_code)
exc_args = "&%s, &%s, &%s" % tuple(exc_vars) exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args, code.putln("if (__Pyx_GetException(%s) < 0) %s" % (
code.error_goto(self.pos))) exc_args, code.error_goto(self.pos)))
for x in exc_vars: for x in exc_vars:
code.put_gotref(x) code.put_gotref(x)
if self.target: if self.target:
...@@ -7253,7 +7214,8 @@ class GILStatNode(NogilTryFinallyStatNode): ...@@ -7253,7 +7214,8 @@ class GILStatNode(NogilTryFinallyStatNode):
def __init__(self, pos, state, body): def __init__(self, pos, state, body):
self.state = state self.state = state
self.create_state_temp_if_needed(pos, state, body) self.create_state_temp_if_needed(pos, state, body)
TryFinallyStatNode.__init__(self, pos, TryFinallyStatNode.__init__(
self, pos,
body=body, body=body,
finally_clause=GILExitNode( finally_clause=GILExitNode(
pos, state=state, state_temp=self.state_temp)) pos, state=state, state_temp=self.state_temp))
...@@ -7712,18 +7674,14 @@ class ParallelStatNode(StatNode, ParallelNode): ...@@ -7712,18 +7674,14 @@ class ParallelStatNode(StatNode, ParallelNode):
self.analyse_sharing_attributes(env) self.analyse_sharing_attributes(env)
if self.num_threads is not None: if self.num_threads is not None:
if (self.parent and self.parent.num_threads is not None and not if self.parent and self.parent.num_threads is not None and not self.parent.is_prange:
self.parent.is_prange): error(self.pos, "num_threads already declared in outer section")
error(self.pos,
"num_threads already declared in outer section")
elif self.parent and not self.parent.is_prange: elif self.parent and not self.parent.is_prange:
error(self.pos, error(self.pos, "num_threads must be declared in the parent parallel section")
"num_threads must be declared in the parent parallel section")
elif (self.num_threads.type.is_int and elif (self.num_threads.type.is_int and
self.num_threads.is_literal and self.num_threads.is_literal and
self.num_threads.compile_time_value(env) <= 0): self.num_threads.compile_time_value(env) <= 0):
error(self.pos, error(self.pos, "argument to num_threads must be greater than 0")
"argument to num_threads must be greater than 0")
if not self.num_threads.is_simple(): if not self.num_threads.is_simple():
self.num_threads = self.num_threads.coerce_to( self.num_threads = self.num_threads.coerce_to(
...@@ -7743,8 +7701,7 @@ class ParallelStatNode(StatNode, ParallelNode): ...@@ -7743,8 +7701,7 @@ class ParallelStatNode(StatNode, ParallelNode):
# assigning to privates in the with parallel block (we # assigning to privates in the with parallel block (we
# consider it too implicit and magicky for users) # consider it too implicit and magicky for users)
if entry in self.parent.assignments: if entry in self.parent.assignments:
error(pos, error(pos, "Cannot assign to private of outer parallel block")
"Cannot assign to private of outer parallel block")
continue continue
if not self.is_prange and op: if not self.is_prange and op:
...@@ -7882,8 +7839,7 @@ class ParallelStatNode(StatNode, ParallelNode): ...@@ -7882,8 +7839,7 @@ class ParallelStatNode(StatNode, ParallelNode):
Write self.num_threads if set as the num_threads OpenMP directive Write self.num_threads if set as the num_threads OpenMP directive
""" """
if self.num_threads is not None: if self.num_threads is not None:
code.put(" num_threads(%s)" % self.evaluate_before_block(code, code.put(" num_threads(%s)" % self.evaluate_before_block(code, self.num_threads))
self.num_threads))
def declare_closure_privates(self, code): def declare_closure_privates(self, code):
...@@ -8105,8 +8061,7 @@ class ParallelStatNode(StatNode, ParallelNode): ...@@ -8105,8 +8061,7 @@ class ParallelStatNode(StatNode, ParallelNode):
that the breaking thread has well-defined values of the lastprivate that the breaking thread has well-defined values of the lastprivate
variables, so we keep those values. variables, so we keep those values.
""" """
section_name = ("__pyx_parallel_lastprivates%d" % section_name = "__pyx_parallel_lastprivates%d" % self.critical_section_counter
self.critical_section_counter)
code.putln_openmp("#pragma omp critical(%s)" % section_name) code.putln_openmp("#pragma omp critical(%s)" % section_name)
ParallelStatNode.critical_section_counter += 1 ParallelStatNode.critical_section_counter += 1
...@@ -8226,11 +8181,8 @@ class ParallelStatNode(StatNode, ParallelNode): ...@@ -8226,11 +8181,8 @@ class ParallelStatNode(StatNode, ParallelNode):
# Firstly, always prefer errors over returning, continue or break # Firstly, always prefer errors over returning, continue or break
if self.error_label_used: if self.error_label_used:
c.putln("const char *%s = NULL; int %s = 0, %s = 0;" % c.putln("const char *%s = NULL; int %s = 0, %s = 0;" % self.parallel_pos_info)
self.parallel_pos_info) c.putln("PyObject *%s = NULL, *%s = NULL, *%s = NULL;" % self.parallel_exc)
c.putln("PyObject *%s = NULL, *%s = NULL, *%s = NULL;" %
self.parallel_exc)
code.putln( code.putln(
"if (%s) {" % Naming.parallel_exc_type) "if (%s) {" % Naming.parallel_exc_type)
...@@ -8324,7 +8276,7 @@ class ParallelWithBlockNode(ParallelStatNode): ...@@ -8324,7 +8276,7 @@ class ParallelWithBlockNode(ParallelStatNode):
if self.privates: if self.privates:
privates = [e.cname for e in self.privates privates = [e.cname for e in self.privates
if not e.type.is_pyobject] if not e.type.is_pyobject]
code.put('private(%s)' % ', '.join(sorted(privates))) code.put('private(%s)' % ', '.join(sorted(privates)))
self.privatization_insertion_point = code.insertion_point() self.privatization_insertion_point = code.insertion_point()
...@@ -8333,7 +8285,7 @@ class ParallelWithBlockNode(ParallelStatNode): ...@@ -8333,7 +8285,7 @@ class ParallelWithBlockNode(ParallelStatNode):
code.putln("#endif /* _OPENMP */") code.putln("#endif /* _OPENMP */")
code.begin_block() # parallel block code.begin_block() # parallel block
self.begin_parallel_block(code) self.begin_parallel_block(code)
self.initialize_privates_to_nan(code) self.initialize_privates_to_nan(code)
code.funcstate.start_collecting_temps() code.funcstate.start_collecting_temps()
...@@ -8341,7 +8293,7 @@ class ParallelWithBlockNode(ParallelStatNode): ...@@ -8341,7 +8293,7 @@ class ParallelWithBlockNode(ParallelStatNode):
self.trap_parallel_exit(code) self.trap_parallel_exit(code)
self.privatize_temps(code) self.privatize_temps(code)
self.end_parallel_block(code) self.end_parallel_block(code)
code.end_block() # end parallel block code.end_block() # end parallel block
continue_ = code.label_used(code.continue_label) continue_ = code.label_used(code.continue_label)
break_ = code.label_used(code.break_label) break_ = code.label_used(code.break_label)
...@@ -8401,10 +8353,8 @@ class ParallelRangeNode(ParallelStatNode): ...@@ -8401,10 +8353,8 @@ class ParallelRangeNode(ParallelStatNode):
if hasattr(self.schedule, 'decode'): if hasattr(self.schedule, 'decode'):
self.schedule = self.schedule.decode('ascii') self.schedule = self.schedule.decode('ascii')
if self.schedule not in (None, 'static', 'dynamic', 'guided', if self.schedule not in (None, 'static', 'dynamic', 'guided', 'runtime'):
'runtime'): error(self.pos, "Invalid schedule argument to prange: %s" % (self.schedule,))
error(self.pos, "Invalid schedule argument to prange: %s" %
(self.schedule,))
def analyse_expressions(self, env): def analyse_expressions(self, env):
was_nogil = env.nogil was_nogil = env.nogil
...@@ -8451,7 +8401,7 @@ class ParallelRangeNode(ParallelStatNode): ...@@ -8451,7 +8401,7 @@ class ParallelRangeNode(ParallelStatNode):
# As we range from 0 to nsteps, computing the index along the # As we range from 0 to nsteps, computing the index along the
# way, we need a fitting type for 'i' and 'nsteps' # way, we need a fitting type for 'i' and 'nsteps'
self.index_type = PyrexTypes.widest_numeric_type( self.index_type = PyrexTypes.widest_numeric_type(
self.index_type, node.type) self.index_type, node.type)
if self.else_clause is not None: if self.else_clause is not None:
self.else_clause = self.else_clause.analyse_expressions(env) self.else_clause = self.else_clause.analyse_expressions(env)
...@@ -8674,8 +8624,7 @@ class ParallelRangeNode(ParallelStatNode): ...@@ -8674,8 +8624,7 @@ class ParallelRangeNode(ParallelStatNode):
if self.schedule: if self.schedule:
if self.chunksize: if self.chunksize:
chunksize = ", %s" % self.evaluate_before_block(code, chunksize = ", %s" % self.evaluate_before_block(code, self.chunksize)
self.chunksize)
else: else:
chunksize = "" chunksize = ""
...@@ -8687,7 +8636,7 @@ class ParallelRangeNode(ParallelStatNode): ...@@ -8687,7 +8636,7 @@ class ParallelRangeNode(ParallelStatNode):
code.putln("#endif /* _OPENMP */") code.putln("#endif /* _OPENMP */")
code.put("for (%(i)s = 0; %(i)s < %(nsteps)s; %(i)s++)" % fmt_dict) code.put("for (%(i)s = 0; %(i)s < %(nsteps)s; %(i)s++)" % fmt_dict)
code.begin_block() # for loop block code.begin_block() # for loop block
guard_around_body_codepoint = code.insertion_point() guard_around_body_codepoint = code.insertion_point()
...@@ -8710,13 +8659,13 @@ class ParallelRangeNode(ParallelStatNode): ...@@ -8710,13 +8659,13 @@ class ParallelRangeNode(ParallelStatNode):
# exceptions might be used # exceptions might be used
guard_around_body_codepoint.putln("if (%s < 2)" % Naming.parallel_why) guard_around_body_codepoint.putln("if (%s < 2)" % Naming.parallel_why)
code.end_block() # end guard around loop body code.end_block() # end guard around loop body
code.end_block() # end for loop block code.end_block() # end for loop block
if self.is_parallel: if self.is_parallel:
# Release the GIL and deallocate the thread state # Release the GIL and deallocate the thread state
self.end_parallel_block(code) self.end_parallel_block(code)
code.end_block() # pragma omp parallel end block code.end_block() # pragma omp parallel end block
class CnameDecoratorNode(StatNode): class CnameDecoratorNode(StatNode):
...@@ -8743,8 +8692,7 @@ class CnameDecoratorNode(StatNode): ...@@ -8743,8 +8692,7 @@ class CnameDecoratorNode(StatNode):
node = node.body.stats[0] node = node.body.stats[0]
self.is_function = isinstance(node, FuncDefNode) self.is_function = isinstance(node, FuncDefNode)
is_struct_or_enum = isinstance(node, (CStructOrUnionDefNode, is_struct_or_enum = isinstance(node, (CStructOrUnionDefNode, CEnumDefNode))
CEnumDefNode))
e = node.entry e = node.entry
if self.is_function: if self.is_function:
...@@ -8792,7 +8740,7 @@ class CnameDecoratorNode(StatNode): ...@@ -8792,7 +8740,7 @@ class CnameDecoratorNode(StatNode):
if isinstance(self.node, DefNode): if isinstance(self.node, DefNode):
self.node.generate_function_header( self.node.generate_function_header(
h_code, with_pymethdef=False, proto_only=True) h_code, with_pymethdef=False, proto_only=True)
else: else:
from . import ModuleNode from . import ModuleNode
entry = self.node.entry entry = self.node.entry
...@@ -8800,10 +8748,10 @@ class CnameDecoratorNode(StatNode): ...@@ -8800,10 +8748,10 @@ class CnameDecoratorNode(StatNode):
entry.cname = entry.func_cname entry.cname = entry.func_cname
ModuleNode.generate_cfunction_declaration( ModuleNode.generate_cfunction_declaration(
entry, entry,
env.global_scope(), env.global_scope(),
h_code, h_code,
definition=True) definition=True)
entry.cname = cname entry.cname = cname
...@@ -8860,14 +8808,15 @@ traceback_utility_code = UtilityCode.load_cached("AddTraceback", "Exceptions.c") ...@@ -8860,14 +8808,15 @@ traceback_utility_code = UtilityCode.load_cached("AddTraceback", "Exceptions.c")
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
get_exception_tuple_utility_code = UtilityCode(proto=""" get_exception_tuple_utility_code = UtilityCode(
proto="""
static PyObject *__Pyx_GetExceptionTuple(PyThreadState *__pyx_tstate); /*proto*/ static PyObject *__Pyx_GetExceptionTuple(PyThreadState *__pyx_tstate); /*proto*/
""", """,
# I doubt that calling __Pyx_GetException() here is correct as it moves # I doubt that calling __Pyx_GetException() here is correct as it moves
# the exception from tstate->curexc_* to tstate->exc_*, which prevents # the exception from tstate->curexc_* to tstate->exc_*, which prevents
# exception handlers later on from receiving it. # exception handlers later on from receiving it.
# NOTE: "__pyx_tstate" may be used by __Pyx_GetException() macro # NOTE: "__pyx_tstate" may be used by __Pyx_GetException() macro
impl = """ impl = """
static PyObject *__Pyx_GetExceptionTuple(CYTHON_UNUSED PyThreadState *__pyx_tstate) { static PyObject *__Pyx_GetExceptionTuple(CYTHON_UNUSED PyThreadState *__pyx_tstate) {
PyObject *type = NULL, *value = NULL, *tb = NULL; PyObject *type = NULL, *value = NULL, *tb = NULL;
if (__Pyx_GetException(&type, &value, &tb) == 0) { if (__Pyx_GetException(&type, &value, &tb) == 0) {
...@@ -8885,4 +8834,4 @@ static PyObject *__Pyx_GetExceptionTuple(CYTHON_UNUSED PyThreadState *__pyx_tsta ...@@ -8885,4 +8834,4 @@ static PyObject *__Pyx_GetExceptionTuple(CYTHON_UNUSED PyThreadState *__pyx_tsta
return NULL; return NULL;
} }
""", """,
requires=[get_exception_utility_code]) requires=[get_exception_utility_code])
...@@ -263,6 +263,7 @@ directive_scopes = { # defaults to available everywhere ...@@ -263,6 +263,7 @@ directive_scopes = { # defaults to available everywhere
'language_level': ('module',), 'language_level': ('module',),
} }
def parse_directive_value(name, value, relaxed_bool=False): def parse_directive_value(name, value, relaxed_bool=False):
""" """
Parses value as an option value for the given name and returns Parses value as an option value for the given name and returns
...@@ -292,16 +293,21 @@ def parse_directive_value(name, value, relaxed_bool=False): ...@@ -292,16 +293,21 @@ def parse_directive_value(name, value, relaxed_bool=False):
ValueError: c_string_type directive must be one of ('bytes', 'bytearray', 'str', 'unicode'), got 'unnicode' ValueError: c_string_type directive must be one of ('bytes', 'bytearray', 'str', 'unicode'), got 'unnicode'
""" """
type = directive_types.get(name) type = directive_types.get(name)
if not type: return None if not type:
return None
orig_value = value orig_value = value
if type is bool: if type is bool:
value = str(value) value = str(value)
if value == 'True': return True if value == 'True':
if value == 'False': return False return True
if value == 'False':
return False
if relaxed_bool: if relaxed_bool:
value = value.lower() value = value.lower()
if value in ("true", "yes"): return True if value in ("true", "yes"):
elif value in ("false", "no"): return False return True
elif value in ("false", "no"):
return False
raise ValueError("%s directive must be set to True or False, got '%s'" % ( raise ValueError("%s directive must be set to True or False, got '%s'" % (
name, orig_value)) name, orig_value))
elif type is int: elif type is int:
...@@ -317,6 +323,7 @@ def parse_directive_value(name, value, relaxed_bool=False): ...@@ -317,6 +323,7 @@ def parse_directive_value(name, value, relaxed_bool=False):
else: else:
assert False assert False
def parse_directive_list(s, relaxed_bool=False, ignore_unknown=False, def parse_directive_list(s, relaxed_bool=False, ignore_unknown=False,
current_settings=None): current_settings=None):
""" """
...@@ -352,9 +359,11 @@ def parse_directive_list(s, relaxed_bool=False, ignore_unknown=False, ...@@ -352,9 +359,11 @@ def parse_directive_list(s, relaxed_bool=False, ignore_unknown=False,
result = current_settings result = current_settings
for item in s.split(','): for item in s.split(','):
item = item.strip() item = item.strip()
if not item: continue if not item:
if not '=' in item: raise ValueError('Expected "=" in option "%s"' % item) continue
name, value = [ s.strip() for s in item.strip().split('=', 1) ] if not '=' in item:
raise ValueError('Expected "=" in option "%s"' % item)
name, value = [s.strip() for s in item.strip().split('=', 1)]
if name not in directive_defaults: if name not in directive_defaults:
found = False found = False
if name.endswith('.all'): if name.endswith('.all'):
......
...@@ -68,7 +68,7 @@ class Method(object): ...@@ -68,7 +68,7 @@ class Method(object):
class CompileTimeScope(object): class CompileTimeScope(object):
def __init__(self, outer = None): def __init__(self, outer=None):
self.entries = {} self.entries = {}
self.outer = outer self.outer = outer
...@@ -97,8 +97,7 @@ class CompileTimeScope(object): ...@@ -97,8 +97,7 @@ class CompileTimeScope(object):
def initial_compile_time_env(): def initial_compile_time_env():
benv = CompileTimeScope() benv = CompileTimeScope()
names = ('UNAME_SYSNAME', 'UNAME_NODENAME', 'UNAME_RELEASE', names = ('UNAME_SYSNAME', 'UNAME_NODENAME', 'UNAME_RELEASE', 'UNAME_VERSION', 'UNAME_MACHINE')
'UNAME_VERSION', 'UNAME_MACHINE')
for name, value in zip(names, platform.uname()): for name, value in zip(names, platform.uname()):
benv.declare(name, value) benv.declare(name, value)
try: try:
...@@ -272,8 +271,8 @@ class StringSourceDescriptor(SourceDescriptor): ...@@ -272,8 +271,8 @@ class StringSourceDescriptor(SourceDescriptor):
if not encoding: if not encoding:
return self.codelines return self.codelines
else: else:
return [ line.encode(encoding, error_handling).decode(encoding) return [line.encode(encoding, error_handling).decode(encoding)
for line in self.codelines ] for line in self.codelines]
def get_description(self): def get_description(self):
return self.name return self.name
...@@ -487,7 +486,7 @@ class PyrexScanner(Scanner): ...@@ -487,7 +486,7 @@ class PyrexScanner(Scanner):
else: else:
self.expected(what, message) self.expected(what, message)
def expected(self, what, message = None): def expected(self, what, message=None):
if message: if message:
self.error(message) self.error(message)
else: else:
......
...@@ -17,8 +17,7 @@ class NonManglingModuleScope(Symtab.ModuleScope): ...@@ -17,8 +17,7 @@ class NonManglingModuleScope(Symtab.ModuleScope):
def add_imported_entry(self, name, entry, pos): def add_imported_entry(self, name, entry, pos):
entry.used = True entry.used = True
return super(NonManglingModuleScope, self).add_imported_entry( return super(NonManglingModuleScope, self).add_imported_entry(name, entry, pos)
name, entry, pos)
def mangle(self, prefix, name=None): def mangle(self, prefix, name=None):
if name: if name:
...@@ -137,26 +136,22 @@ class CythonUtilityCode(Code.UtilityCodeBase): ...@@ -137,26 +136,22 @@ class CythonUtilityCode(Code.UtilityCodeBase):
pipeline = Pipeline.insert_into_pipeline(pipeline, transform, pipeline = Pipeline.insert_into_pipeline(pipeline, transform,
before=before) before=before)
if self.from_scope: def merge_scope(scope):
def scope_transform(module_node): def merge_scope_transform(module_node):
module_node.scope.merge_in(self.from_scope) module_node.scope.merge_in(scope)
return module_node return module_node
return merge_scope_transform
transform = ParseTreeTransforms.AnalyseDeclarationsTransform if self.from_scope:
pipeline = Pipeline.insert_into_pipeline(pipeline, scope_transform, pipeline = Pipeline.insert_into_pipeline(
before=transform) pipeline, merge_scope(self.from_scope),
before=ParseTreeTransforms.AnalyseDeclarationsTransform)
for dep in self.requires: for dep in self.requires:
if (isinstance(dep, CythonUtilityCode) if isinstance(dep, CythonUtilityCode) and hasattr(dep, 'tree') and not cython_scope:
and hasattr(dep, 'tree') pipeline = Pipeline.insert_into_pipeline(
and not cython_scope): pipeline, merge_scope(dep.tree.scope),
def scope_transform(module_node): before=ParseTreeTransforms.AnalyseDeclarationsTransform)
module_node.scope.merge_in(dep.tree.scope)
return module_node
transform = ParseTreeTransforms.AnalyseDeclarationsTransform
pipeline = Pipeline.insert_into_pipeline(pipeline, scope_transform,
before=transform)
if self.outer_module_scope: if self.outer_module_scope:
# inject outer module between utility code module and builtin module # inject outer module between utility code module and builtin module
...@@ -164,9 +159,9 @@ class CythonUtilityCode(Code.UtilityCodeBase): ...@@ -164,9 +159,9 @@ class CythonUtilityCode(Code.UtilityCodeBase):
module_node.scope.outer_scope = self.outer_module_scope module_node.scope.outer_scope = self.outer_module_scope
return module_node return module_node
transform = ParseTreeTransforms.AnalyseDeclarationsTransform pipeline = Pipeline.insert_into_pipeline(
pipeline = Pipeline.insert_into_pipeline(pipeline, scope_transform, pipeline, scope_transform,
before=transform) before=ParseTreeTransforms.AnalyseDeclarationsTransform)
(err, tree) = Pipeline.run_pipeline(pipeline, tree, printtree=False) (err, tree) = Pipeline.run_pipeline(pipeline, tree, printtree=False)
assert not err, err assert not err, err
...@@ -199,13 +194,12 @@ class CythonUtilityCode(Code.UtilityCodeBase): ...@@ -199,13 +194,12 @@ class CythonUtilityCode(Code.UtilityCodeBase):
entries.pop('__builtins__') entries.pop('__builtins__')
entries.pop('__doc__') entries.pop('__doc__')
for name, entry in entries.items(): for entry in entries.values():
entry.utility_code_definition = self entry.utility_code_definition = self
entry.used = used entry.used = used
original_scope = tree.scope original_scope = tree.scope
dest_scope.merge_in(original_scope, merge_unused=True, dest_scope.merge_in(original_scope, merge_unused=True, whitelist=whitelist)
whitelist=whitelist)
tree.scope = dest_scope tree.scope = dest_scope
for dep in self.requires: for dep in self.requires:
...@@ -214,6 +208,7 @@ class CythonUtilityCode(Code.UtilityCodeBase): ...@@ -214,6 +208,7 @@ class CythonUtilityCode(Code.UtilityCodeBase):
return original_scope return original_scope
def declare_declarations_in_scope(declaration_string, env, private_type=True, def declare_declarations_in_scope(declaration_string, env, private_type=True,
*args, **kwargs): *args, **kwargs):
""" """
......
...@@ -77,9 +77,8 @@ class TreeVisitor(object): ...@@ -77,9 +77,8 @@ class TreeVisitor(object):
self.access_path = [] self.access_path = []
def dump_node(self, node, indent=0): def dump_node(self, node, indent=0):
ignored = list(node.child_attrs or []) + [u'child_attrs', u'pos', ignored = list(node.child_attrs or []) + [
u'gil_message', u'cpp_message', u'child_attrs', u'pos', u'gil_message', u'cpp_message', u'subexprs']
u'subexprs']
values = [] values = []
pos = getattr(node, 'pos', None) pos = getattr(node, 'pos', None)
if pos: if pos:
...@@ -93,7 +92,7 @@ class TreeVisitor(object): ...@@ -93,7 +92,7 @@ class TreeVisitor(object):
for attr in attribute_names: for attr in attribute_names:
if attr in ignored: if attr in ignored:
continue continue
if attr.startswith(u'_') or attr.endswith(u'_'): if attr.startswith('_') or attr.endswith('_'):
continue continue
try: try:
value = getattr(node, attr) value = getattr(node, attr)
...@@ -108,8 +107,7 @@ class TreeVisitor(object): ...@@ -108,8 +107,7 @@ class TreeVisitor(object):
else: else:
value = repr(value) value = repr(value)
values.append(u'%s = %s' % (attr, value)) values.append(u'%s = %s' % (attr, value))
return u'%s(%s)' % (node.__class__.__name__, return u'%s(%s)' % (node.__class__.__name__, u',\n '.join(values))
u',\n '.join(values))
def _find_node_path(self, stacktrace): def _find_node_path(self, stacktrace):
import os.path import os.path
...@@ -129,7 +127,6 @@ class TreeVisitor(object): ...@@ -129,7 +127,6 @@ class TreeVisitor(object):
return (last_traceback, nodes) return (last_traceback, nodes)
def _raise_compiler_error(self, child, e): def _raise_compiler_error(self, child, e):
import sys
trace = [''] trace = ['']
for parent, attribute, index in self.access_path: for parent, attribute, index in self.access_path:
node = getattr(parent, attribute) node = getattr(parent, attribute)
...@@ -389,7 +386,7 @@ class EnvTransform(CythonTransform): ...@@ -389,7 +386,7 @@ class EnvTransform(CythonTransform):
def visit_CArgDeclNode(self, node): def visit_CArgDeclNode(self, node):
# default arguments are evaluated in the outer scope # default arguments are evaluated in the outer scope
if node.default: if node.default:
attrs = [ attr for attr in node.child_attrs if attr != 'default' ] attrs = [attr for attr in node.child_attrs if attr != 'default']
self.visitchildren(node, attrs) self.visitchildren(node, attrs)
self.enter_scope(node, self.current_env().outer_scope) self.enter_scope(node, self.current_env().outer_scope)
self.visitchildren(node, ('default',)) self.visitchildren(node, ('default',))
......
...@@ -110,8 +110,8 @@ cclass = ccall = cfunc = _EmptyDecoratorAndManager() ...@@ -110,8 +110,8 @@ cclass = ccall = cfunc = _EmptyDecoratorAndManager()
returns = wraparound = boundscheck = initializedcheck = nonecheck = \ returns = wraparound = boundscheck = initializedcheck = nonecheck = \
overflowcheck = embedsignature = cdivision = cdivision_warnings = \ overflowcheck = embedsignature = cdivision = cdivision_warnings = \
always_allows_keywords = profile = linetrace = infer_type = \ always_allows_keywords = profile = linetrace = infer_type = \
type_version_tag = unraisable_tracebacks = freelist = \ unraisable_tracebacks = freelist = \
lambda arg: _EmptyDecoratorAndManager() lambda arg: _EmptyDecoratorAndManager()
optimization = _Optimization() optimization = _Optimization()
...@@ -120,18 +120,21 @@ overflowcheck.fold = optimization.use_switch = \ ...@@ -120,18 +120,21 @@ overflowcheck.fold = optimization.use_switch = \
final = internal = type_version_tag = no_gc_clear = _empty_decorator final = internal = type_version_tag = no_gc_clear = _empty_decorator
def inline(f, *args, **kwds): def inline(f, *args, **kwds):
if isinstance(f, basestring): if isinstance(f, basestring):
from Cython.Build.Inline import cython_inline from Cython.Build.Inline import cython_inline
return cython_inline(f, *args, **kwds) return cython_inline(f, *args, **kwds)
else: else:
assert len(args) == len(kwds) == 0 assert len(args) == len(kwds) == 0
return f return f
def compile(f): def compile(f):
from Cython.Build.Inline import RuntimeCompiledFunction from Cython.Build.Inline import RuntimeCompiledFunction
return RuntimeCompiledFunction(f) return RuntimeCompiledFunction(f)
# Special functions # Special functions
def cdiv(a, b): def cdiv(a, b):
......
from Cython.Shadow import __version__ from __future__ import absolute_import
from .Shadow import __version__
# Void cython.* directives (for case insensitive operating systems). # Void cython.* directives (for case insensitive operating systems).
from Cython.Shadow import * from .Shadow import *
def load_ipython_extension(ip): def load_ipython_extension(ip):
"""Load the extension in IPython.""" """Load the extension in IPython."""
from Cython.Build.IpythonMagic import CythonMagics # pylint: disable=cyclic-import from .Build.IpythonMagic import CythonMagics # pylint: disable=cyclic-import
ip.register_magics(CythonMagics) ip.register_magics(CythonMagics)
...@@ -103,7 +103,7 @@ function-rgx=[a-z_][a-z0-9_]{2,30}$ ...@@ -103,7 +103,7 @@ function-rgx=[a-z_][a-z0-9_]{2,30}$
method-rgx=[a-z_][a-z0-9_]{2,30}|visit_[A-Za-z]+$ method-rgx=[a-z_][a-z0-9_]{2,30}|visit_[A-Za-z]+$
# Regular expression which should only match correct instance attribute names # Regular expression which should only match correct instance attribute names
attr-rgx=[a-z_][a-z0-9_]{2,30}$ attr-rgx=[a-z_][a-z0-9_]{2,30}|sy$
# Regular expression which should only match correct argument names # Regular expression which should only match correct argument names
argument-rgx=[a-z_][a-z0-9_]{0,30}$ argument-rgx=[a-z_][a-z0-9_]{0,30}$
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment