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):
......
...@@ -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 = {
...@@ -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)
...@@ -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,8 +1345,7 @@ class GlobalState(object): ...@@ -1345,8 +1345,7 @@ 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',
...@@ -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()
...@@ -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':
...@@ -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,8 +1108,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1118,8 +1108,7 @@ 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)
...@@ -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,7 +1235,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1244,7 +1235,8 @@ 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(
"if (CYTHON_COMPILING_IN_CPYTHON && likely((%s > 0) & (t->tp_basicsize == sizeof(%s))%s)) {" % (
freecount_name, obj_struct, type_safety_check)) 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))
...@@ -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,8 +1409,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1417,8 +1409,11 @@ 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)) {" % (
freecount_name,
freelist_size,
type.declaration_code("", deref=True),
type_safety_check)) 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")))
...@@ -1451,8 +1446,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1451,8 +1446,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
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(
"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)) 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,7 +1539,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1550,7 +1539,8 @@ 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(
"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)) 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,18 +1565,16 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1575,18 +1565,16 @@ 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(
...@@ -1609,14 +1597,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1609,14 +1597,12 @@ 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)
...@@ -1632,8 +1618,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1632,8 +1618,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"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)
...@@ -1676,14 +1662,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1676,14 +1662,14 @@ 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)
...@@ -1699,8 +1685,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1699,8 +1685,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"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)
...@@ -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,14 +1755,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1769,14 +1755,14 @@ 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)
...@@ -1788,8 +1774,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1788,8 +1774,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"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)
...@@ -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,14 +1823,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1837,14 +1823,14 @@ 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)
...@@ -1858,8 +1844,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1858,8 +1844,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"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)
...@@ -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,14 +1889,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1903,14 +1889,14 @@ 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__");')
...@@ -1922,8 +1908,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1922,8 +1908,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"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__");')
...@@ -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,8 +1955,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1970,8 +1955,8 @@ 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, ",")
...@@ -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")
...@@ -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
...@@ -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:
...@@ -1303,8 +1301,9 @@ class CVarDefNode(StatNode): ...@@ -1303,8 +1301,9 @@ class CVarDefNode(StatNode):
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
...@@ -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,7 +1340,8 @@ class CVarDefNode(StatNode): ...@@ -1342,7 +1340,8 @@ 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(
name, type, declarator.pos,
cname=cname, visibility=visibility, in_pxd=self.in_pxd, cname=cname, visibility=visibility, in_pxd=self.in_pxd,
api=self.api, is_cdef=1) api=self.api, is_cdef=1)
if Options.docstrings: if Options.docstrings:
...@@ -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,8 +1505,7 @@ class CEnumDefNode(StatNode): ...@@ -1505,8 +1505,7 @@ 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(
...@@ -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,9 +1779,8 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1782,9 +1779,8 @@ 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()
...@@ -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)):
...@@ -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,25 +2355,25 @@ class CFuncDefNode(FuncDefNode): ...@@ -2369,25 +2355,25 @@ 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
...@@ -2395,7 +2381,7 @@ class CFuncDefNode(FuncDefNode): ...@@ -2395,7 +2381,7 @@ class CFuncDefNode(FuncDefNode):
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
...@@ -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)
...@@ -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,9 +2955,7 @@ class DefNode(FuncDefNode): ...@@ -2969,9 +2955,7 @@ 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 "
"(%d declared, %s expected)" % (
desc, self.name, len(self.args), expected_str)) desc, self.name, len(self.args), expected_str))
def declare_pyfunction(self, env): def declare_pyfunction(self, 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,8 +3298,8 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3314,8 +3298,8 @@ 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__'
...@@ -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)
...@@ -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
...@@ -3684,8 +3667,7 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3684,8 +3667,7 @@ 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:
...@@ -3819,7 +3801,7 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3819,7 +3801,7 @@ class DefNodeWrapper(FuncDefNode):
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('}')
...@@ -3849,8 +3831,7 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3849,8 +3831,7 @@ class DefNodeWrapper(FuncDefNode):
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',
...@@ -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,8 +4173,8 @@ class OverrideCheckNode(StatNode): ...@@ -4199,8 +4173,8 @@ 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),
...@@ -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.
...@@ -4616,19 +4587,19 @@ class CClassDefNode(ClassDefNode): ...@@ -4616,19 +4587,19 @@ class CClassDefNode(ClassDefNode):
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,7 +4731,7 @@ class ExprStatNode(StatNode): ...@@ -4760,7 +4731,7 @@ 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):
...@@ -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,8 +5548,7 @@ class ReturnStatNode(StatNode): ...@@ -5579,8 +5548,7 @@ 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:
...@@ -5626,8 +5594,7 @@ class ReturnStatNode(StatNode): ...@@ -5626,8 +5594,7 @@ 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)
...@@ -5690,8 +5657,7 @@ class RaiseStatNode(StatNode): ...@@ -5690,8 +5657,7 @@ 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
...@@ -5823,13 +5789,11 @@ class AssertStatNode(StatNode): ...@@ -5823,13 +5789,11 @@ 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:
...@@ -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,15 +6381,13 @@ class ForFromStatNode(LoopNode, StatNode): ...@@ -6418,15 +6381,13 @@ 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(),
...@@ -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)
...@@ -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
...@@ -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 = ""
...@@ -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:
...@@ -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,7 +110,7 @@ cclass = ccall = cfunc = _EmptyDecoratorAndManager() ...@@ -110,7 +110,7 @@ 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,6 +120,7 @@ overflowcheck.fold = optimization.use_switch = \ ...@@ -120,6 +120,7 @@ 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
...@@ -128,10 +129,12 @@ def inline(f, *args, **kwds): ...@@ -128,10 +129,12 @@ def inline(f, *args, **kwds):
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