diff options
author | Aleksandr <ivansduck@gmail.com> | 2022-02-10 16:47:52 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:47:52 +0300 |
commit | ea6c5b7f172becca389cacaff7d5f45f6adccbe6 (patch) | |
tree | d16cef493ac1e092b4a03ab9437ec06ffe3d188f /contrib/tools/cython/Cython/Compiler/ModuleNode.py | |
parent | 37de222addabbef336dcaaea5f7c7645a629fc6d (diff) | |
download | ydb-ea6c5b7f172becca389cacaff7d5f45f6adccbe6.tar.gz |
Restoring authorship annotation for Aleksandr <ivansduck@gmail.com>. Commit 1 of 2.
Diffstat (limited to 'contrib/tools/cython/Cython/Compiler/ModuleNode.py')
-rw-r--r-- | contrib/tools/cython/Cython/Compiler/ModuleNode.py | 860 |
1 files changed, 430 insertions, 430 deletions
diff --git a/contrib/tools/cython/Cython/Compiler/ModuleNode.py b/contrib/tools/cython/Cython/Compiler/ModuleNode.py index cd7166408e..304f6f9a85 100644 --- a/contrib/tools/cython/Cython/Compiler/ModuleNode.py +++ b/contrib/tools/cython/Cython/Compiler/ModuleNode.py @@ -7,13 +7,13 @@ from __future__ import absolute_import import cython cython.declare(Naming=object, Options=object, PyrexTypes=object, TypeSlots=object, error=object, warning=object, py_object_type=object, UtilityCode=object, - EncodedString=object, re=object) + EncodedString=object, re=object) from collections import defaultdict import json import operator import os -import re +import re from .PyrexTypes import CPtrType from . import Future @@ -24,14 +24,14 @@ from . import Nodes from . import Options from . import TypeSlots from . import PyrexTypes -from . import Pythran +from . import Pythran from .Errors import error, warning from .PyrexTypes import py_object_type from ..Utils import open_new_file, replace_suffix, decode_filename, build_hex_version -from .Code import UtilityCode, IncludeCode +from .Code import UtilityCode, IncludeCode from .StringEncoding import EncodedString -from .Pythran import has_np_pythran +from .Pythran import has_np_pythran def check_c_declarations_pxd(module_node): module_node.scope.check_c_classes_pxd() @@ -87,9 +87,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): self.scope.utility_code_list.extend(scope.utility_code_list) - for inc in scope.c_includes.values(): - self.scope.process_include(inc) - + for inc in scope.c_includes.values(): + self.scope.process_include(inc) + def extend_if_not_in(L1, L2): for x in L2: if x not in L1: @@ -106,8 +106,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): self.scope.merge_in(scope) def analyse_declarations(self, env): - if has_np_pythran(env): - Pythran.include_pythran_generic(env) + if has_np_pythran(env): + Pythran.include_pythran_generic(env) if self.directives: env.old_style_globals = self.directives['old_style_globals'] if not Options.docstrings: @@ -120,7 +120,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): else: env.doc = self.doc env.directives = self.directives - + self.body.analyse_declarations(env) def prepare_utility_code(self): @@ -204,14 +204,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): h_code.putln("") h_code.putln("#endif /* !%s */" % api_guard) h_code.putln("") - h_code.putln("/* WARNING: the interface of the module init function changed in CPython 3.5. */") - h_code.putln("/* It now returns a PyModuleDef instance instead of a PyModule instance. */") - h_code.putln("") + h_code.putln("/* WARNING: the interface of the module init function changed in CPython 3.5. */") + h_code.putln("/* It now returns a PyModuleDef instance instead of a PyModule instance. */") + h_code.putln("") h_code.putln("#if PY_MAJOR_VERSION < 3") init_name = 'init' + (options.init_suffix or env.module_name) h_code.putln("PyMODINIT_FUNC %s(void);" % init_name) h_code.putln("#else") - h_code.putln("PyMODINIT_FUNC %s(void);" % self.mod_init_func_cname('PyInit', env, options)) + h_code.putln("PyMODINIT_FUNC %s(void);" % self.mod_init_func_cname('PyInit', env, options)) h_code.putln("#endif") h_code.putln("") h_code.putln("#endif /* !%s */" % h_guard) @@ -225,7 +225,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): def generate_public_declaration(self, entry, h_code, i_code): h_code.putln("%s %s;" % ( Naming.extern_c_macro, - entry.type.declaration_code(entry.cname))) + entry.type.declaration_code(entry.cname))) if i_code: i_code.putln("cdef extern %s" % ( entry.type.declaration_code(entry.cname, pyrex=1))) @@ -366,16 +366,16 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code = globalstate['before_global_var'] code.putln('#define __Pyx_MODULE_NAME "%s"' % self.full_module_name) - module_is_main = "%s%s" % (Naming.module_is_main, self.full_module_name.replace('.', '__')) - code.putln("extern int %s;" % module_is_main) - code.putln("int %s = 0;" % module_is_main) + module_is_main = "%s%s" % (Naming.module_is_main, self.full_module_name.replace('.', '__')) + code.putln("extern int %s;" % module_is_main) + code.putln("int %s = 0;" % module_is_main) code.putln("") code.putln("/* Implementation of '%s' */" % env.qualified_name) - code = globalstate['late_includes'] - code.putln("/* Late includes */") - self.generate_includes(env, modules, code, early=False) - + code = globalstate['late_includes'] + code.putln("/* Late includes */") + self.generate_includes(env, modules, code, early=False) + code = globalstate['all_the_rest'] self.generate_cached_builtins_decls(env, code) @@ -640,30 +640,30 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("#define PY_SSIZE_T_CLEAN") code.putln("#endif /* PY_SSIZE_T_CLEAN */") - for inc in sorted(env.c_includes.values(), key=IncludeCode.sortkey): - if inc.location == inc.INITIAL: - inc.write(code) + for inc in sorted(env.c_includes.values(), key=IncludeCode.sortkey): + if inc.location == inc.INITIAL: + inc.write(code) code.putln("#ifndef Py_PYTHON_H") code.putln(" #error Python headers needed to compile C extensions, " "please install development version of Python.") code.putln("#elif PY_VERSION_HEX < 0x02060000 || " - "(0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000)") - code.putln(" #error Cython requires Python 2.6+ or Python 3.3+.") + "(0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000)") + code.putln(" #error Cython requires Python 2.6+ or Python 3.3+.") code.putln("#else") code.globalstate["end"].putln("#endif /* Py_PYTHON_H */") from .. import __version__ code.putln('#define CYTHON_ABI "%s"' % __version__.replace('.', '_')) code.putln('#define CYTHON_HEX_VERSION %s' % build_hex_version(__version__)) - code.putln("#define CYTHON_FUTURE_DIVISION %d" % ( - Future.division in env.context.future_directives)) + code.putln("#define CYTHON_FUTURE_DIVISION %d" % ( + Future.division in env.context.future_directives)) self._put_setup_code(code, "CModulePreamble") if env.context.options.cplus: self._put_setup_code(code, "CppInitCode") else: self._put_setup_code(code, "CInitCode") - self._put_setup_code(code, "PythonCompatibility") + self._put_setup_code(code, "PythonCompatibility") self._put_setup_code(code, "MathInitCode") # Using "(void)cname" to prevent "unused" warnings. @@ -686,10 +686,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("#define %s" % Naming.h_guard_prefix + self.api_name(env)) code.putln("#define %s" % Naming.api_guard_prefix + self.api_name(env)) - code.putln("/* Early includes */") - self.generate_includes(env, cimported_modules, code, late=False) + code.putln("/* Early includes */") + self.generate_includes(env, cimported_modules, code, late=False) code.putln("") - code.putln("#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS)") + code.putln("#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS)") code.putln("#define CYTHON_WITHOUT_ASSERTIONS") code.putln("#endif") code.putln("") @@ -729,9 +729,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): PyrexTypes.c_int_type.create_from_py_utility_code(env) code.put(Nodes.branch_prediction_macros) - code.putln('static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; }') + code.putln('static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; }') code.putln('') - code.putln('static PyObject *%s = NULL;' % env.module_cname) + code.putln('static PyObject *%s = NULL;' % env.module_cname) code.putln('static PyObject *%s;' % env.module_dict_cname) code.putln('static PyObject *%s;' % Naming.builtins_cname) code.putln('static PyObject *%s = NULL;' % Naming.cython_runtime_cname) @@ -745,10 +745,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln('static const char * %s= %s;' % (Naming.cfilenm_cname, Naming.file_c_macro)) code.putln('static const char *%s;' % Naming.filename_cname) - env.use_utility_code(UtilityCode.load_cached("FastTypeChecks", "ModuleSetupCode.c")) - if has_np_pythran(env): - env.use_utility_code(UtilityCode.load_cached("PythranConversion", "CppSupport.cpp")) - + env.use_utility_code(UtilityCode.load_cached("FastTypeChecks", "ModuleSetupCode.c")) + if has_np_pythran(env): + env.use_utility_code(UtilityCode.load_cached("PythranConversion", "CppSupport.cpp")) + def generate_extern_c_macro_definition(self, code): name = Naming.extern_c_macro code.putln("#ifndef %s" % name) @@ -764,31 +764,31 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln(" #define DL_IMPORT(_T) _T") code.putln("#endif") - def generate_includes(self, env, cimported_modules, code, early=True, late=True): + def generate_includes(self, env, cimported_modules, code, early=True, late=True): includes = [] - for inc in sorted(env.c_includes.values(), key=IncludeCode.sortkey): - if inc.location == inc.EARLY: - if early: - inc.write(code) - elif inc.location == inc.LATE: - if late: - inc.write(code) - if early: - code.putln_openmp("#include <omp.h>") + for inc in sorted(env.c_includes.values(), key=IncludeCode.sortkey): + if inc.location == inc.EARLY: + if early: + inc.write(code) + elif inc.location == inc.LATE: + if late: + inc.write(code) + if early: + code.putln_openmp("#include <omp.h>") def generate_filename_table(self, code): - from os.path import isabs, basename + from os.path import isabs, basename code.putln("") code.putln("static const char *%s[] = {" % Naming.filetable_cname) if code.globalstate.filename_list: for source_desc in code.globalstate.filename_list: - file_path = source_desc.get_filenametable_entry() - if Options.source_root: - # If source root specified, dump description - it's source root relative filename - file_path = source_desc.get_description() - if isabs(file_path): - file_path = basename(file_path) # never include absolute paths - escaped_filename = file_path.replace("\\", "\\\\").replace('"', r'\"') + file_path = source_desc.get_filenametable_entry() + if Options.source_root: + # If source root specified, dump description - it's source root relative filename + file_path = source_desc.get_description() + if isabs(file_path): + file_path = basename(file_path) # never include absolute paths + escaped_filename = file_path.replace("\\", "\\\\").replace('"', r'\"') code.putln('"%s",' % escaped_filename) else: # Some C compilers don't like an empty array @@ -926,96 +926,96 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): [base_class.empty_declaration_code() for base_class in type.base_classes]) code.put(" : public %s" % base_class_decl) code.putln(" {") - py_attrs = [e for e in scope.entries.values() - if e.type.is_pyobject and not e.is_inherited] + py_attrs = [e for e in scope.entries.values() + if e.type.is_pyobject and not e.is_inherited] has_virtual_methods = False - constructor = None - destructor = None + constructor = None + destructor = None for attr in scope.var_entries: if attr.type.is_cfunction: code.put("inline ") if attr.type.is_cfunction and attr.type.is_static_method: code.put("static ") - elif attr.name == "<init>": - constructor = attr - elif attr.name == "<del>": - destructor = attr - elif attr.type.is_cfunction: + elif attr.name == "<init>": + constructor = attr + elif attr.name == "<del>": + destructor = attr + elif attr.type.is_cfunction: code.put("virtual ") has_virtual_methods = True code.putln("%s;" % attr.type.declaration_code(attr.cname)) - is_implementing = 'init_module' in code.globalstate.parts - if constructor or py_attrs: - if constructor: - arg_decls = [] - arg_names = [] - for arg in constructor.type.original_args[ - :len(constructor.type.args)-constructor.type.optional_arg_count]: - arg_decls.append(arg.declaration_code()) - arg_names.append(arg.cname) - if constructor.type.optional_arg_count: - arg_decls.append(constructor.type.op_arg_struct.declaration_code(Naming.optional_args_cname)) - arg_names.append(Naming.optional_args_cname) - if not arg_decls: - arg_decls = ["void"] - else: - arg_decls = ["void"] - arg_names = [] - if is_implementing: - code.putln("%s(%s) {" % (type.cname, ", ".join(arg_decls))) - if py_attrs: - code.put_ensure_gil() - for attr in py_attrs: - code.put_init_var_to_py_none(attr, nanny=False); - if constructor: - code.putln("%s(%s);" % (constructor.cname, ", ".join(arg_names))) - if py_attrs: - code.put_release_ensured_gil() - code.putln("}") - else: - code.putln("%s(%s);" % (type.cname, ", ".join(arg_decls))) - if destructor or py_attrs or has_virtual_methods: - if has_virtual_methods: - code.put("virtual ") - if is_implementing: - code.putln("~%s() {" % type.cname) - if py_attrs: - code.put_ensure_gil() - if destructor: - code.putln("%s();" % destructor.cname) - if py_attrs: - for attr in py_attrs: - code.put_var_xdecref(attr, nanny=False); - code.put_release_ensured_gil() - code.putln("}") - else: - code.putln("~%s();" % type.cname) - if py_attrs: - # Also need copy constructor and assignment operators. - if is_implementing: - code.putln("%s(const %s& __Pyx_other) {" % (type.cname, type.cname)) - code.put_ensure_gil() - for attr in scope.var_entries: - if not attr.type.is_cfunction: - code.putln("%s = __Pyx_other.%s;" % (attr.cname, attr.cname)) - code.put_var_incref(attr, nanny=False) - code.put_release_ensured_gil() - code.putln("}") - code.putln("%s& operator=(const %s& __Pyx_other) {" % (type.cname, type.cname)) - code.putln("if (this != &__Pyx_other) {") - code.put_ensure_gil() - for attr in scope.var_entries: - if not attr.type.is_cfunction: - code.put_var_xdecref(attr, nanny=False); - code.putln("%s = __Pyx_other.%s;" % (attr.cname, attr.cname)) - code.put_var_incref(attr, nanny=False) - code.put_release_ensured_gil() - code.putln("}") - code.putln("return *this;") - code.putln("}") - else: - code.putln("%s(const %s& __Pyx_other);" % (type.cname, type.cname)) - code.putln("%s& operator=(const %s& __Pyx_other);" % (type.cname, type.cname)) + is_implementing = 'init_module' in code.globalstate.parts + if constructor or py_attrs: + if constructor: + arg_decls = [] + arg_names = [] + for arg in constructor.type.original_args[ + :len(constructor.type.args)-constructor.type.optional_arg_count]: + arg_decls.append(arg.declaration_code()) + arg_names.append(arg.cname) + if constructor.type.optional_arg_count: + arg_decls.append(constructor.type.op_arg_struct.declaration_code(Naming.optional_args_cname)) + arg_names.append(Naming.optional_args_cname) + if not arg_decls: + arg_decls = ["void"] + else: + arg_decls = ["void"] + arg_names = [] + if is_implementing: + code.putln("%s(%s) {" % (type.cname, ", ".join(arg_decls))) + if py_attrs: + code.put_ensure_gil() + for attr in py_attrs: + code.put_init_var_to_py_none(attr, nanny=False); + if constructor: + code.putln("%s(%s);" % (constructor.cname, ", ".join(arg_names))) + if py_attrs: + code.put_release_ensured_gil() + code.putln("}") + else: + code.putln("%s(%s);" % (type.cname, ", ".join(arg_decls))) + if destructor or py_attrs or has_virtual_methods: + if has_virtual_methods: + code.put("virtual ") + if is_implementing: + code.putln("~%s() {" % type.cname) + if py_attrs: + code.put_ensure_gil() + if destructor: + code.putln("%s();" % destructor.cname) + if py_attrs: + for attr in py_attrs: + code.put_var_xdecref(attr, nanny=False); + code.put_release_ensured_gil() + code.putln("}") + else: + code.putln("~%s();" % type.cname) + if py_attrs: + # Also need copy constructor and assignment operators. + if is_implementing: + code.putln("%s(const %s& __Pyx_other) {" % (type.cname, type.cname)) + code.put_ensure_gil() + for attr in scope.var_entries: + if not attr.type.is_cfunction: + code.putln("%s = __Pyx_other.%s;" % (attr.cname, attr.cname)) + code.put_var_incref(attr, nanny=False) + code.put_release_ensured_gil() + code.putln("}") + code.putln("%s& operator=(const %s& __Pyx_other) {" % (type.cname, type.cname)) + code.putln("if (this != &__Pyx_other) {") + code.put_ensure_gil() + for attr in scope.var_entries: + if not attr.type.is_cfunction: + code.put_var_xdecref(attr, nanny=False); + code.putln("%s = __Pyx_other.%s;" % (attr.cname, attr.cname)) + code.put_var_incref(attr, nanny=False) + code.put_release_ensured_gil() + code.putln("}") + code.putln("return *this;") + code.putln("}") + else: + code.putln("%s(const %s& __Pyx_other);" % (type.cname, type.cname)) + code.putln("%s& operator=(const %s& __Pyx_other);" % (type.cname, type.cname)) code.putln("};") def generate_enum_definition(self, entry, code): @@ -1247,31 +1247,31 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): self.generate_traverse_function(scope, code, entry) if scope.needs_tp_clear(): self.generate_clear_function(scope, code, entry) - if scope.defines_any_special(["__getitem__"]): + if scope.defines_any_special(["__getitem__"]): self.generate_getitem_int_function(scope, code) - if scope.defines_any_special(["__setitem__", "__delitem__"]): + if scope.defines_any_special(["__setitem__", "__delitem__"]): self.generate_ass_subscript_function(scope, code) - if scope.defines_any_special(["__getslice__", "__setslice__", "__delslice__"]): + if scope.defines_any_special(["__getslice__", "__setslice__", "__delslice__"]): 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("#error __getslice__, __setslice__, and __delslice__ not supported in Python 3.") code.putln("#endif") - if scope.defines_any_special(["__setslice__", "__delslice__"]): + if scope.defines_any_special(["__setslice__", "__delslice__"]): self.generate_ass_slice_function(scope, code) - if scope.defines_any_special(["__getattr__", "__getattribute__"]): + if scope.defines_any_special(["__getattr__", "__getattribute__"]): self.generate_getattro_function(scope, code) - if scope.defines_any_special(["__setattr__", "__delattr__"]): + if scope.defines_any_special(["__setattr__", "__delattr__"]): self.generate_setattro_function(scope, code) - if scope.defines_any_special(["__get__"]): + if scope.defines_any_special(["__get__"]): self.generate_descr_get_function(scope, code) - if scope.defines_any_special(["__set__", "__delete__"]): + if scope.defines_any_special(["__set__", "__delete__"]): self.generate_descr_set_function(scope, code) - if not scope.is_closure_class_scope and scope.defines_any(["__dict__"]): + if not scope.is_closure_class_scope and scope.defines_any(["__dict__"]): self.generate_dict_getter_function(scope, code) - if scope.defines_any_special(TypeSlots.richcmp_special_methods): - self.generate_richcmp_function(scope, code) + if scope.defines_any_special(TypeSlots.richcmp_special_methods): + self.generate_richcmp_function(scope, code) self.generate_property_accessors(scope, code) self.generate_method_table(scope, code) self.generate_getset_table(scope, code) @@ -1450,11 +1450,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): is_final_type = scope.parent_type.is_final_type needs_gc = scope.needs_gc() - weakref_slot = scope.lookup_here("__weakref__") if not scope.is_closure_class_scope else None + weakref_slot = scope.lookup_here("__weakref__") if not scope.is_closure_class_scope else None if weakref_slot not in scope.var_entries: weakref_slot = None - dict_slot = scope.lookup_here("__dict__") if not scope.is_closure_class_scope else None + dict_slot = scope.lookup_here("__dict__") if not scope.is_closure_class_scope else None if dict_slot not in scope.var_entries: dict_slot = None @@ -1467,15 +1467,15 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): if not is_final_type: # in Py3.4+, call tp_finalize() as early as possible - code.putln("#if CYTHON_USE_TP_FINALIZE") + code.putln("#if CYTHON_USE_TP_FINALIZE") if needs_gc: finalised_check = '!_PyGC_FINALIZED(o)' else: finalised_check = ( '(!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))') - code.putln( - "if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)" - " && Py_TYPE(o)->tp_finalize) && %s) {" % finalised_check) + code.putln( + "if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)" + " && Py_TYPE(o)->tp_finalize) && %s) {" % finalised_check) # if instance was resurrected by finaliser, return code.putln("if (PyObject_CallFinalizerFromDealloc(o)) return;") code.putln("}") @@ -1622,9 +1622,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): for entry in py_attrs: var_code = "p->%s" % entry.cname - var_as_pyobject = PyrexTypes.typecast(py_object_type, entry.type, var_code) + var_as_pyobject = PyrexTypes.typecast(py_object_type, entry.type, var_code) code.putln("if (%s) {" % var_code) - code.putln("e = (*v)(%s, a); if (e) return e;" % var_as_pyobject) + code.putln("e = (*v)(%s, a); if (e) return e;" % var_as_pyobject) code.putln("}") # Traverse buffer exporting objects. @@ -1841,76 +1841,76 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln( "}") - def generate_richcmp_function(self, scope, code): - if scope.lookup_here("__richcmp__"): - # user implemented, nothing to do - return - # otherwise, we have to generate it from the Python special methods - richcmp_cfunc = scope.mangle_internal("tp_richcompare") - code.putln("") - code.putln("static PyObject *%s(PyObject *o1, PyObject *o2, int op) {" % richcmp_cfunc) - code.putln("switch (op) {") - - class_scopes = [] - cls = scope.parent_type - while cls is not None and not cls.entry.visibility == 'extern': - class_scopes.append(cls.scope) - cls = cls.scope.parent_type.base_type - assert scope in class_scopes - - extern_parent = None - if cls and cls.entry.visibility == 'extern': - # need to call up into base classes as we may not know all implemented comparison methods - extern_parent = cls if cls.typeptr_cname else scope.parent_type.base_type - - eq_entry = None - has_ne = False - for cmp_method in TypeSlots.richcmp_special_methods: - for class_scope in class_scopes: - entry = class_scope.lookup_here(cmp_method) - if entry is not None: - break - else: - continue - - cmp_type = cmp_method.strip('_').upper() # e.g. "__eq__" -> EQ - code.putln("case Py_%s: {" % cmp_type) - if cmp_method == '__eq__': - eq_entry = entry - # Python itself does not do this optimisation, it seems... - #code.putln("if (o1 == o2) return __Pyx_NewRef(Py_True);") - elif cmp_method == '__ne__': - has_ne = True - # Python itself does not do this optimisation, it seems... - #code.putln("if (o1 == o2) return __Pyx_NewRef(Py_False);") - code.putln("return %s(o1, o2);" % entry.func_cname) - code.putln("}") - - if eq_entry and not has_ne and not extern_parent: - code.putln("case Py_NE: {") - code.putln("PyObject *ret;") - # Python itself does not do this optimisation, it seems... - #code.putln("if (o1 == o2) return __Pyx_NewRef(Py_False);") - code.putln("ret = %s(o1, o2);" % eq_entry.func_cname) - code.putln("if (likely(ret && ret != Py_NotImplemented)) {") - code.putln("int b = __Pyx_PyObject_IsTrue(ret); Py_DECREF(ret);") - code.putln("if (unlikely(b < 0)) return NULL;") - code.putln("ret = (b) ? Py_False : Py_True;") - code.putln("Py_INCREF(ret);") - code.putln("}") - code.putln("return ret;") - code.putln("}") - - code.putln("default: {") - if extern_parent and extern_parent.typeptr_cname: - code.putln("if (likely(%s->tp_richcompare)) return %s->tp_richcompare(o1, o2, op);" % ( - extern_parent.typeptr_cname, extern_parent.typeptr_cname)) - code.putln("return __Pyx_NewRef(Py_NotImplemented);") - code.putln("}") - - code.putln("}") # switch - code.putln("}") - + def generate_richcmp_function(self, scope, code): + if scope.lookup_here("__richcmp__"): + # user implemented, nothing to do + return + # otherwise, we have to generate it from the Python special methods + richcmp_cfunc = scope.mangle_internal("tp_richcompare") + code.putln("") + code.putln("static PyObject *%s(PyObject *o1, PyObject *o2, int op) {" % richcmp_cfunc) + code.putln("switch (op) {") + + class_scopes = [] + cls = scope.parent_type + while cls is not None and not cls.entry.visibility == 'extern': + class_scopes.append(cls.scope) + cls = cls.scope.parent_type.base_type + assert scope in class_scopes + + extern_parent = None + if cls and cls.entry.visibility == 'extern': + # need to call up into base classes as we may not know all implemented comparison methods + extern_parent = cls if cls.typeptr_cname else scope.parent_type.base_type + + eq_entry = None + has_ne = False + for cmp_method in TypeSlots.richcmp_special_methods: + for class_scope in class_scopes: + entry = class_scope.lookup_here(cmp_method) + if entry is not None: + break + else: + continue + + cmp_type = cmp_method.strip('_').upper() # e.g. "__eq__" -> EQ + code.putln("case Py_%s: {" % cmp_type) + if cmp_method == '__eq__': + eq_entry = entry + # Python itself does not do this optimisation, it seems... + #code.putln("if (o1 == o2) return __Pyx_NewRef(Py_True);") + elif cmp_method == '__ne__': + has_ne = True + # Python itself does not do this optimisation, it seems... + #code.putln("if (o1 == o2) return __Pyx_NewRef(Py_False);") + code.putln("return %s(o1, o2);" % entry.func_cname) + code.putln("}") + + if eq_entry and not has_ne and not extern_parent: + code.putln("case Py_NE: {") + code.putln("PyObject *ret;") + # Python itself does not do this optimisation, it seems... + #code.putln("if (o1 == o2) return __Pyx_NewRef(Py_False);") + code.putln("ret = %s(o1, o2);" % eq_entry.func_cname) + code.putln("if (likely(ret && ret != Py_NotImplemented)) {") + code.putln("int b = __Pyx_PyObject_IsTrue(ret); Py_DECREF(ret);") + code.putln("if (unlikely(b < 0)) return NULL;") + code.putln("ret = (b) ? Py_False : Py_True;") + code.putln("Py_INCREF(ret);") + code.putln("}") + code.putln("return ret;") + code.putln("}") + + code.putln("default: {") + if extern_parent and extern_parent.typeptr_cname: + code.putln("if (likely(%s->tp_richcompare)) return %s->tp_richcompare(o1, o2, op);" % ( + extern_parent.typeptr_cname, extern_parent.typeptr_cname)) + code.putln("return __Pyx_NewRef(Py_NotImplemented);") + code.putln("}") + + code.putln("}") # switch + code.putln("}") + def generate_getattro_function(self, scope, code): # First try to get the attribute using __getattribute__, if defined, or # PyObject_GenericGetAttr. @@ -1918,19 +1918,19 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): # If that raises an AttributeError, call the __getattr__ if defined. # # In both cases, defined can be in this class, or any base class. - def lookup_here_or_base(n, tp=None, extern_return=None): + def lookup_here_or_base(n, tp=None, extern_return=None): # Recursive lookup - if tp is None: - tp = scope.parent_type - r = tp.scope.lookup_here(n) - if r is None: - if tp.is_external and extern_return is not None: - return extern_return - if tp.base_type is not None: - return lookup_here_or_base(n, tp.base_type) - return r - - has_instance_dict = lookup_here_or_base("__dict__", extern_return="extern") + if tp is None: + tp = scope.parent_type + r = tp.scope.lookup_here(n) + if r is None: + if tp.is_external and extern_return is not None: + return extern_return + if tp.base_type is not None: + return lookup_here_or_base(n, tp.base_type) + return r + + has_instance_dict = lookup_here_or_base("__dict__", extern_return="extern") getattr_entry = lookup_here_or_base("__getattr__") getattribute_entry = lookup_here_or_base("__getattribute__") code.putln("") @@ -1942,20 +1942,20 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): "PyObject *v = %s(o, n);" % ( getattribute_entry.func_cname)) else: - if not has_instance_dict and scope.parent_type.is_final_type: - # Final with no dict => use faster type attribute lookup. - code.globalstate.use_utility_code( - UtilityCode.load_cached("PyObject_GenericGetAttrNoDict", "ObjectHandling.c")) - generic_getattr_cfunc = "__Pyx_PyObject_GenericGetAttrNoDict" - elif not has_instance_dict or has_instance_dict == "extern": - # No dict in the known ancestors, but don't know about extern ancestors or subtypes. - code.globalstate.use_utility_code( - UtilityCode.load_cached("PyObject_GenericGetAttr", "ObjectHandling.c")) - generic_getattr_cfunc = "__Pyx_PyObject_GenericGetAttr" - else: - generic_getattr_cfunc = "PyObject_GenericGetAttr" + if not has_instance_dict and scope.parent_type.is_final_type: + # Final with no dict => use faster type attribute lookup. + code.globalstate.use_utility_code( + UtilityCode.load_cached("PyObject_GenericGetAttrNoDict", "ObjectHandling.c")) + generic_getattr_cfunc = "__Pyx_PyObject_GenericGetAttrNoDict" + elif not has_instance_dict or has_instance_dict == "extern": + # No dict in the known ancestors, but don't know about extern ancestors or subtypes. + code.globalstate.use_utility_code( + UtilityCode.load_cached("PyObject_GenericGetAttr", "ObjectHandling.c")) + generic_getattr_cfunc = "__Pyx_PyObject_GenericGetAttr" + else: + generic_getattr_cfunc = "PyObject_GenericGetAttr" code.putln( - "PyObject *v = %s(o, n);" % generic_getattr_cfunc) + "PyObject *v = %s(o, n);" % generic_getattr_cfunc) if getattr_entry is not None: code.putln( "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {") @@ -2311,47 +2311,47 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("return -1;") code.putln("}") code.putln("") - code.putln(UtilityCode.load_as_string("ImportStar", "ImportExport.c")[1]) + code.putln(UtilityCode.load_as_string("ImportStar", "ImportExport.c")[1]) code.exit_cfunc_scope() # done with labels def generate_module_init_func(self, imported_modules, env, options, code): subfunction = self.mod_init_subfunction(self.pos, self.scope, code) - + code.enter_cfunc_scope(self.scope) code.putln("") - code.putln(UtilityCode.load_as_string("PyModInitFuncType", "ModuleSetupCode.c")[0]) + code.putln(UtilityCode.load_as_string("PyModInitFuncType", "ModuleSetupCode.c")[0]) init_name = 'init' + (options.init_suffix or env.module_name) - header2 = "__Pyx_PyMODINIT_FUNC %s(void)" % init_name - header3 = "__Pyx_PyMODINIT_FUNC %s(void)" % self.mod_init_func_cname('PyInit', env, options) + header2 = "__Pyx_PyMODINIT_FUNC %s(void)" % init_name + header3 = "__Pyx_PyMODINIT_FUNC %s(void)" % self.mod_init_func_cname('PyInit', env, options) code.putln("#if PY_MAJOR_VERSION < 3") - # Optimise for small code size as the module init function is only executed once. - code.putln("%s CYTHON_SMALL_CODE; /*proto*/" % header2) + # Optimise for small code size as the module init function is only executed once. + code.putln("%s CYTHON_SMALL_CODE; /*proto*/" % header2) code.putln(header2) code.putln("#else") - code.putln("%s CYTHON_SMALL_CODE; /*proto*/" % header3) + code.putln("%s CYTHON_SMALL_CODE; /*proto*/" % header3) code.putln(header3) - - # CPython 3.5+ supports multi-phase module initialisation (gives access to __spec__, __file__, etc.) - code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT") + + # CPython 3.5+ supports multi-phase module initialisation (gives access to __spec__, __file__, etc.) + code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT") code.putln("{") - code.putln("return PyModuleDef_Init(&%s);" % Naming.pymoduledef_cname) - code.putln("}") - - mod_create_func = UtilityCode.load_as_string("ModuleCreationPEP489", "ModuleSetupCode.c")[1] - code.put(mod_create_func) - - code.putln("") - # main module init code lives in Py_mod_exec function, not in PyInit function + code.putln("return PyModuleDef_Init(&%s);" % Naming.pymoduledef_cname) + code.putln("}") + + mod_create_func = UtilityCode.load_as_string("ModuleCreationPEP489", "ModuleSetupCode.c")[1] + code.put(mod_create_func) + + code.putln("") + # main module init code lives in Py_mod_exec function, not in PyInit function code.putln("static CYTHON_SMALL_CODE int %s(PyObject *%s)" % ( - self.mod_init_func_cname(Naming.pymodule_exec_func_cname, env), - Naming.pymodinit_module_arg)) - code.putln("#endif") # PEP489 - - code.putln("#endif") # Py3 - - # start of module init/exec function (pre/post PEP 489) - code.putln("{") - + self.mod_init_func_cname(Naming.pymodule_exec_func_cname, env), + Naming.pymodinit_module_arg)) + code.putln("#endif") # PEP489 + + code.putln("#endif") # Py3 + + # start of module init/exec function (pre/post PEP 489) + code.putln("{") + tempdecl_code = code.insertion_point() profile = code.globalstate.directives['profile'] @@ -2360,34 +2360,34 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.globalstate.use_utility_code(UtilityCode.load_cached("Profile", "Profile.c")) code.put_declare_refcount_context() - code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT") + code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT") # Most extension modules simply can't deal with it, and Cython isn't ready either. # See issues listed here: https://docs.python.org/3/c-api/init.html#sub-interpreter-support code.putln("if (%s) {" % Naming.module_cname) - # Hack: enforce single initialisation. + # Hack: enforce single initialisation. code.putln("if (%s == %s) return 0;" % ( - Naming.module_cname, - Naming.pymodinit_module_arg, - )) + Naming.module_cname, + Naming.pymodinit_module_arg, + )) code.putln('PyErr_SetString(PyExc_RuntimeError,' ' "Module \'%s\' has already been imported. Re-initialisation is not supported.");' % env.module_name) code.putln("return -1;") code.putln("}") - code.putln("#elif PY_MAJOR_VERSION >= 3") - # Hack: enforce single initialisation also on reimports under different names on Python 3 (with PEP 3121/489). - code.putln("if (%s) return __Pyx_NewRef(%s);" % ( - Naming.module_cname, - Naming.module_cname, - )) - code.putln("#endif") - + code.putln("#elif PY_MAJOR_VERSION >= 3") + # Hack: enforce single initialisation also on reimports under different names on Python 3 (with PEP 3121/489). + code.putln("if (%s) return __Pyx_NewRef(%s);" % ( + Naming.module_cname, + Naming.module_cname, + )) + code.putln("#endif") + if profile or linetrace: tempdecl_code.put_trace_declarations() code.put_trace_frame_init() - refnanny_import_code = UtilityCode.load_as_string("ImportRefnannyAPI", "ModuleSetupCode.c")[1] - code.putln(refnanny_import_code.rstrip()) + refnanny_import_code = UtilityCode.load_as_string("ImportRefnannyAPI", "ModuleSetupCode.c")[1] + code.putln(refnanny_import_code.rstrip()) code.put_setup_refcount_context(header3) env.use_utility_code(UtilityCode.load("CheckBinaryVersion", "ModuleSetupCode.c")) @@ -2403,14 +2403,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("%s = PyUnicode_FromStringAndSize(\"\", 0); %s" % ( Naming.empty_unicode, code.error_goto_if_null(Naming.empty_unicode, self.pos))) - for ext_type in ('CyFunction', 'FusedFunction', 'Coroutine', 'Generator', 'AsyncGen', 'StopAsyncIteration'): + for ext_type in ('CyFunction', 'FusedFunction', 'Coroutine', 'Generator', 'AsyncGen', 'StopAsyncIteration'): code.putln("#ifdef __Pyx_%s_USED" % ext_type) code.put_error_if_neg(self.pos, "__pyx_%s_init()" % ext_type) code.putln("#endif") code.putln("/*--- Library function declarations ---*/") - if env.directives['np_pythran']: - code.put_error_if_neg(self.pos, "_import_array()") + if env.directives['np_pythran']: + code.put_error_if_neg(self.pos, "_import_array()") code.putln("/*--- Threads initialization code ---*/") code.putln("#if defined(WITH_THREAD) && PY_VERSION_HEX < 0x030700F0 " @@ -2446,33 +2446,33 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("/*--- Constants init code ---*/") code.put_error_if_neg(self.pos, "__Pyx_InitCachedConstants()") - code.putln("/*--- Global type/function init code ---*/") - - with subfunction("Global init code") as inner_code: - self.generate_global_init_code(env, inner_code) + code.putln("/*--- Global type/function init code ---*/") - with subfunction("Variable export code") as inner_code: - self.generate_c_variable_export_code(env, inner_code) + with subfunction("Global init code") as inner_code: + self.generate_global_init_code(env, inner_code) - with subfunction("Function export code") as inner_code: - self.generate_c_function_export_code(env, inner_code) + with subfunction("Variable export code") as inner_code: + self.generate_c_variable_export_code(env, inner_code) - with subfunction("Type init code") as inner_code: - self.generate_type_init_code(env, inner_code) + with subfunction("Function export code") as inner_code: + self.generate_c_function_export_code(env, inner_code) - with subfunction("Type import code") as inner_code: - for module in imported_modules: - self.generate_type_import_code_for_module(module, env, inner_code) + with subfunction("Type init code") as inner_code: + self.generate_type_init_code(env, inner_code) - with subfunction("Variable import code") as inner_code: - for module in imported_modules: - self.generate_c_variable_import_code_for_module(module, env, inner_code) + with subfunction("Type import code") as inner_code: + for module in imported_modules: + self.generate_type_import_code_for_module(module, env, inner_code) - with subfunction("Function import code") as inner_code: - for module in imported_modules: - self.specialize_fused_types(module) - self.generate_c_function_import_code_for_module(module, env, inner_code) + with subfunction("Variable import code") as inner_code: + for module in imported_modules: + self.generate_c_variable_import_code_for_module(module, env, inner_code) + with subfunction("Function import code") as inner_code: + for module in imported_modules: + self.specialize_fused_types(module) + self.generate_c_function_import_code_for_module(module, env, inner_code) + code.putln("/*--- Execution code ---*/") code.mark_pos(None) @@ -2522,11 +2522,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.put_finish_refcount_context() - code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT") - code.putln("return (%s != NULL) ? 0 : -1;" % env.module_cname) - code.putln("#elif PY_MAJOR_VERSION >= 3") - code.putln("return %s;" % env.module_cname) - code.putln("#else") + code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT") + code.putln("return (%s != NULL) ? 0 : -1;" % env.module_cname) + code.putln("#elif PY_MAJOR_VERSION >= 3") + code.putln("return %s;" % env.module_cname) + code.putln("#else") code.putln("return;") code.putln("#endif") code.putln('}') @@ -2536,86 +2536,86 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.exit_cfunc_scope() def mod_init_subfunction(self, pos, scope, orig_code): - """ - Return a context manager that allows deviating the module init code generation - into a separate function and instead inserts a call to it. - - Can be reused sequentially to create multiple functions. - The functions get inserted at the point where the context manager was created. - The call gets inserted where the context manager is used (on entry). - """ - prototypes = orig_code.insertion_point() - prototypes.putln("") - function_code = orig_code.insertion_point() - function_code.putln("") - - class ModInitSubfunction(object): - def __init__(self, code_type): - cname = '_'.join(code_type.lower().split()) - assert re.match("^[a-z0-9_]+$", cname) - self.cfunc_name = "__Pyx_modinit_%s" % cname - self.description = code_type - self.tempdecl_code = None - self.call_code = None - - def __enter__(self): - self.call_code = orig_code.insertion_point() - code = function_code - code.enter_cfunc_scope(scope) + """ + Return a context manager that allows deviating the module init code generation + into a separate function and instead inserts a call to it. + + Can be reused sequentially to create multiple functions. + The functions get inserted at the point where the context manager was created. + The call gets inserted where the context manager is used (on entry). + """ + prototypes = orig_code.insertion_point() + prototypes.putln("") + function_code = orig_code.insertion_point() + function_code.putln("") + + class ModInitSubfunction(object): + def __init__(self, code_type): + cname = '_'.join(code_type.lower().split()) + assert re.match("^[a-z0-9_]+$", cname) + self.cfunc_name = "__Pyx_modinit_%s" % cname + self.description = code_type + self.tempdecl_code = None + self.call_code = None + + def __enter__(self): + self.call_code = orig_code.insertion_point() + code = function_code + code.enter_cfunc_scope(scope) prototypes.putln("static CYTHON_SMALL_CODE int %s(void); /*proto*/" % self.cfunc_name) - code.putln("static int %s(void) {" % self.cfunc_name) - code.put_declare_refcount_context() - self.tempdecl_code = code.insertion_point() - code.put_setup_refcount_context(self.cfunc_name) - # Leave a grepable marker that makes it easy to find the generator source. - code.putln("/*--- %s ---*/" % self.description) - return code - - def __exit__(self, *args): - code = function_code - code.put_finish_refcount_context() - code.putln("return 0;") - - self.tempdecl_code.put_temp_declarations(code.funcstate) - self.tempdecl_code = None - - needs_error_handling = code.label_used(code.error_label) - if needs_error_handling: - code.put_label(code.error_label) - for cname, type in code.funcstate.all_managed_temps(): - code.put_xdecref(cname, type) - code.put_finish_refcount_context() - code.putln("return -1;") - code.putln("}") - code.exit_cfunc_scope() - code.putln("") - - if needs_error_handling: + code.putln("static int %s(void) {" % self.cfunc_name) + code.put_declare_refcount_context() + self.tempdecl_code = code.insertion_point() + code.put_setup_refcount_context(self.cfunc_name) + # Leave a grepable marker that makes it easy to find the generator source. + code.putln("/*--- %s ---*/" % self.description) + return code + + def __exit__(self, *args): + code = function_code + code.put_finish_refcount_context() + code.putln("return 0;") + + self.tempdecl_code.put_temp_declarations(code.funcstate) + self.tempdecl_code = None + + needs_error_handling = code.label_used(code.error_label) + if needs_error_handling: + code.put_label(code.error_label) + for cname, type in code.funcstate.all_managed_temps(): + code.put_xdecref(cname, type) + code.put_finish_refcount_context() + code.putln("return -1;") + code.putln("}") + code.exit_cfunc_scope() + code.putln("") + + if needs_error_handling: self.call_code.putln( self.call_code.error_goto_if_neg("%s()" % self.cfunc_name, pos)) - else: - self.call_code.putln("(void)%s();" % self.cfunc_name) - self.call_code = None - - return ModInitSubfunction - + else: + self.call_code.putln("(void)%s();" % self.cfunc_name) + self.call_code = None + + return ModInitSubfunction + def generate_module_import_setup(self, env, code): module_path = env.directives['set_initial_path'] if module_path == 'SOURCEFILE': module_path = self.pos[0].filename if module_path: - code.putln('if (!CYTHON_PEP489_MULTI_PHASE_INIT) {') + code.putln('if (!CYTHON_PEP489_MULTI_PHASE_INIT) {') code.putln('if (PyObject_SetAttrString(%s, "__file__", %s) < 0) %s;' % ( env.module_cname, code.globalstate.get_py_string_const( EncodedString(decode_filename(module_path))).cname, code.error_goto(self.pos))) - code.putln("}") + code.putln("}") if env.is_package: # set __path__ to mark the module as package - code.putln('if (!CYTHON_PEP489_MULTI_PHASE_INIT) {') + code.putln('if (!CYTHON_PEP489_MULTI_PHASE_INIT) {') temp = code.funcstate.allocate_temp(py_object_type, True) code.putln('%s = Py_BuildValue("[O]", %s); %s' % ( temp, @@ -2629,12 +2629,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): env.module_cname, temp, code.error_goto(self.pos))) code.put_decref_clear(temp, py_object_type) code.funcstate.release_temp(temp) - code.putln("}") + code.putln("}") elif env.is_package: # packages require __path__, so all we can do is try to figure # out the module path at runtime by rerunning the import lookup - code.putln("if (!CYTHON_PEP489_MULTI_PHASE_INIT) {") + code.putln("if (!CYTHON_PEP489_MULTI_PHASE_INIT) {") package_name, _ = self.full_module_name.rsplit('.', 1) if '.' in package_name: parent_name = '"%s"' % (package_name.rsplit('.', 1)[0],) @@ -2648,7 +2648,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.globalstate.get_py_string_const( EncodedString(env.module_name)).cname), self.pos)) - code.putln("}") + code.putln("}") # CPython may not have put us into sys.modules yet, but relative imports and reimports require it fq_module_name = self.full_module_name @@ -2750,9 +2750,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): main_method=Options.embed, wmain_method=wmain)) - def mod_init_func_cname(self, prefix, env, options=None): + def mod_init_func_cname(self, prefix, env, options=None): return '%s_%s' % (prefix, options and options.init_suffix or env.module_name) - + def generate_pymoduledef_struct(self, env, options, code): if env.doc: doc = "%s" % code.get_string_const(env.doc) @@ -2765,35 +2765,35 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("") code.putln("#if PY_MAJOR_VERSION >= 3") - code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT") - exec_func_cname = self.mod_init_func_cname(Naming.pymodule_exec_func_cname, env) - code.putln("static PyObject* %s(PyObject *spec, PyModuleDef *def); /*proto*/" % - Naming.pymodule_create_func_cname) - code.putln("static int %s(PyObject* module); /*proto*/" % exec_func_cname) - - code.putln("static PyModuleDef_Slot %s[] = {" % Naming.pymoduledef_slots_cname) - code.putln("{Py_mod_create, (void*)%s}," % Naming.pymodule_create_func_cname) - code.putln("{Py_mod_exec, (void*)%s}," % exec_func_cname) - code.putln("{0, NULL}") - code.putln("};") - code.putln("#endif") - - code.putln("") + code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT") + exec_func_cname = self.mod_init_func_cname(Naming.pymodule_exec_func_cname, env) + code.putln("static PyObject* %s(PyObject *spec, PyModuleDef *def); /*proto*/" % + Naming.pymodule_create_func_cname) + code.putln("static int %s(PyObject* module); /*proto*/" % exec_func_cname) + + code.putln("static PyModuleDef_Slot %s[] = {" % Naming.pymoduledef_slots_cname) + code.putln("{Py_mod_create, (void*)%s}," % Naming.pymodule_create_func_cname) + code.putln("{Py_mod_exec, (void*)%s}," % exec_func_cname) + code.putln("{0, NULL}") + code.putln("};") + code.putln("#endif") + + code.putln("") code.putln("static struct PyModuleDef %s = {" % Naming.pymoduledef_cname) code.putln(" PyModuleDef_HEAD_INIT,") code.putln(' "%s",' % (options.module_name or env.module_name)) code.putln(" %s, /* m_doc */" % doc) - code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT") - code.putln(" 0, /* m_size */") - code.putln("#else") + code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT") + code.putln(" 0, /* m_size */") + code.putln("#else") code.putln(" -1, /* m_size */") - code.putln("#endif") + code.putln("#endif") code.putln(" %s /* m_methods */," % env.method_table_cname) - code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT") - code.putln(" %s, /* m_slots */" % Naming.pymoduledef_slots_cname) - code.putln("#else") + code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT") + code.putln(" %s, /* m_slots */" % Naming.pymoduledef_slots_cname) + code.putln("#else") code.putln(" NULL, /* m_reload */") - code.putln("#endif") + code.putln("#endif") code.putln(" NULL, /* m_traverse */") code.putln(" NULL, /* m_clear */") code.putln(" %s /* m_free */" % cleanup_func) @@ -2807,13 +2807,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): doc = "%s" % code.get_string_const(env.doc) else: doc = "0" - - code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT") - code.putln("%s = %s;" % ( - env.module_cname, - Naming.pymodinit_module_arg)) - code.put_incref(env.module_cname, py_object_type, nanny=False) - code.putln("#else") + + code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT") + code.putln("%s = %s;" % ( + env.module_cname, + Naming.pymodinit_module_arg)) + code.put_incref(env.module_cname, py_object_type, nanny=False) + code.putln("#else") code.putln("#if PY_MAJOR_VERSION < 3") code.putln( '%s = Py_InitModule4("%s", %s, %s, 0, PYTHON_API_VERSION); Py_XINCREF(%s);' % ( @@ -2829,8 +2829,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): Naming.pymoduledef_cname)) code.putln("#endif") code.putln(code.error_goto_if_null(env.module_cname, self.pos)) - code.putln("#endif") # CYTHON_PEP489_MULTI_PHASE_INIT - + code.putln("#endif") # CYTHON_PEP489_MULTI_PHASE_INIT + code.putln( "%s = PyModule_GetDict(%s); %s" % ( env.module_dict_cname, env.module_cname, @@ -2842,10 +2842,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): Naming.builtins_cname, code.error_goto_if_null(Naming.builtins_cname, self.pos))) code.put_incref(Naming.builtins_cname, py_object_type, nanny=False) - code.putln( - '%s = PyImport_AddModule((char *) "cython_runtime"); %s' % ( - Naming.cython_runtime_cname, - code.error_goto_if_null(Naming.cython_runtime_cname, self.pos))) + code.putln( + '%s = PyImport_AddModule((char *) "cython_runtime"); %s' % ( + Naming.cython_runtime_cname, + code.error_goto_if_null(Naming.cython_runtime_cname, self.pos))) code.put_incref(Naming.cython_runtime_cname, py_object_type, nanny=False) code.putln( 'if (PyObject_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % ( @@ -3110,8 +3110,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln(' if (!%s) %s' % (type.typeptr_cname, error_code)) - def generate_type_ready_code(self, entry, code): - Nodes.CClassDefNode.generate_type_ready_code(entry, code) + def generate_type_ready_code(self, entry, code): + Nodes.CClassDefNode.generate_type_ready_code(entry, code) def generate_exttype_vtable_init_code(self, entry, code): # Generate code to initialise the C method table of an @@ -3188,7 +3188,7 @@ def generate_cfunction_declaration(entry, env, code, definition): dll_linkage = "DL_IMPORT" elif entry.visibility == 'public': storage_class = Naming.extern_c_macro - dll_linkage = None + dll_linkage = None elif entry.visibility == 'private': storage_class = "static" dll_linkage = None |