1#
2#   Module parse tree node
3#
4
5from __future__ import absolute_import
6
7import cython
8cython.declare(Naming=object, Options=object, PyrexTypes=object, TypeSlots=object,
9               error=object, warning=object, py_object_type=object, UtilityCode=object,
10               EncodedString=object, re=object)
11
12from collections import defaultdict
13import json
14import operator
15import os
16import re
17import sys
18
19from .PyrexTypes import CPtrType
20from . import Future
21from . import Annotate
22from . import Code
23from . import Naming
24from . import Nodes
25from . import Options
26from . import TypeSlots
27from . import PyrexTypes
28from . import Pythran
29
30from .Errors import error, warning, CompileError
31from .PyrexTypes import py_object_type
32from ..Utils import open_new_file, replace_suffix, decode_filename, build_hex_version, is_cython_generated_file
33from .Code import UtilityCode, IncludeCode, TempitaUtilityCode
34from .StringEncoding import EncodedString, encoded_string_or_bytes_literal
35from .Pythran import has_np_pythran
36
37
38def replace_suffix_encoded(path, newsuf):
39    # calls replace suffix and returns a EncodedString or BytesLiteral with the encoding set
40    newpath = replace_suffix(path, newsuf)
41    return as_encoded_filename(newpath)
42
43def as_encoded_filename(path):
44    # wraps the path with either EncodedString or BytesLiteral (depending on its input type)
45    # and sets the encoding to the file system encoding
46    return encoded_string_or_bytes_literal(path, sys.getfilesystemencoding())
47
48
49def check_c_declarations_pxd(module_node):
50    module_node.scope.check_c_classes_pxd()
51    return module_node
52
53
54def check_c_declarations(module_node):
55    module_node.scope.check_c_classes()
56    module_node.scope.check_c_functions()
57    return module_node
58
59
60def generate_c_code_config(env, options):
61    if Options.annotate or options.annotate:
62        emit_linenums = False
63    else:
64        emit_linenums = options.emit_linenums
65
66    if hasattr(options, "emit_code_comments"):
67        print('Warning: option emit_code_comments is deprecated. '
68              'Instead, use compiler directive emit_code_comments.')
69
70    return Code.CCodeConfig(
71        emit_linenums=emit_linenums,
72        emit_code_comments=env.directives['emit_code_comments'],
73        c_line_in_traceback=options.c_line_in_traceback)
74
75# The code required to generate one comparison from another.
76# The keys are (from, to).
77# The comparison operator always goes first, with equality possibly second.
78# The first value specifies if the comparison is inverted. The second is the
79# logic op to use, and the third is if the equality is inverted or not.
80TOTAL_ORDERING = {
81    # a > b from (not a < b) and (a != b)
82    ('__lt__', '__gt__'): (True, '&&', True),
83    # a <= b from (a < b) or (a == b)
84    ('__lt__', '__le__'): (False, '||', False),
85    # a >= b from (not a < b).
86    ('__lt__', '__ge__'): (True, '', None),
87
88    # a >= b from (not a <= b) or (a == b)
89    ('__le__', '__ge__'): (True, '||', False),
90    # a < b, from (a <= b) and (a != b)
91    ('__le__', '__lt__'): (False, '&&', True),
92    # a > b from (not a <= b)
93    ('__le__', '__gt__'): (True, '', None),
94
95    # a < b from (not a > b) and (a != b)
96    ('__gt__', '__lt__'): (True, '&&', True),
97    # a >= b from (a > b) or (a == b)
98    ('__gt__', '__ge__'): (False, '||', False),
99    # a <= b from (not a > b)
100    ('__gt__', '__le__'): (True, '', None),
101
102    # Return a <= b from (not a >= b) or (a == b)
103    ('__ge__', '__le__'): (True, '||', False),
104    # a > b from (a >= b) and (a != b)
105    ('__ge__', '__gt__'): (False, '&&', True),
106    # a < b from (not a >= b)
107    ('__ge__', '__lt__'): (True, '', None),
108}
109
110
111class ModuleNode(Nodes.Node, Nodes.BlockNode):
112    #  doc       string or None
113    #  body      StatListNode
114    #
115    #  referenced_modules   [ModuleScope]
116    #  full_module_name     string
117    #
118    #  scope                The module scope.
119    #  compilation_source   A CompilationSource (see Main)
120    #  directives           Top-level compiler directives
121
122    child_attrs = ["body"]
123    directives = None
124
125    def merge_in(self, tree, scope, merge_scope=False):
126        # Merges in the contents of another tree, and possibly scope. With the
127        # current implementation below, this must be done right prior
128        # to code generation.
129        #
130        # Note: This way of doing it seems strange -- I believe the
131        # right concept is to split ModuleNode into a ModuleNode and a
132        # CodeGenerator, and tell that CodeGenerator to generate code
133        # from multiple sources.
134        assert isinstance(self.body, Nodes.StatListNode)
135        if scope.directives != self.scope.directives:
136            # merged in nodes should keep their original compiler directives
137            # (for example inline cdef functions)
138            tree = Nodes.CompilerDirectivesNode(tree.pos, body=tree, directives=scope.directives)
139        if isinstance(tree, Nodes.StatListNode):
140            self.body.stats.extend(tree.stats)
141        else:
142            self.body.stats.append(tree)
143
144        self.scope.utility_code_list.extend(scope.utility_code_list)
145
146        for inc in scope.c_includes.values():
147            self.scope.process_include(inc)
148
149        def extend_if_not_in(L1, L2):
150            for x in L2:
151                if x not in L1:
152                    L1.append(x)
153
154        extend_if_not_in(self.scope.included_files, scope.included_files)
155
156        if merge_scope:
157            # Ensure that we don't generate import code for these entries!
158            for entry in scope.c_class_entries:
159                entry.type.module_name = self.full_module_name
160                entry.type.scope.directives["internal"] = True
161
162            self.scope.merge_in(scope)
163
164    def with_compiler_directives(self):
165        # When merging a utility code module into the user code we need to preserve
166        # the original compiler directives. This returns the body of the module node,
167        # wrapped in its set of directives.
168        body = Nodes.CompilerDirectivesNode(self.pos, directives=self.directives, body=self.body)
169        return body
170
171    def analyse_declarations(self, env):
172        if has_np_pythran(env):
173            Pythran.include_pythran_generic(env)
174        if self.directives:
175            env.old_style_globals = self.directives['old_style_globals']
176        if not Options.docstrings:
177            env.doc = self.doc = None
178        elif Options.embed_pos_in_docstring:
179            env.doc = EncodedString(u'File: %s (starting at line %s)' % Nodes.relative_position(self.pos))
180            if self.doc is not None:
181                env.doc = EncodedString(env.doc + u'\n' + self.doc)
182                env.doc.encoding = self.doc.encoding
183        else:
184            env.doc = self.doc
185        env.directives = self.directives
186
187        self.body.analyse_declarations(env)
188
189    def prepare_utility_code(self):
190        # prepare any utility code that must be created before code generation
191        # specifically: CythonUtilityCode
192        env = self.scope
193        if env.has_import_star:
194            self.create_import_star_conversion_utility_code(env)
195        for name, entry in sorted(env.entries.items()):
196            if (entry.create_wrapper and entry.scope is env
197                    and entry.is_type and (entry.type.is_enum or entry.type.is_cpp_enum)):
198                entry.type.create_type_wrapper(env)
199
200    def process_implementation(self, options, result):
201        env = self.scope
202        env.return_type = PyrexTypes.c_void_type
203        self.referenced_modules = []
204        self.find_referenced_modules(env, self.referenced_modules, {})
205        self.sort_cdef_classes(env)
206        self.generate_c_code(env, options, result)
207        self.generate_h_code(env, options, result)
208        self.generate_api_code(env, options, result)
209
210    def has_imported_c_functions(self):
211        for module in self.referenced_modules:
212            for entry in module.cfunc_entries:
213                if entry.defined_in_pxd:
214                    return 1
215        return 0
216
217    def assure_safe_target(self, path, allow_failed=False):
218        # Check for a common gotcha for new users: naming your .pyx file after the .c file you want to wrap
219        if not is_cython_generated_file(path, allow_failed=allow_failed, if_not_found=True):
220            # Raising a fatal CompileError instead of calling error() to prevent castrating an existing file.
221            raise CompileError(
222                self.pos, 'The output file already exists and does not look like it was generated by Cython: "%s"' %
223                          os.path.basename(path))
224
225    def generate_h_code(self, env, options, result):
226        def h_entries(entries, api=0, pxd=0):
227            return [entry for entry in entries
228                    if ((entry.visibility == 'public') or
229                        (api and entry.api) or
230                        (pxd and entry.defined_in_pxd))]
231        h_types = h_entries(env.type_entries, api=1)
232        h_vars = h_entries(env.var_entries)
233        h_funcs = h_entries(env.cfunc_entries)
234        h_extension_types = h_entries(env.c_class_entries)
235
236        if h_types or h_vars or h_funcs or h_extension_types:
237            result.h_file = replace_suffix_encoded(result.c_file, ".h")
238            self.assure_safe_target(result.h_file)
239
240            h_code_writer = Code.CCodeWriter()
241            c_code_config = generate_c_code_config(env, options)
242            globalstate = Code.GlobalState(h_code_writer, self, c_code_config)
243            globalstate.initialize_main_h_code()  # in-case utility code is used in the header
244            h_code_start = globalstate.parts['h_code']
245            h_code_main = globalstate.parts['type_declarations']
246            h_code_end = globalstate.parts['end']
247            if options.generate_pxi:
248                result.i_file = replace_suffix_encoded(result.c_file, ".pxi")
249                i_code = Code.PyrexCodeWriter(result.i_file)
250            else:
251                i_code = None
252
253            h_code_start.put_generated_by()
254            h_guard = self.api_name(Naming.h_guard_prefix, env)
255            h_code_start.put_h_guard(h_guard)
256            h_code_start.putln("")
257            h_code_start.putln('#include "Python.h"')
258            self.generate_type_header_code(h_types, h_code_start)
259            if options.capi_reexport_cincludes:
260                self.generate_includes(env, [], h_code_start)
261            h_code_start.putln("")
262            api_guard = self.api_name(Naming.api_guard_prefix, env)
263            h_code_start.putln("#ifndef %s" % api_guard)
264            h_code_start.putln("")
265            self.generate_extern_c_macro_definition(h_code_start)
266            h_code_start.putln("")
267            self.generate_dl_import_macro(h_code_start)
268            if h_extension_types:
269                h_code_main.putln("")
270                for entry in h_extension_types:
271                    self.generate_cclass_header_code(entry.type, h_code_main)
272                    if i_code:
273                        self.generate_cclass_include_code(entry.type, i_code)
274            if h_funcs:
275                h_code_main.putln("")
276                for entry in h_funcs:
277                    self.generate_public_declaration(entry, h_code_main, i_code)
278            if h_vars:
279                h_code_main.putln("")
280                for entry in h_vars:
281                    self.generate_public_declaration(entry, h_code_main, i_code)
282            h_code_main.putln("")
283            h_code_main.putln("#endif /* !%s */" % api_guard)
284            h_code_main.putln("")
285            h_code_main.putln("/* WARNING: the interface of the module init function changed in CPython 3.5. */")
286            h_code_main.putln("/* It now returns a PyModuleDef instance instead of a PyModule instance. */")
287            h_code_main.putln("")
288            h_code_main.putln("#if PY_MAJOR_VERSION < 3")
289            if env.module_name.isascii():
290                py2_mod_name = env.module_name
291            else:
292                py2_mod_name = env.module_name.encode("ascii", errors="ignore").decode("utf-8")
293                h_code_main.putln('#error "Unicode module names are not supported in Python 2";')
294            h_code_main.putln("PyMODINIT_FUNC init%s(void);" % py2_mod_name)
295            h_code_main.putln("#else")
296            py3_mod_func_name = self.mod_init_func_cname('PyInit', env)
297            warning_string = EncodedString('Use PyImport_AppendInittab("%s", %s) instead of calling %s directly.' % (
298                py2_mod_name, py3_mod_func_name, py3_mod_func_name))
299            h_code_main.putln('/* WARNING: %s from Python 3.5 */' % warning_string.rstrip('.'))
300            h_code_main.putln("PyMODINIT_FUNC %s(void);" % py3_mod_func_name)
301            h_code_main.putln("")
302            h_code_main.putln("#if PY_VERSION_HEX >= 0x03050000 "
303                "&& (defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER) "
304                "|| (defined(__cplusplus) && __cplusplus >= 201402L))")
305            h_code_main.putln("#if defined(__cplusplus) && __cplusplus >= 201402L")
306            h_code_main.putln("[[deprecated(%s)]] inline" % warning_string.as_c_string_literal())
307            h_code_main.putln("#elif defined(__GNUC__) || defined(__clang__)")
308            h_code_main.putln('__attribute__ ((__deprecated__(%s), __unused__)) __inline__' % (
309                warning_string.as_c_string_literal()))
310            h_code_main.putln("#elif defined(_MSC_VER)")
311            h_code_main.putln('__declspec(deprecated(%s)) __inline' % (
312                warning_string.as_c_string_literal()))
313            h_code_main.putln('#endif')
314            h_code_main.putln("static PyObject* __PYX_WARN_IF_%s_INIT_CALLED(PyObject* res) {" % py3_mod_func_name)
315            h_code_main.putln("return res;")
316            h_code_main.putln("}")
317            # Function call is converted to warning macro; uncalled (pointer) is not
318            h_code_main.putln('#define %s() __PYX_WARN_IF_%s_INIT_CALLED(%s())' % (
319                py3_mod_func_name, py3_mod_func_name, py3_mod_func_name))
320            h_code_main.putln('#endif')
321            h_code_main.putln('#endif')
322
323            h_code_end.putln("")
324            h_code_end.putln("#endif /* !%s */" % h_guard)
325
326            with open_new_file(result.h_file) as f:
327                h_code_writer.copyto(f)
328
329    def generate_public_declaration(self, entry, h_code, i_code):
330        h_code.putln("%s %s;" % (
331            Naming.extern_c_macro,
332            entry.type.declaration_code(entry.cname)))
333        if i_code:
334            i_code.putln("cdef extern %s" % (
335                entry.type.declaration_code(entry.cname, pyrex=1)))
336
337    def api_name(self, prefix, env):
338        api_name = self.punycode_module_name(prefix, env.qualified_name)
339        return api_name.replace(".", "__")
340
341    def generate_api_code(self, env, options, result):
342        def api_entries(entries, pxd=0):
343            return [entry for entry in entries
344                    if entry.api or (pxd and entry.defined_in_pxd)]
345        api_vars = api_entries(env.var_entries)
346        api_funcs = api_entries(env.cfunc_entries)
347        api_extension_types = api_entries(env.c_class_entries)
348
349        if api_vars or api_funcs or api_extension_types:
350            result.api_file = replace_suffix_encoded(result.c_file, "_api.h")
351            self.assure_safe_target(result.api_file)
352
353            h_code = Code.CCodeWriter()
354            c_code_config = generate_c_code_config(env, options)
355            Code.GlobalState(h_code, self, c_code_config)
356            h_code.put_generated_by()
357            api_guard = self.api_name(Naming.api_guard_prefix, env)
358            h_code.put_h_guard(api_guard)
359            # Work around https://bugs.python.org/issue4709
360            h_code.putln('#ifdef __MINGW64__')
361            h_code.putln('#define MS_WIN64')
362            h_code.putln('#endif')
363
364            h_code.putln('#include "Python.h"')
365            if result.h_file:
366                h_filename = os.path.basename(result.h_file)
367                h_filename = as_encoded_filename(h_filename)
368                h_code.putln('#include %s' % h_filename.as_c_string_literal())
369            if api_extension_types:
370                h_code.putln("")
371                for entry in api_extension_types:
372                    type = entry.type
373                    h_code.putln("static PyTypeObject *%s = 0;" % type.typeptr_cname)
374                    h_code.putln("#define %s (*%s)" % (
375                        type.typeobj_cname, type.typeptr_cname))
376            if api_funcs:
377                h_code.putln("")
378                for entry in api_funcs:
379                    type = CPtrType(entry.type)
380                    cname = env.mangle(Naming.func_prefix_api, entry.name)
381                    h_code.putln("static %s = 0;" % type.declaration_code(cname))
382                    h_code.putln("#define %s %s" % (entry.name, cname))
383            if api_vars:
384                h_code.putln("")
385                for entry in api_vars:
386                    type = CPtrType(entry.type)
387                    cname = env.mangle(Naming.varptr_prefix_api, entry.name)
388                    h_code.putln("static %s = 0;" % type.declaration_code(cname))
389                    h_code.putln("#define %s (*%s)" % (entry.name, cname))
390            h_code.put(UtilityCode.load_as_string("PyIdentifierFromString", "ImportExport.c")[0])
391            if api_vars:
392                h_code.put(UtilityCode.load_as_string("VoidPtrImport", "ImportExport.c")[1])
393            if api_funcs:
394                h_code.put(UtilityCode.load_as_string("FunctionImport", "ImportExport.c")[1])
395            if api_extension_types:
396                h_code.put(UtilityCode.load_as_string("TypeImport", "ImportExport.c")[0])
397                h_code.put(UtilityCode.load_as_string("TypeImport", "ImportExport.c")[1])
398            h_code.putln("")
399            h_code.putln("static int %s(void) {" % self.api_name("import", env))
400            h_code.putln("PyObject *module = 0;")
401            h_code.putln('module = PyImport_ImportModule(%s);' % env.qualified_name.as_c_string_literal())
402            h_code.putln("if (!module) goto bad;")
403            for entry in api_funcs:
404                cname = env.mangle(Naming.func_prefix_api, entry.name)
405                sig = entry.type.signature_string()
406                h_code.putln(
407                    'if (__Pyx_ImportFunction(module, %s, (void (**)(void))&%s, "%s") < 0) goto bad;'
408                    % (entry.name.as_c_string_literal(), cname, sig))
409            for entry in api_vars:
410                cname = env.mangle(Naming.varptr_prefix_api, entry.name)
411                sig = entry.type.empty_declaration_code()
412                h_code.putln(
413                    'if (__Pyx_ImportVoidPtr(module, %s, (void **)&%s, "%s") < 0) goto bad;'
414                    % (entry.name.as_c_string_literal(), cname, sig))
415            with ModuleImportGenerator(h_code, imported_modules={env.qualified_name: 'module'}) as import_generator:
416                for entry in api_extension_types:
417                    self.generate_type_import_call(entry.type, h_code, import_generator, error_code="goto bad;")
418            h_code.putln("Py_DECREF(module); module = 0;")
419            h_code.putln("return 0;")
420            h_code.putln("bad:")
421            h_code.putln("Py_XDECREF(module);")
422            h_code.putln("return -1;")
423            h_code.putln("}")
424            h_code.putln("")
425            h_code.putln("#endif /* !%s */" % api_guard)
426
427            f = open_new_file(result.api_file)
428            try:
429                h_code.copyto(f)
430            finally:
431                f.close()
432
433    def generate_cclass_header_code(self, type, h_code):
434        h_code.putln("%s %s %s;" % (
435            Naming.extern_c_macro,
436            PyrexTypes.public_decl("PyTypeObject", "DL_IMPORT"),
437            type.typeobj_cname))
438
439    def generate_cclass_include_code(self, type, i_code):
440        i_code.putln("cdef extern class %s.%s:" % (
441            type.module_name, type.name))
442        i_code.indent()
443        var_entries = type.scope.var_entries
444        if var_entries:
445            for entry in var_entries:
446                i_code.putln("cdef %s" % (
447                    entry.type.declaration_code(entry.cname, pyrex=1)))
448        else:
449            i_code.putln("pass")
450        i_code.dedent()
451
452    def generate_c_code(self, env, options, result):
453        self.assure_safe_target(result.c_file, allow_failed=True)
454        modules = self.referenced_modules
455
456        if Options.annotate or options.annotate:
457            show_entire_c_code = Options.annotate == "fullc" or options.annotate == "fullc"
458            rootwriter = Annotate.AnnotationCCodeWriter(
459                show_entire_c_code=show_entire_c_code,
460                source_desc=self.compilation_source.source_desc,
461            )
462        else:
463            rootwriter = Code.CCodeWriter()
464
465        c_code_config = generate_c_code_config(env, options)
466
467        globalstate = Code.GlobalState(
468            rootwriter, self,
469            code_config=c_code_config,
470            common_utility_include_dir=options.common_utility_include_dir,
471        )
472        globalstate.initialize_main_c_code()
473        h_code = globalstate['h_code']
474
475        self.generate_module_preamble(env, options, modules, result.embedded_metadata, h_code)
476
477        globalstate.module_pos = self.pos
478        globalstate.directives = self.directives
479
480        globalstate.use_utility_code(refnanny_utility_code)
481
482        code = globalstate['before_global_var']
483        code.putln('#define __Pyx_MODULE_NAME %s' %
484                   self.full_module_name.as_c_string_literal())
485        module_is_main = self.is_main_module_flag_cname()
486        code.putln("extern int %s;" % module_is_main)
487        code.putln("int %s = 0;" % module_is_main)
488        code.putln("")
489        code.putln("/* Implementation of %s */" % env.qualified_name.as_c_string_literal())
490
491        code = globalstate['late_includes']
492        self.generate_includes(env, modules, code, early=False)
493
494        code = globalstate['module_code']
495
496        self.generate_cached_builtins_decls(env, code)
497
498        # generate normal variable and function definitions
499        self.generate_lambda_definitions(env, code)
500        self.generate_variable_definitions(env, code)
501        self.body.generate_function_definitions(env, code)
502
503        code.mark_pos(None)
504        self.generate_typeobj_definitions(env, code)
505        self.generate_method_table(env, code)
506        if env.has_import_star:
507            self.generate_import_star(env, code)
508
509        # initialise the macro to reduce the code size of one-time functionality
510        code.putln(UtilityCode.load_as_string("SmallCodeConfig", "ModuleSetupCode.c")[0].strip())
511
512        self.generate_module_state_start(env, globalstate['module_state'])
513        self.generate_module_state_defines(env, globalstate['module_state_defines'])
514        self.generate_module_state_clear(env, globalstate['module_state_clear'])
515        self.generate_module_state_traverse(env, globalstate['module_state_traverse'])
516
517        # init_globals is inserted before this
518        self.generate_module_init_func(modules[:-1], env, globalstate['init_module'])
519        self.generate_module_cleanup_func(env, globalstate['cleanup_module'])
520        if Options.embed:
521            self.generate_main_method(env, globalstate['main_method'])
522        self.generate_filename_table(globalstate['filename_table'])
523
524        self.generate_declarations_for_modules(env, modules, globalstate)
525        h_code.write('\n')
526
527        for utilcode in env.utility_code_list[:]:
528            globalstate.use_utility_code(utilcode)
529        globalstate.finalize_main_c_code()
530
531        self.generate_module_state_end(env, modules, globalstate)
532
533        f = open_new_file(result.c_file)
534        try:
535            rootwriter.copyto(f)
536        finally:
537            f.close()
538        result.c_file_generated = 1
539        if options.gdb_debug:
540            self._serialize_lineno_map(env, rootwriter)
541        if Options.annotate or options.annotate:
542            self._generate_annotations(rootwriter, result, options)
543
544    def _generate_annotations(self, rootwriter, result, options):
545        self.annotate(rootwriter)
546
547        coverage_xml_filename = Options.annotate_coverage_xml or options.annotate_coverage_xml
548        if coverage_xml_filename and os.path.exists(coverage_xml_filename):
549            try:
550                import xml.etree.cElementTree as ET
551            except ImportError:
552                import xml.etree.ElementTree as ET
553            coverage_xml = ET.parse(coverage_xml_filename).getroot()
554            for el in coverage_xml.iter():
555                el.tail = None  # save some memory
556        else:
557            coverage_xml = None
558
559        rootwriter.save_annotation(result.main_source_file, result.c_file, coverage_xml=coverage_xml)
560
561        # if we included files, additionally generate one annotation file for each
562        if not self.scope.included_files:
563            return
564
565        search_include_file = self.scope.context.search_include_directories
566        target_dir = os.path.abspath(os.path.dirname(result.c_file))
567        for included_file in self.scope.included_files:
568            target_file = os.path.abspath(os.path.join(target_dir, included_file))
569            target_file_dir = os.path.dirname(target_file)
570            if not target_file_dir.startswith(target_dir):
571                # any other directories may not be writable => avoid trying
572                continue
573            source_file = search_include_file(included_file, source_pos=self.pos, include=True)
574            if not source_file:
575                continue
576            if target_file_dir != target_dir and not os.path.exists(target_file_dir):
577                try:
578                    os.makedirs(target_file_dir)
579                except OSError as e:
580                    import errno
581                    if e.errno != errno.EEXIST:
582                        raise
583            rootwriter.save_annotation(source_file, target_file, coverage_xml=coverage_xml)
584
585    def _serialize_lineno_map(self, env, ccodewriter):
586        tb = env.context.gdb_debug_outputwriter
587        markers = ccodewriter.buffer.allmarkers()
588
589        d = defaultdict(list)
590        for c_lineno, (src_desc, src_lineno) in enumerate(markers):
591            if src_lineno > 0 and src_desc.filename is not None:
592                d[src_desc, src_lineno].append(c_lineno + 1)
593
594        tb.start('LineNumberMapping')
595        for (src_desc, src_lineno), c_linenos in sorted(d.items()):
596            assert src_desc.filename is not None
597            tb.add_entry(
598                'LineNumber',
599                c_linenos=' '.join(map(str, c_linenos)),
600                src_path=src_desc.filename,
601                src_lineno=str(src_lineno),
602            )
603        tb.end('LineNumberMapping')
604        tb.serialize()
605
606    def find_referenced_modules(self, env, module_list, modules_seen):
607        if env not in modules_seen:
608            modules_seen[env] = 1
609            for imported_module in env.cimported_modules:
610                self.find_referenced_modules(imported_module, module_list, modules_seen)
611            module_list.append(env)
612
613    def sort_types_by_inheritance(self, type_dict, type_order, getkey):
614        # copy the types into a list moving each parent type before
615        # its first child
616        type_list = []
617        for i, key in enumerate(type_order):
618            new_entry = type_dict[key]
619
620            # collect all base classes to check for children
621            hierarchy = set()
622            base = new_entry
623            while base:
624                base_type = base.type.base_type
625                if not base_type:
626                    break
627                base_key = getkey(base_type)
628                hierarchy.add(base_key)
629                base = type_dict.get(base_key)
630            new_entry.base_keys = hierarchy
631
632            # find the first (sub-)subclass and insert before that
633            for j in range(i):
634                entry = type_list[j]
635                if key in entry.base_keys:
636                    type_list.insert(j, new_entry)
637                    break
638            else:
639                type_list.append(new_entry)
640        return type_list
641
642    def sort_type_hierarchy(self, module_list, env):
643        # poor developer's OrderedDict
644        vtab_dict, vtab_dict_order = {}, []
645        vtabslot_dict, vtabslot_dict_order = {}, []
646
647        for module in module_list:
648            for entry in module.c_class_entries:
649                if entry.used and not entry.in_cinclude:
650                    type = entry.type
651                    key = type.vtabstruct_cname
652                    if not key:
653                        continue
654                    if key in vtab_dict:
655                        # FIXME: this should *never* happen, but apparently it does
656                        # for Cython generated utility code
657                        from .UtilityCode import NonManglingModuleScope
658                        assert isinstance(entry.scope, NonManglingModuleScope), str(entry.scope)
659                        assert isinstance(vtab_dict[key].scope, NonManglingModuleScope), str(vtab_dict[key].scope)
660                    else:
661                        vtab_dict[key] = entry
662                        vtab_dict_order.append(key)
663            all_defined_here = module is env
664            for entry in module.type_entries:
665                if entry.used and (all_defined_here or entry.defined_in_pxd):
666                    type = entry.type
667                    if type.is_extension_type and not entry.in_cinclude:
668                        type = entry.type
669                        key = type.objstruct_cname
670                        assert key not in vtabslot_dict, key
671                        vtabslot_dict[key] = entry
672                        vtabslot_dict_order.append(key)
673
674        def vtabstruct_cname(entry_type):
675            return entry_type.vtabstruct_cname
676        vtab_list = self.sort_types_by_inheritance(
677            vtab_dict, vtab_dict_order, vtabstruct_cname)
678
679        def objstruct_cname(entry_type):
680            return entry_type.objstruct_cname
681        vtabslot_list = self.sort_types_by_inheritance(
682            vtabslot_dict, vtabslot_dict_order, objstruct_cname)
683
684        return (vtab_list, vtabslot_list)
685
686    def sort_cdef_classes(self, env):
687        key_func = operator.attrgetter('objstruct_cname')
688        entry_dict, entry_order = {}, []
689        for entry in env.c_class_entries:
690            key = key_func(entry.type)
691            assert key not in entry_dict, key
692            entry_dict[key] = entry
693            entry_order.append(key)
694        env.c_class_entries[:] = self.sort_types_by_inheritance(
695            entry_dict, entry_order, key_func)
696
697    def generate_type_definitions(self, env, modules, vtab_list, vtabslot_list, code):
698        # TODO: Why are these separated out?
699        for entry in vtabslot_list:
700            self.generate_objstruct_predeclaration(entry.type, code)
701        vtabslot_entries = set(vtabslot_list)
702        ctuple_names = set()
703        for module in modules:
704            definition = module is env
705            type_entries = []
706            for entry in module.type_entries:
707                if entry.type.is_ctuple and entry.used:
708                    if entry.name not in ctuple_names:
709                        ctuple_names.add(entry.name)
710                        type_entries.append(entry)
711                elif definition or entry.defined_in_pxd:
712                    type_entries.append(entry)
713            type_entries = [t for t in type_entries if t not in vtabslot_entries]
714            self.generate_type_header_code(type_entries, code)
715        for entry in vtabslot_list:
716            self.generate_objstruct_definition(entry.type, code)
717            self.generate_typeobj_predeclaration(entry, code)
718        for entry in vtab_list:
719            self.generate_typeobj_predeclaration(entry, code)
720            self.generate_exttype_vtable_struct(entry, code)
721            self.generate_exttype_vtabptr_declaration(entry, code)
722            self.generate_exttype_final_methods_declaration(entry, code)
723
724    def generate_declarations_for_modules(self, env, modules, globalstate):
725        typecode = globalstate['type_declarations']
726        typecode.putln("")
727        typecode.putln("/*--- Type declarations ---*/")
728        # This is to work around the fact that array.h isn't part of the C-API,
729        # but we need to declare it earlier than utility code.
730        if 'cpython.array' in [m.qualified_name for m in modules]:
731            typecode.putln('#ifndef _ARRAYARRAY_H')
732            typecode.putln('struct arrayobject;')
733            typecode.putln('typedef struct arrayobject arrayobject;')
734            typecode.putln('#endif')
735        vtab_list, vtabslot_list = self.sort_type_hierarchy(modules, env)
736        self.generate_type_definitions(
737            env, modules, vtab_list, vtabslot_list, typecode)
738        modulecode = globalstate['module_declarations']
739        for module in modules:
740            defined_here = module is env
741            modulecode.putln("")
742            modulecode.putln("/* Module declarations from %s */" % module.qualified_name.as_c_string_literal())
743            self.generate_c_class_declarations(module, modulecode, defined_here, globalstate)
744            self.generate_cvariable_declarations(module, modulecode, defined_here)
745            self.generate_cfunction_declarations(module, modulecode, defined_here)
746
747    @staticmethod
748    def _put_setup_code(code, name):
749        code.put(UtilityCode.load_as_string(name, "ModuleSetupCode.c")[1])
750
751    def generate_module_preamble(self, env, options, cimported_modules, metadata, code):
752        code.put_generated_by()
753        if metadata:
754            code.putln("/* BEGIN: Cython Metadata")
755            code.putln(json.dumps(metadata, indent=4, sort_keys=True))
756            code.putln("END: Cython Metadata */")
757            code.putln("")
758
759        code.putln("#ifndef PY_SSIZE_T_CLEAN")
760        code.putln("#define PY_SSIZE_T_CLEAN")
761        code.putln("#endif /* PY_SSIZE_T_CLEAN */")
762        self._put_setup_code(code, "InitLimitedAPI")
763
764        for inc in sorted(env.c_includes.values(), key=IncludeCode.sortkey):
765            if inc.location == inc.INITIAL:
766                inc.write(code)
767        code.putln("#ifndef Py_PYTHON_H")
768        code.putln("    #error Python headers needed to compile C extensions, "
769                   "please install development version of Python.")
770        code.putln("#elif PY_VERSION_HEX < 0x02070000 || "
771                   "(0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000)")
772        code.putln("    #error Cython requires Python 2.7+ or Python 3.3+.")
773        code.putln("#else")
774        code.globalstate["end"].putln("#endif /* Py_PYTHON_H */")
775
776        from .. import __version__
777        code.putln('#define CYTHON_ABI "%s"' % __version__.replace('.', '_'))
778        code.putln('#define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI')
779        code.putln('#define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "."')
780        code.putln('#define CYTHON_HEX_VERSION %s' % build_hex_version(__version__))
781        code.putln("#define CYTHON_FUTURE_DIVISION %d" % (
782            Future.division in env.context.future_directives))
783
784        self._put_setup_code(code, "CModulePreamble")
785        if env.context.options.cplus:
786            self._put_setup_code(code, "CppInitCode")
787        else:
788            self._put_setup_code(code, "CInitCode")
789        self._put_setup_code(code, "PythonCompatibility")
790        self._put_setup_code(code, "MathInitCode")
791
792        # Using "(void)cname" to prevent "unused" warnings.
793        if options.c_line_in_traceback:
794            cinfo = "%s = %s; (void)%s; " % (Naming.clineno_cname, Naming.line_c_macro, Naming.clineno_cname)
795        else:
796            cinfo = ""
797        code.putln("#define __PYX_MARK_ERR_POS(f_index, lineno) \\")
798        code.putln("    { %s = %s[f_index]; (void)%s; %s = lineno; (void)%s; %s}" % (
799            Naming.filename_cname, Naming.filetable_cname, Naming.filename_cname,
800            Naming.lineno_cname, Naming.lineno_cname,
801            cinfo
802        ))
803        code.putln("#define __PYX_ERR(f_index, lineno, Ln_error) \\")
804        code.putln("    { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; }")
805
806        code.putln("")
807        self.generate_extern_c_macro_definition(code)
808        code.putln("")
809
810        code.putln("#define %s" % self.api_name(Naming.h_guard_prefix, env))
811        code.putln("#define %s" % self.api_name(Naming.api_guard_prefix, env))
812        code.putln("/* Early includes */")
813        self.generate_includes(env, cimported_modules, code, late=False)
814        code.putln("")
815        code.putln("#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS)")
816        code.putln("#define CYTHON_WITHOUT_ASSERTIONS")
817        code.putln("#endif")
818        code.putln("")
819
820        if env.directives['ccomplex']:
821            code.putln("")
822            code.putln("#if !defined(CYTHON_CCOMPLEX)")
823            code.putln("#define CYTHON_CCOMPLEX 1")
824            code.putln("#endif")
825            code.putln("")
826        code.put(UtilityCode.load_as_string("UtilityFunctionPredeclarations", "ModuleSetupCode.c")[0])
827
828        c_string_type = env.directives['c_string_type']
829        c_string_encoding = env.directives['c_string_encoding']
830        if c_string_type not in ('bytes', 'bytearray') and not c_string_encoding:
831            error(self.pos, "a default encoding must be provided if c_string_type is not a byte type")
832        code.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII %s' % int(c_string_encoding == 'ascii'))
833        code.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 %s' %
834                int(c_string_encoding.replace('-', '').lower() == 'utf8'))
835        if c_string_encoding == 'default':
836            code.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 1')
837        else:
838            code.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT '
839                    '(PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8)')
840            code.putln('#define __PYX_DEFAULT_STRING_ENCODING "%s"' % c_string_encoding)
841        if c_string_type == 'bytearray':
842            c_string_func_name = 'ByteArray'
843        else:
844            c_string_func_name = c_string_type.title()
845        code.putln('#define __Pyx_PyObject_FromString __Pyx_Py%s_FromString' % c_string_func_name)
846        code.putln('#define __Pyx_PyObject_FromStringAndSize __Pyx_Py%s_FromStringAndSize' % c_string_func_name)
847        code.put(UtilityCode.load_as_string("TypeConversions", "TypeConversion.c")[0])
848        env.use_utility_code(UtilityCode.load_cached("FormatTypeName", "ObjectHandling.c"))
849
850        # These utility functions are assumed to exist and used elsewhere.
851        PyrexTypes.c_long_type.create_to_py_utility_code(env)
852        PyrexTypes.c_long_type.create_from_py_utility_code(env)
853        PyrexTypes.c_int_type.create_from_py_utility_code(env)
854
855        code.put(Nodes.branch_prediction_macros)
856        code.putln('static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; }')
857        code.putln('')
858        code.putln('#if !CYTHON_USE_MODULE_STATE')
859        code.putln('static PyObject *%s = NULL;' % env.module_cname)
860        code.putln('static PyObject *%s;' % env.module_dict_cname)
861        code.putln('static PyObject *%s;' % Naming.builtins_cname)
862        code.putln('static PyObject *%s = NULL;' % Naming.cython_runtime_cname)
863        code.putln('static PyObject *%s;' % Naming.empty_tuple)
864        code.putln('static PyObject *%s;' % Naming.empty_bytes)
865        code.putln('static PyObject *%s;' % Naming.empty_unicode)
866        if Options.pre_import is not None:
867            code.putln('static PyObject *%s;' % Naming.preimport_cname)
868        code.putln('#endif')
869
870        code.putln('static int %s;' % Naming.lineno_cname)
871        code.putln('static int %s = 0;' % Naming.clineno_cname)
872        code.putln('static const char * %s = %s;' % (Naming.cfilenm_cname, Naming.file_c_macro))
873        code.putln('static const char *%s;' % Naming.filename_cname)
874
875        env.use_utility_code(UtilityCode.load_cached("FastTypeChecks", "ModuleSetupCode.c"))
876        if has_np_pythran(env):
877            env.use_utility_code(UtilityCode.load_cached("PythranConversion", "CppSupport.cpp"))
878
879    def generate_extern_c_macro_definition(self, code):
880        name = Naming.extern_c_macro
881        code.putln("#ifndef %s" % name)
882        code.putln("  #ifdef __cplusplus")
883        code.putln('    #define %s extern "C"' % name)
884        code.putln("  #else")
885        code.putln("    #define %s extern" % name)
886        code.putln("  #endif")
887        code.putln("#endif")
888
889    def generate_dl_import_macro(self, code):
890        code.putln("#ifndef DL_IMPORT")
891        code.putln("  #define DL_IMPORT(_T) _T")
892        code.putln("#endif")
893
894    def generate_includes(self, env, cimported_modules, code, early=True, late=True):
895        for inc in sorted(env.c_includes.values(), key=IncludeCode.sortkey):
896            if inc.location == inc.EARLY:
897                if early:
898                    inc.write(code)
899            elif inc.location == inc.LATE:
900                if late:
901                    inc.write(code)
902        if early:
903            code.putln_openmp("#include <omp.h>")
904
905    def generate_filename_table(self, code):
906        from os.path import isabs, basename
907        code.putln("")
908        code.putln("static const char *%s[] = {" % Naming.filetable_cname)
909        if code.globalstate.filename_list:
910            for source_desc in code.globalstate.filename_list:
911                file_path = source_desc.get_filenametable_entry()
912                if isabs(file_path):
913                    file_path = basename(file_path)  # never include absolute paths
914                escaped_filename = file_path.replace("\\", "\\\\").replace('"', r'\"')
915                escaped_filename = as_encoded_filename(escaped_filename)
916                code.putln('%s,' % escaped_filename.as_c_string_literal())
917        else:
918            # Some C compilers don't like an empty array
919            code.putln("0")
920        code.putln("};")
921
922    def generate_type_predeclarations(self, env, code):
923        pass
924
925    def generate_type_header_code(self, type_entries, code):
926        # Generate definitions of structs/unions/enums/typedefs/objstructs.
927        #self.generate_gcc33_hack(env, code) # Is this still needed?
928        # Forward declarations
929        for entry in type_entries:
930            if not entry.in_cinclude:
931                #print "generate_type_header_code:", entry.name, repr(entry.type) ###
932                type = entry.type
933                if type.is_typedef:  # Must test this first!
934                    pass
935                elif type.is_struct_or_union or type.is_cpp_class:
936                    self.generate_struct_union_predeclaration(entry, code)
937                elif type.is_ctuple and entry.used:
938                    self.generate_struct_union_predeclaration(entry.type.struct_entry, code)
939                elif type.is_extension_type:
940                    self.generate_objstruct_predeclaration(type, code)
941        # Actual declarations
942        for entry in type_entries:
943            if not entry.in_cinclude:
944                #print "generate_type_header_code:", entry.name, repr(entry.type) ###
945                type = entry.type
946                if type.is_typedef:  # Must test this first!
947                    self.generate_typedef(entry, code)
948                elif type.is_enum or type.is_cpp_enum:
949                    self.generate_enum_definition(entry, code)
950                elif type.is_struct_or_union:
951                    self.generate_struct_union_definition(entry, code)
952                elif type.is_ctuple and entry.used:
953                    self.generate_struct_union_definition(entry.type.struct_entry, code)
954                elif type.is_cpp_class:
955                    self.generate_cpp_class_definition(entry, code)
956                elif type.is_extension_type:
957                    self.generate_objstruct_definition(type, code)
958
959    def generate_gcc33_hack(self, env, code):
960        # Workaround for spurious warning generation in gcc 3.3
961        code.putln("")
962        for entry in env.c_class_entries:
963            type = entry.type
964            if not type.typedef_flag:
965                name = type.objstruct_cname
966                if name.startswith("__pyx_"):
967                    tail = name[6:]
968                else:
969                    tail = name
970                code.putln("typedef struct %s __pyx_gcc33_%s;" % (
971                    name, tail))
972
973    def generate_typedef(self, entry, code):
974        base_type = entry.type.typedef_base_type
975        if base_type.is_numeric:
976            try:
977                writer = code.globalstate['numeric_typedefs']
978            except KeyError:
979                writer = code
980        else:
981            writer = code
982        writer.mark_pos(entry.pos)
983        writer.putln("typedef %s;" % base_type.declaration_code(entry.cname))
984
985    def sue_predeclaration(self, type, kind, name):
986        if type.typedef_flag:
987            return "%s %s;\ntypedef %s %s %s;" % (
988                kind, name,
989                kind, name, name)
990        else:
991            return "%s %s;" % (kind, name)
992
993    def generate_struct_union_predeclaration(self, entry, code):
994        type = entry.type
995        if type.is_cpp_class and type.templates:
996            code.putln("template <typename %s>" % ", typename ".join(
997                [T.empty_declaration_code() for T in type.templates]))
998        code.putln(self.sue_predeclaration(type, type.kind, type.cname))
999
1000    def sue_header_footer(self, type, kind, name):
1001        header = "%s %s {" % (kind, name)
1002        footer = "};"
1003        return header, footer
1004
1005    def generate_struct_union_definition(self, entry, code):
1006        code.mark_pos(entry.pos)
1007        type = entry.type
1008        scope = type.scope
1009        if scope:
1010            kind = type.kind
1011            packed = type.is_struct and type.packed
1012            if packed:
1013                kind = "%s %s" % (type.kind, "__Pyx_PACKED")
1014                code.globalstate.use_utility_code(packed_struct_utility_code)
1015            header, footer = \
1016                self.sue_header_footer(type, kind, type.cname)
1017            if packed:
1018                code.putln("#if defined(__SUNPRO_C)")
1019                code.putln("  #pragma pack(1)")
1020                code.putln("#elif !defined(__GNUC__)")
1021                code.putln("  #pragma pack(push, 1)")
1022                code.putln("#endif")
1023            code.putln(header)
1024            var_entries = scope.var_entries
1025            for attr in var_entries:
1026                code.putln(
1027                    "%s;" % attr.type.declaration_code(attr.cname))
1028            code.putln(footer)
1029            if packed:
1030                code.putln("#if defined(__SUNPRO_C)")
1031                code.putln("  #pragma pack()")
1032                code.putln("#elif !defined(__GNUC__)")
1033                code.putln("  #pragma pack(pop)")
1034                code.putln("#endif")
1035
1036    def generate_cpp_class_definition(self, entry, code):
1037        code.mark_pos(entry.pos)
1038        type = entry.type
1039        scope = type.scope
1040        if scope:
1041            if type.templates:
1042                code.putln("template <class %s>" % ", class ".join(
1043                    [T.empty_declaration_code() for T in type.templates]))
1044            # Just let everything be public.
1045            code.put("struct %s" % type.cname)
1046            if type.base_classes:
1047                base_class_decl = ", public ".join(
1048                    [base_class.empty_declaration_code() for base_class in type.base_classes])
1049                code.put(" : public %s" % base_class_decl)
1050            code.putln(" {")
1051            py_attrs = [e for e in scope.entries.values()
1052                        if e.type.is_pyobject and not e.is_inherited]
1053            has_virtual_methods = False
1054            constructor = None
1055            destructor = None
1056            for attr in scope.var_entries:
1057                if attr.type.is_cfunction and attr.type.is_static_method:
1058                    code.put("static ")
1059                elif attr.name == "<init>":
1060                    constructor = attr
1061                elif attr.name == "<del>":
1062                    destructor = attr
1063                elif attr.type.is_cfunction:
1064                    code.put("virtual ")
1065                    has_virtual_methods = True
1066                code.putln("%s;" % attr.type.declaration_code(attr.cname))
1067            is_implementing = 'init_module' in code.globalstate.parts
1068            if constructor or py_attrs:
1069                if constructor:
1070                    arg_decls = []
1071                    arg_names = []
1072                    for arg in constructor.type.original_args[
1073                            :len(constructor.type.args)-constructor.type.optional_arg_count]:
1074                        arg_decls.append(arg.declaration_code())
1075                        arg_names.append(arg.cname)
1076                    if constructor.type.optional_arg_count:
1077                        arg_decls.append(constructor.type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1078                        arg_names.append(Naming.optional_args_cname)
1079                    if not arg_decls:
1080                        arg_decls = ["void"]
1081                else:
1082                    arg_decls = ["void"]
1083                    arg_names = []
1084                if is_implementing:
1085                    code.putln("%s(%s) {" % (type.cname, ", ".join(arg_decls)))
1086                    if py_attrs:
1087                        code.put_ensure_gil()
1088                        for attr in py_attrs:
1089                            code.put_init_var_to_py_none(attr, nanny=False)
1090                    if constructor:
1091                        code.putln("%s(%s);" % (constructor.cname, ", ".join(arg_names)))
1092                    if py_attrs:
1093                        code.put_release_ensured_gil()
1094                    code.putln("}")
1095                else:
1096                    code.putln("%s(%s);" % (type.cname, ", ".join(arg_decls)))
1097            if destructor or py_attrs or has_virtual_methods:
1098                if has_virtual_methods:
1099                    code.put("virtual ")
1100                if is_implementing:
1101                    code.putln("~%s() {" % type.cname)
1102                    if py_attrs:
1103                        code.put_ensure_gil()
1104                    if destructor:
1105                        code.putln("%s();" % destructor.cname)
1106                    if py_attrs:
1107                        for attr in py_attrs:
1108                            code.put_var_xdecref(attr, nanny=False)
1109                        code.put_release_ensured_gil()
1110                    code.putln("}")
1111                else:
1112                    code.putln("~%s();" % type.cname)
1113            if py_attrs:
1114                # Also need copy constructor and assignment operators.
1115                if is_implementing:
1116                    code.putln("%s(const %s& __Pyx_other) {" % (type.cname, type.cname))
1117                    code.put_ensure_gil()
1118                    for attr in scope.var_entries:
1119                        if not attr.type.is_cfunction:
1120                            code.putln("%s = __Pyx_other.%s;" % (attr.cname, attr.cname))
1121                            code.put_var_incref(attr, nanny=False)
1122                    code.put_release_ensured_gil()
1123                    code.putln("}")
1124                    code.putln("%s& operator=(const %s& __Pyx_other) {" % (type.cname, type.cname))
1125                    code.putln("if (this != &__Pyx_other) {")
1126                    code.put_ensure_gil()
1127                    for attr in scope.var_entries:
1128                        if not attr.type.is_cfunction:
1129                            code.put_var_xdecref(attr, nanny=False)
1130                            code.putln("%s = __Pyx_other.%s;" % (attr.cname, attr.cname))
1131                            code.put_var_incref(attr, nanny=False)
1132                    code.put_release_ensured_gil()
1133                    code.putln("}")
1134                    code.putln("return *this;")
1135                    code.putln("}")
1136                else:
1137                    code.putln("%s(const %s& __Pyx_other);" % (type.cname, type.cname))
1138                    code.putln("%s& operator=(const %s& __Pyx_other);" % (type.cname, type.cname))
1139            code.putln("};")
1140
1141    def generate_enum_definition(self, entry, code):
1142        code.mark_pos(entry.pos)
1143        type = entry.type
1144        name = entry.cname or entry.name or ""
1145
1146        kind = "enum class" if entry.type.is_cpp_enum else "enum"
1147        header, footer = self.sue_header_footer(type, kind, name)
1148        code.putln(header)
1149        enum_values = entry.enum_values
1150        if not enum_values:
1151            error(entry.pos, "Empty enum definition not allowed outside a 'cdef extern from' block")
1152        else:
1153            last_entry = enum_values[-1]
1154            # this does not really generate code, just builds the result value
1155            for value_entry in enum_values:
1156                if value_entry.value_node is not None:
1157                    value_entry.value_node.generate_evaluation_code(code)
1158
1159            for value_entry in enum_values:
1160                if value_entry.value_node is None:
1161                    value_code = value_entry.cname.split("::")[-1]
1162                else:
1163                    value_code = ("%s = %s" % (
1164                        value_entry.cname.split("::")[-1],
1165                        value_entry.value_node.result()))
1166                if value_entry is not last_entry:
1167                    value_code += ","
1168                code.putln(value_code)
1169        code.putln(footer)
1170
1171        if entry.type.is_enum:
1172            if entry.type.typedef_flag:
1173                # Not pre-declared.
1174                code.putln("typedef enum %s %s;" % (name, name))
1175
1176    def generate_typeobj_predeclaration(self, entry, code):
1177        code.putln("")
1178        name = entry.type.typeobj_cname
1179        if name:
1180            if entry.visibility == 'extern' and not entry.in_cinclude:
1181                code.putln("%s %s %s;" % (
1182                    Naming.extern_c_macro,
1183                    PyrexTypes.public_decl("PyTypeObject", "DL_IMPORT"),
1184                    name))
1185            elif entry.visibility == 'public':
1186                code.putln("%s %s %s;" % (
1187                    Naming.extern_c_macro,
1188                    PyrexTypes.public_decl("PyTypeObject", "DL_EXPORT"),
1189                    name))
1190            # ??? Do we really need the rest of this? ???
1191            #else:
1192            #    code.putln("static PyTypeObject %s;" % name)
1193
1194    def generate_exttype_vtable_struct(self, entry, code):
1195        if not entry.used:
1196            return
1197
1198        code.mark_pos(entry.pos)
1199        # Generate struct declaration for an extension type's vtable.
1200        type = entry.type
1201        scope = type.scope
1202
1203        self.specialize_fused_types(scope)
1204
1205        if type.vtabstruct_cname:
1206            code.putln("")
1207            code.putln("struct %s {" % type.vtabstruct_cname)
1208            if type.base_type and type.base_type.vtabstruct_cname:
1209                code.putln("struct %s %s;" % (
1210                    type.base_type.vtabstruct_cname,
1211                    Naming.obj_base_cname))
1212            for method_entry in scope.cfunc_entries:
1213                if not method_entry.is_inherited:
1214                    code.putln("%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.cname))
1215            code.putln("};")
1216
1217    def generate_exttype_vtabptr_declaration(self, entry, code):
1218        if not entry.used:
1219            return
1220
1221        code.mark_pos(entry.pos)
1222        # Generate declaration of pointer to an extension type's vtable.
1223        type = entry.type
1224        if type.vtabptr_cname:
1225            code.putln("static struct %s *%s;" % (
1226                type.vtabstruct_cname,
1227                type.vtabptr_cname))
1228
1229    def generate_exttype_final_methods_declaration(self, entry, code):
1230        if not entry.used:
1231            return
1232
1233        code.mark_pos(entry.pos)
1234        # Generate final methods prototypes
1235        type = entry.type
1236        for method_entry in entry.type.scope.cfunc_entries:
1237            if not method_entry.is_inherited and method_entry.final_func_cname:
1238                declaration = method_entry.type.declaration_code(
1239                    method_entry.final_func_cname)
1240                modifiers = code.build_function_modifiers(method_entry.func_modifiers)
1241                code.putln("static %s%s;" % (modifiers, declaration))
1242
1243    def generate_objstruct_predeclaration(self, type, code):
1244        if not type.scope:
1245            return
1246        code.putln(self.sue_predeclaration(type, "struct", type.objstruct_cname))
1247
1248    def generate_objstruct_definition(self, type, code):
1249        code.mark_pos(type.pos)
1250        # Generate object struct definition for an
1251        # extension type.
1252        if not type.scope:
1253            return  # Forward declared but never defined
1254        header, footer = \
1255            self.sue_header_footer(type, "struct", type.objstruct_cname)
1256        code.putln(header)
1257        base_type = type.base_type
1258        if base_type:
1259            basestruct_cname = base_type.objstruct_cname
1260            if basestruct_cname == "PyTypeObject":
1261                # User-defined subclasses of type are heap allocated.
1262                basestruct_cname = "PyHeapTypeObject"
1263            code.putln(
1264                "%s%s %s;" % (
1265                    ("struct ", "")[base_type.typedef_flag],
1266                    basestruct_cname,
1267                    Naming.obj_base_cname))
1268        else:
1269            code.putln(
1270                "PyObject_HEAD")
1271        if type.vtabslot_cname and not (type.base_type and type.base_type.vtabslot_cname):
1272            code.putln(
1273                "struct %s *%s;" % (
1274                    type.vtabstruct_cname,
1275                    type.vtabslot_cname))
1276        for attr in type.scope.var_entries:
1277            if attr.is_declared_generic:
1278                attr_type = py_object_type
1279            else:
1280                attr_type = attr.type
1281            if attr.is_cpp_optional:
1282                decl = attr_type.cpp_optional_declaration_code(attr.cname)
1283            else:
1284                decl = attr_type.declaration_code(attr.cname)
1285            type.scope.use_entry_utility_code(attr)
1286            code.putln("%s;" % decl)
1287        code.putln(footer)
1288        if type.objtypedef_cname is not None:
1289            # Only for exposing public typedef name.
1290            code.putln("typedef struct %s %s;" % (type.objstruct_cname, type.objtypedef_cname))
1291
1292    def generate_c_class_declarations(self, env, code, definition, globalstate):
1293        module_state = globalstate['module_state']
1294        module_state_defines = globalstate['module_state_defines']
1295        module_state_clear = globalstate['module_state_clear']
1296        module_state_traverse = globalstate['module_state_traverse']
1297        code.putln("#if !CYTHON_USE_MODULE_STATE")
1298        for entry in env.c_class_entries:
1299            if definition or entry.defined_in_pxd:
1300                code.putln("static PyTypeObject *%s = 0;" % (
1301                    entry.type.typeptr_cname))
1302                module_state.putln("PyTypeObject *%s;" % entry.type.typeptr_cname)
1303                module_state_defines.putln("#define %s %s->%s" % (
1304                    entry.type.typeptr_cname,
1305                    Naming.modulestateglobal_cname,
1306                    entry.type.typeptr_cname))
1307                module_state_clear.putln(
1308                    "Py_CLEAR(clear_module_state->%s);" %
1309                    entry.type.typeptr_cname)
1310                module_state_traverse.putln(
1311                    "Py_VISIT(traverse_module_state->%s);" %
1312                    entry.type.typeptr_cname)
1313                if entry.type.typeobj_cname is not None:
1314                    module_state.putln("PyObject *%s;" % entry.type.typeobj_cname)
1315                    module_state_defines.putln("#define %s %s->%s" % (
1316                        entry.type.typeobj_cname,
1317                        Naming.modulestateglobal_cname,
1318                        entry.type.typeobj_cname))
1319                    module_state_clear.putln(
1320                        "Py_CLEAR(clear_module_state->%s);" % (
1321                        entry.type.typeobj_cname))
1322                    module_state_traverse.putln(
1323                        "Py_VISIT(traverse_module_state->%s);" % (
1324                        entry.type.typeobj_cname))
1325        code.putln("#endif")
1326
1327    def generate_cvariable_declarations(self, env, code, definition):
1328        if env.is_cython_builtin:
1329            return
1330        for entry in env.var_entries:
1331            if (entry.in_cinclude or entry.in_closure or
1332                    (entry.visibility == 'private' and not (entry.defined_in_pxd or entry.used))):
1333                continue
1334
1335            storage_class = None
1336            dll_linkage = None
1337            init = None
1338
1339            if entry.visibility == 'extern':
1340                storage_class = Naming.extern_c_macro
1341                dll_linkage = "DL_IMPORT"
1342            elif entry.visibility == 'public':
1343                storage_class = Naming.extern_c_macro
1344                if definition:
1345                    dll_linkage = "DL_EXPORT"
1346                else:
1347                    dll_linkage = "DL_IMPORT"
1348            elif entry.visibility == 'private':
1349                storage_class = "static"
1350                dll_linkage = None
1351                if entry.init is not None:
1352                    init = entry.type.literal_code(entry.init)
1353            type = entry.type
1354            cname = entry.cname
1355
1356            if entry.defined_in_pxd and not definition:
1357                storage_class = "static"
1358                dll_linkage = None
1359                type = CPtrType(type)
1360                cname = env.mangle(Naming.varptr_prefix, entry.name)
1361                init = 0
1362
1363            if storage_class:
1364                code.put("%s " % storage_class)
1365            if entry.is_cpp_optional:
1366                code.put(type.cpp_optional_declaration_code(
1367                    cname, dll_linkage=dll_linkage))
1368            else:
1369                code.put(type.declaration_code(
1370                    cname, dll_linkage=dll_linkage))
1371            if init is not None:
1372                code.put_safe(" = %s" % init)
1373            code.putln(";")
1374            if entry.cname != cname:
1375                code.putln("#define %s (*%s)" % (entry.cname, cname))
1376            env.use_entry_utility_code(entry)
1377
1378    def generate_cfunction_declarations(self, env, code, definition):
1379        for entry in env.cfunc_entries:
1380            if entry.used or (entry.visibility == 'public' or entry.api):
1381                generate_cfunction_declaration(entry, env, code, definition)
1382
1383    def generate_variable_definitions(self, env, code):
1384        for entry in env.var_entries:
1385            if not entry.in_cinclude and entry.visibility == "public":
1386                code.put(entry.type.declaration_code(entry.cname))
1387                if entry.init is not None:
1388                    init = entry.type.literal_code(entry.init)
1389                    code.put_safe(" = %s" % init)
1390                code.putln(";")
1391
1392    def generate_typeobj_definitions(self, env, code):
1393        full_module_name = env.qualified_name
1394        for entry in env.c_class_entries:
1395            #print "generate_typeobj_definitions:", entry.name
1396            #print "...visibility =", entry.visibility
1397            if entry.visibility != 'extern':
1398                type = entry.type
1399                scope = type.scope
1400                if scope:  # could be None if there was an error
1401                    self.generate_exttype_vtable(scope, code)
1402                    self.generate_new_function(scope, code, entry)
1403                    self.generate_dealloc_function(scope, code)
1404
1405                    if scope.needs_gc():
1406                        self.generate_traverse_function(scope, code, entry)
1407                        if scope.needs_tp_clear():
1408                            self.generate_clear_function(scope, code, entry)
1409                    if scope.defines_any_special(["__getitem__"]):
1410                        self.generate_getitem_int_function(scope, code)
1411                    if scope.defines_any_special(["__setitem__", "__delitem__"]):
1412                        self.generate_ass_subscript_function(scope, code)
1413                    if scope.defines_any_special(["__getslice__", "__setslice__", "__delslice__"]):
1414                        warning(self.pos,
1415                                "__getslice__, __setslice__, and __delslice__ are not supported by Python 3, "
1416                                "use __getitem__, __setitem__, and __delitem__ instead", 1)
1417                        code.putln("#if PY_MAJOR_VERSION >= 3")
1418                        code.putln("#error __getslice__, __setslice__, and __delslice__ not supported in Python 3.")
1419                        code.putln("#endif")
1420                    if scope.defines_any_special(["__setslice__", "__delslice__"]):
1421                        self.generate_ass_slice_function(scope, code)
1422                    if scope.defines_any_special(["__getattr__", "__getattribute__"]):
1423                        self.generate_getattro_function(scope, code)
1424                    if scope.defines_any_special(["__setattr__", "__delattr__"]):
1425                        self.generate_setattro_function(scope, code)
1426                    if scope.defines_any_special(["__get__"]):
1427                        self.generate_descr_get_function(scope, code)
1428                    if scope.defines_any_special(["__set__", "__delete__"]):
1429                        self.generate_descr_set_function(scope, code)
1430                    if not scope.is_closure_class_scope and scope.defines_any(["__dict__"]):
1431                        self.generate_dict_getter_function(scope, code)
1432
1433                    if scope.defines_any_special(TypeSlots.richcmp_special_methods):
1434                        self.generate_richcmp_function(scope, code)
1435                    elif scope.directives.get('total_ordering'):
1436                        # Warn if this is used when it can't have any effect.
1437                        warning(scope.parent_type.pos,
1438                                "total_ordering directive used, but no comparison and equality methods defined")
1439
1440                    for slot in TypeSlots.PyNumberMethods:
1441                        if slot.is_binop and scope.defines_any_special(slot.user_methods):
1442                            self.generate_binop_function(scope, slot, code, entry.pos)
1443
1444                    self.generate_property_accessors(scope, code)
1445                    self.generate_method_table(scope, code)
1446                    self.generate_getset_table(scope, code)
1447                    code.putln("#if CYTHON_USE_TYPE_SPECS")
1448                    self.generate_typeobj_spec(entry, code)
1449                    code.putln("#else")
1450                    self.generate_typeobj_definition(full_module_name, entry, code)
1451                    code.putln("#endif")
1452
1453    def generate_exttype_vtable(self, scope, code):
1454        # Generate the definition of an extension type's vtable.
1455        type = scope.parent_type
1456        if type.vtable_cname:
1457            code.putln("static struct %s %s;" % (
1458                type.vtabstruct_cname,
1459                type.vtable_cname))
1460
1461    def generate_self_cast(self, scope, code):
1462        type = scope.parent_type
1463        code.putln(
1464            "%s = (%s)o;" % (
1465                type.declaration_code("p"),
1466                type.empty_declaration_code()))
1467
1468    def generate_new_function(self, scope, code, cclass_entry):
1469        tp_slot = TypeSlots.ConstructorSlot("tp_new", "__cinit__")
1470        slot_func = scope.mangle_internal("tp_new")
1471        if tp_slot.slot_code(scope) != slot_func:
1472            return  # never used
1473
1474        type = scope.parent_type
1475        base_type = type.base_type
1476
1477        have_entries, (py_attrs, py_buffers, memoryview_slices) = \
1478                        scope.get_refcounted_entries()
1479        is_final_type = scope.parent_type.is_final_type
1480        if scope.is_internal:
1481            # internal classes (should) never need None inits, normal zeroing will do
1482            py_attrs = []
1483        cpp_constructable_attrs = [entry for entry in scope.var_entries if entry.type.needs_cpp_construction]
1484
1485        cinit_func_entry = scope.lookup_here("__cinit__")
1486        if cinit_func_entry and not cinit_func_entry.is_special:
1487            cinit_func_entry = None
1488
1489        if base_type or (cinit_func_entry and not cinit_func_entry.trivial_signature):
1490            unused_marker = ''
1491        else:
1492            unused_marker = 'CYTHON_UNUSED '
1493
1494        if base_type:
1495            freelist_size = 0  # not currently supported
1496        else:
1497            freelist_size = scope.directives.get('freelist', 0)
1498        freelist_name = scope.mangle_internal(Naming.freelist_name)
1499        freecount_name = scope.mangle_internal(Naming.freecount_name)
1500
1501        decls = code.globalstate['decls']
1502        decls.putln("static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/" %
1503                    slot_func)
1504        code.putln("")
1505        if freelist_size:
1506            code.putln("static %s[%d];" % (
1507                scope.parent_type.declaration_code(freelist_name),
1508                freelist_size))
1509            code.putln("static int %s = 0;" % freecount_name)
1510            code.putln("")
1511        code.putln(
1512            "static PyObject *%s(PyTypeObject *t, %sPyObject *a, %sPyObject *k) {" % (
1513                slot_func, unused_marker, unused_marker))
1514
1515        need_self_cast = (type.vtabslot_cname or
1516                          (py_buffers or memoryview_slices or py_attrs) or
1517                          cpp_constructable_attrs)
1518        if need_self_cast:
1519            code.putln("%s;" % scope.parent_type.declaration_code("p"))
1520        if base_type:
1521            code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
1522            code.putln("newfunc new_func = (newfunc)PyType_GetSlot(%s, Py_tp_new);" %
1523                base_type.typeptr_cname)
1524            code.putln("PyObject *o = new_func(t, a, k);")
1525            code.putln("#else")
1526            tp_new = TypeSlots.get_base_slot_function(scope, tp_slot)
1527            if tp_new is None:
1528                tp_new = "%s->tp_new" % base_type.typeptr_cname
1529            code.putln("PyObject *o = %s(t, a, k);" % tp_new)
1530            code.putln("#endif")
1531        else:
1532            code.putln("PyObject *o;")
1533            code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
1534            code.putln("allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc);")
1535            code.putln("o = alloc_func(t, 0);")
1536            code.putln("#else")
1537            if freelist_size:
1538                code.globalstate.use_utility_code(
1539                    UtilityCode.load_cached("IncludeStringH", "StringTools.c"))
1540                if is_final_type:
1541                    type_safety_check = ''
1542                else:
1543                    type_safety_check = ' & (!__Pyx_PyType_HasFeature(t, (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)))'
1544                obj_struct = type.declaration_code("", deref=True)
1545                code.putln(
1546                    "if (CYTHON_COMPILING_IN_CPYTHON && likely((%s > 0) & (t->tp_basicsize == sizeof(%s))%s)) {" % (
1547                        freecount_name, obj_struct, type_safety_check))
1548                code.putln("o = (PyObject*)%s[--%s];" % (
1549                    freelist_name, freecount_name))
1550                code.putln("memset(o, 0, sizeof(%s));" % obj_struct)
1551                code.putln("(void) PyObject_INIT(o, t);")
1552                if scope.needs_gc():
1553                    code.putln("PyObject_GC_Track(o);")
1554                code.putln("} else {")
1555            if not is_final_type:
1556                code.putln("if (likely(!__Pyx_PyType_HasFeature(t, Py_TPFLAGS_IS_ABSTRACT))) {")
1557            code.putln("o = (*t->tp_alloc)(t, 0);")
1558            if not is_final_type:
1559                code.putln("} else {")
1560                code.putln("o = (PyObject *) PyBaseObject_Type.tp_new(t, %s, 0);" % Naming.empty_tuple)
1561                code.putln("}")
1562        code.putln("if (unlikely(!o)) return 0;")
1563        if freelist_size and not base_type:
1564            code.putln('}')
1565        if not base_type:
1566            code.putln("#endif")
1567        if need_self_cast:
1568            code.putln("p = %s;" % type.cast_code("o"))
1569        #if need_self_cast:
1570        #    self.generate_self_cast(scope, code)
1571
1572        # from this point on, ensure DECREF(o) on failure
1573        needs_error_cleanup = False
1574
1575        if type.vtabslot_cname:
1576            vtab_base_type = type
1577            while vtab_base_type.base_type and vtab_base_type.base_type.vtabstruct_cname:
1578                vtab_base_type = vtab_base_type.base_type
1579            if vtab_base_type is not type:
1580                struct_type_cast = "(struct %s*)" % vtab_base_type.vtabstruct_cname
1581            else:
1582                struct_type_cast = ""
1583            code.putln("p->%s = %s%s;" % (
1584                type.vtabslot_cname,
1585                struct_type_cast, type.vtabptr_cname))
1586
1587        for entry in cpp_constructable_attrs:
1588            if entry.is_cpp_optional:
1589                decl_code = entry.type.cpp_optional_declaration_code("")
1590            else:
1591                decl_code = entry.type.empty_declaration_code()
1592            code.putln("new((void*)&(p->%s)) %s();" % (
1593                entry.cname, decl_code))
1594
1595        for entry in py_attrs:
1596            if entry.name == "__dict__":
1597                needs_error_cleanup = True
1598                code.put("p->%s = PyDict_New(); if (unlikely(!p->%s)) goto bad;" % (
1599                    entry.cname, entry.cname))
1600            else:
1601                code.put_init_var_to_py_none(entry, "p->%s", nanny=False)
1602
1603        for entry in memoryview_slices:
1604            code.putln("p->%s.data = NULL;" % entry.cname)
1605            code.putln("p->%s.memview = NULL;" % entry.cname)
1606
1607        for entry in py_buffers:
1608            code.putln("p->%s.obj = NULL;" % entry.cname)
1609
1610        if cclass_entry.cname == '__pyx_memoryviewslice':
1611            code.putln("p->from_slice.memview = NULL;")
1612
1613        if cinit_func_entry:
1614            if cinit_func_entry.trivial_signature:
1615                cinit_args = "o, %s, NULL" % Naming.empty_tuple
1616            else:
1617                cinit_args = "o, a, k"
1618            needs_error_cleanup = True
1619            code.putln("if (unlikely(%s(%s) < 0)) goto bad;" % (
1620                cinit_func_entry.func_cname, cinit_args))
1621
1622        code.putln(
1623            "return o;")
1624        if needs_error_cleanup:
1625            code.putln("bad:")
1626            code.put_decref_clear("o", py_object_type, nanny=False)
1627            code.putln("return NULL;")
1628        code.putln(
1629            "}")
1630
1631    def generate_dealloc_function(self, scope, code):
1632        tp_slot = TypeSlots.ConstructorSlot("tp_dealloc", '__dealloc__')
1633        slot_func = scope.mangle_internal("tp_dealloc")
1634        base_type = scope.parent_type.base_type
1635        if tp_slot.slot_code(scope) != slot_func:
1636            return  # never used
1637
1638        slot_func_cname = scope.mangle_internal("tp_dealloc")
1639        code.putln("")
1640        code.putln(
1641            "static void %s(PyObject *o) {" % slot_func_cname)
1642
1643        is_final_type = scope.parent_type.is_final_type
1644        needs_gc = scope.needs_gc()
1645        needs_trashcan = scope.needs_trashcan()
1646
1647        weakref_slot = scope.lookup_here("__weakref__") if not scope.is_closure_class_scope else None
1648        if weakref_slot not in scope.var_entries:
1649            weakref_slot = None
1650
1651        dict_slot = scope.lookup_here("__dict__") if not scope.is_closure_class_scope else None
1652        if dict_slot not in scope.var_entries:
1653            dict_slot = None
1654
1655        _, (py_attrs, _, memoryview_slices) = scope.get_refcounted_entries()
1656        cpp_destructable_attrs = [entry for entry in scope.var_entries
1657                           if entry.type.needs_cpp_construction]
1658
1659        if py_attrs or cpp_destructable_attrs or memoryview_slices or weakref_slot or dict_slot:
1660            self.generate_self_cast(scope, code)
1661
1662        if not is_final_type:
1663            # in Py3.4+, call tp_finalize() as early as possible
1664            code.putln("#if CYTHON_USE_TP_FINALIZE")
1665            if needs_gc:
1666                finalised_check = '!_PyGC_FINALIZED(o)'
1667            else:
1668                finalised_check = (
1669                    '(!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))')
1670            code.putln(
1671                "if (unlikely("
1672                "(PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE))"
1673                " && Py_TYPE(o)->tp_finalize) && %s) {" % finalised_check)
1674            # if instance was resurrected by finaliser, return
1675            code.putln("if (PyObject_CallFinalizerFromDealloc(o)) return;")
1676            code.putln("}")
1677            code.putln("#endif")
1678
1679        if needs_gc:
1680            # We must mark this object as (gc) untracked while tearing
1681            # it down, lest the garbage collection is invoked while
1682            # running this destructor.
1683            code.putln("PyObject_GC_UnTrack(o);")
1684
1685        if needs_trashcan:
1686            code.globalstate.use_utility_code(
1687                UtilityCode.load_cached("PyTrashcan", "ExtensionTypes.c"))
1688            code.putln("__Pyx_TRASHCAN_BEGIN(o, %s)" % slot_func_cname)
1689
1690        if weakref_slot:
1691            # We must clean the weakreferences before calling the user's __dealloc__
1692            # because if the __dealloc__ releases the GIL, a weakref can be
1693            # dereferenced accessing the object in an inconsistent state or
1694            # resurrecting it.
1695            code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);")
1696
1697        # call the user's __dealloc__
1698        self.generate_usr_dealloc_call(scope, code)
1699
1700        if dict_slot:
1701            code.putln("if (p->__dict__) PyDict_Clear(p->__dict__);")
1702
1703        for entry in cpp_destructable_attrs:
1704            code.putln("__Pyx_call_destructor(p->%s);" % entry.cname)
1705
1706        for entry in (py_attrs + memoryview_slices):
1707            code.put_xdecref_clear("p->%s" % entry.cname, entry.type, nanny=False,
1708                                   clear_before_decref=True, have_gil=True)
1709
1710        if base_type:
1711            if needs_gc:
1712                # The base class deallocator probably expects this to be tracked,
1713                # so undo the untracking above.
1714                if base_type.scope and base_type.scope.needs_gc():
1715                    code.putln("PyObject_GC_Track(o);")
1716                else:
1717                    code.putln("#if CYTHON_USE_TYPE_SLOTS")
1718                    code.putln("if (PyType_IS_GC(Py_TYPE(o)->tp_base))")
1719                    code.putln("#endif")
1720                    code.putln("PyObject_GC_Track(o);")
1721
1722            tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot)
1723            if tp_dealloc is not None:
1724                code.putln("%s(o);" % tp_dealloc)
1725            elif base_type.is_builtin_type:
1726                code.putln("%s->tp_dealloc(o);" % base_type.typeptr_cname)
1727            else:
1728                # This is an externally defined type.  Calling through the
1729                # cimported base type pointer directly interacts badly with
1730                # the module cleanup, which may already have cleared it.
1731                # In that case, fall back to traversing the type hierarchy.
1732                base_cname = base_type.typeptr_cname
1733                code.putln("if (likely(%s)) %s->tp_dealloc(o); "
1734                           "else __Pyx_call_next_tp_dealloc(o, %s);" % (
1735                               base_cname, base_cname, slot_func_cname))
1736                code.globalstate.use_utility_code(
1737                    UtilityCode.load_cached("CallNextTpDealloc", "ExtensionTypes.c"))
1738        else:
1739            freelist_size = scope.directives.get('freelist', 0)
1740            if freelist_size:
1741                freelist_name = scope.mangle_internal(Naming.freelist_name)
1742                freecount_name = scope.mangle_internal(Naming.freecount_name)
1743
1744                if is_final_type:
1745                    type_safety_check = ''
1746                else:
1747                    type_safety_check = (
1748                        ' & (!__Pyx_PyType_HasFeature(Py_TYPE(o), (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)))')
1749
1750                type = scope.parent_type
1751                code.putln(
1752                    "if (CYTHON_COMPILING_IN_CPYTHON && ((%s < %d) & (Py_TYPE(o)->tp_basicsize == sizeof(%s))%s)) {" % (
1753                        freecount_name,
1754                        freelist_size,
1755                        type.declaration_code("", deref=True),
1756                        type_safety_check))
1757                code.putln("%s[%s++] = %s;" % (
1758                    freelist_name, freecount_name, type.cast_code("o")))
1759                code.putln("} else {")
1760            code.putln("(*Py_TYPE(o)->tp_free)(o);")
1761            if freelist_size:
1762                code.putln("}")
1763
1764        if needs_trashcan:
1765            code.putln("__Pyx_TRASHCAN_END")
1766
1767        code.putln(
1768            "}")
1769
1770    def generate_usr_dealloc_call(self, scope, code):
1771        entry = scope.lookup_here("__dealloc__")
1772        if not entry or not entry.is_special:
1773            return
1774
1775        code.putln("{")
1776        code.putln("PyObject *etype, *eval, *etb;")
1777        code.putln("PyErr_Fetch(&etype, &eval, &etb);")
1778        # increase the refcount while we are calling into user code
1779        # to prevent recursive deallocation
1780        code.putln("__Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1);")
1781        code.putln("%s(o);" % entry.func_cname)
1782        code.putln("__Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1);")
1783        code.putln("PyErr_Restore(etype, eval, etb);")
1784        code.putln("}")
1785
1786    def generate_traverse_function(self, scope, code, cclass_entry):
1787        tp_slot = TypeSlots.GCDependentSlot("tp_traverse")
1788        slot_func = scope.mangle_internal("tp_traverse")
1789        base_type = scope.parent_type.base_type
1790        if tp_slot.slot_code(scope) != slot_func:
1791            return  # never used
1792        code.putln("")
1793        code.putln(
1794            "static int %s(PyObject *o, visitproc v, void *a) {" % slot_func)
1795
1796        have_entries, (py_attrs, py_buffers, memoryview_slices) = (
1797            scope.get_refcounted_entries(include_gc_simple=False))
1798
1799        if base_type or py_attrs:
1800            code.putln("int e;")
1801
1802        if py_attrs or py_buffers:
1803            self.generate_self_cast(scope, code)
1804
1805        if base_type:
1806            # want to call it explicitly if possible so inlining can be performed
1807            static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
1808            if static_call:
1809                code.putln("e = %s(o, v, a); if (e) return e;" % static_call)
1810            elif base_type.is_builtin_type:
1811                base_cname = base_type.typeptr_cname
1812                code.putln("if (!%s->tp_traverse); else { e = %s->tp_traverse(o,v,a); if (e) return e; }" % (
1813                    base_cname, base_cname))
1814            else:
1815                # This is an externally defined type.  Calling through the
1816                # cimported base type pointer directly interacts badly with
1817                # the module cleanup, which may already have cleared it.
1818                # In that case, fall back to traversing the type hierarchy.
1819                base_cname = base_type.typeptr_cname
1820                code.putln(
1821                    "e = ((likely(%s)) ? ((%s->tp_traverse) ? %s->tp_traverse(o, v, a) : 0) : "
1822                    "__Pyx_call_next_tp_traverse(o, v, a, %s)); if (e) return e;" % (
1823                        base_cname, base_cname, base_cname, slot_func))
1824                code.globalstate.use_utility_code(
1825                    UtilityCode.load_cached("CallNextTpTraverse", "ExtensionTypes.c"))
1826
1827        for entry in py_attrs:
1828            var_code = "p->%s" % entry.cname
1829            var_as_pyobject = PyrexTypes.typecast(py_object_type, entry.type, var_code)
1830            code.putln("if (%s) {" % var_code)
1831            code.putln("e = (*v)(%s, a); if (e) return e;" % var_as_pyobject)
1832            code.putln("}")
1833
1834        # Traverse buffer exporting objects.
1835        # Note: not traversing memoryview attributes of memoryview slices!
1836        # When triggered by the GC, it would cause multiple visits (gc_refs
1837        # subtractions which is not matched by its reference count!)
1838        for entry in py_buffers:
1839            cname = entry.cname + ".obj"
1840            code.putln("if (p->%s) {" % cname)
1841            code.putln("e = (*v)(p->%s, a); if (e) return e;" % cname)
1842            code.putln("}")
1843
1844        code.putln("return 0;")
1845        code.putln("}")
1846
1847    def generate_clear_function(self, scope, code, cclass_entry):
1848        tp_slot = TypeSlots.get_slot_by_name("tp_clear")
1849        slot_func = scope.mangle_internal("tp_clear")
1850        base_type = scope.parent_type.base_type
1851        if tp_slot.slot_code(scope) != slot_func:
1852            return  # never used
1853
1854        have_entries, (py_attrs, py_buffers, memoryview_slices) = (
1855            scope.get_refcounted_entries(include_gc_simple=False))
1856
1857        if py_attrs or py_buffers or base_type:
1858            unused = ''
1859        else:
1860            unused = 'CYTHON_UNUSED '
1861
1862        code.putln("")
1863        code.putln("static int %s(%sPyObject *o) {" % (slot_func, unused))
1864
1865        if py_attrs and Options.clear_to_none:
1866            code.putln("PyObject* tmp;")
1867
1868        if py_attrs or py_buffers:
1869            self.generate_self_cast(scope, code)
1870
1871        if base_type:
1872            # want to call it explicitly if possible so inlining can be performed
1873            static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
1874            if static_call:
1875                code.putln("%s(o);" % static_call)
1876            elif base_type.is_builtin_type:
1877                base_cname = base_type.typeptr_cname
1878                code.putln("if (!%s->tp_clear); else %s->tp_clear(o);" % (
1879                    base_cname, base_cname))
1880            else:
1881                # This is an externally defined type.  Calling through the
1882                # cimported base type pointer directly interacts badly with
1883                # the module cleanup, which may already have cleared it.
1884                # In that case, fall back to traversing the type hierarchy.
1885                base_cname = base_type.typeptr_cname
1886                code.putln(
1887                    "if (likely(%s)) { if (%s->tp_clear) %s->tp_clear(o); } else __Pyx_call_next_tp_clear(o, %s);" % (
1888                        base_cname, base_cname, base_cname, slot_func))
1889                code.globalstate.use_utility_code(
1890                    UtilityCode.load_cached("CallNextTpClear", "ExtensionTypes.c"))
1891
1892        if Options.clear_to_none:
1893            for entry in py_attrs:
1894                name = "p->%s" % entry.cname
1895                code.putln("tmp = ((PyObject*)%s);" % name)
1896                if entry.is_declared_generic:
1897                    code.put_init_to_py_none(name, py_object_type, nanny=False)
1898                else:
1899                    code.put_init_to_py_none(name, entry.type, nanny=False)
1900                code.putln("Py_XDECREF(tmp);")
1901        else:
1902            for entry in py_attrs:
1903                code.putln("Py_CLEAR(p->%s);" % entry.cname)
1904
1905        for entry in py_buffers:
1906            # Note: shouldn't this call __Pyx_ReleaseBuffer ??
1907            code.putln("Py_CLEAR(p->%s.obj);" % entry.cname)
1908
1909        if cclass_entry.cname == '__pyx_memoryviewslice':
1910            code.putln("__PYX_XCLEAR_MEMVIEW(&p->from_slice, 1);")
1911
1912        code.putln("return 0;")
1913        code.putln("}")
1914
1915    def generate_getitem_int_function(self, scope, code):
1916        # This function is put into the sq_item slot when
1917        # a __getitem__ method is present. It converts its
1918        # argument to a Python integer and calls mp_subscript.
1919        code.putln(
1920            "static PyObject *%s(PyObject *o, Py_ssize_t i) {" % (
1921                scope.mangle_internal("sq_item")))
1922        code.putln(
1923            "PyObject *r;")
1924        code.putln(
1925            "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;")
1926        code.putln(
1927            "r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);")
1928        code.putln(
1929            "Py_DECREF(x);")
1930        code.putln(
1931            "return r;")
1932        code.putln(
1933            "}")
1934
1935    def generate_ass_subscript_function(self, scope, code):
1936        # Setting and deleting an item are both done through
1937        # the ass_subscript method, so we dispatch to user's __setitem__
1938        # or __delitem__, or raise an exception.
1939        base_type = scope.parent_type.base_type
1940        set_entry = scope.lookup_here("__setitem__")
1941        del_entry = scope.lookup_here("__delitem__")
1942        code.putln("")
1943        code.putln(
1944            "static int %s(PyObject *o, PyObject *i, PyObject *v) {" % (
1945                scope.mangle_internal("mp_ass_subscript")))
1946        code.putln(
1947            "if (v) {")
1948        if set_entry:
1949            code.putln("return %s(o, i, v);" % set_entry.func_cname)
1950        else:
1951            code.putln(
1952                "__Pyx_TypeName o_type_name;")
1953            self.generate_guarded_basetype_call(
1954                base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
1955            code.putln(
1956                "o_type_name = __Pyx_PyType_GetName(Py_TYPE(o));")
1957            code.putln(
1958                "PyErr_Format(PyExc_NotImplementedError,")
1959            code.putln(
1960                '  "Subscript assignment not supported by " __Pyx_FMT_TYPENAME, o_type_name);')
1961            code.putln(
1962                "__Pyx_DECREF_TypeName(o_type_name);")
1963            code.putln(
1964                "return -1;")
1965        code.putln(
1966            "}")
1967        code.putln(
1968            "else {")
1969        if del_entry:
1970            code.putln(
1971                "return %s(o, i);" % (
1972                    del_entry.func_cname))
1973        else:
1974            code.putln(
1975                "__Pyx_TypeName o_type_name;")
1976            self.generate_guarded_basetype_call(
1977                base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
1978            code.putln(
1979                "o_type_name = __Pyx_PyType_GetName(Py_TYPE(o));")
1980            code.putln(
1981                "PyErr_Format(PyExc_NotImplementedError,")
1982            code.putln(
1983                '  "Subscript deletion not supported by " __Pyx_FMT_TYPENAME, o_type_name);')
1984            code.putln(
1985                "__Pyx_DECREF_TypeName(o_type_name);")
1986            code.putln(
1987                "return -1;")
1988        code.putln(
1989            "}")
1990        code.putln(
1991            "}")
1992
1993    def generate_guarded_basetype_call(
1994            self, base_type, substructure, slot, args, code):
1995        if base_type:
1996            base_tpname = base_type.typeptr_cname
1997            if substructure:
1998                code.putln(
1999                    "if (%s->%s && %s->%s->%s)" % (
2000                        base_tpname, substructure, base_tpname, substructure, slot))
2001                code.putln(
2002                    "  return %s->%s->%s(%s);" % (
2003                        base_tpname, substructure, slot, args))
2004            else:
2005                code.putln(
2006                    "if (%s->%s)" % (
2007                        base_tpname, slot))
2008                code.putln(
2009                    "  return %s->%s(%s);" % (
2010                        base_tpname, slot, args))
2011
2012    def generate_ass_slice_function(self, scope, code):
2013        # Setting and deleting a slice are both done through
2014        # the ass_slice method, so we dispatch to user's __setslice__
2015        # or __delslice__, or raise an exception.
2016        base_type = scope.parent_type.base_type
2017        set_entry = scope.lookup_here("__setslice__")
2018        del_entry = scope.lookup_here("__delslice__")
2019        code.putln("")
2020        code.putln(
2021            "static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" % (
2022                scope.mangle_internal("sq_ass_slice")))
2023        code.putln(
2024            "if (v) {")
2025        if set_entry:
2026            code.putln(
2027                "return %s(o, i, j, v);" % (
2028                    set_entry.func_cname))
2029        else:
2030            code.putln(
2031                "__Pyx_TypeName o_type_name;")
2032            self.generate_guarded_basetype_call(
2033                base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
2034            code.putln(
2035                "o_type_name = __Pyx_PyType_GetName(Py_TYPE(o));")
2036            code.putln(
2037                "PyErr_Format(PyExc_NotImplementedError,")
2038            code.putln(
2039                '  "2-element slice assignment not supported by " __Pyx_FMT_TYPENAME, o_type_name);')
2040            code.putln(
2041                "__Pyx_DECREF_TypeName(o_type_name);")
2042            code.putln(
2043                "return -1;")
2044        code.putln(
2045            "}")
2046        code.putln(
2047            "else {")
2048        if del_entry:
2049            code.putln(
2050                "return %s(o, i, j);" % (
2051                    del_entry.func_cname))
2052        else:
2053            code.putln(
2054                "__Pyx_TypeName o_type_name;")
2055            self.generate_guarded_basetype_call(
2056                base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
2057            code.putln(
2058                "o_type_name = __Pyx_PyType_GetName(Py_TYPE(o));")
2059            code.putln(
2060                "PyErr_Format(PyExc_NotImplementedError,")
2061            code.putln(
2062                '  "2-element slice deletion not supported by " __Pyx_FMT_TYPENAME, o_type_name);')
2063            code.putln(
2064                "__Pyx_DECREF_TypeName(o_type_name);")
2065            code.putln(
2066                "return -1;")
2067        code.putln(
2068            "}")
2069        code.putln(
2070            "}")
2071
2072    def generate_richcmp_function(self, scope, code):
2073        if scope.lookup_here("__richcmp__"):
2074            # user implemented, nothing to do
2075            return
2076        # otherwise, we have to generate it from the Python special methods
2077        richcmp_cfunc = scope.mangle_internal("tp_richcompare")
2078        code.putln("")
2079        code.putln("static PyObject *%s(PyObject *o1, PyObject *o2, int op) {" % richcmp_cfunc)
2080        code.putln("switch (op) {")
2081
2082        class_scopes = []
2083        cls = scope.parent_type
2084        while cls is not None and not cls.entry.visibility == 'extern':
2085            class_scopes.append(cls.scope)
2086            cls = cls.scope.parent_type.base_type
2087        assert scope in class_scopes
2088
2089        extern_parent = None
2090        if cls and cls.entry.visibility == 'extern':
2091            # need to call up into base classes as we may not know all implemented comparison methods
2092            extern_parent = cls if cls.typeptr_cname else scope.parent_type.base_type
2093
2094        total_ordering = scope.directives.get('total_ordering', False)
2095
2096        comp_entry = {}
2097
2098        for cmp_method in TypeSlots.richcmp_special_methods:
2099            for class_scope in class_scopes:
2100                entry = class_scope.lookup_here(cmp_method)
2101                if entry is not None:
2102                    comp_entry[cmp_method] = entry
2103                    break
2104
2105        if total_ordering:
2106            # Check this is valid - we must have at least 1 operation defined.
2107            comp_names = [from_name for from_name, to_name in TOTAL_ORDERING if from_name in comp_entry]
2108            if not comp_names:
2109                if '__eq__' not in comp_entry and '__ne__'  not in comp_entry:
2110                    warning(scope.parent_type.pos,
2111                            "total_ordering directive used, but no comparison and equality methods defined")
2112                else:
2113                    warning(scope.parent_type.pos,
2114                          "total_ordering directive used, but no comparison methods defined")
2115                total_ordering = False
2116            else:
2117                if '__eq__' not in comp_entry and '__ne__' not in comp_entry:
2118                    warning(scope.parent_type.pos, "total_ordering directive used, but no equality method defined")
2119                    total_ordering = False
2120
2121                # Same priority as functools, prefers
2122                # __lt__ to __le__ to __gt__ to __ge__
2123                ordering_source = max(comp_names)
2124
2125        for cmp_method in TypeSlots.richcmp_special_methods:
2126            cmp_type = cmp_method.strip('_').upper()  # e.g. "__eq__" -> EQ
2127            entry = comp_entry.get(cmp_method)
2128            if entry is None and (not total_ordering or cmp_type in ('NE', 'EQ')):
2129                # No definition, fall back to superclasses.
2130                # eq/ne methods shouldn't use the total_ordering code.
2131                continue
2132
2133            code.putln("case Py_%s: {" % cmp_type)
2134            if entry is None:
2135                assert total_ordering
2136                # We need to generate this from the other methods.
2137                invert_comp, comp_op, invert_equals = TOTAL_ORDERING[ordering_source, cmp_method]
2138
2139                # First we always do the comparison.
2140                code.putln("PyObject *ret;")
2141                code.putln("ret = %s(o1, o2);" % comp_entry[ordering_source].func_cname)
2142                code.putln("if (likely(ret && ret != Py_NotImplemented)) {")
2143                code.putln("int order_res = __Pyx_PyObject_IsTrue(ret);")
2144                code.putln("Py_DECREF(ret);")
2145                code.putln("if (unlikely(order_res < 0)) return NULL;")
2146                # We may need to check equality too. For some combos it's never required.
2147                if invert_equals is not None:
2148                    # Implement the and/or check with an if.
2149                    if comp_op == '&&':
2150                        code.putln("if (%s order_res) {" % ('!!' if invert_comp else '!'))
2151                        code.putln("ret = __Pyx_NewRef(Py_False);")
2152                        code.putln("} else {")
2153                    elif comp_op == '||':
2154                        code.putln("if (%s order_res) {" % ('!' if invert_comp else ''))
2155                        code.putln("ret = __Pyx_NewRef(Py_True);")
2156                        code.putln("} else {")
2157                    else:
2158                        raise AssertionError('Unknown op %s' % (comp_op, ))
2159                    if '__eq__' in comp_entry:
2160                        eq_func = '__eq__'
2161                    else:
2162                        # Fall back to NE, which is defined here.
2163                        eq_func = '__ne__'
2164                        invert_equals = not invert_equals
2165
2166                    code.putln("ret = %s(o1, o2);" % comp_entry[eq_func].func_cname)
2167                    code.putln("if (likely(ret && ret != Py_NotImplemented)) {")
2168                    code.putln("int eq_res = __Pyx_PyObject_IsTrue(ret);")
2169                    code.putln("Py_DECREF(ret);")
2170                    code.putln("if (unlikely(eq_res < 0)) return NULL;")
2171                    if invert_equals:
2172                        code.putln("ret = eq_res ? Py_False : Py_True;")
2173                    else:
2174                        code.putln("ret = eq_res ? Py_True : Py_False;")
2175                    code.putln("Py_INCREF(ret);")
2176                    code.putln("}")  # equals success
2177                    code.putln("}")  # Needs to try equals
2178                else:
2179                    # Convert direct to a boolean.
2180                    if invert_comp:
2181                        code.putln("ret = order_res ? Py_False : Py_True;")
2182                    else:
2183                        code.putln("ret = order_res ? Py_True : Py_False;")
2184                    code.putln("Py_INCREF(ret);")
2185                code.putln("}")  # comp_op
2186                code.putln("return ret;")
2187            else:
2188                code.putln("return %s(o1, o2);" % entry.func_cname)
2189            code.putln("}")  # Case
2190
2191        if '__eq__' in comp_entry and '__ne__' not in comp_entry and not extern_parent:
2192            code.putln("case Py_NE: {")
2193            code.putln("PyObject *ret;")
2194            # Python itself does not do this optimisation, it seems...
2195            #code.putln("if (o1 == o2) return __Pyx_NewRef(Py_False);")
2196            code.putln("ret = %s(o1, o2);" % comp_entry['__eq__'].func_cname)
2197            code.putln("if (likely(ret && ret != Py_NotImplemented)) {")
2198            code.putln("int b = __Pyx_PyObject_IsTrue(ret);")
2199            code.putln("Py_DECREF(ret);")
2200            code.putln("if (unlikely(b < 0)) return NULL;")
2201            code.putln("ret = (b) ? Py_False : Py_True;")
2202            code.putln("Py_INCREF(ret);")
2203            code.putln("}")
2204            code.putln("return ret;")
2205            code.putln("}")
2206
2207        code.putln("default: {")
2208        if extern_parent and extern_parent.typeptr_cname:
2209            code.putln("if (likely(%s->tp_richcompare)) return %s->tp_richcompare(o1, o2, op);" % (
2210                extern_parent.typeptr_cname, extern_parent.typeptr_cname))
2211        code.putln("return __Pyx_NewRef(Py_NotImplemented);")
2212        code.putln("}")
2213
2214        code.putln("}")  # switch
2215        code.putln("}")
2216
2217    def generate_binop_function(self, scope, slot, code, pos):
2218        func_name = scope.mangle_internal(slot.slot_name)
2219        if scope.directives['c_api_binop_methods']:
2220            code.putln('#define %s %s' % (func_name, slot.left_slot.slot_code(scope)))
2221            return
2222
2223        code.putln()
2224        preprocessor_guard = slot.preprocessor_guard_code()
2225        if preprocessor_guard:
2226            code.putln(preprocessor_guard)
2227
2228        if slot.left_slot.signature == TypeSlots.binaryfunc:
2229            slot_type = 'binaryfunc'
2230            extra_arg = extra_arg_decl = ''
2231        elif slot.left_slot.signature == TypeSlots.ternaryfunc:
2232            slot_type = 'ternaryfunc'
2233            extra_arg = ', extra_arg'
2234            extra_arg_decl = ', PyObject* extra_arg'
2235        else:
2236            error(pos, "Unexpected type slot signature: %s" % slot)
2237            return
2238
2239        def get_slot_method_cname(method_name):
2240            entry = scope.lookup(method_name)
2241            return entry.func_cname if entry and entry.is_special else None
2242
2243        def call_slot_method(method_name, reverse):
2244            func_cname = get_slot_method_cname(method_name)
2245            if func_cname:
2246                return "%s(%s%s)" % (
2247                    func_cname,
2248                    "right, left" if reverse else "left, right",
2249                    extra_arg)
2250            else:
2251                return '%s_maybe_call_slot(%s->tp_base, left, right %s)' % (
2252                    func_name,
2253                    scope.parent_type.typeptr_cname,
2254                    extra_arg)
2255
2256        if get_slot_method_cname(slot.left_slot.method_name) and not get_slot_method_cname(slot.right_slot.method_name):
2257            warning(pos, "Extension type implements %s() but not %s(). "
2258                         "The behaviour has changed from previous Cython versions to match Python semantics. "
2259                         "You can implement both special methods in a backwards compatible way." % (
2260                slot.left_slot.method_name,
2261                slot.right_slot.method_name,
2262            ))
2263
2264        overloads_left = int(bool(get_slot_method_cname(slot.left_slot.method_name)))
2265        overloads_right = int(bool(get_slot_method_cname(slot.right_slot.method_name)))
2266        code.putln(
2267            TempitaUtilityCode.load_as_string(
2268                "BinopSlot", "ExtensionTypes.c",
2269                context={
2270                    "func_name": func_name,
2271                    "slot_name": slot.slot_name,
2272                    "overloads_left": overloads_left,
2273                    "overloads_right": overloads_right,
2274                    "call_left": call_slot_method(slot.left_slot.method_name, reverse=False),
2275                    "call_right": call_slot_method(slot.right_slot.method_name, reverse=True),
2276                    "type_cname": scope.parent_type.typeptr_cname,
2277                    "slot_type": slot_type,
2278                    "extra_arg": extra_arg,
2279                    "extra_arg_decl": extra_arg_decl,
2280                    })[1])
2281        if preprocessor_guard:
2282            code.putln("#endif")
2283
2284    def generate_getattro_function(self, scope, code):
2285        # First try to get the attribute using __getattribute__, if defined, or
2286        # PyObject_GenericGetAttr.
2287        #
2288        # If that raises an AttributeError, call the __getattr__ if defined.
2289        #
2290        # In both cases, defined can be in this class, or any base class.
2291        def lookup_here_or_base(n, tp=None, extern_return=None):
2292            # Recursive lookup
2293            if tp is None:
2294                tp = scope.parent_type
2295            r = tp.scope.lookup_here(n)
2296            if r is None:
2297                if tp.is_external and extern_return is not None:
2298                    return extern_return
2299                if tp.base_type is not None:
2300                    return lookup_here_or_base(n, tp.base_type)
2301            return r
2302
2303        has_instance_dict = lookup_here_or_base("__dict__", extern_return="extern")
2304        getattr_entry = lookup_here_or_base("__getattr__")
2305        getattribute_entry = lookup_here_or_base("__getattribute__")
2306        code.putln("")
2307        code.putln(
2308            "static PyObject *%s(PyObject *o, PyObject *n) {" % (
2309                scope.mangle_internal("tp_getattro")))
2310        if getattribute_entry is not None:
2311            code.putln(
2312                "PyObject *v = %s(o, n);" % (
2313                    getattribute_entry.func_cname))
2314        else:
2315            if not has_instance_dict and scope.parent_type.is_final_type:
2316                # Final with no dict => use faster type attribute lookup.
2317                code.globalstate.use_utility_code(
2318                    UtilityCode.load_cached("PyObject_GenericGetAttrNoDict", "ObjectHandling.c"))
2319                generic_getattr_cfunc = "__Pyx_PyObject_GenericGetAttrNoDict"
2320            elif not has_instance_dict or has_instance_dict == "extern":
2321                # No dict in the known ancestors, but don't know about extern ancestors or subtypes.
2322                code.globalstate.use_utility_code(
2323                    UtilityCode.load_cached("PyObject_GenericGetAttr", "ObjectHandling.c"))
2324                generic_getattr_cfunc = "__Pyx_PyObject_GenericGetAttr"
2325            else:
2326                generic_getattr_cfunc = "PyObject_GenericGetAttr"
2327            code.putln(
2328                "PyObject *v = %s(o, n);" % generic_getattr_cfunc)
2329        if getattr_entry is not None:
2330            code.putln(
2331                "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
2332            code.putln(
2333                "PyErr_Clear();")
2334            code.putln(
2335                "v = %s(o, n);" % (
2336                    getattr_entry.func_cname))
2337            code.putln(
2338                "}")
2339        code.putln(
2340            "return v;")
2341        code.putln(
2342            "}")
2343
2344    def generate_setattro_function(self, scope, code):
2345        # Setting and deleting an attribute are both done through
2346        # the setattro method, so we dispatch to user's __setattr__
2347        # or __delattr__ or fall back on PyObject_GenericSetAttr.
2348        base_type = scope.parent_type.base_type
2349        set_entry = scope.lookup_here("__setattr__")
2350        del_entry = scope.lookup_here("__delattr__")
2351        code.putln("")
2352        code.putln(
2353            "static int %s(PyObject *o, PyObject *n, PyObject *v) {" % (
2354                scope.mangle_internal("tp_setattro")))
2355        code.putln(
2356            "if (v) {")
2357        if set_entry:
2358            code.putln(
2359                "return %s(o, n, v);" % (
2360                    set_entry.func_cname))
2361        else:
2362            self.generate_guarded_basetype_call(
2363                base_type, None, "tp_setattro", "o, n, v", code)
2364            code.putln(
2365                "return PyObject_GenericSetAttr(o, n, v);")
2366        code.putln(
2367            "}")
2368        code.putln(
2369            "else {")
2370        if del_entry:
2371            code.putln(
2372                "return %s(o, n);" % (
2373                    del_entry.func_cname))
2374        else:
2375            self.generate_guarded_basetype_call(
2376                base_type, None, "tp_setattro", "o, n, v", code)
2377            code.putln(
2378                "return PyObject_GenericSetAttr(o, n, 0);")
2379        code.putln(
2380            "}")
2381        code.putln(
2382            "}")
2383
2384    def generate_descr_get_function(self, scope, code):
2385        # The __get__ function of a descriptor object can be
2386        # called with NULL for the second or third arguments
2387        # under some circumstances, so we replace them with
2388        # None in that case.
2389        user_get_entry = scope.lookup_here("__get__")
2390        code.putln("")
2391        code.putln(
2392            "static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" % (
2393                scope.mangle_internal("tp_descr_get")))
2394        code.putln(
2395            "PyObject *r = 0;")
2396        code.putln(
2397            "if (!i) i = Py_None;")
2398        code.putln(
2399            "if (!c) c = Py_None;")
2400        #code.put_incref("i", py_object_type)
2401        #code.put_incref("c", py_object_type)
2402        code.putln(
2403            "r = %s(o, i, c);" % (
2404                user_get_entry.func_cname))
2405        #code.put_decref("i", py_object_type)
2406        #code.put_decref("c", py_object_type)
2407        code.putln(
2408            "return r;")
2409        code.putln(
2410            "}")
2411
2412    def generate_descr_set_function(self, scope, code):
2413        # Setting and deleting are both done through the __set__
2414        # method of a descriptor, so we dispatch to user's __set__
2415        # or __delete__ or raise an exception.
2416        base_type = scope.parent_type.base_type
2417        user_set_entry = scope.lookup_here("__set__")
2418        user_del_entry = scope.lookup_here("__delete__")
2419        code.putln("")
2420        code.putln(
2421            "static int %s(PyObject *o, PyObject *i, PyObject *v) {" % (
2422                scope.mangle_internal("tp_descr_set")))
2423        code.putln(
2424            "if (v) {")
2425        if user_set_entry:
2426            code.putln(
2427                "return %s(o, i, v);" % (
2428                    user_set_entry.func_cname))
2429        else:
2430            self.generate_guarded_basetype_call(
2431                base_type, None, "tp_descr_set", "o, i, v", code)
2432            code.putln(
2433                'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
2434            code.putln(
2435                "return -1;")
2436        code.putln(
2437            "}")
2438        code.putln(
2439            "else {")
2440        if user_del_entry:
2441            code.putln(
2442                "return %s(o, i);" % (
2443                    user_del_entry.func_cname))
2444        else:
2445            self.generate_guarded_basetype_call(
2446                base_type, None, "tp_descr_set", "o, i, v", code)
2447            code.putln(
2448                'PyErr_SetString(PyExc_NotImplementedError, "__delete__");')
2449            code.putln(
2450                "return -1;")
2451        code.putln(
2452            "}")
2453        code.putln(
2454            "}")
2455
2456    def generate_property_accessors(self, cclass_scope, code):
2457        for entry in cclass_scope.property_entries:
2458            property_scope = entry.scope
2459            if property_scope.defines_any(["__get__"]):
2460                self.generate_property_get_function(entry, code)
2461            if property_scope.defines_any(["__set__", "__del__"]):
2462                self.generate_property_set_function(entry, code)
2463
2464    def generate_property_get_function(self, property_entry, code):
2465        property_scope = property_entry.scope
2466        property_entry.getter_cname = property_scope.parent_scope.mangle(
2467            Naming.prop_get_prefix, property_entry.name)
2468        get_entry = property_scope.lookup_here("__get__")
2469        code.putln("")
2470        code.putln(
2471            "static PyObject *%s(PyObject *o, CYTHON_UNUSED void *x) {" % (
2472                property_entry.getter_cname))
2473        code.putln(
2474            "return %s(o);" % (
2475                get_entry.func_cname))
2476        code.putln(
2477            "}")
2478
2479    def generate_property_set_function(self, property_entry, code):
2480        property_scope = property_entry.scope
2481        property_entry.setter_cname = property_scope.parent_scope.mangle(
2482            Naming.prop_set_prefix, property_entry.name)
2483        set_entry = property_scope.lookup_here("__set__")
2484        del_entry = property_scope.lookup_here("__del__")
2485        code.putln("")
2486        code.putln(
2487            "static int %s(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {" % (
2488                property_entry.setter_cname))
2489        code.putln(
2490            "if (v) {")
2491        if set_entry:
2492            code.putln(
2493                "return %s(o, v);" % (
2494                    set_entry.func_cname))
2495        else:
2496            code.putln(
2497                'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
2498            code.putln(
2499                "return -1;")
2500        code.putln(
2501            "}")
2502        code.putln(
2503            "else {")
2504        if del_entry:
2505            code.putln(
2506                "return %s(o);" % (
2507                    del_entry.func_cname))
2508        else:
2509            code.putln(
2510                'PyErr_SetString(PyExc_NotImplementedError, "__del__");')
2511            code.putln(
2512                "return -1;")
2513        code.putln(
2514            "}")
2515        code.putln(
2516            "}")
2517
2518    def generate_typeobj_spec(self, entry, code):
2519        ext_type = entry.type
2520        scope = ext_type.scope
2521
2522        members_slot = TypeSlots.get_slot_by_name("tp_members")
2523        members_slot.generate_substructure_spec(scope, code)
2524
2525        buffer_slot = TypeSlots.get_slot_by_name("tp_as_buffer")
2526        if not buffer_slot.is_empty(scope):
2527            code.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
2528            buffer_slot.generate_substructure(scope, code)
2529            code.putln("#endif")
2530
2531        code.putln("static PyType_Slot %s_slots[] = {" % ext_type.typeobj_cname)
2532        for slot in TypeSlots.slot_table:
2533            slot.generate_spec(scope, code)
2534        code.putln("{0, 0},")
2535        code.putln("};")
2536
2537        if ext_type.typedef_flag:
2538            objstruct = ext_type.objstruct_cname
2539        else:
2540            objstruct = "struct %s" % ext_type.objstruct_cname
2541        classname = scope.class_name.as_c_string_literal()
2542        code.putln("static PyType_Spec %s_spec = {" % ext_type.typeobj_cname)
2543        code.putln('"%s.%s",' % (self.full_module_name, classname.replace('"', '')))
2544        code.putln("sizeof(%s)," % objstruct)
2545        code.putln("0,")
2546        code.putln("%s," % TypeSlots.get_slot_by_name("tp_flags").slot_code(scope))
2547        code.putln("%s_slots," % ext_type.typeobj_cname)
2548        code.putln("};")
2549
2550    def generate_typeobj_definition(self, modname, entry, code):
2551        type = entry.type
2552        scope = type.scope
2553        for suite in TypeSlots.substructures:
2554            suite.generate_substructure(scope, code)
2555        code.putln("")
2556        if entry.visibility == 'public':
2557            header = "DL_EXPORT(PyTypeObject) %s = {"
2558        else:
2559            header = "static PyTypeObject %s = {"
2560        #code.putln(header % scope.parent_type.typeobj_cname)
2561        code.putln(header % type.typeobj_cname)
2562        code.putln(
2563            "PyVarObject_HEAD_INIT(0, 0)")
2564        classname = scope.class_name.as_c_string_literal()
2565        code.putln(
2566            '"%s."%s, /*tp_name*/' % (
2567                self.full_module_name,
2568                classname))
2569        if type.typedef_flag:
2570            objstruct = type.objstruct_cname
2571        else:
2572            objstruct = "struct %s" % type.objstruct_cname
2573        code.putln(
2574            "sizeof(%s), /*tp_basicsize*/" % objstruct)
2575        code.putln(
2576            "0, /*tp_itemsize*/")
2577        for slot in TypeSlots.slot_table:
2578            slot.generate(scope, code)
2579        code.putln(
2580            "};")
2581
2582    def generate_method_table(self, env, code):
2583        if env.is_c_class_scope and not env.pyfunc_entries:
2584            return
2585        binding = env.directives['binding']
2586
2587        code.putln("")
2588        wrapper_code_writer = code.insertion_point()
2589
2590        code.putln(
2591            "static PyMethodDef %s[] = {" % (
2592                env.method_table_cname))
2593        for entry in env.pyfunc_entries:
2594            if not entry.fused_cfunction and not (binding and entry.is_overridable):
2595                code.put_pymethoddef(entry, ",", wrapper_code_writer=wrapper_code_writer)
2596        code.putln(
2597            "{0, 0, 0, 0}")
2598        code.putln(
2599            "};")
2600
2601        if wrapper_code_writer.getvalue():
2602            wrapper_code_writer.putln("")
2603
2604    def generate_dict_getter_function(self, scope, code):
2605        dict_attr = scope.lookup_here("__dict__")
2606        if not dict_attr or not dict_attr.is_variable:
2607            return
2608        func_name = scope.mangle_internal("__dict__getter")
2609        dict_name = dict_attr.cname
2610        code.putln("")
2611        code.putln("static PyObject *%s(PyObject *o, CYTHON_UNUSED void *x) {" % func_name)
2612        self.generate_self_cast(scope, code)
2613        code.putln("if (unlikely(!p->%s)){" % dict_name)
2614        code.putln("p->%s = PyDict_New();" % dict_name)
2615        code.putln("}")
2616        code.putln("Py_XINCREF(p->%s);" % dict_name)
2617        code.putln("return p->%s;" % dict_name)
2618        code.putln("}")
2619
2620    def generate_getset_table(self, env, code):
2621        if env.property_entries:
2622            code.putln("")
2623            code.putln(
2624                "static struct PyGetSetDef %s[] = {" %
2625                env.getset_table_cname)
2626            for entry in env.property_entries:
2627                doc = entry.doc
2628                if doc:
2629                    if doc.is_unicode:
2630                        doc = doc.as_utf8_string()
2631                    doc_code = "PyDoc_STR(%s)" % doc.as_c_string_literal()
2632                else:
2633                    doc_code = "0"
2634                code.putln(
2635                    '{(char *)%s, %s, %s, (char *)%s, 0},' % (
2636                        entry.name.as_c_string_literal(),
2637                        entry.getter_cname or "0",
2638                        entry.setter_cname or "0",
2639                        doc_code))
2640            code.putln(
2641                "{0, 0, 0, 0, 0}")
2642            code.putln(
2643                "};")
2644
2645    def create_import_star_conversion_utility_code(self, env):
2646        # Create all conversion helpers that are needed for "import *" assignments.
2647        # Must be done before code generation to support CythonUtilityCode.
2648        for name, entry in sorted(env.entries.items()):
2649            if entry.is_cglobal and entry.used:
2650                if not entry.type.is_pyobject:
2651                    entry.type.create_from_py_utility_code(env)
2652
2653    def generate_import_star(self, env, code):
2654        env.use_utility_code(UtilityCode.load_cached("CStringEquals", "StringTools.c"))
2655        code.putln()
2656        code.enter_cfunc_scope()  # as we need labels
2657        code.putln("static int %s(PyObject *o, PyObject* py_name, char *name) {" % Naming.import_star_set)
2658
2659        code.putln("static const char* internal_type_names[] = {")
2660        for name, entry in sorted(env.entries.items()):
2661            if entry.is_type:
2662                code.putln('"%s",' % name)
2663        code.putln("0")
2664        code.putln("};")
2665
2666        code.putln("const char** type_name = internal_type_names;")
2667        code.putln("while (*type_name) {")
2668        code.putln("if (__Pyx_StrEq(name, *type_name)) {")
2669        code.putln('PyErr_Format(PyExc_TypeError, "Cannot overwrite C type %s", name);')
2670        code.putln('goto bad;')
2671        code.putln("}")
2672        code.putln("type_name++;")
2673        code.putln("}")
2674
2675        old_error_label = code.new_error_label()
2676        code.putln("if (0);")  # so the first one can be "else if"
2677        msvc_count = 0
2678        for name, entry in sorted(env.entries.items()):
2679            if entry.is_cglobal and entry.used and not entry.type.is_const:
2680                msvc_count += 1
2681                if msvc_count % 100 == 0:
2682                    code.putln("#ifdef _MSC_VER")
2683                    code.putln("if (0);  /* Workaround for MSVC C1061. */")
2684                    code.putln("#endif")
2685                code.putln('else if (__Pyx_StrEq(name, "%s")) {' % name)
2686                if entry.type.is_pyobject:
2687                    if entry.type.is_extension_type or entry.type.is_builtin_type:
2688                        code.putln("if (!(%s)) %s;" % (
2689                            entry.type.type_test_code("o"),
2690                            code.error_goto(entry.pos)))
2691                    code.putln("Py_INCREF(o);")
2692                    code.put_decref(entry.cname, entry.type, nanny=False)
2693                    code.putln("%s = %s;" % (
2694                        entry.cname,
2695                        PyrexTypes.typecast(entry.type, py_object_type, "o")))
2696                elif entry.type.create_from_py_utility_code(env):
2697                    # if available, utility code was already created in self.prepare_utility_code()
2698                    code.putln(entry.type.from_py_call_code(
2699                        'o', entry.cname, entry.pos, code))
2700                else:
2701                    code.putln('PyErr_Format(PyExc_TypeError, "Cannot convert Python object %s to %s");' % (
2702                        name, entry.type))
2703                    code.putln(code.error_goto(entry.pos))
2704                code.putln("}")
2705        code.putln("else {")
2706        code.putln("if (PyObject_SetAttr(%s, py_name, o) < 0) goto bad;" % Naming.module_cname)
2707        code.putln("}")
2708        code.putln("return 0;")
2709        if code.label_used(code.error_label):
2710            code.put_label(code.error_label)
2711            # This helps locate the offending name.
2712            code.put_add_traceback(EncodedString(self.full_module_name))
2713        code.error_label = old_error_label
2714        code.putln("bad:")
2715        code.putln("return -1;")
2716        code.putln("}")
2717        code.putln("")
2718        code.putln(UtilityCode.load_as_string("ImportStar", "ImportExport.c")[1])
2719        code.exit_cfunc_scope()  # done with labels
2720
2721    def generate_module_state_start(self, env, code):
2722        # TODO: Refactor to move module state struct decl closer to the static decl
2723        code.putln("#if CYTHON_USE_MODULE_STATE")
2724        code.putln('typedef struct {')
2725        code.putln('PyObject *%s;' % env.module_dict_cname)
2726        code.putln('PyObject *%s;' % Naming.builtins_cname)
2727        code.putln('PyObject *%s;' % Naming.cython_runtime_cname)
2728        code.putln('PyObject *%s;' % Naming.empty_tuple)
2729        code.putln('PyObject *%s;' % Naming.empty_bytes)
2730        code.putln('PyObject *%s;' % Naming.empty_unicode)
2731        if Options.pre_import is not None:
2732            code.putln('PyObject *%s;' % Naming.preimport_cname)
2733        code.putln('#ifdef __Pyx_CyFunction_USED')
2734        code.putln('PyTypeObject *%s;' % Naming.cyfunction_type_cname)
2735        code.putln('#endif')
2736        code.putln('#ifdef __Pyx_FusedFunction_USED')
2737        code.putln('PyTypeObject *%s;' % Naming.fusedfunction_type_cname)
2738        code.putln('#endif')
2739
2740    def generate_module_state_end(self, env, modules, globalstate):
2741        module_state = globalstate['module_state']
2742        module_state_defines = globalstate['module_state_defines']
2743        module_state_clear = globalstate['module_state_clear']
2744        module_state_traverse = globalstate['module_state_traverse']
2745        module_state.putln('} %s;' % Naming.modulestate_cname)
2746        module_state.putln('')
2747        module_state.putln('#ifdef __cplusplus')
2748        module_state.putln('namespace {')
2749        module_state.putln('extern struct PyModuleDef %s;' % Naming.pymoduledef_cname)
2750        module_state.putln('} /* anonymous namespace */')
2751        module_state.putln('#else')
2752        module_state.putln('static struct PyModuleDef %s;' % Naming.pymoduledef_cname)
2753        module_state.putln('#endif')
2754        module_state.putln('')
2755        module_state.putln('#define %s(o) ((%s *)__Pyx_PyModule_GetState(o))' % (
2756            Naming.modulestate_cname,
2757            Naming.modulestate_cname))
2758        module_state.putln('')
2759        module_state.putln('#define %s (%s(PyState_FindModule(&%s)))' % (
2760            Naming.modulestateglobal_cname,
2761            Naming.modulestate_cname,
2762            Naming.pymoduledef_cname))
2763        module_state.putln('')
2764        module_state.putln('#define %s (PyState_FindModule(&%s))' % (
2765            env.module_cname,
2766            Naming.pymoduledef_cname))
2767        module_state.putln("#endif")
2768        module_state_defines.putln("#endif")
2769        module_state_clear.putln("return 0;")
2770        module_state_clear.putln("}")
2771        module_state_clear.putln("#endif")
2772        module_state_traverse.putln("return 0;")
2773        module_state_traverse.putln("}")
2774        module_state_traverse.putln("#endif")
2775
2776    def generate_module_state_defines(self, env, code):
2777        code.putln("#if CYTHON_USE_MODULE_STATE")
2778        code.putln('#define %s %s->%s' % (
2779            env.module_dict_cname,
2780            Naming.modulestateglobal_cname,
2781            env.module_dict_cname))
2782        code.putln('#define %s %s->%s' % (
2783            Naming.builtins_cname,
2784            Naming.modulestateglobal_cname,
2785            Naming.builtins_cname))
2786        code.putln('#define %s %s->%s' % (
2787            Naming.cython_runtime_cname,
2788            Naming.modulestateglobal_cname,
2789            Naming.cython_runtime_cname))
2790        code.putln('#define %s %s->%s' % (
2791            Naming.empty_tuple,
2792            Naming.modulestateglobal_cname,
2793            Naming.empty_tuple))
2794        code.putln('#define %s %s->%s' % (
2795            Naming.empty_bytes,
2796            Naming.modulestateglobal_cname,
2797            Naming.empty_bytes))
2798        code.putln('#define %s %s->%s' % (
2799            Naming.empty_unicode,
2800            Naming.modulestateglobal_cname,
2801            Naming.empty_unicode))
2802        if Options.pre_import is not None:
2803            code.putln('#define %s %s->%s' % (
2804                Naming.preimport_cname,
2805                Naming.modulestateglobal_cname,
2806                Naming.preimport_cname))
2807        code.putln('#ifdef __Pyx_CyFunction_USED')
2808        code.putln('#define %s %s->%s' % (
2809            Naming.cyfunction_type_cname,
2810            Naming.modulestateglobal_cname,
2811            Naming.cyfunction_type_cname))
2812        code.putln('#endif')
2813        code.putln('#ifdef __Pyx_FusedFunction_USED')
2814        code.putln('#define %s %s->%s' %
2815            (Naming.fusedfunction_type_cname,
2816            Naming.modulestateglobal_cname,
2817            Naming.fusedfunction_type_cname))
2818        code.putln('#endif')
2819
2820    def generate_module_state_clear(self, env, code):
2821        code.putln("#if CYTHON_USE_MODULE_STATE")
2822        code.putln("static int %s_clear(PyObject *m) {" % Naming.module_cname)
2823        code.putln("%s *clear_module_state = %s(m);" % (
2824            Naming.modulestate_cname,
2825            Naming.modulestate_cname))
2826        code.putln("if (!clear_module_state) return 0;")
2827        code.putln('Py_CLEAR(clear_module_state->%s);' %
2828            env.module_dict_cname)
2829        code.putln('Py_CLEAR(clear_module_state->%s);' %
2830            Naming.builtins_cname)
2831        code.putln('Py_CLEAR(clear_module_state->%s);' %
2832            Naming.cython_runtime_cname)
2833        code.putln('Py_CLEAR(clear_module_state->%s);' %
2834            Naming.empty_tuple)
2835        code.putln('Py_CLEAR(clear_module_state->%s);' %
2836            Naming.empty_bytes)
2837        code.putln('Py_CLEAR(clear_module_state->%s);' %
2838            Naming.empty_unicode)
2839        code.putln('#ifdef __Pyx_CyFunction_USED')
2840        code.putln('Py_CLEAR(clear_module_state->%s);' %
2841            Naming.cyfunction_type_cname)
2842        code.putln('#endif')
2843        code.putln('#ifdef __Pyx_FusedFunction_USED')
2844        code.putln('Py_CLEAR(clear_module_state->%s);' %
2845            Naming.fusedfunction_type_cname)
2846        code.putln('#endif')
2847
2848    def generate_module_state_traverse(self, env, code):
2849        code.putln("#if CYTHON_USE_MODULE_STATE")
2850        code.putln("static int %s_traverse(PyObject *m, visitproc visit, void *arg) {" % Naming.module_cname)
2851        code.putln("%s *traverse_module_state = %s(m);" % (
2852            Naming.modulestate_cname,
2853            Naming.modulestate_cname))
2854        code.putln("if (!traverse_module_state) return 0;")
2855        code.putln('Py_VISIT(traverse_module_state->%s);' %
2856            env.module_dict_cname)
2857        code.putln('Py_VISIT(traverse_module_state->%s);' %
2858            Naming.builtins_cname)
2859        code.putln('Py_VISIT(traverse_module_state->%s);' %
2860            Naming.cython_runtime_cname)
2861        code.putln('Py_VISIT(traverse_module_state->%s);' %
2862            Naming.empty_tuple)
2863        code.putln('Py_VISIT(traverse_module_state->%s);' %
2864            Naming.empty_bytes)
2865        code.putln('Py_VISIT(traverse_module_state->%s);' %
2866            Naming.empty_unicode)
2867        code.putln('#ifdef __Pyx_CyFunction_USED')
2868        code.putln('Py_VISIT(traverse_module_state->%s);' %
2869            Naming.cyfunction_type_cname)
2870        code.putln('#endif')
2871        code.putln('#ifdef __Pyx_FusedFunction_USED')
2872        code.putln('Py_VISIT(traverse_module_state->%s);' %
2873            Naming.fusedfunction_type_cname)
2874        code.putln('#endif')
2875
2876    def generate_module_init_func(self, imported_modules, env, code):
2877        subfunction = self.mod_init_subfunction(self.pos, self.scope, code)
2878
2879        self.generate_pymoduledef_struct(env, code)
2880
2881        code.enter_cfunc_scope(self.scope)
2882        code.putln("")
2883        code.putln(UtilityCode.load_as_string("PyModInitFuncType", "ModuleSetupCode.c")[0])
2884        if env.module_name.isascii():
2885            py2_mod_name = env.module_name
2886            fail_compilation_in_py2 = False
2887        else:
2888            fail_compilation_in_py2 = True
2889            # at this point py2_mod_name is largely a placeholder and the value doesn't matter
2890            py2_mod_name = env.module_name.encode("ascii", errors="ignore").decode("utf8")
2891
2892        header2 = "__Pyx_PyMODINIT_FUNC init%s(void)" % py2_mod_name
2893        header3 = "__Pyx_PyMODINIT_FUNC %s(void)" % self.mod_init_func_cname('PyInit', env)
2894        header3 = EncodedString(header3)
2895        code.putln("#if PY_MAJOR_VERSION < 3")
2896        # Optimise for small code size as the module init function is only executed once.
2897        code.putln("%s CYTHON_SMALL_CODE; /*proto*/" % header2)
2898        if fail_compilation_in_py2:
2899            code.putln('#error "Unicode module names are not supported in Python 2";')
2900        if self.scope.is_package:
2901            code.putln("#if !defined(CYTHON_NO_PYINIT_EXPORT) && (defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS))")
2902            code.putln("__Pyx_PyMODINIT_FUNC init__init__(void) { init%s(); }" % py2_mod_name)
2903            code.putln("#endif")
2904        code.putln(header2)
2905        code.putln("#else")
2906        code.putln("%s CYTHON_SMALL_CODE; /*proto*/" % header3)
2907        if self.scope.is_package:
2908            code.putln("#if !defined(CYTHON_NO_PYINIT_EXPORT) && (defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS))")
2909            code.putln("__Pyx_PyMODINIT_FUNC PyInit___init__(void) { return %s(); }" % (
2910                self.mod_init_func_cname('PyInit', env)))
2911            code.putln("#endif")
2912        # Hack for a distutils bug - https://bugs.python.org/issue39432
2913        # distutils attempts to make visible a slightly wrong PyInitU module name. Just create a dummy
2914        # function to keep it quiet
2915        wrong_punycode_module_name = self.wrong_punycode_module_name(env.module_name)
2916        if wrong_punycode_module_name:
2917            code.putln("#if !defined(CYTHON_NO_PYINIT_EXPORT) && (defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS))")
2918            code.putln("void %s(void) {} /* workaround for https://bugs.python.org/issue39432 */" % wrong_punycode_module_name)
2919            code.putln("#endif")
2920        code.putln(header3)
2921
2922        # CPython 3.5+ supports multi-phase module initialisation (gives access to __spec__, __file__, etc.)
2923        code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT")
2924        code.putln("{")
2925        code.putln("return PyModuleDef_Init(&%s);" % Naming.pymoduledef_cname)
2926        code.putln("}")
2927
2928        mod_create_func = UtilityCode.load_as_string("ModuleCreationPEP489", "ModuleSetupCode.c")[1]
2929        code.put(mod_create_func)
2930
2931        code.putln("")
2932        # main module init code lives in Py_mod_exec function, not in PyInit function
2933        code.putln("static CYTHON_SMALL_CODE int %s(PyObject *%s)" % (
2934            self.module_init_func_cname(),
2935            Naming.pymodinit_module_arg))
2936        code.putln("#endif")  # PEP489
2937
2938        code.putln("#endif")  # Py3
2939
2940        # start of module init/exec function (pre/post PEP 489)
2941        code.putln("{")
2942        code.putln('int stringtab_initialized = 0;')
2943        tempdecl_code = code.insertion_point()
2944
2945        profile = code.globalstate.directives['profile']
2946        linetrace = code.globalstate.directives['linetrace']
2947        if profile or linetrace:
2948            if linetrace:
2949                code.use_fast_gil_utility_code()
2950            code.globalstate.use_utility_code(UtilityCode.load_cached("Profile", "Profile.c"))
2951
2952        code.put_declare_refcount_context()
2953        code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT")
2954        # Most extension modules simply can't deal with it, and Cython isn't ready either.
2955        # See issues listed here: https://docs.python.org/3/c-api/init.html#sub-interpreter-support
2956        code.putln("if (%s) {" % Naming.module_cname)
2957        # Hack: enforce single initialisation.
2958        code.putln("if (%s == %s) return 0;" % (
2959            Naming.module_cname,
2960            Naming.pymodinit_module_arg,
2961        ))
2962        code.putln('PyErr_SetString(PyExc_RuntimeError,'
2963                   ' "Module \'%s\' has already been imported. Re-initialisation is not supported.");' %
2964                   env.module_name.as_c_string_literal()[1:-1])
2965        code.putln("return -1;")
2966        code.putln("}")
2967        code.putln("#elif PY_MAJOR_VERSION >= 3")
2968        # Hack: enforce single initialisation also on reimports under different names on Python 3 (with PEP 3121/489).
2969        code.putln("if (%s) return __Pyx_NewRef(%s);" % (
2970            Naming.module_cname,
2971            Naming.module_cname,
2972        ))
2973        code.putln("#endif")
2974
2975        code.putln("/*--- Module creation code ---*/")
2976        self.generate_module_creation_code(env, code)
2977
2978        if profile or linetrace:
2979            tempdecl_code.put_trace_declarations()
2980            code.put_trace_frame_init()
2981
2982        refnanny_import_code = UtilityCode.load_as_string("ImportRefnannyAPI", "ModuleSetupCode.c")[1]
2983        code.putln(refnanny_import_code.rstrip())
2984        code.put_setup_refcount_context(header3)
2985
2986        env.use_utility_code(UtilityCode.load("CheckBinaryVersion", "ModuleSetupCode.c"))
2987        code.put_error_if_neg(self.pos, "__Pyx_check_binary_version()")
2988
2989        code.putln("#ifdef __Pxy_PyFrame_Initialize_Offsets")
2990        code.putln("__Pxy_PyFrame_Initialize_Offsets();")
2991        code.putln("#endif")
2992        code.putln("%s = PyTuple_New(0); %s" % (
2993            Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos)))
2994        code.putln("%s = PyBytes_FromStringAndSize(\"\", 0); %s" % (
2995            Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos)))
2996        code.putln("%s = PyUnicode_FromStringAndSize(\"\", 0); %s" % (
2997            Naming.empty_unicode, code.error_goto_if_null(Naming.empty_unicode, self.pos)))
2998
2999        for ext_type in ('CyFunction', 'FusedFunction', 'Coroutine', 'Generator', 'AsyncGen', 'StopAsyncIteration'):
3000            code.putln("#ifdef __Pyx_%s_USED" % ext_type)
3001            code.put_error_if_neg(self.pos, "__pyx_%s_init(%s)" % (ext_type, env.module_cname))
3002            code.putln("#endif")
3003
3004        code.putln("/*--- Library function declarations ---*/")
3005        if env.directives['np_pythran']:
3006            code.put_error_if_neg(self.pos, "_import_array()")
3007
3008        code.putln("/*--- Threads initialization code ---*/")
3009        code.putln("#if defined(WITH_THREAD) && PY_VERSION_HEX < 0x030700F0 "
3010                   "&& defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS")
3011        code.putln("PyEval_InitThreads();")
3012        code.putln("#endif")
3013
3014        code.putln("/*--- Initialize various global constants etc. ---*/")
3015        code.put_error_if_neg(self.pos, "__Pyx_InitConstants()")
3016        code.putln("stringtab_initialized = 1;")
3017        code.put_error_if_neg(self.pos, "__Pyx_InitGlobals()")  # calls any utility code
3018
3019
3020        code.putln("#if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || "
3021                   "__PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)")
3022        code.put_error_if_neg(self.pos, "__Pyx_init_sys_getdefaultencoding_params()")
3023        code.putln("#endif")
3024
3025        code.putln("if (%s) {" % self.is_main_module_flag_cname())
3026        code.put_error_if_neg(self.pos, 'PyObject_SetAttr(%s, %s, %s)' % (
3027            env.module_cname,
3028            code.intern_identifier(EncodedString("__name__")),
3029            code.intern_identifier(EncodedString("__main__"))))
3030        code.putln("}")
3031
3032        # set up __file__ and __path__, then add the module to sys.modules
3033        self.generate_module_import_setup(env, code)
3034
3035        if Options.cache_builtins:
3036            code.putln("/*--- Builtin init code ---*/")
3037            code.put_error_if_neg(self.pos, "__Pyx_InitCachedBuiltins()")
3038
3039        code.putln("/*--- Constants init code ---*/")
3040        code.put_error_if_neg(self.pos, "__Pyx_InitCachedConstants()")
3041
3042        code.putln("/*--- Global type/function init code ---*/")
3043
3044        with subfunction("Global init code") as inner_code:
3045            self.generate_global_init_code(env, inner_code)
3046
3047        with subfunction("Variable export code") as inner_code:
3048            self.generate_c_variable_export_code(env, inner_code)
3049
3050        with subfunction("Function export code") as inner_code:
3051            self.generate_c_function_export_code(env, inner_code)
3052
3053        with subfunction("Type init code") as inner_code:
3054            self.generate_type_init_code(env, inner_code)
3055
3056        with subfunction("Type import code") as inner_code:
3057            for module in imported_modules:
3058                self.generate_type_import_code_for_module(module, env, inner_code)
3059
3060        with subfunction("Variable import code") as inner_code:
3061            for module in imported_modules:
3062                self.generate_c_variable_import_code_for_module(module, env, inner_code)
3063
3064        with subfunction("Function import code") as inner_code:
3065            for module in imported_modules:
3066                self.specialize_fused_types(module)
3067                self.generate_c_function_import_code_for_module(module, env, inner_code)
3068
3069        code.putln("/*--- Execution code ---*/")
3070        code.mark_pos(None)
3071
3072        code.putln("#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED)")
3073        code.put_error_if_neg(self.pos, "__Pyx_patch_abc()")
3074        code.putln("#endif")
3075
3076        if profile or linetrace:
3077            code.put_trace_call(header3, self.pos, nogil=not code.funcstate.gil_owned)
3078            code.funcstate.can_trace = True
3079
3080        self.body.generate_execution_code(code)
3081
3082        if profile or linetrace:
3083            code.funcstate.can_trace = False
3084            code.put_trace_return("Py_None", nogil=not code.funcstate.gil_owned)
3085
3086        code.putln()
3087        code.putln("/*--- Wrapped vars code ---*/")
3088        self.generate_wrapped_entries_code(env, code)
3089        code.putln()
3090
3091        if Options.generate_cleanup_code:
3092            code.globalstate.use_utility_code(
3093                UtilityCode.load_cached("RegisterModuleCleanup", "ModuleSetupCode.c"))
3094            code.putln("if (__Pyx_RegisterCleanup()) %s;" % code.error_goto(self.pos))
3095
3096        code.put_goto(code.return_label)
3097        code.put_label(code.error_label)
3098        for cname, type in code.funcstate.all_managed_temps():
3099            code.put_xdecref(cname, type)
3100        code.putln('if (%s) {' % env.module_cname)
3101        code.putln('if (%s && stringtab_initialized) {' % env.module_dict_cname)
3102        # We can run into errors before the module or stringtab are initialized.
3103        # In this case it is not safe to add a traceback (because it uses the stringtab)
3104        code.put_add_traceback(EncodedString("init %s" % env.qualified_name))
3105        code.globalstate.use_utility_code(Nodes.traceback_utility_code)
3106        # Module reference and module dict are in global variables which might still be needed
3107        # for cleanup, atexit code, etc., so leaking is better than crashing.
3108        # At least clearing the module dict here might be a good idea, but could still break
3109        # user code in atexit or other global registries.
3110        ##code.put_decref_clear(env.module_dict_cname, py_object_type, nanny=False)
3111        code.putln('}')
3112        code.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
3113        code.put_decref_clear(env.module_cname, py_object_type, nanny=False, clear_before_decref=True)
3114        code.putln("#endif")
3115        code.putln('} else if (!PyErr_Occurred()) {')
3116        code.putln('PyErr_SetString(PyExc_ImportError, "init %s");' %
3117                   env.qualified_name.as_c_string_literal()[1:-1])
3118        code.putln('}')
3119        code.put_label(code.return_label)
3120
3121        code.put_finish_refcount_context()
3122
3123        code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT")
3124        code.putln("return (%s != NULL) ? 0 : -1;" % env.module_cname)
3125        code.putln("#elif PY_MAJOR_VERSION >= 3")
3126        code.putln("return %s;" % env.module_cname)
3127        code.putln("#else")
3128        code.putln("return;")
3129        code.putln("#endif")
3130        code.putln('}')
3131
3132        tempdecl_code.put_temp_declarations(code.funcstate)
3133
3134        code.exit_cfunc_scope()
3135
3136    def mod_init_subfunction(self, pos, scope, orig_code):
3137        """
3138        Return a context manager that allows deviating the module init code generation
3139        into a separate function and instead inserts a call to it.
3140
3141        Can be reused sequentially to create multiple functions.
3142        The functions get inserted at the point where the context manager was created.
3143        The call gets inserted where the context manager is used (on entry).
3144        """
3145        prototypes = orig_code.insertion_point()
3146        prototypes.putln("")
3147        function_code = orig_code.insertion_point()
3148        function_code.putln("")
3149
3150        class ModInitSubfunction(object):
3151            def __init__(self, code_type):
3152                cname = '_'.join(code_type.lower().split())
3153                assert re.match("^[a-z0-9_]+$", cname)
3154                self.cfunc_name = "__Pyx_modinit_%s" % cname
3155                self.description = code_type
3156                self.tempdecl_code = None
3157                self.call_code = None
3158
3159            def __enter__(self):
3160                self.call_code = orig_code.insertion_point()
3161                code = function_code
3162                code.enter_cfunc_scope(scope)
3163                prototypes.putln("static CYTHON_SMALL_CODE int %s(void); /*proto*/" % self.cfunc_name)
3164                code.putln("static int %s(void) {" % self.cfunc_name)
3165                code.put_declare_refcount_context()
3166                self.tempdecl_code = code.insertion_point()
3167                code.put_setup_refcount_context(EncodedString(self.cfunc_name))
3168                # Leave a grepable marker that makes it easy to find the generator source.
3169                code.putln("/*--- %s ---*/" % self.description)
3170                return code
3171
3172            def __exit__(self, *args):
3173                code = function_code
3174                code.put_finish_refcount_context()
3175                code.putln("return 0;")
3176
3177                self.tempdecl_code.put_temp_declarations(code.funcstate)
3178                self.tempdecl_code = None
3179
3180                needs_error_handling = code.label_used(code.error_label)
3181                if needs_error_handling:
3182                    code.put_label(code.error_label)
3183                    for cname, type in code.funcstate.all_managed_temps():
3184                        code.put_xdecref(cname, type)
3185                    code.put_finish_refcount_context()
3186                    code.putln("return -1;")
3187                code.putln("}")
3188                code.exit_cfunc_scope()
3189                code.putln("")
3190
3191                if needs_error_handling:
3192                    self.call_code.putln(
3193                        self.call_code.error_goto_if_neg("%s()" % self.cfunc_name, pos))
3194                else:
3195                    self.call_code.putln("(void)%s();" % self.cfunc_name)
3196                self.call_code = None
3197
3198        return ModInitSubfunction
3199
3200    def generate_module_import_setup(self, env, code):
3201        module_path = env.directives['set_initial_path']
3202        if module_path == 'SOURCEFILE':
3203            module_path = self.pos[0].filename
3204
3205        if module_path:
3206            code.putln('if (!CYTHON_PEP489_MULTI_PHASE_INIT) {')
3207            code.putln('if (PyObject_SetAttrString(%s, "__file__", %s) < 0) %s;' % (
3208                env.module_cname,
3209                code.globalstate.get_py_string_const(
3210                    EncodedString(decode_filename(module_path))).cname,
3211                code.error_goto(self.pos)))
3212            code.putln("}")
3213
3214            if env.is_package:
3215                # set __path__ to mark the module as package
3216                code.putln('if (!CYTHON_PEP489_MULTI_PHASE_INIT) {')
3217                temp = code.funcstate.allocate_temp(py_object_type, True)
3218                code.putln('%s = Py_BuildValue("[O]", %s); %s' % (
3219                    temp,
3220                    code.globalstate.get_py_string_const(
3221                        EncodedString(decode_filename(
3222                            os.path.dirname(module_path)))).cname,
3223                    code.error_goto_if_null(temp, self.pos)))
3224                code.put_gotref(temp, py_object_type)
3225                code.putln(
3226                    'if (PyObject_SetAttrString(%s, "__path__", %s) < 0) %s;' % (
3227                        env.module_cname, temp, code.error_goto(self.pos)))
3228                code.put_decref_clear(temp, py_object_type)
3229                code.funcstate.release_temp(temp)
3230                code.putln("}")
3231
3232        elif env.is_package:
3233            # packages require __path__, so all we can do is try to figure
3234            # out the module path at runtime by rerunning the import lookup
3235            code.putln("if (!CYTHON_PEP489_MULTI_PHASE_INIT) {")
3236            package_name, _ = self.full_module_name.rsplit('.', 1)
3237            if '.' in package_name:
3238                parent_name = '"%s"' % (package_name.rsplit('.', 1)[0],)
3239            else:
3240                parent_name = 'NULL'
3241            code.globalstate.use_utility_code(UtilityCode.load(
3242                "SetPackagePathFromImportLib", "ImportExport.c"))
3243            code.putln(code.error_goto_if_neg(
3244                '__Pyx_SetPackagePathFromImportLib(%s, %s)' % (
3245                    parent_name,
3246                    code.globalstate.get_py_string_const(
3247                        EncodedString(env.module_name)).cname),
3248                self.pos))
3249            code.putln("}")
3250
3251        # CPython may not have put us into sys.modules yet, but relative imports and reimports require it
3252        fq_module_name = self.full_module_name
3253        if fq_module_name.endswith('.__init__'):
3254            fq_module_name = EncodedString(fq_module_name[:-len('.__init__')])
3255        fq_module_name_cstring = fq_module_name.as_c_string_literal()
3256        code.putln("#if PY_MAJOR_VERSION >= 3")
3257        code.putln("{")
3258        code.putln("PyObject *modules = PyImport_GetModuleDict(); %s" %
3259                   code.error_goto_if_null("modules", self.pos))
3260        code.putln('if (!PyDict_GetItemString(modules, %s)) {' % fq_module_name_cstring)
3261        code.putln(code.error_goto_if_neg('PyDict_SetItemString(modules, %s, %s)' % (
3262            fq_module_name_cstring, env.module_cname), self.pos))
3263        code.putln("}")
3264        code.putln("}")
3265        code.putln("#endif")
3266
3267    def generate_module_cleanup_func(self, env, code):
3268        if not Options.generate_cleanup_code:
3269            return
3270
3271        code.putln('static void %s(CYTHON_UNUSED PyObject *self) {' %
3272                   Naming.cleanup_cname)
3273        code.enter_cfunc_scope(env)
3274
3275        if Options.generate_cleanup_code >= 2:
3276            code.putln("/*--- Global cleanup code ---*/")
3277            rev_entries = list(env.var_entries)
3278            rev_entries.reverse()
3279            for entry in rev_entries:
3280                if entry.visibility != 'extern':
3281                    if entry.type.is_pyobject and entry.used:
3282                        code.put_xdecref_clear(
3283                            entry.cname, entry.type,
3284                            clear_before_decref=True,
3285                            nanny=False)
3286        code.putln("__Pyx_CleanupGlobals();")
3287        if Options.generate_cleanup_code >= 3:
3288            code.putln("/*--- Type import cleanup code ---*/")
3289            for ext_type in sorted(env.types_imported, key=operator.attrgetter('typeptr_cname')):
3290                code.put_xdecref_clear(
3291                    ext_type.typeptr_cname, ext_type,
3292                    clear_before_decref=True,
3293                    nanny=False)
3294        if Options.cache_builtins:
3295            code.putln("/*--- Builtin cleanup code ---*/")
3296            for entry in env.cached_builtins:
3297                code.put_xdecref_clear(
3298                    entry.cname, PyrexTypes.py_object_type,
3299                    clear_before_decref=True,
3300                    nanny=False)
3301        code.putln("/*--- Intern cleanup code ---*/")
3302        code.put_decref_clear(Naming.empty_tuple,
3303                              PyrexTypes.py_object_type,
3304                              clear_before_decref=True,
3305                              nanny=False)
3306        for entry in env.c_class_entries:
3307            cclass_type = entry.type
3308            if cclass_type.is_external or cclass_type.base_type:
3309                continue
3310            if cclass_type.scope.directives.get('freelist', 0):
3311                scope = cclass_type.scope
3312                freelist_name = scope.mangle_internal(Naming.freelist_name)
3313                freecount_name = scope.mangle_internal(Naming.freecount_name)
3314                code.putln("while (%s > 0) {" % freecount_name)
3315                code.putln("PyObject* o = (PyObject*)%s[--%s];" % (
3316                    freelist_name, freecount_name))
3317                code.putln("(*Py_TYPE(o)->tp_free)(o);")
3318                code.putln("}")
3319#        for entry in env.pynum_entries:
3320#            code.put_decref_clear(entry.cname,
3321#                                  PyrexTypes.py_object_type,
3322#                                  nanny=False)
3323#        for entry in env.all_pystring_entries:
3324#            if entry.is_interned:
3325#                code.put_decref_clear(entry.pystring_cname,
3326#                                      PyrexTypes.py_object_type,
3327#                                      nanny=False)
3328#        for entry in env.default_entries:
3329#            if entry.type.is_pyobject and entry.used:
3330#                code.putln("Py_DECREF(%s); %s = 0;" % (
3331#                    code.entry_as_pyobject(entry), entry.cname))
3332        if Options.pre_import is not None:
3333            code.put_decref_clear(Naming.preimport_cname, py_object_type,
3334                                  nanny=False, clear_before_decref=True)
3335        for cname in [Naming.cython_runtime_cname, Naming.builtins_cname]:
3336            code.put_decref_clear(cname, py_object_type, nanny=False, clear_before_decref=True)
3337        code.put_decref_clear(env.module_dict_cname, py_object_type, nanny=False, clear_before_decref=True)
3338
3339    def generate_main_method(self, env, code):
3340        module_is_main = self.is_main_module_flag_cname()
3341        if Options.embed == "main":
3342            wmain = "wmain"
3343        else:
3344            wmain = Options.embed
3345        main_method = UtilityCode.load_cached("MainFunction", "Embed.c")
3346        code.globalstate.use_utility_code(
3347            main_method.specialize(
3348                module_name=env.module_name,
3349                module_is_main=module_is_main,
3350                main_method=Options.embed,
3351                wmain_method=wmain))
3352
3353    def punycode_module_name(self, prefix, name):
3354        # adapted from PEP483
3355        try:
3356            name = '_' + name.encode('ascii').decode('ascii')
3357        except UnicodeEncodeError:
3358            name = 'U_' + name.encode('punycode').replace(b'-', b'_').decode('ascii')
3359        return "%s%s" % (prefix, name)
3360
3361    def wrong_punycode_module_name(self, name):
3362        # to work around a distutils bug by also generating an incorrect symbol...
3363        try:
3364            name.encode("ascii")
3365            return None  # workaround is not needed
3366        except UnicodeEncodeError:
3367            return "PyInitU" + (u"_"+name).encode('punycode').replace(b'-', b'_').decode('ascii')
3368
3369    def mod_init_func_cname(self, prefix, env):
3370        # from PEP483
3371        return self.punycode_module_name(prefix, env.module_name)
3372
3373    # Returns the name of the C-function that corresponds to the module initialisation.
3374    # (module initialisation == the cython code outside of functions)
3375    # Note that this should never be the name of a wrapper and always the name of the
3376    # function containing the actual code. Otherwise, cygdb will experience problems.
3377    def module_init_func_cname(self):
3378        env = self.scope
3379        return self.mod_init_func_cname(Naming.pymodule_exec_func_cname, env)
3380
3381    def generate_pymoduledef_struct(self, env, code):
3382        if env.doc:
3383            doc = "%s" % code.get_string_const(env.doc)
3384        else:
3385            doc = "0"
3386        if Options.generate_cleanup_code:
3387            cleanup_func = "(freefunc)%s" % Naming.cleanup_cname
3388        else:
3389            cleanup_func = 'NULL'
3390
3391        code.putln("")
3392        code.putln("#if PY_MAJOR_VERSION >= 3")
3393        code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT")
3394        exec_func_cname = self.module_init_func_cname()
3395        code.putln("static PyObject* %s(PyObject *spec, PyModuleDef *def); /*proto*/" %
3396                   Naming.pymodule_create_func_cname)
3397        code.putln("static int %s(PyObject* module); /*proto*/" % exec_func_cname)
3398
3399        code.putln("static PyModuleDef_Slot %s[] = {" % Naming.pymoduledef_slots_cname)
3400        code.putln("{Py_mod_create, (void*)%s}," % Naming.pymodule_create_func_cname)
3401        code.putln("{Py_mod_exec, (void*)%s}," % exec_func_cname)
3402        code.putln("{0, NULL}")
3403        code.putln("};")
3404        if not env.module_name.isascii():
3405            code.putln("#else /* CYTHON_PEP489_MULTI_PHASE_INIT */")
3406            code.putln('#error "Unicode module names are only supported with multi-phase init'
3407                       ' as per PEP489"')
3408        code.putln("#endif")
3409
3410        code.putln("")
3411        code.putln('#ifdef __cplusplus')
3412        code.putln('namespace {')
3413        code.putln("struct PyModuleDef %s =" % Naming.pymoduledef_cname)
3414        code.putln('#else')
3415        code.putln("static struct PyModuleDef %s =" % Naming.pymoduledef_cname)
3416        code.putln('#endif')
3417        code.putln('{')
3418        code.putln("  PyModuleDef_HEAD_INIT,")
3419        code.putln('  %s,' % env.module_name.as_c_string_literal())
3420        code.putln("  %s, /* m_doc */" % doc)
3421        code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT")
3422        code.putln("  0, /* m_size */")
3423        code.putln("#elif CYTHON_USE_MODULE_STATE")  # FIXME: should allow combination with PEP-489
3424        code.putln("  sizeof(%s), /* m_size */" % Naming.modulestate_cname)
3425        code.putln("#else")
3426        code.putln("  -1, /* m_size */")
3427        code.putln("#endif")
3428        code.putln("  %s /* m_methods */," % env.method_table_cname)
3429        code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT")
3430        code.putln("  %s, /* m_slots */" % Naming.pymoduledef_slots_cname)
3431        code.putln("#else")
3432        code.putln("  NULL, /* m_reload */")
3433        code.putln("#endif")
3434        code.putln("#if CYTHON_USE_MODULE_STATE")
3435        code.putln("  %s_traverse, /* m_traverse */" % Naming.module_cname)
3436        code.putln("  %s_clear, /* m_clear */" % Naming.module_cname)
3437        code.putln("  %s /* m_free */" % cleanup_func)
3438        code.putln("#else")
3439        code.putln("  NULL, /* m_traverse */")
3440        code.putln("  NULL, /* m_clear */")
3441        code.putln("  %s /* m_free */" % cleanup_func)
3442        code.putln("#endif")
3443        code.putln("};")
3444        code.putln('#ifdef __cplusplus')
3445        code.putln('} /* anonymous namespace */')
3446        code.putln('#endif')
3447        code.putln("#endif")
3448
3449    def generate_module_creation_code(self, env, code):
3450        # Generate code to create the module object and
3451        # install the builtins.
3452        if env.doc:
3453            doc = "%s" % code.get_string_const(env.doc)
3454        else:
3455            doc = "0"
3456
3457        code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT")
3458        code.putln("%s = %s;" % (
3459            env.module_cname,
3460            Naming.pymodinit_module_arg))
3461        code.put_incref(env.module_cname, py_object_type, nanny=False)
3462        code.putln("#else")
3463        code.putln("#if PY_MAJOR_VERSION < 3")
3464        code.putln(
3465            '%s = Py_InitModule4(%s, %s, %s, 0, PYTHON_API_VERSION); Py_XINCREF(%s);' % (
3466                env.module_cname,
3467                env.module_name.as_c_string_literal(),
3468                env.method_table_cname,
3469                doc,
3470                env.module_cname))
3471        code.putln(code.error_goto_if_null(env.module_cname, self.pos))
3472        code.putln("#elif CYTHON_COMPILING_IN_LIMITED_API")
3473        module_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
3474        code.putln(
3475            "%s = PyModule_Create(&%s); %s" % (
3476                module_temp,
3477                Naming.pymoduledef_cname,
3478                code.error_goto_if_null(module_temp, self.pos)))
3479        code.put_gotref(module_temp, py_object_type)
3480        code.putln(code.error_goto_if_neg("PyState_AddModule(%s, &%s)" % (
3481            module_temp, Naming.pymoduledef_cname), self.pos))
3482        code.put_decref_clear(module_temp, type=py_object_type)
3483        code.funcstate.release_temp(module_temp)
3484        code.putln('#else')
3485        code.putln(
3486            "%s = PyModule_Create(&%s);" % (
3487                env.module_cname,
3488                Naming.pymoduledef_cname))
3489        code.putln(code.error_goto_if_null(env.module_cname, self.pos))
3490        code.putln("#endif")
3491        code.putln("#endif")  # CYTHON_PEP489_MULTI_PHASE_INIT
3492
3493        code.putln(
3494            "%s = PyModule_GetDict(%s); %s" % (
3495                env.module_dict_cname, env.module_cname,
3496                code.error_goto_if_null(env.module_dict_cname, self.pos)))
3497        code.put_incref(env.module_dict_cname, py_object_type, nanny=False)
3498
3499        code.putln(
3500            '%s = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); %s' % (
3501                Naming.builtins_cname,
3502                code.error_goto_if_null(Naming.builtins_cname, self.pos)))
3503        code.put_incref(Naming.builtins_cname, py_object_type, nanny=False)
3504        code.putln(
3505            '%s = PyImport_AddModule((char *) "cython_runtime"); %s' % (
3506                Naming.cython_runtime_cname,
3507                code.error_goto_if_null(Naming.cython_runtime_cname, self.pos)))
3508        code.put_incref(Naming.cython_runtime_cname, py_object_type, nanny=False)
3509        code.putln(
3510            'if (PyObject_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % (
3511                env.module_cname,
3512                Naming.builtins_cname,
3513                code.error_goto(self.pos)))
3514        if Options.pre_import is not None:
3515            code.putln(
3516                '%s = PyImport_AddModule("%s"); %s' % (
3517                    Naming.preimport_cname,
3518                    Options.pre_import,
3519                    code.error_goto_if_null(Naming.preimport_cname, self.pos)))
3520            code.put_incref(Naming.preimport_cname, py_object_type, nanny=False)
3521
3522    def generate_global_init_code(self, env, code):
3523        # Generate code to initialise global PyObject *
3524        # variables to None.
3525        for entry in env.var_entries:
3526            if entry.visibility != 'extern':
3527                if entry.used:
3528                    entry.type.global_init_code(entry, code)
3529
3530    def generate_wrapped_entries_code(self, env, code):
3531        for name, entry in sorted(env.entries.items()):
3532            if (entry.create_wrapper
3533                    and not entry.is_type
3534                    and entry.scope is env):
3535                if not entry.type.create_to_py_utility_code(env):
3536                    error(entry.pos, "Cannot convert '%s' to Python object" % entry.type)
3537                code.putln("{")
3538                code.putln("PyObject* wrapped = %s(%s);"  % (
3539                    entry.type.to_py_function,
3540                    entry.cname))
3541                code.putln(code.error_goto_if_null("wrapped", entry.pos))
3542                code.putln(
3543                    'if (PyObject_SetAttrString(%s, "%s", wrapped) < 0) %s;' % (
3544                        env.module_cname,
3545                        name,
3546                        code.error_goto(entry.pos)))
3547                code.putln("}")
3548
3549    def generate_c_variable_export_code(self, env, code):
3550        # Generate code to create PyCFunction wrappers for exported C functions.
3551        entries = []
3552        for entry in env.var_entries:
3553            if (entry.api
3554                    or entry.defined_in_pxd
3555                    or (Options.cimport_from_pyx and not entry.visibility == 'extern')):
3556                entries.append(entry)
3557        if entries:
3558            env.use_utility_code(UtilityCode.load_cached("VoidPtrExport", "ImportExport.c"))
3559            for entry in entries:
3560                signature = entry.type.empty_declaration_code()
3561                name = code.intern_identifier(entry.name)
3562                code.putln('if (__Pyx_ExportVoidPtr(%s, (void *)&%s, "%s") < 0) %s' % (
3563                    name, entry.cname, signature,
3564                    code.error_goto(self.pos)))
3565
3566    def generate_c_function_export_code(self, env, code):
3567        # Generate code to create PyCFunction wrappers for exported C functions.
3568        entries = []
3569        for entry in env.cfunc_entries:
3570            if (entry.api
3571                    or entry.defined_in_pxd
3572                    or (Options.cimport_from_pyx and not entry.visibility == 'extern')):
3573                entries.append(entry)
3574        if entries:
3575            env.use_utility_code(
3576                UtilityCode.load_cached("FunctionExport", "ImportExport.c"))
3577            # Note: while this looks like it could be more cheaply stored and read from a struct array,
3578            # investigation shows that the resulting binary is smaller with repeated functions calls.
3579            for entry in entries:
3580                signature = entry.type.signature_string()
3581                code.putln('if (__Pyx_ExportFunction(%s, (void (*)(void))%s, "%s") < 0) %s' % (
3582                    entry.name.as_c_string_literal(),
3583                    entry.cname,
3584                    signature,
3585                    code.error_goto(self.pos)))
3586
3587    def generate_type_import_code_for_module(self, module, env, code):
3588        # Generate type import code for all exported extension types in
3589        # an imported module.
3590        #if module.c_class_entries:
3591        with ModuleImportGenerator(code) as import_generator:
3592            for entry in module.c_class_entries:
3593                if entry.defined_in_pxd:
3594                    self.generate_type_import_code(env, entry.type, entry.pos, code, import_generator)
3595
3596    def specialize_fused_types(self, pxd_env):
3597        """
3598        If fused c(p)def functions are defined in an imported pxd, but not
3599        used in this implementation file, we still have fused entries and
3600        not specialized ones. This method replaces any fused entries with their
3601        specialized ones.
3602        """
3603        for entry in pxd_env.cfunc_entries[:]:
3604            if entry.type.is_fused:
3605                # This call modifies the cfunc_entries in-place
3606                entry.type.get_all_specialized_function_types()
3607
3608    def generate_c_variable_import_code_for_module(self, module, env, code):
3609        # Generate import code for all exported C functions in a cimported module.
3610        entries = []
3611        for entry in module.var_entries:
3612            if entry.defined_in_pxd:
3613                entries.append(entry)
3614        if entries:
3615            env.use_utility_code(
3616                UtilityCode.load_cached("VoidPtrImport", "ImportExport.c"))
3617            temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
3618            code.putln(
3619                '%s = PyImport_ImportModule("%s"); if (!%s) %s' % (
3620                    temp,
3621                    module.qualified_name,
3622                    temp,
3623                    code.error_goto(self.pos)))
3624            code.put_gotref(temp, py_object_type)
3625            for entry in entries:
3626                if env is module:
3627                    cname = entry.cname
3628                else:
3629                    cname = module.mangle(Naming.varptr_prefix, entry.name)
3630                signature = entry.type.empty_declaration_code()
3631                code.putln(
3632                    'if (__Pyx_ImportVoidPtr(%s, "%s", (void **)&%s, "%s") < 0) %s' % (
3633                        temp, entry.name, cname, signature,
3634                        code.error_goto(self.pos)))
3635            code.put_decref_clear(temp, py_object_type)
3636            code.funcstate.release_temp(temp)
3637
3638    def generate_c_function_import_code_for_module(self, module, env, code):
3639        # Generate import code for all exported C functions in a cimported module.
3640        entries = []
3641        for entry in module.cfunc_entries:
3642            if entry.defined_in_pxd and entry.used:
3643                entries.append(entry)
3644        if entries:
3645            env.use_utility_code(
3646                UtilityCode.load_cached("FunctionImport", "ImportExport.c"))
3647            temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
3648            code.putln(
3649                '%s = PyImport_ImportModule("%s"); if (!%s) %s' % (
3650                    temp,
3651                    module.qualified_name,
3652                    temp,
3653                    code.error_goto(self.pos)))
3654            code.put_gotref(temp, py_object_type)
3655            for entry in entries:
3656                code.putln(
3657                    'if (__Pyx_ImportFunction(%s, %s, (void (**)(void))&%s, "%s") < 0) %s' % (
3658                        temp,
3659                        entry.name.as_c_string_literal(),
3660                        entry.cname,
3661                        entry.type.signature_string(),
3662                        code.error_goto(self.pos)))
3663            code.put_decref_clear(temp, py_object_type)
3664            code.funcstate.release_temp(temp)
3665
3666    def generate_type_init_code(self, env, code):
3667        # Generate type import code for extern extension types
3668        # and type ready code for non-extern ones.
3669        with ModuleImportGenerator(code) as import_generator:
3670            for entry in env.c_class_entries:
3671                if entry.visibility == 'extern' and not entry.utility_code_definition:
3672                    self.generate_type_import_code(env, entry.type, entry.pos, code, import_generator)
3673                else:
3674                    self.generate_base_type_import_code(env, entry, code, import_generator)
3675                    self.generate_exttype_vtable_init_code(entry, code)
3676                    if entry.type.early_init:
3677                        self.generate_type_ready_code(entry, code)
3678
3679    def generate_base_type_import_code(self, env, entry, code, import_generator):
3680        base_type = entry.type.base_type
3681        if (base_type and base_type.module_name != env.qualified_name and not
3682                (base_type.is_builtin_type or base_type.is_cython_builtin_type)
3683                 and not entry.utility_code_definition):
3684            self.generate_type_import_code(env, base_type, self.pos, code, import_generator)
3685
3686    def generate_type_import_code(self, env, type, pos, code, import_generator):
3687        # If not already done, generate code to import the typeobject of an
3688        # extension type defined in another module, and extract its C method
3689        # table pointer if any.
3690        if type in env.types_imported:
3691            return
3692        if type.name not in Code.ctypedef_builtins_map:
3693            # see corresponding condition in generate_type_import_call() below!
3694            code.globalstate.use_utility_code(
3695                UtilityCode.load_cached("TypeImport", "ImportExport.c"))
3696        self.generate_type_import_call(type, code, import_generator, error_pos=pos)
3697        if type.vtabptr_cname:
3698            code.globalstate.use_utility_code(
3699                UtilityCode.load_cached('GetVTable', 'ImportExport.c'))
3700            code.putln("%s = (struct %s*)__Pyx_GetVtable(%s); %s" % (
3701                type.vtabptr_cname,
3702                type.vtabstruct_cname,
3703                type.typeptr_cname,
3704                code.error_goto_if_null(type.vtabptr_cname, pos)))
3705        env.types_imported.add(type)
3706
3707    def generate_type_import_call(self, type, code, import_generator, error_code=None, error_pos=None):
3708        if type.typedef_flag:
3709            objstruct = type.objstruct_cname
3710        else:
3711            objstruct = "struct %s" % type.objstruct_cname
3712        sizeof_objstruct = objstruct
3713        module_name = type.module_name
3714        condition = replacement = None
3715        if module_name not in ('__builtin__', 'builtins'):
3716            module_name = '"%s"' % module_name
3717        elif type.name in Code.ctypedef_builtins_map:
3718            # Fast path for special builtins, don't actually import
3719            ctypename = Code.ctypedef_builtins_map[type.name]
3720            code.putln('%s = %s;' % (type.typeptr_cname, ctypename))
3721            return
3722        else:
3723            module_name = '__Pyx_BUILTIN_MODULE_NAME'
3724            if type.name in Code.non_portable_builtins_map:
3725                condition, replacement = Code.non_portable_builtins_map[type.name]
3726            if objstruct in Code.basicsize_builtins_map:
3727                # Some builtin types have a tp_basicsize which differs from sizeof(...):
3728                sizeof_objstruct = Code.basicsize_builtins_map[objstruct]
3729
3730        if not error_code:
3731            assert error_pos is not None
3732            error_code = code.error_goto(error_pos)
3733
3734        module = import_generator.imported_module(module_name, error_code)
3735        code.put('%s = __Pyx_ImportType(%s, %s,' % (
3736            type.typeptr_cname,
3737            module,
3738            module_name))
3739
3740        type_name = type.name.as_c_string_literal()
3741
3742        if condition and replacement:
3743            code.putln("")  # start in new line
3744            code.putln("#if %s" % condition)
3745            code.putln('"%s",' % replacement)
3746            code.putln("#else")
3747            code.putln('%s,' % type_name)
3748            code.putln("#endif")
3749        else:
3750            code.put(' %s, ' % type_name)
3751
3752        if sizeof_objstruct != objstruct:
3753            if not condition:
3754                code.putln("")  # start in new line
3755            code.putln("#if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000")
3756            code.putln('sizeof(%s),' % objstruct)
3757            code.putln("#elif CYTHON_COMPILING_IN_LIMITED_API")
3758            code.putln('sizeof(%s),' % objstruct)
3759            code.putln("#else")
3760            code.putln('sizeof(%s),' % sizeof_objstruct)
3761            code.putln("#endif")
3762        else:
3763            code.put('sizeof(%s), ' % objstruct)
3764
3765        # check_size
3766        if type.check_size and type.check_size in ('error', 'warn', 'ignore'):
3767            check_size = type.check_size
3768        elif not type.is_external or type.is_subclassed:
3769            check_size = 'error'
3770        else:
3771            raise RuntimeError("invalid value for check_size '%s' when compiling %s.%s" % (
3772                type.check_size, module_name, type.name))
3773        code.putln('__Pyx_ImportType_CheckSize_%s);' % check_size.title())
3774
3775        code.putln(' if (!%s) %s' % (type.typeptr_cname, error_code))
3776
3777    def generate_type_ready_code(self, entry, code):
3778        Nodes.CClassDefNode.generate_type_ready_code(entry, code)
3779
3780    def is_main_module_flag_cname(self):
3781        full_module_name = self.full_module_name.replace('.', '__')
3782        return self.punycode_module_name(Naming.module_is_main, full_module_name)
3783
3784    def generate_exttype_vtable_init_code(self, entry, code):
3785        # Generate code to initialise the C method table of an
3786        # extension type.
3787        type = entry.type
3788        if type.vtable_cname:
3789            code.putln(
3790                "%s = &%s;" % (
3791                    type.vtabptr_cname,
3792                    type.vtable_cname))
3793            if type.base_type and type.base_type.vtabptr_cname:
3794                code.putln(
3795                    "%s.%s = *%s;" % (
3796                        type.vtable_cname,
3797                        Naming.obj_base_cname,
3798                        type.base_type.vtabptr_cname))
3799
3800            c_method_entries = [
3801                entry for entry in type.scope.cfunc_entries
3802                if entry.func_cname]
3803            if c_method_entries:
3804                for meth_entry in c_method_entries:
3805                    cast = meth_entry.type.signature_cast_string()
3806                    code.putln(
3807                        "%s.%s = %s%s;" % (
3808                            type.vtable_cname,
3809                            meth_entry.cname,
3810                            cast,
3811                            meth_entry.func_cname))
3812
3813
3814class ModuleImportGenerator(object):
3815    """
3816    Helper to generate module import while importing external types.
3817    This is used to avoid excessive re-imports of external modules when multiple types are looked up.
3818    """
3819    def __init__(self, code, imported_modules=None):
3820        self.code = code
3821        self.imported = {}
3822        if imported_modules:
3823            for name, cname in imported_modules.items():
3824                self.imported['"%s"' % name] = cname
3825        self.temps = []  # remember original import order for freeing
3826
3827    def imported_module(self, module_name_string, error_code):
3828        if module_name_string in self.imported:
3829            return self.imported[module_name_string]
3830
3831        code = self.code
3832        temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
3833        self.temps.append(temp)
3834        code.putln('%s = PyImport_ImportModule(%s); if (unlikely(!%s)) %s' % (
3835            temp, module_name_string, temp, error_code))
3836        code.put_gotref(temp, py_object_type)
3837        self.imported[module_name_string] = temp
3838        return temp
3839
3840    def __enter__(self):
3841        return self
3842
3843    def __exit__(self, *exc):
3844        code = self.code
3845        for temp in self.temps:
3846            code.put_decref_clear(temp, py_object_type)
3847            code.funcstate.release_temp(temp)
3848
3849
3850def generate_cfunction_declaration(entry, env, code, definition):
3851    from_cy_utility = entry.used and entry.utility_code_definition
3852    if entry.used and entry.inline_func_in_pxd or (not entry.in_cinclude and (
3853            definition or entry.defined_in_pxd or entry.visibility == 'extern' or from_cy_utility)):
3854        if entry.visibility == 'extern':
3855            storage_class = Naming.extern_c_macro
3856            dll_linkage = "DL_IMPORT"
3857        elif entry.visibility == 'public':
3858            storage_class = Naming.extern_c_macro
3859            dll_linkage = None
3860        elif entry.visibility == 'private':
3861            storage_class = "static"
3862            dll_linkage = None
3863        else:
3864            storage_class = "static"
3865            dll_linkage = None
3866        type = entry.type
3867
3868        if entry.defined_in_pxd and not definition:
3869            storage_class = "static"
3870            dll_linkage = None
3871            type = CPtrType(type)
3872
3873        header = type.declaration_code(
3874            entry.cname, dll_linkage=dll_linkage)
3875        modifiers = code.build_function_modifiers(entry.func_modifiers)
3876        code.putln("%s %s%s; /*proto*/" % (
3877            storage_class,
3878            modifiers,
3879            header))
3880
3881#------------------------------------------------------------------------------------
3882#
3883#  Runtime support code
3884#
3885#------------------------------------------------------------------------------------
3886
3887refnanny_utility_code = UtilityCode.load("Refnanny", "ModuleSetupCode.c")
3888
3889packed_struct_utility_code = UtilityCode(proto="""
3890#if defined(__GNUC__)
3891#define __Pyx_PACKED __attribute__((__packed__))
3892#else
3893#define __Pyx_PACKED
3894#endif
3895""", impl="", proto_block='utility_code_proto_before_types')
3896
3897capsule_utility_code = UtilityCode.load("Capsule", "Capsule.c")
3898