ModuleNode.py 119 KB
Newer Older
1
#
2
#   Module parse tree node
3 4
#

5 6 7
import cython
cython.declare(Naming=object, Options=object, PyrexTypes=object, TypeSlots=object,
               error=object, warning=object, py_object_type=object, UtilityCode=object,
Stefan Behnel's avatar
Stefan Behnel committed
8
               EncodedString=object)
9

10 11
import os
import operator
12
from PyrexTypes import CPtrType
Robert Bradshaw's avatar
Robert Bradshaw committed
13
import Future
14

15
import Annotate
16 17 18 19 20 21
import Code
import Naming
import Nodes
import Options
import TypeSlots
import Version
22
import PyrexTypes
23

24
from Errors import error, warning
25
from PyrexTypes import py_object_type
26
from Cython.Utils import open_new_file, replace_suffix, decode_filename
27
from Code import UtilityCode
Stefan Behnel's avatar
Stefan Behnel committed
28
from StringEncoding import EncodedString
29

Gary Furnish's avatar
Gary Furnish committed
30

31

32 33 34 35
def check_c_declarations_pxd(module_node):
    module_node.scope.check_c_classes_pxd()
    return module_node

36
def check_c_declarations(module_node):
37
    module_node.scope.check_c_classes()
38
    module_node.scope.check_c_functions()
39 40
    return module_node

41 42 43
class ModuleNode(Nodes.Node, Nodes.BlockNode):
    #  doc       string or None
    #  body      StatListNode
44 45
    #
    #  referenced_modules   [ModuleScope]
46
    #  full_module_name     string
47 48 49
    #
    #  scope                The module scope.
    #  compilation_source   A CompilationSource (see Main)
50
    #  directives           Top-level compiler directives
51

52
    child_attrs = ["body"]
53
    directives = None
54

55 56 57 58 59 60 61 62 63 64 65 66 67 68
    def merge_in(self, tree, scope, merge_scope=False):
        # Merges in the contents of another tree, and possibly scope. With the
        # current implementation below, this must be done right prior
        # to code generation.
        #
        # Note: This way of doing it seems strange -- I believe the
        # right concept is to split ModuleNode into a ModuleNode and a
        # CodeGenerator, and tell that CodeGenerator to generate code
        # from multiple sources.
        assert isinstance(self.body, Nodes.StatListNode)
        if isinstance(tree, Nodes.StatListNode):
            self.body.stats.extend(tree.stats)
        else:
            self.body.stats.append(tree)
69 70 71 72 73 74 75 76 77 78 79 80 81

        self.scope.utility_code_list.extend(scope.utility_code_list)

        def extend_if_not_in(L1, L2):
            for x in L2:
                if x not in L1:
                    L1.append(x)

        extend_if_not_in(self.scope.include_files, scope.include_files)
        extend_if_not_in(self.scope.included_files, scope.included_files)
        extend_if_not_in(self.scope.python_include_files,
                         scope.python_include_files)

82
        if merge_scope:
83 84 85
            # Ensure that we don't generate import code for these entries!
            for entry in scope.c_class_entries:
                entry.type.module_name = self.full_module_name
86
                entry.type.scope.directives["internal"] = True
87

88
            self.scope.merge_in(scope)
89

90
    def analyse_declarations(self, env):
91 92 93
        if not Options.docstrings:
            env.doc = self.doc = None
        elif Options.embed_pos_in_docstring:
Robert Bradshaw's avatar
Robert Bradshaw committed
94
            env.doc = EncodedString(u'File: %s (starting at line %s)' % Nodes.relative_position(self.pos))
95
            if not self.doc is None:
96
                env.doc = EncodedString(env.doc + u'\n' + self.doc)
Robert Bradshaw's avatar
Robert Bradshaw committed
97
                env.doc.encoding = self.doc.encoding
98 99
        else:
            env.doc = self.doc
100
        env.directives = self.directives
101
        self.body.analyse_declarations(env)
102

103 104
    def process_implementation(self, options, result):
        env = self.scope
105
        env.return_type = PyrexTypes.c_void_type
106 107
        self.referenced_modules = []
        self.find_referenced_modules(env, self.referenced_modules, {})
108
        self.sort_cdef_classes(env)
109
        self.generate_c_code(env, options, result)
110 111
        self.generate_h_code(env, options, result)
        self.generate_api_code(env, result)
Robert Bradshaw's avatar
Robert Bradshaw committed
112

113 114 115 116 117 118
    def has_imported_c_functions(self):
        for module in self.referenced_modules:
            for entry in module.cfunc_entries:
                if entry.defined_in_pxd:
                    return 1
        return 0
119

120
    def generate_h_code(self, env, options, result):
121
        def h_entries(entries, api=0, pxd=0):
Stefan Behnel's avatar
Stefan Behnel committed
122
            return [entry for entry in entries
123 124 125 126
                    if ((entry.visibility == 'public') or
                        (api and entry.api) or
                        (pxd and entry.defined_in_pxd))]
        h_types = h_entries(env.type_entries, api=1)
Stefan Behnel's avatar
Stefan Behnel committed
127 128 129
        h_vars = h_entries(env.var_entries)
        h_funcs = h_entries(env.cfunc_entries)
        h_extension_types = h_entries(env.c_class_entries)
130
        if (h_types or  h_vars or h_funcs or h_extension_types):
131
            result.h_file = replace_suffix(result.c_file, ".h")
132
            h_code = Code.CCodeWriter()
133
            Code.GlobalState(h_code, self)
134 135 136 137 138
            if options.generate_pxi:
                result.i_file = replace_suffix(result.c_file, ".pxi")
                i_code = Code.PyrexCodeWriter(result.i_file)
            else:
                i_code = None
139 140 141

            h_guard = Naming.h_guard_prefix + self.api_name(env)
            h_code.put_h_guard(h_guard)
142
            h_code.putln("")
Stefan Behnel's avatar
Stefan Behnel committed
143
            self.generate_type_header_code(h_types, h_code)
144 145
            if options.capi_reexport_cincludes:
                self.generate_includes(env, [], h_code)
146
            h_code.putln("")
147 148
            api_guard = Naming.api_guard_prefix + self.api_name(env)
            h_code.putln("#ifndef %s" % api_guard)
149 150
            h_code.putln("")
            self.generate_extern_c_macro_definition(h_code)
Stefan Behnel's avatar
Stefan Behnel committed
151
            if h_extension_types:
152
                h_code.putln("")
Stefan Behnel's avatar
Stefan Behnel committed
153
                for entry in h_extension_types:
154 155 156
                    self.generate_cclass_header_code(entry.type, h_code)
                    if i_code:
                        self.generate_cclass_include_code(entry.type, i_code)
157 158 159 160 161 162 163 164
            if h_funcs:
                h_code.putln("")
                for entry in h_funcs:
                    self.generate_public_declaration(entry, h_code, i_code)
            if h_vars:
                h_code.putln("")
                for entry in h_vars:
                    self.generate_public_declaration(entry, h_code, i_code)
165
            h_code.putln("")
166
            h_code.putln("#endif /* !%s */" % api_guard)
167
            h_code.putln("")
168
            h_code.putln("#if PY_MAJOR_VERSION < 3")
169
            h_code.putln("PyMODINIT_FUNC init%s(void);" % env.module_name)
170 171
            h_code.putln("#else")
            h_code.putln("PyMODINIT_FUNC PyInit_%s(void);" % env.module_name)
172
            h_code.putln("#endif")
173 174
            h_code.putln("")
            h_code.putln("#endif /* !%s */" % h_guard)
175

176 177 178 179 180
            f = open_new_file(result.h_file)
            try:
                h_code.copyto(f)
            finally:
                f.close()
181

182 183 184 185
    def generate_public_declaration(self, entry, h_code, i_code):
        h_code.putln("%s %s;" % (
            Naming.extern_c_macro,
            entry.type.declaration_code(
Mark Florisson's avatar
Mark Florisson committed
186
                entry.cname, dll_linkage = "DL_IMPORT")))
187
        if i_code:
188
            i_code.putln("cdef extern %s" %
Mark Florisson's avatar
Mark Florisson committed
189
                entry.type.declaration_code(entry.cname, pyrex = 1))
190

191 192
    def api_name(self, env):
        return env.qualified_name.replace(".", "__")
Robert Bradshaw's avatar
Robert Bradshaw committed
193

194
    def generate_api_code(self, env, result):
195
        def api_entries(entries, pxd=0):
196 197 198 199 200 201
            return [entry for entry in entries
                    if entry.api or (pxd and entry.defined_in_pxd)]
        api_vars = api_entries(env.var_entries)
        api_funcs = api_entries(env.cfunc_entries)
        api_extension_types = api_entries(env.c_class_entries)
        if api_vars or api_funcs or api_extension_types:
202
            result.api_file = replace_suffix(result.c_file, "_api.h")
203
            h_code = Code.CCodeWriter()
204
            Code.GlobalState(h_code, self)
205 206
            api_guard = Naming.api_guard_prefix + self.api_name(env)
            h_code.put_h_guard(api_guard)
207 208 209
            h_code.putln('#include "Python.h"')
            if result.h_file:
                h_code.putln('#include "%s"' % os.path.basename(result.h_file))
210
            if api_extension_types:
211
                h_code.putln("")
212 213 214 215 216
                for entry in api_extension_types:
                    type = entry.type
                    h_code.putln("static PyTypeObject *%s = 0;" % type.typeptr_cname)
                    h_code.putln("#define %s (*%s)" % (
                        type.typeobj_cname, type.typeptr_cname))
217 218 219 220
            if api_funcs:
                h_code.putln("")
                for entry in api_funcs:
                    type = CPtrType(entry.type)
221 222 223 224 225 226 227
                    cname = env.mangle(Naming.func_prefix, entry.name)
                    h_code.putln("static %s = 0;" % type.declaration_code(cname))
                    h_code.putln("#define %s %s" % (entry.name, cname))
            if api_vars:
                h_code.putln("")
                for entry in api_vars:
                    type = CPtrType(entry.type)
228
                    cname = env.mangle(Naming.varptr_prefix, entry.name)
229 230
                    h_code.putln("static %s = 0;" %  type.declaration_code(cname))
                    h_code.putln("#define %s (*%s)" % (entry.name, cname))
231 232
            h_code.put(UtilityCode.load_as_string("PyIdentifierFromString", "ImportExport.c")[0])
            h_code.put(UtilityCode.load_as_string("ModuleImport", "ImportExport.c")[1])
233
            if api_vars:
234
                h_code.put(UtilityCode.load_as_string("VoidPtrImport", "ImportExport.c")[1])
235
            if api_funcs:
236
                h_code.put(UtilityCode.load_as_string("FunctionImport", "ImportExport.c")[1])
237
            if api_extension_types:
238
                h_code.put(UtilityCode.load_as_string("TypeImport", "ImportExport.c")[1])
239
            h_code.putln("")
240
            h_code.putln("static int import_%s(void) {" % self.api_name(env))
241
            h_code.putln("PyObject *module = 0;")
242
            h_code.putln('module = __Pyx_ImportModule("%s");' % env.qualified_name)
243 244
            h_code.putln("if (!module) goto bad;")
            for entry in api_funcs:
245
                cname = env.mangle(Naming.func_prefix, entry.name)
246 247
                sig = entry.type.signature_string()
                h_code.putln(
248 249 250
                    'if (__Pyx_ImportFunction(module, "%s", (void (**)(void))&%s, "%s") < 0) goto bad;'
                    % (entry.name, cname, sig))
            for entry in api_vars:
251
                cname = env.mangle(Naming.varptr_prefix, entry.name)
252 253 254 255
                sig = entry.type.declaration_code("")
                h_code.putln(
                    'if (__Pyx_ImportVoidPtr(module, "%s", (void **)&%s, "%s") < 0) goto bad;'
                    % (entry.name, cname, sig))
256
            h_code.putln("Py_DECREF(module); module = 0;")
257
            for entry in api_extension_types:
258 259 260
                self.generate_type_import_call(
                    entry.type, h_code,
                    "if (!%s) goto bad;" % entry.type.typeptr_cname)
261 262 263 264 265 266
            h_code.putln("return 0;")
            h_code.putln("bad:")
            h_code.putln("Py_XDECREF(module);")
            h_code.putln("return -1;")
            h_code.putln("}")
            h_code.putln("")
267
            h_code.putln("#endif /* !%s */" % api_guard)
268

269 270 271 272 273
            f = open_new_file(result.api_file)
            try:
                h_code.copyto(f)
            finally:
                f.close()
274

275
    def generate_cclass_header_code(self, type, h_code):
276
        h_code.putln("%s %s %s;" % (
Robert Bradshaw's avatar
Robert Bradshaw committed
277
            Naming.extern_c_macro,
278
            PyrexTypes.public_decl("PyTypeObject", "DL_IMPORT"),
279
            type.typeobj_cname))
280

281 282 283 284 285 286 287
    def generate_cclass_include_code(self, type, i_code):
        i_code.putln("cdef extern class %s.%s:" % (
            type.module_name, type.name))
        i_code.indent()
        var_entries = type.scope.var_entries
        if var_entries:
            for entry in var_entries:
288
                i_code.putln("cdef %s" %
289 290 291 292
                    entry.type.declaration_code(entry.cname, pyrex = 1))
        else:
            i_code.putln("pass")
        i_code.dedent()
293

294
    def generate_c_code(self, env, options, result):
295
        modules = self.referenced_modules
296

297
        if Options.annotate or options.annotate:
298 299
            emit_linenums = False
            rootwriter = Annotate.AnnotationCCodeWriter()
300
        else:
301
            emit_linenums = options.emit_linenums
302
            rootwriter = Code.CCodeWriter(emit_linenums=emit_linenums, c_line_in_traceback=options.c_line_in_traceback)
303
        globalstate = Code.GlobalState(rootwriter, self, emit_linenums, options.common_utility_include_dir)
304
        globalstate.initialize_main_c_code()
305
        h_code = globalstate['h_code']
306

307
        self.generate_module_preamble(env, modules, h_code)
308

309 310
        globalstate.module_pos = self.pos
        globalstate.directives = self.directives
311

312
        globalstate.use_utility_code(refnanny_utility_code)
313

314
        code = globalstate['before_global_var']
315
        code.putln('#define __Pyx_MODULE_NAME "%s"' % self.full_module_name)
316
        code.putln("int %s%s = 0;" % (Naming.module_is_main, self.full_module_name.replace('.', '__')))
317
        code.putln("")
318
        code.putln("/* Implementation of '%s' */" % env.qualified_name)
319

320
        code = globalstate['all_the_rest']
321

322
        self.generate_cached_builtins_decls(env, code)
323
        self.generate_lambda_definitions(env, code)
324 325
        # generate normal variable and function definitions
        self.generate_variable_definitions(env, code)
326
        self.body.generate_function_definitions(env, code)
Robert Bradshaw's avatar
Robert Bradshaw committed
327
        code.mark_pos(None)
328 329
        self.generate_typeobj_definitions(env, code)
        self.generate_method_table(env, code)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
330 331
        if env.has_import_star:
            self.generate_import_star(env, code)
332
        self.generate_pymoduledef_struct(env, code)
333

334 335 336
        # init_globals is inserted before this
        self.generate_module_init_func(modules[:-1], env, globalstate['init_module'])
        self.generate_module_cleanup_func(env, globalstate['cleanup_module'])
337
        if Options.embed:
338 339
            self.generate_main_method(env, globalstate['main_method'])
        self.generate_filename_table(globalstate['filename_table'])
340

341
        self.generate_declarations_for_modules(env, modules, globalstate)
342
        h_code.write('\n')
Gary Furnish's avatar
Gary Furnish committed
343

344
        for utilcode in env.utility_code_list[:]:
345
            globalstate.use_utility_code(utilcode)
346
        globalstate.finalize_main_c_code()
347

348
        f = open_new_file(result.c_file)
349
        rootwriter.copyto(f)
350
        if options.gdb_debug:
Mark Florisson's avatar
Mark Florisson committed
351
            self._serialize_lineno_map(env, rootwriter)
352 353
        f.close()
        result.c_file_generated = 1
354
        if Options.annotate or options.annotate:
355 356
            self.annotate(rootwriter)
            rootwriter.save_annotation(result.main_source_file, result.c_file)
357

Mark Florisson's avatar
Mark Florisson committed
358
    def _serialize_lineno_map(self, env, ccodewriter):
359
        tb = env.context.gdb_debug_outputwriter
Mark Florisson's avatar
Mark Florisson committed
360
        markers = ccodewriter.buffer.allmarkers()
361

Mark Florisson's avatar
Mark Florisson committed
362
        d = {}
363
        for c_lineno, cython_lineno in enumerate(markers):
Mark Florisson's avatar
Mark Florisson committed
364 365
            if cython_lineno > 0:
                d.setdefault(cython_lineno, []).append(c_lineno + 1)
366

Mark Florisson's avatar
Mark Florisson committed
367 368 369 370 371 372 373 374 375 376
        tb.start('LineNumberMapping')
        for cython_lineno, c_linenos in sorted(d.iteritems()):
                attrs = {
                    'c_linenos': ' '.join(map(str, c_linenos)),
                    'cython_lineno': str(cython_lineno),
                }
                tb.start('LineNumber', attrs)
                tb.end('LineNumber')
        tb.end('LineNumberMapping')
        tb.serialize()
377

378 379 380 381 382 383
    def find_referenced_modules(self, env, module_list, modules_seen):
        if env not in modules_seen:
            modules_seen[env] = 1
            for imported_module in env.cimported_modules:
                self.find_referenced_modules(imported_module, module_list, modules_seen)
            module_list.append(env)
Gary Furnish's avatar
Gary Furnish committed
384

385 386 387 388 389 390 391 392 393
    def sort_types_by_inheritance(self, type_dict, getkey):
        # copy the types into a list moving each parent type before
        # its first child
        type_items = type_dict.items()
        type_list = []
        for i, item in enumerate(type_items):
            key, new_entry = item

            # collect all base classes to check for children
394
            hierarchy = set()
395
            base = new_entry
396 397 398 399 400 401 402
            while base:
                base_type = base.type.base_type
                if not base_type:
                    break
                base_key = getkey(base_type)
                hierarchy.add(base_key)
                base = type_dict.get(base_key)
403
            new_entry.base_keys = hierarchy
404

405
            # find the first (sub-)subclass and insert before that
406 407
            for j in range(i):
                entry = type_list[j]
408
                if key in entry.base_keys:
409 410 411 412 413 414 415
                    type_list.insert(j, new_entry)
                    break
            else:
                type_list.append(new_entry)
        return type_list

    def sort_type_hierarchy(self, module_list, env):
Gary Furnish's avatar
Gary Furnish committed
416
        vtab_dict = {}
417
        vtabslot_dict = {}
Gary Furnish's avatar
Gary Furnish committed
418 419 420 421 422
        for module in module_list:
            for entry in module.c_class_entries:
                if not entry.in_cinclude:
                    type = entry.type
                    if type.vtabstruct_cname:
423 424 425 426
                        vtab_dict[type.vtabstruct_cname] = entry
            all_defined_here = module is env
            for entry in module.type_entries:
                if all_defined_here or entry.defined_in_pxd:
Gary Furnish's avatar
Gary Furnish committed
427
                    type = entry.type
428 429 430
                    if type.is_extension_type and not entry.in_cinclude:
                        type = entry.type
                        vtabslot_dict[type.objstruct_cname] = entry
431

432 433
        def vtabstruct_cname(entry_type):
            return entry_type.vtabstruct_cname
434 435
        vtab_list = self.sort_types_by_inheritance(
            vtab_dict, vtabstruct_cname)
436 437 438

        def objstruct_cname(entry_type):
            return entry_type.objstruct_cname
439 440
        vtabslot_list = self.sort_types_by_inheritance(
            vtabslot_dict, objstruct_cname)
441

442
        return (vtab_list, vtabslot_list)
443

444
    def sort_cdef_classes(self, env):
445
        key_func = operator.attrgetter('objstruct_cname')
446 447
        entry_dict = {}
        for entry in env.c_class_entries:
Stefan Behnel's avatar
Stefan Behnel committed
448 449 450
            key = key_func(entry.type)
            assert key not in entry_dict
            entry_dict[key] = entry
451 452
        env.c_class_entries[:] = self.sort_types_by_inheritance(
            entry_dict, key_func)
453

Gary Furnish's avatar
Gary Furnish committed
454
    def generate_type_definitions(self, env, modules, vtab_list, vtabslot_list, code):
455 456 457
        # TODO: Why are these separated out?
        for entry in vtabslot_list:
            self.generate_objstruct_predeclaration(entry.type, code)
458
        vtabslot_entries = set(vtabslot_list)
Gary Furnish's avatar
Gary Furnish committed
459 460 461 462 463 464 465 466 467
        for module in modules:
            definition = module is env
            if definition:
                type_entries = module.type_entries
            else:
                type_entries = []
                for entry in module.type_entries:
                    if entry.defined_in_pxd:
                        type_entries.append(entry)
468
            type_entries = [t for t in type_entries if t not in vtabslot_entries]
469
            self.generate_type_header_code(type_entries, code)
Gary Furnish's avatar
Gary Furnish committed
470
        for entry in vtabslot_list:
471
            self.generate_objstruct_definition(entry.type, code)
472
            self.generate_typeobj_predeclaration(entry, code)
Gary Furnish's avatar
Gary Furnish committed
473
        for entry in vtab_list:
474
            self.generate_typeobj_predeclaration(entry, code)
Gary Furnish's avatar
Gary Furnish committed
475 476
            self.generate_exttype_vtable_struct(entry, code)
            self.generate_exttype_vtabptr_declaration(entry, code)
477
            self.generate_exttype_final_methods_declaration(entry, code)
Gary Furnish's avatar
Gary Furnish committed
478

479 480 481
    def generate_declarations_for_modules(self, env, modules, globalstate):
        typecode = globalstate['type_declarations']
        typecode.putln("")
482
        typecode.putln("/*--- Type declarations ---*/")
483 484 485 486 487 488 489
        # This is to work around the fact that array.h isn't part of the C-API,
        # but we need to declare it earlier than utility code.
        if 'cpython.array' in [m.qualified_name for m in modules]:
            typecode.putln('#ifndef _ARRAYARRAY_H')
            typecode.putln('struct arrayobject;')
            typecode.putln('typedef struct arrayobject arrayobject;')
            typecode.putln('#endif')
490 491
        vtab_list, vtabslot_list = self.sort_type_hierarchy(modules, env)
        self.generate_type_definitions(
492 493
            env, modules, vtab_list, vtabslot_list, typecode)
        modulecode = globalstate['module_declarations']
Gary Furnish's avatar
Gary Furnish committed
494
        for module in modules:
495
            defined_here = module is env
496 497 498 499 500
            modulecode.putln("")
            modulecode.putln("/* Module declarations from '%s' */" % module.qualified_name)
            self.generate_c_class_declarations(module, modulecode, defined_here)
            self.generate_cvariable_declarations(module, modulecode, defined_here)
            self.generate_cfunction_declarations(module, modulecode, defined_here)
Gary Furnish's avatar
Gary Furnish committed
501

502
    def generate_module_preamble(self, env, cimported_modules, code):
503
        code.putln("/* Generated by Cython %s */" % Version.watermark)
504 505
        code.putln("")
        code.putln("#define PY_SSIZE_T_CLEAN")
506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526

        # sizeof(PyLongObject.ob_digit[0]) may have been determined dynamically
        # at compile time in CPython, in which case we can't know the correct
        # storage size for an installed system.  We can rely on it only if
        # pyconfig.h defines it statically, i.e. if it was set by "configure".
        # Once we include "Python.h", it will come up with its own idea about
        # a suitable value, which may or may not match the real one.
        code.putln("#ifndef CYTHON_USE_PYLONG_INTERNALS")
        code.putln("#ifdef PYLONG_BITS_IN_DIGIT")
        # assume it's an incorrect left-over
        code.putln("#define CYTHON_USE_PYLONG_INTERNALS 0")
        code.putln("#else")
        code.putln('#include "pyconfig.h"')
        code.putln("#ifdef PYLONG_BITS_IN_DIGIT")
        code.putln("#define CYTHON_USE_PYLONG_INTERNALS 1")
        code.putln("#else")
        code.putln("#define CYTHON_USE_PYLONG_INTERNALS 0")
        code.putln("#endif")
        code.putln("#endif")
        code.putln("#endif")

527 528
        for filename in env.python_include_files:
            code.putln('#include "%s"' % filename)
529 530
        code.putln("#ifndef Py_PYTHON_H")
        code.putln("    #error Python headers needed to compile C extensions, please install development version of Python.")
Robert Bradshaw's avatar
Robert Bradshaw committed
531
        code.putln("#elif PY_VERSION_HEX < 0x02040000")
532
        code.putln("    #error Cython requires Python 2.4+.")
533 534
        code.putln("#else")
        code.globalstate["end"].putln("#endif /* Py_PYTHON_H */")
535

536
        code.put(UtilityCode.load_as_string("CModulePreamble", "ModuleSetupCode.c")[1])
537 538 539

        code.put("""
#if PY_MAJOR_VERSION >= 3
540 541 542 543
  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
#else
""")
Robert Bradshaw's avatar
Robert Bradshaw committed
544 545
        if Future.division in env.context.future_directives:
            code.putln("  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)")
Stefan Behnel's avatar
Stefan Behnel committed
546
            code.putln("  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)")
Robert Bradshaw's avatar
Robert Bradshaw committed
547 548
        else:
            code.putln("  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)")
Stefan Behnel's avatar
Stefan Behnel committed
549
            code.putln("  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)")
550
        code.putln("#endif")
551

552
        code.putln("")
553
        self.generate_extern_c_macro_definition(code)
554
        code.putln("")
555

556 557 558
        code.putln("#if defined(WIN32) || defined(MS_WINDOWS)")
        code.putln("#define _USE_MATH_DEFINES")
        code.putln("#endif")
559
        code.putln("#include <math.h>")
560

561
        code.putln("#define %s" % Naming.h_guard_prefix + self.api_name(env))
562
        code.putln("#define %s" % Naming.api_guard_prefix + self.api_name(env))
563
        self.generate_includes(env, cimported_modules, code)
564 565 566 567 568
        code.putln("")
        code.putln("#ifdef PYREX_WITHOUT_ASSERTIONS")
        code.putln("#define CYTHON_WITHOUT_ASSERTIONS")
        code.putln("#endif")
        code.putln("")
569

570 571 572 573
        if env.directives['ccomplex']:
            code.putln("")
            code.putln("#if !defined(CYTHON_CCOMPLEX)")
            code.putln("#define CYTHON_CCOMPLEX 1")
574
            code.putln("#endif")
575
            code.putln("")
576
        code.put(UtilityCode.load_as_string("UtilityFunctionPredeclarations", "ModuleSetupCode.c")[0])
577 578 579 580 581 582

        c_string_type = env.directives['c_string_type']
        c_string_encoding = env.directives['c_string_encoding']
        if c_string_type != 'bytes' and not c_string_encoding:
            error(self.pos, "a default encoding must be provided if c_string_type != bytes")
        code.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII %s' % int(c_string_encoding == 'ascii'))
583 584 585 586 587
        if c_string_encoding == 'default':
            code.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 1')
        else:
            code.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0')
            code.putln('#define __PYX_DEFAULT_STRING_ENCODING "%s"' % c_string_encoding)
588 589
        code.putln('#define __Pyx_PyObject_FromString __Pyx_Py%s_FromString' % c_string_type.title())
        code.putln('#define __Pyx_PyObject_FromStringAndSize __Pyx_Py%s_FromStringAndSize' % c_string_type.title())
590
        code.put(UtilityCode.load_as_string("TypeConversions", "TypeConversion.c")[0])
591
        
Robert Bradshaw's avatar
Robert Bradshaw committed
592
        code.put(Nodes.branch_prediction_macros)
593 594
        code.putln('')
        code.putln('static PyObject *%s;' % env.module_cname)
595
        code.putln('static PyObject *%s;' % env.module_dict_cname)
596
        code.putln('static PyObject *%s;' % Naming.builtins_cname)
Robert Bradshaw's avatar
Robert Bradshaw committed
597
        code.putln('static PyObject *%s;' % Naming.empty_tuple)
Robert Bradshaw's avatar
Robert Bradshaw committed
598
        code.putln('static PyObject *%s;' % Naming.empty_bytes)
599 600
        if Options.pre_import is not None:
            code.putln('static PyObject *%s;' % Naming.preimport_cname)
601
        code.putln('static int %s;' % Naming.lineno_cname)
602
        code.putln('static int %s = 0;' % Naming.clineno_cname)
603 604
        code.putln('static const char * %s= %s;' % (Naming.cfilenm_cname, Naming.file_c_macro))
        code.putln('static const char *%s;' % Naming.filename_cname)
605

606 607 608 609 610 611
        # XXX this is a mess
        for utility_code in PyrexTypes.c_int_from_py_function.specialize_list:
            env.use_utility_code(utility_code)
        for utility_code in PyrexTypes.c_long_from_py_function.specialize_list:
            env.use_utility_code(utility_code)

612 613
    def generate_extern_c_macro_definition(self, code):
        name = Naming.extern_c_macro
614 615 616 617 618 619
        code.putln("#ifndef %s" % name)
        code.putln("  #ifdef __cplusplus")
        code.putln('    #define %s extern "C"' % name)
        code.putln("  #else")
        code.putln("    #define %s extern" % name)
        code.putln("  #endif")
620 621 622
        code.putln("#endif")

    def generate_includes(self, env, cimported_modules, code):
623
        includes = []
Robert Bradshaw's avatar
Robert Bradshaw committed
624
        for filename in env.include_files:
Stefan Behnel's avatar
Stefan Behnel committed
625 626 627
            byte_decoded_filenname = str(filename)
            if byte_decoded_filenname[0] == '<' and byte_decoded_filenname[-1] == '>':
                code.putln('#include %s' % byte_decoded_filenname)
628
            else:
Stefan Behnel's avatar
Stefan Behnel committed
629
                code.putln('#include "%s"' % byte_decoded_filenname)
630

631 632
        code.putln_openmp("#include <omp.h>")

633 634
    def generate_filename_table(self, code):
        code.putln("")
Robert Bradshaw's avatar
Robert Bradshaw committed
635
        code.putln("static const char *%s[] = {" % Naming.filetable_cname)
636 637
        if code.globalstate.filename_list:
            for source_desc in code.globalstate.filename_list:
638
                filename = os.path.basename(source_desc.get_filenametable_entry())
639
                escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"')
Robert Bradshaw's avatar
Robert Bradshaw committed
640
                code.putln('"%s",' % escaped_filename)
641 642 643 644
        else:
            # Some C compilers don't like an empty array
            code.putln("0")
        code.putln("};")
645 646 647 648

    def generate_type_predeclarations(self, env, code):
        pass

649
    def generate_type_header_code(self, type_entries, code):
650 651
        # Generate definitions of structs/unions/enums/typedefs/objstructs.
        #self.generate_gcc33_hack(env, code) # Is this still needed?
652
        # Forward declarations
653
        for entry in type_entries:
654
            if not entry.in_cinclude:
655
                #print "generate_type_header_code:", entry.name, repr(entry.type) ###
656
                type = entry.type
657
                if type.is_typedef: # Must test this first!
658
                    pass
659
                elif type.is_struct_or_union or type.is_cpp_class:
660 661 662 663 664 665 666 667 668 669
                    self.generate_struct_union_predeclaration(entry, code)
                elif type.is_extension_type:
                    self.generate_objstruct_predeclaration(type, code)
        # Actual declarations
        for entry in type_entries:
            if not entry.in_cinclude:
                #print "generate_type_header_code:", entry.name, repr(entry.type) ###
                type = entry.type
                if type.is_typedef: # Must test this first!
                    self.generate_typedef(entry, code)
670
                elif type.is_enum:
671
                    self.generate_enum_definition(entry, code)
672 673
                elif type.is_struct_or_union:
                    self.generate_struct_union_definition(entry, code)
674 675
                elif type.is_cpp_class:
                    self.generate_cpp_class_definition(entry, code)
676
                elif type.is_extension_type:
677
                    self.generate_objstruct_definition(type, code)
678

679 680 681 682 683 684 685 686 687 688 689 690 691
    def generate_gcc33_hack(self, env, code):
        # Workaround for spurious warning generation in gcc 3.3
        code.putln("")
        for entry in env.c_class_entries:
            type = entry.type
            if not type.typedef_flag:
                name = type.objstruct_cname
                if name.startswith("__pyx_"):
                    tail = name[6:]
                else:
                    tail = name
                code.putln("typedef struct %s __pyx_gcc33_%s;" % (
                    name, tail))
692

693 694
    def generate_typedef(self, entry, code):
        base_type = entry.type.typedef_base_type
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
695
        if base_type.is_numeric:
696 697 698 699
            try:
                writer = code.globalstate['numeric_typedefs']
            except KeyError:
                writer = code
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
700 701
        else:
            writer = code
702
        writer.mark_pos(entry.pos)
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
703
        writer.putln("typedef %s;" % base_type.declaration_code(entry.cname))
704

705
    def sue_predeclaration(self, type, kind, name):
706
        if type.typedef_flag:
707 708 709
            return "%s %s;\ntypedef %s %s %s;" % (
                kind, name,
                kind, name, name)
710
        else:
711 712 713 714
            return "%s %s;" % (kind, name)

    def generate_struct_union_predeclaration(self, entry, code):
        type = entry.type
715
        if type.is_cpp_class and type.templates:
716
            code.putln("template <typename %s>" % ", typename ".join([T.declaration_code("") for T in type.templates]))
717 718 719 720 721
        code.putln(self.sue_predeclaration(type, type.kind, type.cname))

    def sue_header_footer(self, type, kind, name):
        header = "%s %s {" % (kind, name)
        footer = "};"
722
        return header, footer
723

724
    def generate_struct_union_definition(self, entry, code):
725
        code.mark_pos(entry.pos)
726 727 728
        type = entry.type
        scope = type.scope
        if scope:
729 730 731 732 733
            kind = type.kind
            packed = type.is_struct and type.packed
            if packed:
                kind = "%s %s" % (type.kind, "__Pyx_PACKED")
                code.globalstate.use_utility_code(packed_struct_utility_code)
734
            header, footer = \
735 736
                self.sue_header_footer(type, kind, type.cname)
            if packed:
737 738 739 740
                code.putln("#if defined(__SUNPRO_C)")
                code.putln("  #pragma pack(1)")
                code.putln("#elif !defined(__GNUC__)")
                code.putln("  #pragma pack(push, 1)")
741
                code.putln("#endif")
742 743 744 745 746 747 748 749 750 751 752
            code.putln(header)
            var_entries = scope.var_entries
            if not var_entries:
                error(entry.pos,
                    "Empty struct or union definition not allowed outside a"
                    " 'cdef extern from' block")
            for attr in var_entries:
                code.putln(
                    "%s;" %
                        attr.type.declaration_code(attr.cname))
            code.putln(footer)
753
            if packed:
754 755 756 757
                code.putln("#if defined(__SUNPRO_C)")
                code.putln("  #pragma pack()")
                code.putln("#elif !defined(__GNUC__)")
                code.putln("  #pragma pack(pop)")
758
                code.putln("#endif")
759

760 761 762 763 764 765 766 767 768 769 770 771 772 773 774
    def generate_cpp_class_definition(self, entry, code):
        code.mark_pos(entry.pos)
        type = entry.type
        scope = type.scope
        if scope:
            if type.templates:
                code.putln("template <class %s>" % ", class ".join([T.declaration_code("") for T in type.templates]))
            # Just let everything be public.
            code.put("struct %s" % type.cname)
            if type.base_classes:
                base_class_decl = ", public ".join(
                    [base_class.declaration_code("") for base_class in type.base_classes])
                code.put(" : public %s" % base_class_decl)
            code.putln(" {")
            for attr in scope.var_entries:
775
                if attr.type.is_cfunction and attr.name != "<init>":
776 777 778 779 780 781
                    code.put("virtual ")
                code.putln(
                    "%s;" %
                        attr.type.declaration_code(attr.cname))
            code.putln("};")

782
    def generate_enum_definition(self, entry, code):
783
        code.mark_pos(entry.pos)
784 785 786 787 788 789 790 791 792 793 794 795
        type = entry.type
        name = entry.cname or entry.name or ""
        header, footer = \
            self.sue_header_footer(type, "enum", name)
        code.putln(header)
        enum_values = entry.enum_values
        if not enum_values:
            error(entry.pos,
                "Empty enum definition not allowed outside a"
                " 'cdef extern from' block")
        else:
            last_entry = enum_values[-1]
796
            # this does not really generate code, just builds the result value
797
            for value_entry in enum_values:
798 799 800 801 802
                if value_entry.value_node is not None:
                    value_entry.value_node.generate_evaluation_code(code)

            for value_entry in enum_values:
                if value_entry.value_node is None:
803 804 805 806
                    value_code = value_entry.cname
                else:
                    value_code = ("%s = %s" % (
                        value_entry.cname,
807
                        value_entry.value_node.result()))
808 809 810 811
                if value_entry is not last_entry:
                    value_code += ","
                code.putln(value_code)
        code.putln(footer)
812 813 814
        if entry.type.typedef_flag:
            # Not pre-declared.
            code.putln("typedef enum %s %s;" % (name, name))
815

816
    def generate_typeobj_predeclaration(self, entry, code):
817 818 819 820
        code.putln("")
        name = entry.type.typeobj_cname
        if name:
            if entry.visibility == 'extern' and not entry.in_cinclude:
821
                code.putln("%s %s %s;" % (
822
                    Naming.extern_c_macro,
823
                    PyrexTypes.public_decl("PyTypeObject", "DL_IMPORT"),
824 825
                    name))
            elif entry.visibility == 'public':
826
                code.putln("%s %s %s;" % (
827
                    Naming.extern_c_macro,
828
                    PyrexTypes.public_decl("PyTypeObject", "DL_EXPORT"),
829 830 831
                    name))
            # ??? Do we really need the rest of this? ???
            #else:
832
            #    code.putln("static PyTypeObject %s;" % name)
833

834
    def generate_exttype_vtable_struct(self, entry, code):
835 836 837
        if not entry.used:
            return

838
        code.mark_pos(entry.pos)
839 840 841
        # Generate struct declaration for an extension type's vtable.
        type = entry.type
        scope = type.scope
842 843 844

        self.specialize_fused_types(scope)

845 846 847 848 849 850 851 852 853 854 855 856
        if type.vtabstruct_cname:
            code.putln("")
            code.putln(
                "struct %s {" %
                    type.vtabstruct_cname)
            if type.base_type and type.base_type.vtabstruct_cname:
                code.putln("struct %s %s;" % (
                    type.base_type.vtabstruct_cname,
                    Naming.obj_base_cname))
            for method_entry in scope.cfunc_entries:
                if not method_entry.is_inherited:
                    code.putln(
857
                        "%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.cname))
858 859
            code.putln(
                "};")
860

861
    def generate_exttype_vtabptr_declaration(self, entry, code):
862 863 864
        if not entry.used:
            return

865
        code.mark_pos(entry.pos)
866 867 868 869 870 871
        # Generate declaration of pointer to an extension type's vtable.
        type = entry.type
        if type.vtabptr_cname:
            code.putln("static struct %s *%s;" % (
                type.vtabstruct_cname,
                type.vtabptr_cname))
872

873 874 875 876 877 878 879 880 881 882 883
    def generate_exttype_final_methods_declaration(self, entry, code):
        if not entry.used:
            return

        code.mark_pos(entry.pos)
        # Generate final methods prototypes
        type = entry.type
        for method_entry in entry.type.scope.cfunc_entries:
            if not method_entry.is_inherited and method_entry.final_func_cname:
                declaration = method_entry.type.declaration_code(
                    method_entry.final_func_cname)
884 885
                modifiers = code.build_function_modifiers(method_entry.func_modifiers)
                code.putln("static %s%s;" % (modifiers, declaration))
886

887 888 889 890
    def generate_objstruct_predeclaration(self, type, code):
        if not type.scope:
            return
        code.putln(self.sue_predeclaration(type, "struct", type.objstruct_cname))
Vitja Makarov's avatar
Vitja Makarov committed
891

892
    def generate_objstruct_definition(self, type, code):
893
        code.mark_pos(type.pos)
894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916
        # Generate object struct definition for an
        # extension type.
        if not type.scope:
            return # Forward declared but never defined
        header, footer = \
            self.sue_header_footer(type, "struct", type.objstruct_cname)
        code.putln(header)
        base_type = type.base_type
        if base_type:
            code.putln(
                "%s%s %s;" % (
                    ("struct ", "")[base_type.typedef_flag],
                    base_type.objstruct_cname,
                    Naming.obj_base_cname))
        else:
            code.putln(
                "PyObject_HEAD")
        if type.vtabslot_cname and not (type.base_type and type.base_type.vtabslot_cname):
            code.putln(
                "struct %s *%s;" % (
                    type.vtabstruct_cname,
                    type.vtabslot_cname))
        for attr in type.scope.var_entries:
917 918 919 920
            if attr.is_declared_generic:
                attr_type = py_object_type
            else:
                attr_type = attr.type
921 922
            code.putln(
                "%s;" %
923
                    attr_type.declaration_code(attr.cname))
924
        code.putln(footer)
925 926 927
        if type.objtypedef_cname is not None:
            # Only for exposing public typedef name.
            code.putln("typedef struct %s %s;" % (type.objstruct_cname, type.objtypedef_cname))
928

929
    def generate_c_class_declarations(self, env, code, definition):
930
        for entry in env.c_class_entries:
931
            if definition or entry.defined_in_pxd:
932
                code.putln("static PyTypeObject *%s = 0;" %
933
                    entry.type.typeptr_cname)
934

935
    def generate_cvariable_declarations(self, env, code, definition):
936 937
        if env.is_cython_builtin:
            return
938 939 940 941
        for entry in env.var_entries:
            if (entry.in_cinclude or entry.in_closure or
                (entry.visibility == 'private' and
                 not (entry.defined_in_pxd or entry.used))):
942
                continue
943 944 945 946 947 948 949 950 951 952

            storage_class = None
            dll_linkage = None
            cname = None
            init = None

            if entry.visibility == 'extern':
                storage_class = Naming.extern_c_macro
                dll_linkage = "DL_IMPORT"
            elif entry.visibility == 'public':
953
                storage_class = Naming.extern_c_macro
954 955 956 957 958 959
                if definition:
                    dll_linkage = "DL_EXPORT"
                else:
                    dll_linkage = "DL_IMPORT"
            elif entry.visibility == 'private':
                storage_class = "static"
960 961 962 963 964
                dll_linkage = None
                if entry.init is not None:
                    init =  entry.type.literal_code(entry.init)
            type = entry.type
            cname = entry.cname
965 966 967 968

            if entry.defined_in_pxd and not definition:
                storage_class = "static"
                dll_linkage = None
969
                type = CPtrType(type)
970 971 972 973 974 975 976 977 978 979 980 981 982 983
                cname = env.mangle(Naming.varptr_prefix, entry.name)
                init = 0

            if storage_class:
                code.put("%s " % storage_class)
            code.put(type.declaration_code(
                cname, dll_linkage = dll_linkage))
            if init is not None:
                code.put_safe(" = %s" % init)
            code.putln(";")
            if entry.cname != cname:
                code.putln("#define %s (*%s)" % (entry.cname, cname))

    def generate_cfunction_declarations(self, env, code, definition):
984
        for entry in env.cfunc_entries:
985
            if entry.used or (entry.visibility == 'public' or entry.api):
986
                generate_cfunction_declaration(entry, env, code, definition)
987

988 989
    def generate_variable_definitions(self, env, code):
        for entry in env.var_entries:
Vitja Makarov's avatar
Vitja Makarov committed
990
            if (not entry.in_cinclude and
991 992 993 994 995 996 997
                entry.visibility == "public"):
                code.put(entry.type.declaration_code(entry.cname))
                if entry.init is not None:
                    init =  entry.type.literal_code(entry.init)
                    code.put_safe(" = %s" % init)
                code.putln(";")

998 999 1000 1001 1002
    def generate_typeobj_definitions(self, env, code):
        full_module_name = env.qualified_name
        for entry in env.c_class_entries:
            #print "generate_typeobj_definitions:", entry.name
            #print "...visibility =", entry.visibility
Stefan Behnel's avatar
Stefan Behnel committed
1003
            if entry.visibility != 'extern':
1004 1005 1006 1007
                type = entry.type
                scope = type.scope
                if scope: # could be None if there was an error
                    self.generate_exttype_vtable(scope, code)
1008
                    self.generate_new_function(scope, code, entry)
1009
                    self.generate_dealloc_function(scope, code)
1010
                    if scope.needs_gc():
1011 1012
                        self.generate_traverse_function(scope, code, entry)
                        self.generate_clear_function(scope, code, entry)
1013 1014 1015 1016
                    if scope.defines_any(["__getitem__"]):
                        self.generate_getitem_int_function(scope, code)
                    if scope.defines_any(["__setitem__", "__delitem__"]):
                        self.generate_ass_subscript_function(scope, code)
1017 1018 1019 1020 1021
                    if scope.defines_any(["__getslice__", "__setslice__", "__delslice__"]):
                        warning(self.pos, "__getslice__, __setslice__, and __delslice__ are not supported by Python 3, use __getitem__, __setitem__, and __delitem__ instead", 1)
                        code.putln("#if PY_MAJOR_VERSION >= 3")
                        code.putln("#error __getslice__, __setslice__, and __delslice__ not supported in Python 3.")
                        code.putln("#endif")
1022 1023
                    if scope.defines_any(["__setslice__", "__delslice__"]):
                        self.generate_ass_slice_function(scope, code)
1024
                    if scope.defines_any(["__getattr__","__getattribute__"]):
1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035
                        self.generate_getattro_function(scope, code)
                    if scope.defines_any(["__setattr__", "__delattr__"]):
                        self.generate_setattro_function(scope, code)
                    if scope.defines_any(["__get__"]):
                        self.generate_descr_get_function(scope, code)
                    if scope.defines_any(["__set__", "__delete__"]):
                        self.generate_descr_set_function(scope, code)
                    self.generate_property_accessors(scope, code)
                    self.generate_method_table(scope, code)
                    self.generate_getset_table(scope, code)
                    self.generate_typeobj_definition(full_module_name, entry, code)
1036

1037 1038 1039 1040 1041 1042 1043
    def generate_exttype_vtable(self, scope, code):
        # Generate the definition of an extension type's vtable.
        type = scope.parent_type
        if type.vtable_cname:
            code.putln("static struct %s %s;" % (
                type.vtabstruct_cname,
                type.vtable_cname))
1044

1045 1046 1047 1048 1049 1050
    def generate_self_cast(self, scope, code):
        type = scope.parent_type
        code.putln(
            "%s = (%s)o;" % (
                type.declaration_code("p"),
                type.declaration_code("")))
1051

1052
    def generate_new_function(self, scope, code, cclass_entry):
1053 1054
        tp_slot = TypeSlots.ConstructorSlot("tp_new", '__new__')
        slot_func = scope.mangle_internal("tp_new")
1055 1056
        type = scope.parent_type
        base_type = type.base_type
1057

1058 1059
        have_entries, (py_attrs, py_buffers, memoryview_slices) = \
                        scope.get_refcounted_entries(include_weakref=True)
Robert Bradshaw's avatar
Robert Bradshaw committed
1060
        cpp_class_attrs = [entry for entry in scope.var_entries if entry.type.is_cpp_class]
1061

1062 1063 1064 1065 1066 1067 1068
        new_func_entry = scope.lookup_here("__new__")
        if base_type or (new_func_entry and new_func_entry.is_special
                         and not new_func_entry.trivial_signature):
            unused_marker = ''
        else:
            unused_marker = 'CYTHON_UNUSED '

1069 1070 1071 1072 1073 1074 1075
        if base_type:
            freelist_size = 0  # not currently supported
        else:
            freelist_size = scope.directives.get('freelist', 0)
        freelist_name = scope.mangle_internal(Naming.freelist_name)
        freecount_name = scope.mangle_internal(Naming.freecount_name)

1076 1077 1078
        decls = code.globalstate['decls']
        decls.putln("static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/" %
                    slot_func)
1079
        code.putln("")
1080 1081 1082 1083 1084 1085
        if freelist_size:
            code.putln("static %s[%d];" % (
                scope.parent_type.declaration_code(freelist_name),
                freelist_size))
            code.putln("static int %s = 0;" % freecount_name)
            code.putln("")
1086
        code.putln(
1087
            "static PyObject *%s(PyTypeObject *t, %sPyObject *a, %sPyObject *k) {"
1088 1089 1090
                % (slot_func, unused_marker, unused_marker))

        need_self_cast = type.vtabslot_cname or have_entries or cpp_class_attrs
1091
        if need_self_cast:
1092
            code.putln("%s;" % scope.parent_type.declaration_code("p"))
1093
        if base_type:
Robert Bradshaw's avatar
Robert Bradshaw committed
1094 1095
            tp_new = TypeSlots.get_base_slot_function(scope, tp_slot)
            if tp_new is None:
1096
                tp_new = "%s->tp_new" % base_type.typeptr_cname
1097
            code.putln("PyObject *o = %s(t, a, k);" % tp_new)
1098
        else:
1099 1100
            code.putln("PyObject *o;")
            if freelist_size:
1101 1102 1103
                code.globalstate.use_utility_code(
                    UtilityCode.load_cached("IncludeStringH", "StringTools.c"))
                obj_struct = type.declaration_code("", deref=True)
1104
                code.putln("if (likely((%s > 0) & (t->tp_basicsize == sizeof(%s)))) {" % (
1105
                    freecount_name, obj_struct))
1106 1107
                code.putln("o = (PyObject*)%s[--%s];" % (
                    freelist_name, freecount_name))
1108
                code.putln("memset(o, 0, sizeof(%s));" % obj_struct)
1109
                code.putln("PyObject_INIT(o, t);")
1110 1111 1112 1113
                if scope.needs_gc():
                    code.putln("PyObject_GC_Track(o);")
                code.putln("} else {")
            code.putln("o = (*t->tp_alloc)(t, 0);")
1114
        code.putln("if (unlikely(!o)) return 0;")
1115 1116
        if freelist_size and not base_type:
            code.putln('}')
1117
        if need_self_cast:
1118
            code.putln("p = %s;" % type.cast_code("o"))
1119
        #if need_self_cast:
Robert Bradshaw's avatar
Robert Bradshaw committed
1120
        #    self.generate_self_cast(scope, code)
1121
        if type.vtabslot_cname:
1122 1123 1124 1125 1126
            vtab_base_type = type
            while vtab_base_type.base_type and vtab_base_type.base_type.vtabstruct_cname:
                vtab_base_type = vtab_base_type.base_type
            if vtab_base_type is not type:
                struct_type_cast = "(struct %s*)" % vtab_base_type.vtabstruct_cname
1127 1128 1129
            else:
                struct_type_cast = ""
            code.putln("p->%s = %s%s;" % (
1130
                type.vtabslot_cname,
1131
                struct_type_cast, type.vtabptr_cname))
1132

Robert Bradshaw's avatar
Robert Bradshaw committed
1133 1134
        for entry in cpp_class_attrs:
            code.putln("new((void*)&(p->%s)) %s();" % 
1135
                       (entry.cname, entry.type.declaration_code("")))
1136

1137
        for entry in py_attrs:
1138 1139
            if scope.is_internal or entry.name == "__weakref__":
                # internal classes do not need None inits
1140
                code.putln("p->%s = 0;" % entry.cname)
1141
            else:
1142
                code.put_init_var_to_py_none(entry, "p->%s", nanny=False)
1143

1144
        for entry in memoryview_slices:
1145
            code.putln("p->%s.data = NULL;" % entry.cname)
1146
            code.putln("p->%s.memview = NULL;" % entry.cname)
1147 1148 1149 1150 1151 1152 1153

        for entry in py_buffers:
            code.putln("p->%s.obj = NULL;" % entry.cname)

        if cclass_entry.cname == '__pyx_memoryviewslice':
            code.putln("p->from_slice.memview = NULL;")

1154 1155
        if new_func_entry and new_func_entry.is_special:
            if new_func_entry.trivial_signature:
1156 1157 1158
                cinit_args = "o, %s, NULL" % Naming.empty_tuple
            else:
                cinit_args = "o, a, k"
1159
            code.putln(
1160
                "if (unlikely(%s(%s) < 0)) {" %
1161
                    (new_func_entry.func_cname, cinit_args))
1162
            code.put_decref_clear("o", py_object_type, nanny=False)
1163 1164 1165 1166 1167 1168
            code.putln(
                "}")
        code.putln(
            "return o;")
        code.putln(
            "}")
1169

1170
    def generate_dealloc_function(self, scope, code):
1171 1172
        tp_slot = TypeSlots.ConstructorSlot("tp_dealloc", '__dealloc__')
        slot_func = scope.mangle_internal("tp_dealloc")
1173
        base_type = scope.parent_type.base_type
1174 1175
        if tp_slot.slot_code(scope) != slot_func:
            return # never used
1176 1177

        slot_func_cname = scope.mangle_internal("tp_dealloc")
1178 1179
        code.putln("")
        code.putln(
1180
            "static void %s(PyObject *o) {" % slot_func_cname)
1181

1182
        weakref_slot = scope.lookup_here("__weakref__")
1183
        _, (py_attrs, _, memoryview_slices) = scope.get_refcounted_entries()
Robert Bradshaw's avatar
Robert Bradshaw committed
1184
        cpp_class_attrs = [entry for entry in scope.var_entries if entry.type.is_cpp_class]
1185

Robert Bradshaw's avatar
Robert Bradshaw committed
1186 1187 1188 1189
        if (py_attrs
            or cpp_class_attrs
            or memoryview_slices
            or weakref_slot in scope.var_entries):
1190
            self.generate_self_cast(scope, code)
1191 1192 1193 1194
        
        # We must mark ths object as (gc) untracked while tearing it down, lest
        # the garbage collection is invoked while running this destructor.
        if scope.needs_gc():
1195
            code.putln("PyObject_GC_UnTrack(o);")
1196 1197

        # call the user's __dealloc__
1198
        self.generate_usr_dealloc_call(scope, code)
1199
        if weakref_slot in scope.var_entries:
1200
            code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);")
1201

Robert Bradshaw's avatar
Robert Bradshaw committed
1202
        for entry in cpp_class_attrs:
1203 1204 1205 1206 1207
            split_cname = entry.type.cname.split('::')
            destructor_name = split_cname.pop()
            # Make sure the namespace delimiter was not in a template arg.
            while destructor_name.count('<') != destructor_name.count('>'):
                destructor_name = split_cname.pop() + '::' + destructor_name
Olivier Parcollet's avatar
Olivier Parcollet committed
1208
            destructor_name = destructor_name.split('<',1)[0]
1209 1210
            code.putln("p->%s.%s::~%s();" %
                (entry.cname, entry.type.declaration_code(""), destructor_name))
1211

1212
        for entry in py_attrs:
1213 1214
            code.put_xdecref_clear("p->%s" % entry.cname, entry.type, nanny=False,
                                   clear_before_decref=True)
1215 1216 1217 1218 1219

        for entry in memoryview_slices:
            code.put_xdecref_memoryviewslice("p->%s" % entry.cname,
                                             have_gil=True)

1220
        if base_type:
1221 1222 1223 1224 1225
            # The base class deallocator probably expects this to be tracked, so
            # undo the untracking above.
            if scope.needs_gc():
                code.putln("PyObject_GC_Track(o);")

Robert Bradshaw's avatar
Robert Bradshaw committed
1226
            tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot)
1227 1228
            if tp_dealloc is not None:
                code.putln("%s(o);" % tp_dealloc)
1229 1230
            elif base_type.is_builtin_type:
                code.putln("%s->tp_dealloc(o);" % base_type.typeptr_cname)
1231 1232 1233 1234 1235 1236 1237 1238 1239 1240
            else:
                # This is an externally defined type.  Calling through the
                # cimported base type pointer directly interacts badly with
                # the module cleanup, which may already have cleared it.
                # In that case, fall back to traversing the type hierarchy.
                base_cname = base_type.typeptr_cname
                code.putln("if (likely(%s)) %s->tp_dealloc(o); else __Pyx_call_next_tp_dealloc(o, %s);" % (
                    base_cname, base_cname, slot_func_cname))
                code.globalstate.use_utility_code(
                    UtilityCode.load_cached("CallNextTpDealloc", "ExtensionTypes.c"))
1241
        else:
1242 1243 1244 1245 1246 1247
            freelist_size = scope.directives.get('freelist', 0)
            if freelist_size:
                freelist_name = scope.mangle_internal(Naming.freelist_name)
                freecount_name = scope.mangle_internal(Naming.freecount_name)

                type = scope.parent_type
1248 1249
                code.putln("if ((%s < %d) & (Py_TYPE(o)->tp_basicsize == sizeof(%s))) {" % (
                    freecount_name, freelist_size, type.declaration_code("", deref=True)))
1250 1251 1252 1253 1254 1255
                code.putln("%s[%s++] = %s;" % (
                    freelist_name, freecount_name, type.cast_code("o")))
                code.putln("} else {")
            code.putln("(*Py_TYPE(o)->tp_free)(o);")
            if freelist_size:
                code.putln("}")
1256 1257
        code.putln(
            "}")
1258

1259 1260 1261 1262 1263 1264 1265 1266 1267 1268
    def generate_usr_dealloc_call(self, scope, code):
        entry = scope.lookup_here("__dealloc__")
        if entry:
            code.putln(
                "{")
            code.putln(
                    "PyObject *etype, *eval, *etb;")
            code.putln(
                    "PyErr_Fetch(&etype, &eval, &etb);")
            code.putln(
1269
                    "++Py_REFCNT(o);")
1270
            code.putln(
1271
                    "%s(o);" %
1272 1273 1274 1275
                        entry.func_cname)
            code.putln(
                    "if (PyErr_Occurred()) PyErr_WriteUnraisable(o);")
            code.putln(
1276
                    "--Py_REFCNT(o);")
1277 1278 1279 1280
            code.putln(
                    "PyErr_Restore(etype, eval, etb);")
            code.putln(
                "}")
1281

1282
    def generate_traverse_function(self, scope, code, cclass_entry):
1283 1284
        tp_slot = TypeSlots.GCDependentSlot("tp_traverse")
        slot_func = scope.mangle_internal("tp_traverse")
1285
        base_type = scope.parent_type.base_type
1286 1287
        if tp_slot.slot_code(scope) != slot_func:
            return # never used
1288 1289 1290
        code.putln("")
        code.putln(
            "static int %s(PyObject *o, visitproc v, void *a) {"
1291
                % slot_func)
1292

1293 1294
        have_entries, (py_attrs, py_buffers,
                       memoryview_slices) = scope.get_refcounted_entries()
1295

1296
        if base_type or py_attrs:
1297
            code.putln("int e;")
1298 1299

        if py_attrs or py_buffers:
1300
            self.generate_self_cast(scope, code)
1301

1302
        if base_type:
1303
            # want to call it explicitly if possible so inlining can be performed
Robert Bradshaw's avatar
Robert Bradshaw committed
1304 1305 1306
            static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
            if static_call:
                code.putln("e = %s(o, v, a); if (e) return e;" % static_call)
1307 1308 1309 1310
            elif base_type.is_builtin_type:
                base_cname = base_type.typeptr_cname
                code.putln("if (!%s->tp_traverse); else { e = %s->tp_traverse(o,v,a); if (e) return e; }" % (
                    base_cname, base_cname))
1311
            else:
1312 1313 1314 1315 1316 1317 1318 1319 1320
                # This is an externally defined type.  Calling through the
                # cimported base type pointer directly interacts badly with
                # the module cleanup, which may already have cleared it.
                # In that case, fall back to traversing the type hierarchy.
                base_cname = base_type.typeptr_cname
                code.putln("e = ((likely(%s)) ? ((%s->tp_traverse) ? %s->tp_traverse(o, v, a) : 0) : __Pyx_call_next_tp_traverse(o, v, a, %s)); if (e) return e;" % (
                    base_cname, base_cname, base_cname, slot_func))
                code.globalstate.use_utility_code(
                    UtilityCode.load_cached("CallNextTpTraverse", "ExtensionTypes.c"))
1321

1322 1323 1324 1325 1326 1327 1328 1329
        for entry in py_attrs:
            var_code = "p->%s" % entry.cname
            code.putln(
                    "if (%s) {"
                        % var_code)
            if entry.type.is_extension_type:
                var_code = "((PyObject*)%s)" % var_code
            code.putln(
1330
                        "e = (*v)(%s, a); if (e) return e;"
1331 1332 1333
                            % var_code)
            code.putln(
                    "}")
1334

Stefan Behnel's avatar
Stefan Behnel committed
1335 1336
        # Traverse buffer exporting objects.
        # Note: not traversing memoryview attributes of memoryview slices!
1337 1338
        # When triggered by the GC, it would cause multiple visits (gc_refs
        # subtractions which is not matched by its reference count!)
Stefan Behnel's avatar
Stefan Behnel committed
1339 1340
        for entry in py_buffers:
            cname = entry.cname + ".obj"
1341 1342
            code.putln("if (p->%s) {" % cname)
            code.putln(    "e = (*v)(p->%s, a); if (e) return e;" % cname)
1343 1344
            code.putln("}")

1345 1346 1347 1348
        code.putln(
                "return 0;")
        code.putln(
            "}")
1349

1350
    def generate_clear_function(self, scope, code, cclass_entry):
1351 1352
        tp_slot = TypeSlots.GCDependentSlot("tp_clear")
        slot_func = scope.mangle_internal("tp_clear")
1353
        base_type = scope.parent_type.base_type
1354 1355
        if tp_slot.slot_code(scope) != slot_func:
            return # never used
1356

1357
        py_attrs = []
1358
        py_buffers = []
1359
        for entry in scope.var_entries:
1360
            if entry.type.is_pyobject and entry.name != "__weakref__":
1361
                py_attrs.append(entry)
1362 1363 1364
            if entry.type == PyrexTypes.c_py_buffer_type:
                py_buffers.append(entry)

1365 1366 1367 1368 1369 1370 1371 1372
        if py_attrs or py_buffers or base_type:
            unused = ''
        else:
            unused = 'CYTHON_UNUSED '

        code.putln("")
        code.putln("static int %s(%sPyObject *o) {" % (slot_func, unused))

1373
        if py_attrs or py_buffers:
1374
            self.generate_self_cast(scope, code)
1375
            code.putln("PyObject* tmp;")
1376

1377
        if base_type:
1378
            # want to call it explicitly if possible so inlining can be performed
Robert Bradshaw's avatar
Robert Bradshaw committed
1379 1380 1381
            static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
            if static_call:
                code.putln("%s(o);" % static_call)
1382 1383 1384 1385
            elif base_type.is_builtin_type:
                base_cname = base_type.typeptr_cname
                code.putln("if (!%s->tp_clear); else %s->tp_clear(o);" % (
                    base_cname, base_cname))
1386
            else:
1387 1388 1389 1390 1391 1392 1393 1394 1395
                # This is an externally defined type.  Calling through the
                # cimported base type pointer directly interacts badly with
                # the module cleanup, which may already have cleared it.
                # In that case, fall back to traversing the type hierarchy.
                base_cname = base_type.typeptr_cname
                code.putln("if (likely(%s)) { if (%s->tp_clear) %s->tp_clear(o); } else __Pyx_call_next_tp_clear(o, %s);" % (
                    base_cname, base_cname, base_cname, slot_func))
                code.globalstate.use_utility_code(
                    UtilityCode.load_cached("CallNextTpClear", "ExtensionTypes.c"))
1396

1397 1398
        for entry in py_attrs:
            name = "p->%s" % entry.cname
1399
            code.putln("tmp = ((PyObject*)%s);" % name)
1400 1401 1402 1403
            if entry.is_declared_generic:
                code.put_init_to_py_none(name, py_object_type, nanny=False)
            else:
                code.put_init_to_py_none(name, entry.type, nanny=False)
1404
            code.putln("Py_XDECREF(tmp);")
1405 1406

        for entry in py_buffers:
1407
            # Note: shouldn't this call __Pyx_ReleaseBuffer ??
1408 1409 1410 1411 1412
            code.putln("Py_CLEAR(p->%s.obj);" % entry.cname)

        if cclass_entry.cname == '__pyx_memoryviewslice':
            code.putln("__PYX_XDEC_MEMVIEW(&p->from_slice, 1);")

1413 1414 1415 1416
        code.putln(
            "return 0;")
        code.putln(
            "}")
1417

1418 1419 1420 1421 1422
    def generate_getitem_int_function(self, scope, code):
        # This function is put into the sq_item slot when
        # a __getitem__ method is present. It converts its
        # argument to a Python integer and calls mp_subscript.
        code.putln(
1423
            "static PyObject *%s(PyObject *o, Py_ssize_t i) {" %
1424 1425 1426 1427
                scope.mangle_internal("sq_item"))
        code.putln(
                "PyObject *r;")
        code.putln(
1428
                "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;")
1429
        code.putln(
1430
                "r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);")
1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460
        code.putln(
                "Py_DECREF(x);")
        code.putln(
                "return r;")
        code.putln(
            "}")

    def generate_ass_subscript_function(self, scope, code):
        # Setting and deleting an item are both done through
        # the ass_subscript method, so we dispatch to user's __setitem__
        # or __delitem__, or raise an exception.
        base_type = scope.parent_type.base_type
        set_entry = scope.lookup_here("__setitem__")
        del_entry = scope.lookup_here("__delitem__")
        code.putln("")
        code.putln(
            "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
                scope.mangle_internal("mp_ass_subscript"))
        code.putln(
                "if (v) {")
        if set_entry:
            code.putln(
                    "return %s(o, i, v);" %
                        set_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
            code.putln(
                    "PyErr_Format(PyExc_NotImplementedError,")
            code.putln(
1461
                    '  "Subscript assignment not supported by %s", Py_TYPE(o)->tp_name);')
1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
                "else {")
        if del_entry:
            code.putln(
                    "return %s(o, i);" %
                        del_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
            code.putln(
                    "PyErr_Format(PyExc_NotImplementedError,")
            code.putln(
1478
                    '  "Subscript deletion not supported by %s", Py_TYPE(o)->tp_name);')
1479 1480 1481 1482 1483 1484
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
            "}")
1485

1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513
    def generate_guarded_basetype_call(
            self, base_type, substructure, slot, args, code):
        if base_type:
            base_tpname = base_type.typeptr_cname
            if substructure:
                code.putln(
                    "if (%s->%s && %s->%s->%s)" % (
                        base_tpname, substructure, base_tpname, substructure, slot))
                code.putln(
                    "  return %s->%s->%s(%s);" % (
                        base_tpname, substructure, slot, args))
            else:
                code.putln(
                    "if (%s->%s)" % (
                        base_tpname, slot))
                code.putln(
                    "  return %s->%s(%s);" % (
                        base_tpname, slot, args))

    def generate_ass_slice_function(self, scope, code):
        # Setting and deleting a slice are both done through
        # the ass_slice method, so we dispatch to user's __setslice__
        # or __delslice__, or raise an exception.
        base_type = scope.parent_type.base_type
        set_entry = scope.lookup_here("__setslice__")
        del_entry = scope.lookup_here("__delslice__")
        code.putln("")
        code.putln(
1514
            "static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" %
1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527
                scope.mangle_internal("sq_ass_slice"))
        code.putln(
                "if (v) {")
        if set_entry:
            code.putln(
                    "return %s(o, i, j, v);" %
                        set_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
            code.putln(
                    "PyErr_Format(PyExc_NotImplementedError,")
            code.putln(
1528
                    '  "2-element slice assignment not supported by %s", Py_TYPE(o)->tp_name);')
1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
                "else {")
        if del_entry:
            code.putln(
                    "return %s(o, i, j);" %
                        del_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
            code.putln(
                    "PyErr_Format(PyExc_NotImplementedError,")
            code.putln(
1545
                    '  "2-element slice deletion not supported by %s", Py_TYPE(o)->tp_name);')
1546 1547 1548 1549 1550 1551 1552 1553
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
            "}")

    def generate_getattro_function(self, scope, code):
1554 1555 1556
        # First try to get the attribute using __getattribute__, if defined, or
        # PyObject_GenericGetAttr.
        #
1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571
        # If that raises an AttributeError, call the __getattr__ if defined.
        #
        # In both cases, defined can be in this class, or any base class.
        def lookup_here_or_base(n,type=None):
            # Recursive lookup
            if type is None:
                type = scope.parent_type
            r = type.scope.lookup_here(n)
            if r is None and \
               type.base_type is not None:
                return lookup_here_or_base(n,type.base_type)
            else:
                return r
        getattr_entry = lookup_here_or_base("__getattr__")
        getattribute_entry = lookup_here_or_base("__getattribute__")
1572 1573 1574 1575
        code.putln("")
        code.putln(
            "static PyObject *%s(PyObject *o, PyObject *n) {"
                % scope.mangle_internal("tp_getattro"))
1576 1577 1578 1579 1580 1581
        if getattribute_entry is not None:
            code.putln(
                "PyObject *v = %s(o, n);" %
                    getattribute_entry.func_cname)
        else:
            code.putln(
1582
                "PyObject *v = PyObject_GenericGetAttr(o, n);")
1583 1584
        if getattr_entry is not None:
            code.putln(
1585
                "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
1586 1587 1588 1589 1590 1591
            code.putln(
                "PyErr_Clear();")
            code.putln(
                "v = %s(o, n);" %
                    getattr_entry.func_cname)
            code.putln(
1592 1593
                "}")
        code.putln(
1594
            "return v;")
1595 1596
        code.putln(
            "}")
1597

1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636
    def generate_setattro_function(self, scope, code):
        # Setting and deleting an attribute are both done through
        # the setattro method, so we dispatch to user's __setattr__
        # or __delattr__ or fall back on PyObject_GenericSetAttr.
        base_type = scope.parent_type.base_type
        set_entry = scope.lookup_here("__setattr__")
        del_entry = scope.lookup_here("__delattr__")
        code.putln("")
        code.putln(
            "static int %s(PyObject *o, PyObject *n, PyObject *v) {" %
                scope.mangle_internal("tp_setattro"))
        code.putln(
                "if (v) {")
        if set_entry:
            code.putln(
                    "return %s(o, n, v);" %
                        set_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, None, "tp_setattro", "o, n, v", code)
            code.putln(
                    "return PyObject_GenericSetAttr(o, n, v);")
        code.putln(
                "}")
        code.putln(
                "else {")
        if del_entry:
            code.putln(
                    "return %s(o, n);" %
                        del_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, None, "tp_setattro", "o, n, v", code)
            code.putln(
                    "return PyObject_GenericSetAttr(o, n, 0);")
        code.putln(
                "}")
        code.putln(
            "}")
1637

1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664
    def generate_descr_get_function(self, scope, code):
        # The __get__ function of a descriptor object can be
        # called with NULL for the second or third arguments
        # under some circumstances, so we replace them with
        # None in that case.
        user_get_entry = scope.lookup_here("__get__")
        code.putln("")
        code.putln(
            "static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" %
                scope.mangle_internal("tp_descr_get"))
        code.putln(
            "PyObject *r = 0;")
        code.putln(
            "if (!i) i = Py_None;")
        code.putln(
            "if (!c) c = Py_None;")
        #code.put_incref("i", py_object_type)
        #code.put_incref("c", py_object_type)
        code.putln(
            "r = %s(o, i, c);" %
                user_get_entry.func_cname)
        #code.put_decref("i", py_object_type)
        #code.put_decref("c", py_object_type)
        code.putln(
            "return r;")
        code.putln(
            "}")
1665

1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705
    def generate_descr_set_function(self, scope, code):
        # Setting and deleting are both done through the __set__
        # method of a descriptor, so we dispatch to user's __set__
        # or __delete__ or raise an exception.
        base_type = scope.parent_type.base_type
        user_set_entry = scope.lookup_here("__set__")
        user_del_entry = scope.lookup_here("__delete__")
        code.putln("")
        code.putln(
            "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
                scope.mangle_internal("tp_descr_set"))
        code.putln(
                "if (v) {")
        if user_set_entry:
            code.putln(
                    "return %s(o, i, v);" %
                        user_set_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, None, "tp_descr_set", "o, i, v", code)
            code.putln(
                    'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
                "else {")
        if user_del_entry:
            code.putln(
                    "return %s(o, i);" %
                        user_del_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, None, "tp_descr_set", "o, i, v", code)
            code.putln(
                    'PyErr_SetString(PyExc_NotImplementedError, "__delete__");')
            code.putln(
                    "return -1;")
        code.putln(
1706
                "}")
1707 1708
        code.putln(
            "}")
1709

1710 1711 1712 1713 1714 1715 1716
    def generate_property_accessors(self, cclass_scope, code):
        for entry in cclass_scope.property_entries:
            property_scope = entry.scope
            if property_scope.defines_any(["__get__"]):
                self.generate_property_get_function(entry, code)
            if property_scope.defines_any(["__set__", "__del__"]):
                self.generate_property_set_function(entry, code)
1717

1718 1719 1720 1721 1722 1723 1724
    def generate_property_get_function(self, property_entry, code):
        property_scope = property_entry.scope
        property_entry.getter_cname = property_scope.parent_scope.mangle(
            Naming.prop_get_prefix, property_entry.name)
        get_entry = property_scope.lookup_here("__get__")
        code.putln("")
        code.putln(
1725
            "static PyObject *%s(PyObject *o, CYTHON_UNUSED void *x) {" %
1726 1727 1728 1729 1730 1731
                property_entry.getter_cname)
        code.putln(
                "return %s(o);" %
                    get_entry.func_cname)
        code.putln(
            "}")
1732

1733 1734 1735 1736 1737 1738 1739 1740
    def generate_property_set_function(self, property_entry, code):
        property_scope = property_entry.scope
        property_entry.setter_cname = property_scope.parent_scope.mangle(
            Naming.prop_set_prefix, property_entry.name)
        set_entry = property_scope.lookup_here("__set__")
        del_entry = property_scope.lookup_here("__del__")
        code.putln("")
        code.putln(
1741
            "static int %s(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {" %
1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780
                property_entry.setter_cname)
        code.putln(
                "if (v) {")
        if set_entry:
            code.putln(
                    "return %s(o, v);" %
                        set_entry.func_cname)
        else:
            code.putln(
                    'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
                "else {")
        if del_entry:
            code.putln(
                    "return %s(o);" %
                        del_entry.func_cname)
        else:
            code.putln(
                    'PyErr_SetString(PyExc_NotImplementedError, "__del__");')
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
            "}")

    def generate_typeobj_definition(self, modname, entry, code):
        type = entry.type
        scope = type.scope
        for suite in TypeSlots.substructures:
            suite.generate_substructure(scope, code)
        code.putln("")
        if entry.visibility == 'public':
            header = "DL_EXPORT(PyTypeObject) %s = {"
        else:
1781
            header = "static PyTypeObject %s = {"
1782 1783 1784
        #code.putln(header % scope.parent_type.typeobj_cname)
        code.putln(header % type.typeobj_cname)
        code.putln(
1785
            "PyVarObject_HEAD_INIT(0, 0)")
1786
        code.putln(
1787
            '__Pyx_NAMESTR("%s.%s"), /*tp_name*/' % (
1788
                self.full_module_name, scope.class_name))
1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801
        if type.typedef_flag:
            objstruct = type.objstruct_cname
        else:
            objstruct = "struct %s" % type.objstruct_cname
        code.putln(
            "sizeof(%s), /*tp_basicsize*/" %
                objstruct)
        code.putln(
            "0, /*tp_itemsize*/")
        for slot in TypeSlots.slot_table:
            slot.generate(scope, code)
        code.putln(
            "};")
1802

1803 1804 1805
    def generate_method_table(self, env, code):
        code.putln("")
        code.putln(
1806
            "static PyMethodDef %s[] = {" %
1807 1808
                env.method_table_cname)
        for entry in env.pyfunc_entries:
1809 1810
            if not entry.fused_cfunction:
                code.put_pymethoddef(entry, ",")
1811 1812 1813 1814
        code.putln(
                "{0, 0, 0, 0}")
        code.putln(
            "};")
1815

1816 1817 1818 1819 1820 1821 1822
    def generate_getset_table(self, env, code):
        if env.property_entries:
            code.putln("")
            code.putln(
                "static struct PyGetSetDef %s[] = {" %
                    env.getset_table_cname)
            for entry in env.property_entries:
1823 1824 1825 1826
                if entry.doc:
                    doc_code = "__Pyx_DOCSTR(%s)" % code.get_string_const(entry.doc)
                else:
                    doc_code = "0"
1827
                code.putln(
1828
                    '{(char *)"%s", %s, %s, %s, 0},' % (
1829 1830 1831
                        entry.name,
                        entry.getter_cname or "0",
                        entry.setter_cname or "0",
1832
                        doc_code))
1833 1834 1835 1836
            code.putln(
                    "{0, 0, 0, 0, 0}")
            code.putln(
                "};")
1837

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1838
    def generate_import_star(self, env, code):
1839
        env.use_utility_code(streq_utility_code)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1840
        code.putln()
1841
        code.putln("static char* %s_type_names[] = {" % Naming.import_star)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1842 1843 1844 1845 1846 1847
        for name, entry in env.entries.items():
            if entry.is_type:
                code.putln('"%s",' % name)
        code.putln("0")
        code.putln("};")
        code.putln()
1848
        code.enter_cfunc_scope() # as we need labels
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1849 1850 1851
        code.putln("static int %s(PyObject *o, PyObject* py_name, char *name) {" % Naming.import_star_set)
        code.putln("char** type_name = %s_type_names;" % Naming.import_star)
        code.putln("while (*type_name) {")
1852
        code.putln("if (__Pyx_StrEq(name, *type_name)) {")
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1853 1854 1855 1856 1857 1858 1859 1860 1861
        code.putln('PyErr_Format(PyExc_TypeError, "Cannot overwrite C type %s", name);')
        code.putln('goto bad;')
        code.putln("}")
        code.putln("type_name++;")
        code.putln("}")
        old_error_label = code.new_error_label()
        code.putln("if (0);") # so the first one can be "else if"
        for name, entry in env.entries.items():
            if entry.is_cglobal and entry.used:
1862
                code.putln('else if (__Pyx_StrEq(name, "%s")) {' % name)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1863 1864 1865 1866 1867
                if entry.type.is_pyobject:
                    if entry.type.is_extension_type or entry.type.is_builtin_type:
                        code.putln("if (!(%s)) %s;" % (
                            entry.type.type_test_code("o"),
                            code.error_goto(entry.pos)))
1868 1869
                    code.putln("Py_INCREF(o);")
                    code.put_decref(entry.cname, entry.type, nanny=False)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1870
                    code.putln("%s = %s;" % (
1871
                        entry.cname,
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1872 1873 1874 1875
                        PyrexTypes.typecast(entry.type, py_object_type, "o")))
                elif entry.type.from_py_function:
                    rhs = "%s(o)" % entry.type.from_py_function
                    if entry.type.is_enum:
1876
                        rhs = PyrexTypes.typecast(entry.type, PyrexTypes.c_long_type, rhs)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889
                    code.putln("%s = %s; if (%s) %s;" % (
                        entry.cname,
                        rhs,
                        entry.type.error_condition(entry.cname),
                        code.error_goto(entry.pos)))
                else:
                    code.putln('PyErr_Format(PyExc_TypeError, "Cannot convert Python object %s to %s");' % (name, entry.type))
                    code.putln(code.error_goto(entry.pos))
                code.putln("}")
        code.putln("else {")
        code.putln("if (PyObject_SetAttr(%s, py_name, o) < 0) goto bad;" % Naming.module_cname)
        code.putln("}")
        code.putln("return 0;")
1890 1891 1892
        if code.label_used(code.error_label):
            code.put_label(code.error_label)
            # This helps locate the offending name.
1893
            code.put_add_traceback(self.full_module_name)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1894 1895 1896 1897 1898
        code.error_label = old_error_label
        code.putln("bad:")
        code.putln("return -1;")
        code.putln("}")
        code.putln(import_star_utility_code)
1899
        code.exit_cfunc_scope() # done with labels
1900 1901

    def generate_module_init_func(self, imported_modules, env, code):
1902
        code.enter_cfunc_scope()
1903
        code.putln("")
1904 1905 1906 1907 1908 1909 1910 1911 1912 1913
        header2 = "PyMODINIT_FUNC init%s(void)" % env.module_name
        header3 = "PyMODINIT_FUNC PyInit_%s(void)" % env.module_name
        code.putln("#if PY_MAJOR_VERSION < 3")
        code.putln("%s; /*proto*/" % header2)
        code.putln(header2)
        code.putln("#else")
        code.putln("%s; /*proto*/" % header3)
        code.putln(header3)
        code.putln("#endif")
        code.putln("{")
1914
        tempdecl_code = code.insertion_point()
Robert Bradshaw's avatar
Robert Bradshaw committed
1915

1916
        code.put_declare_refcount_context()
1917 1918 1919
        code.putln("#if CYTHON_REFNANNY")
        code.putln("__Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"refnanny\");")
        code.putln("if (!__Pyx_RefNanny) {")
1920
        code.putln("  PyErr_Clear();")
1921 1922 1923
        code.putln("  __Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"Cython.Runtime.refnanny\");")
        code.putln("  if (!__Pyx_RefNanny)")
        code.putln("      Py_FatalError(\"failed to import 'refnanny' module\");")
1924
        code.putln("}")
1925
        code.putln("#endif")
1926
        code.put_setup_refcount_context(header3)
1927

1928
        env.use_utility_code(UtilityCode.load("CheckBinaryVersion", "ModuleSetupCode.c"))
1929
        code.putln("if ( __Pyx_check_binary_version() < 0) %s" % code.error_goto(self.pos))
1930

1931 1932
        code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos)))
        code.putln("%s = PyBytes_FromStringAndSize(\"\", 0); %s" % (Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos)))
1933

1934 1935
        code.putln("#ifdef __Pyx_CyFunction_USED")
        code.putln("if (__Pyx_CyFunction_init() < 0) %s" % code.error_goto(self.pos))
Robert Bradshaw's avatar
Robert Bradshaw committed
1936
        code.putln("#endif")
1937

1938 1939
        code.putln("#ifdef __Pyx_FusedFunction_USED")
        code.putln("if (__pyx_FusedFunction_init() < 0) %s" % code.error_goto(self.pos))
Robert Bradshaw's avatar
Robert Bradshaw committed
1940
        code.putln("#endif")
1941

1942 1943 1944 1945
        code.putln("#ifdef __Pyx_Generator_USED")
        code.putln("if (__pyx_Generator_init() < 0) %s" % code.error_goto(self.pos))
        code.putln("#endif")

1946
        code.putln("/*--- Library function declarations ---*/")
1947
        env.generate_library_function_declarations(code)
1948

1949 1950
        code.putln("/*--- Threads initialization code ---*/")
        code.putln("#if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS")
1951
        code.putln("#ifdef WITH_THREAD /* Python build with threading support? */")
1952 1953 1954 1955
        code.putln("PyEval_InitThreads();")
        code.putln("#endif")
        code.putln("#endif")

1956
        code.putln("/*--- Module creation code ---*/")
1957
        self.generate_module_creation_code(env, code)
1958

1959 1960 1961
        code.putln("/*--- Initialize various global constants etc. ---*/")
        code.putln(code.error_goto_if_neg("__Pyx_InitGlobals()", self.pos))

1962
        code.putln("#if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)")
Robert Bradshaw's avatar
Robert Bradshaw committed
1963
        code.putln("if (__Pyx_init_sys_getdefaultencoding_params() < 0) %s" % code.error_goto(self.pos))
1964 1965
        code.putln("#endif")

1966 1967
        __main__name = code.globalstate.get_py_string_const(
            EncodedString("__main__"), identifier=True)
1968 1969 1970 1971
        code.putln("if (%s%s) {" % (Naming.module_is_main, self.full_module_name.replace('.', '__')))
        code.putln(
            'if (__Pyx_SetAttrString(%s, "__name__", %s) < 0) %s;' % (
                env.module_cname,
1972
                __main__name.cname,
1973 1974
                code.error_goto(self.pos)))
        code.putln("}")
1975

1976
        self.generate_module_path_setup(env, code)
1977

Robert Bradshaw's avatar
Robert Bradshaw committed
1978 1979
        if Options.cache_builtins:
            code.putln("/*--- Builtin init code ---*/")
1980 1981 1982 1983
            code.putln(code.error_goto_if_neg("__Pyx_InitCachedBuiltins()", self.pos))

        code.putln("/*--- Constants init code ---*/")
        code.putln(code.error_goto_if_neg("__Pyx_InitCachedConstants()", self.pos))
1984

1985
        code.putln("/*--- Global init code ---*/")
1986
        self.generate_global_init_code(env, code)
Gary Furnish's avatar
Gary Furnish committed
1987

1988 1989 1990
        code.putln("/*--- Variable export code ---*/")
        self.generate_c_variable_export_code(env, code)

1991
        code.putln("/*--- Function export code ---*/")
1992 1993
        self.generate_c_function_export_code(env, code)

1994
        code.putln("/*--- Type init code ---*/")
1995
        self.generate_type_init_code(env, code)
1996

1997
        code.putln("/*--- Type import code ---*/")
1998 1999 2000
        for module in imported_modules:
            self.generate_type_import_code_for_module(module, env, code)

2001 2002 2003 2004
        code.putln("/*--- Variable import code ---*/")
        for module in imported_modules:
            self.generate_c_variable_import_code_for_module(module, env, code)

Gary Furnish's avatar
Gary Furnish committed
2005 2006
        code.putln("/*--- Function import code ---*/")
        for module in imported_modules:
2007
            self.specialize_fused_types(module)
Gary Furnish's avatar
Gary Furnish committed
2008 2009
            self.generate_c_function_import_code_for_module(module, env, code)

2010
        code.putln("/*--- Execution code ---*/")
Robert Bradshaw's avatar
Robert Bradshaw committed
2011
        code.mark_pos(None)
2012

2013
        self.body.generate_execution_code(code)
2014

2015
        if Options.generate_cleanup_code:
2016 2017
            code.globalstate.use_utility_code(
                UtilityCode.load_cached("RegisterModuleCleanup", "ModuleSetupCode.c"))
2018
            code.putln("if (__Pyx_RegisterCleanup()) %s;" % code.error_goto(self.pos))
2019

2020
        code.put_goto(code.return_label)
2021
        code.put_label(code.error_label)
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
2022 2023
        for cname, type in code.funcstate.all_managed_temps():
            code.put_xdecref(cname, type)
2024
        code.putln('if (%s) {' % env.module_cname)
2025
        code.put_add_traceback("init %s" % env.qualified_name)
2026
        env.use_utility_code(Nodes.traceback_utility_code)
2027
        code.put_decref_clear(env.module_cname, py_object_type, nanny=False)
2028 2029 2030
        code.putln('} else if (!PyErr_Occurred()) {')
        code.putln('PyErr_SetString(PyExc_ImportError, "init %s");' % env.qualified_name)
        code.putln('}')
2031
        code.put_label(code.return_label)
2032 2033 2034

        code.put_finish_refcount_context()

2035 2036 2037
        code.putln("#if PY_MAJOR_VERSION < 3")
        code.putln("return;")
        code.putln("#else")
2038
        code.putln("return %s;" % env.module_cname)
2039
        code.putln("#endif")
2040
        code.putln('}')
2041

2042
        tempdecl_code.put_temp_declarations(code.funcstate)
2043

2044
        code.exit_cfunc_scope()
2045

2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058
    def generate_module_path_setup(self, env, code):
        if not env.directives['set_initial_path']:
            return
        module_path = env.directives['set_initial_path']
        if module_path == 'SOURCEFILE':
            module_path = self.pos[0].filename
            if not module_path:
                return
        code.putln('if (__Pyx_SetAttrString(%s, "__file__", %s) < 0) %s;' % (
            env.module_cname,
            code.globalstate.get_py_string_const(
                EncodedString(decode_filename(module_path))).cname,
            code.error_goto(self.pos)))
Stefan Behnel's avatar
Stefan Behnel committed
2059
        if env.is_package:
2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074
            # compiling a package => set __path__ as well
            temp = code.funcstate.allocate_temp(py_object_type, True)
            code.putln('%s = Py_BuildValue("[O]", %s); %s' % (
                temp,
                code.globalstate.get_py_string_const(
                    EncodedString(decode_filename(os.path.dirname(module_path)))).cname,
                code.error_goto_if_null(temp, self.pos)))
            code.put_gotref(temp)
            code.putln('if (__Pyx_SetAttrString(%s, "__path__", %s) < 0) %s;' % (
                env.module_cname,
                temp,
                code.error_goto(self.pos)))
            code.put_decref_clear(temp, py_object_type)
            code.funcstate.release_temp(temp)

2075 2076 2077
    def generate_module_cleanup_func(self, env, code):
        if not Options.generate_cleanup_code:
            return
2078

2079
        code.putln('static void %s(CYTHON_UNUSED PyObject *self) {' %
2080
                   Naming.cleanup_cname)
2081 2082
        if Options.generate_cleanup_code >= 2:
            code.putln("/*--- Global cleanup code ---*/")
2083 2084 2085
            rev_entries = list(env.var_entries)
            rev_entries.reverse()
            for entry in rev_entries:
2086
                if entry.visibility != 'extern':
2087
                    if entry.type.is_pyobject and entry.used:
2088 2089 2090 2091
                        code.put_xdecref_clear(
                            entry.cname, entry.type,
                            clear_before_decref=True,
                            nanny=False)
2092
        code.putln("__Pyx_CleanupGlobals();")
2093 2094
        if Options.generate_cleanup_code >= 3:
            code.putln("/*--- Type import cleanup code ---*/")
2095 2096 2097 2098 2099
            for type in env.types_imported:
                code.put_xdecref_clear(
                    type.typeptr_cname, type,
                    clear_before_decref=True,
                    nanny=False)
2100 2101
        if Options.cache_builtins:
            code.putln("/*--- Builtin cleanup code ---*/")
2102
            for entry in env.cached_builtins:
2103 2104 2105 2106
                code.put_xdecref_clear(
                    entry.cname, PyrexTypes.py_object_type,
                    clear_before_decref=True,
                    nanny=False)
2107
        code.putln("/*--- Intern cleanup code ---*/")
2108 2109
        code.put_decref_clear(Naming.empty_tuple,
                              PyrexTypes.py_object_type,
2110
                              clear_before_decref=True,
2111
                              nanny=False)
2112 2113
        for entry in env.c_class_entries:
            cclass_type = entry.type
2114
            if cclass_type.is_external or cclass_type.base_type:
2115 2116 2117 2118 2119 2120 2121 2122 2123 2124
                continue
            if cclass_type.scope.directives.get('freelist', 0):
                scope = cclass_type.scope
                freelist_name = scope.mangle_internal(Naming.freelist_name)
                freecount_name = scope.mangle_internal(Naming.freecount_name)
                code.putln("while (%s > 0) {" % freecount_name)
                code.putln("PyObject* o = (PyObject*)%s[--%s];" % (
                    freelist_name, freecount_name))
                code.putln("(*Py_TYPE(o)->tp_free)(o);")
                code.putln("}")
2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137
#        for entry in env.pynum_entries:
#            code.put_decref_clear(entry.cname,
#                                  PyrexTypes.py_object_type,
#                                  nanny=False)
#        for entry in env.all_pystring_entries:
#            if entry.is_interned:
#                code.put_decref_clear(entry.pystring_cname,
#                                      PyrexTypes.py_object_type,
#                                      nanny=False)
#        for entry in env.default_entries:
#            if entry.type.is_pyobject and entry.used:
#                code.putln("Py_DECREF(%s); %s = 0;" % (
#                    code.entry_as_pyobject(entry), entry.cname))
2138 2139 2140
        code.putln('#if CYTHON_COMPILING_IN_PYPY')
        code.putln('Py_CLEAR(%s);' % Naming.builtins_cname)
        code.putln('#endif')
2141

2142
    def generate_main_method(self, env, code):
2143
        module_is_main = "%s%s" % (Naming.module_is_main, self.full_module_name.replace('.', '__'))
2144 2145 2146 2147 2148 2149 2150 2151 2152 2153
        if Options.embed == "main":
            wmain = "wmain"
        else:
            wmain = Options.embed
        code.globalstate.use_utility_code(
            main_method.specialize(
                module_name = env.module_name,
                module_is_main = module_is_main,
                main_method = Options.embed,
                wmain_method = wmain))
2154

2155 2156
    def generate_pymoduledef_struct(self, env, code):
        if env.doc:
2157
            doc = "__Pyx_DOCSTR(%s)" % code.get_string_const(env.doc)
2158 2159
        else:
            doc = "0"
2160
        if Options.generate_cleanup_code:
Stefan Behnel's avatar
Stefan Behnel committed
2161
            cleanup_func = "(freefunc)%s" % Naming.cleanup_cname
2162 2163
        else:
            cleanup_func = 'NULL'
2164 2165 2166

        code.putln("")
        code.putln("#if PY_MAJOR_VERSION >= 3")
2167
        code.putln("static struct PyModuleDef %s = {" % Naming.pymoduledef_cname)
2168 2169 2170 2171
        code.putln("#if PY_VERSION_HEX < 0x03020000")
        # fix C compiler warnings due to missing initialisers
        code.putln("  { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },")
        code.putln("#else")
2172
        code.putln("  PyModuleDef_HEAD_INIT,")
2173
        code.putln("#endif")
2174
        code.putln('  __Pyx_NAMESTR("%s"),' % env.module_name)
2175 2176 2177 2178 2179 2180
        code.putln("  %s, /* m_doc */" % doc)
        code.putln("  -1, /* m_size */")
        code.putln("  %s /* m_methods */," % env.method_table_cname)
        code.putln("  NULL, /* m_reload */")
        code.putln("  NULL, /* m_traverse */")
        code.putln("  NULL, /* m_clear */")
Stefan Behnel's avatar
Stefan Behnel committed
2181
        code.putln("  %s /* m_free */" % cleanup_func)
2182 2183 2184
        code.putln("};")
        code.putln("#endif")

2185 2186 2187 2188
    def generate_module_creation_code(self, env, code):
        # Generate code to create the module object and
        # install the builtins.
        if env.doc:
2189
            doc = "__Pyx_DOCSTR(%s)" % code.get_string_const(env.doc)
2190 2191
        else:
            doc = "0"
2192
        code.putln("#if PY_MAJOR_VERSION < 3")
2193
        code.putln(
2194
            '%s = Py_InitModule4(__Pyx_NAMESTR("%s"), %s, %s, 0, PYTHON_API_VERSION); Py_XINCREF(%s);' % (
2195 2196 2197
                env.module_cname,
                env.module_name,
                env.method_table_cname,
2198 2199
                doc,
                env.module_cname))
2200 2201 2202 2203 2204 2205
        code.putln("#else")
        code.putln(
            "%s = PyModule_Create(&%s);" % (
                env.module_cname,
                Naming.pymoduledef_cname))
        code.putln("#endif")
2206
        code.putln(code.error_goto_if_null(env.module_cname, self.pos))
2207 2208 2209 2210 2211
        code.putln(
            "%s = PyModule_GetDict(%s); %s" % (
                env.module_dict_cname, env.module_cname,
                code.error_goto_if_null(env.module_dict_cname, self.pos)))
        code.put_incref(env.module_dict_cname, py_object_type, nanny=False)
2212

2213
        # CPython may not have put us into sys.modules yet, but relative imports and reimports require it
2214 2215 2216
        fq_module_name = env.qualified_name
        if fq_module_name.endswith('.__init__'):
            fq_module_name = fq_module_name[:-len('.__init__')]
2217 2218 2219 2220
        code.putln("#if PY_MAJOR_VERSION >= 3")
        code.putln("{")
        code.putln("PyObject *modules = PyImport_GetModuleDict(); %s" %
                   code.error_goto_if_null("modules", self.pos))
2221
        code.putln('if (!PyDict_GetItemString(modules, "%s")) {' % fq_module_name)
2222
        code.putln(code.error_goto_if_neg('PyDict_SetItemString(modules, "%s", %s)' % (
2223
            fq_module_name, env.module_cname), self.pos))
2224 2225 2226
        code.putln("}")
        code.putln("}")
        code.putln("#endif")
2227

2228
        code.putln(
2229
            '%s = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); %s' % (
2230
                Naming.builtins_cname,
2231
                code.error_goto_if_null(Naming.builtins_cname, self.pos)))
2232 2233 2234
        code.putln('#if CYTHON_COMPILING_IN_PYPY')
        code.putln('Py_INCREF(%s);' % Naming.builtins_cname)
        code.putln('#endif')
2235
        code.putln(
2236
            'if (__Pyx_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % (
2237 2238 2239
                env.module_cname,
                Naming.builtins_cname,
                code.error_goto(self.pos)))
2240 2241
        if Options.pre_import is not None:
            code.putln(
2242
                '%s = PyImport_AddModule(__Pyx_NAMESTR("%s")); %s' % (
2243
                    Naming.preimport_cname,
2244 2245
                    Options.pre_import,
                    code.error_goto_if_null(Naming.preimport_cname, self.pos)))
2246

2247 2248 2249 2250
    def generate_global_init_code(self, env, code):
        # Generate code to initialise global PyObject *
        # variables to None.
        for entry in env.var_entries:
2251
            if entry.visibility != 'extern':
2252 2253
                if entry.used:
                    entry.type.global_init_code(entry, code)
2254

2255 2256
    def generate_c_variable_export_code(self, env, code):
        # Generate code to create PyCFunction wrappers for exported C functions.
2257
        entries = []
2258
        for entry in env.var_entries:
Robert Bradshaw's avatar
Robert Bradshaw committed
2259 2260 2261
            if (entry.api
                or entry.defined_in_pxd
                or (Options.cimport_from_pyx and not entry.visibility == 'extern')):
2262 2263
                entries.append(entry)
        if entries:
2264
            env.use_utility_code(UtilityCode.load_cached("VoidPtrExport", "ImportExport.c"))
2265
            for entry in entries:
2266
                signature = entry.type.declaration_code("")
2267 2268 2269
                name = code.intern_identifier(entry.name)
                code.putln('if (__Pyx_ExportVoidPtr(%s, (void *)&%s, "%s") < 0) %s' % (
                    name, entry.cname, signature,
2270 2271
                    code.error_goto(self.pos)))

2272 2273
    def generate_c_function_export_code(self, env, code):
        # Generate code to create PyCFunction wrappers for exported C functions.
2274
        entries = []
2275
        for entry in env.cfunc_entries:
Robert Bradshaw's avatar
Robert Bradshaw committed
2276 2277 2278
            if (entry.api
                or entry.defined_in_pxd
                or (Options.cimport_from_pyx and not entry.visibility == 'extern')):
2279 2280
                entries.append(entry)
        if entries:
2281 2282
            env.use_utility_code(
                UtilityCode.load_cached("FunctionExport", "ImportExport.c"))
2283
            for entry in entries:
Mark Florisson's avatar
Mark Florisson committed
2284 2285 2286 2287 2288 2289
                signature = entry.type.signature_string()
                code.putln('if (__Pyx_ExportFunction("%s", (void (*)(void))%s, "%s") < 0) %s' % (
                    entry.name,
                    entry.cname,
                    signature,
                    code.error_goto(self.pos)))
2290

2291
    def generate_type_import_code_for_module(self, module, env, code):
2292
        # Generate type import code for all exported extension types in
2293
        # an imported module.
2294 2295 2296
        #if module.c_class_entries:
        for entry in module.c_class_entries:
            if entry.defined_in_pxd:
2297
                self.generate_type_import_code(env, entry.type, entry.pos, code)
2298

2299
    def specialize_fused_types(self, pxd_env):
2300 2301 2302 2303 2304 2305 2306 2307 2308
        """
        If fused c(p)def functions are defined in an imported pxd, but not
        used in this implementation file, we still have fused entries and
        not specialized ones. This method replaces any fused entries with their
        specialized ones.
        """
        for entry in pxd_env.cfunc_entries[:]:
            if entry.type.is_fused:
                # This call modifies the cfunc_entries in-place
2309
                entry.type.get_all_specialized_function_types()
2310

2311 2312 2313 2314 2315 2316 2317
    def generate_c_variable_import_code_for_module(self, module, env, code):
        # Generate import code for all exported C functions in a cimported module.
        entries = []
        for entry in module.var_entries:
            if entry.defined_in_pxd:
                entries.append(entry)
        if entries:
2318 2319 2320 2321
            env.use_utility_code(
                UtilityCode.load_cached("ModuleImport", "ImportExport.c"))
            env.use_utility_code(
                UtilityCode.load_cached("VoidPtrImport", "ImportExport.c"))
2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340
            temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
            code.putln(
                '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % (
                    temp,
                    module.qualified_name,
                    temp,
                    code.error_goto(self.pos)))
            for entry in entries:
                if env is module:
                    cname = entry.cname
                else:
                    cname = module.mangle(Naming.varptr_prefix, entry.name)
                signature = entry.type.declaration_code("")
                code.putln(
                    'if (__Pyx_ImportVoidPtr(%s, "%s", (void **)&%s, "%s") < 0) %s' % (
                        temp, entry.name, cname, signature,
                        code.error_goto(self.pos)))
            code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp))

2341 2342 2343 2344
    def generate_c_function_import_code_for_module(self, module, env, code):
        # Generate import code for all exported C functions in a cimported module.
        entries = []
        for entry in module.cfunc_entries:
2345
            if entry.defined_in_pxd and entry.used:
2346 2347
                entries.append(entry)
        if entries:
2348 2349 2350 2351
            env.use_utility_code(
                UtilityCode.load_cached("ModuleImport", "ImportExport.c"))
            env.use_utility_code(
                UtilityCode.load_cached("FunctionImport", "ImportExport.c"))
2352
            temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2353 2354 2355 2356 2357 2358
            code.putln(
                '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % (
                    temp,
                    module.qualified_name,
                    temp,
                    code.error_goto(self.pos)))
2359
            for entry in entries:
Mark Florisson's avatar
Mark Florisson committed
2360 2361 2362 2363 2364 2365 2366
                code.putln(
                    'if (__Pyx_ImportFunction(%s, "%s", (void (**)(void))&%s, "%s") < 0) %s' % (
                        temp,
                        entry.name,
                        entry.cname,
                        entry.type.signature_string(),
                        code.error_goto(self.pos)))
2367
            code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp))
2368

2369 2370 2371 2372
    def generate_type_init_code(self, env, code):
        # Generate type import code for extern extension types
        # and type ready code for non-extern ones.
        for entry in env.c_class_entries:
2373
            if entry.visibility == 'extern' and not entry.utility_code_definition:
2374 2375 2376 2377 2378 2379
                self.generate_type_import_code(env, entry.type, entry.pos, code)
            else:
                self.generate_base_type_import_code(env, entry, code)
                self.generate_exttype_vtable_init_code(entry, code)
                self.generate_type_ready_code(env, entry, code)
                self.generate_typeptr_assignment_code(entry, code)
2380

2381 2382
    def generate_base_type_import_code(self, env, entry, code):
        base_type = entry.type.base_type
2383 2384
        if (base_type and base_type.module_name != env.qualified_name and not
               base_type.is_builtin_type and not entry.utility_code_definition):
2385
            self.generate_type_import_code(env, base_type, self.pos, code)
2386

2387 2388 2389 2390 2391 2392
    def generate_type_import_code(self, env, type, pos, code):
        # If not already done, generate code to import the typeobject of an
        # extension type defined in another module, and extract its C method
        # table pointer if any.
        if type in env.types_imported:
            return
2393
        env.use_utility_code(UtilityCode.load_cached("TypeImport", "ImportExport.c"))
2394 2395
        self.generate_type_import_call(type, code,
                                       code.error_goto_if_null(type.typeptr_cname, pos))
2396
        if type.vtabptr_cname:
2397
            code.globalstate.use_utility_code(
2398
                UtilityCode.load_cached('GetVTable', 'ImportExport.c'))
2399 2400 2401 2402 2403
            code.putln("%s = (struct %s*)__Pyx_GetVtable(%s->tp_dict); %s" % (
                type.vtabptr_cname,
                type.vtabstruct_cname,
                type.typeptr_cname,
                code.error_goto_if_null(type.vtabptr_cname, pos)))
2404
        env.types_imported[type] = 1
2405

2406 2407
    py3_type_name_map = {'str' : 'bytes', 'unicode' : 'str'}

2408 2409 2410 2411 2412
    def generate_type_import_call(self, type, code, error_code):
        if type.typedef_flag:
            objstruct = type.objstruct_cname
        else:
            objstruct = "struct %s" % type.objstruct_cname
2413
        sizeof_objstruct = objstruct
2414
        module_name = type.module_name
2415
        condition = replacement = None
2416 2417 2418 2419
        if module_name not in ('__builtin__', 'builtins'):
            module_name = '"%s"' % module_name
        else:
            module_name = '__Pyx_BUILTIN_MODULE_NAME'
2420
            if type.name in Code.non_portable_builtins_map:
Stefan Behnel's avatar
Stefan Behnel committed
2421
                condition, replacement = Code.non_portable_builtins_map[type.name]
2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446
            if objstruct in Code.basicsize_builtins_map:
                # Some builtin types have a tp_basicsize which differs from sizeof(...):
                sizeof_objstruct = Code.basicsize_builtins_map[objstruct]

        code.put('%s = __Pyx_ImportType(%s,' % (
            type.typeptr_cname,
            module_name))

        if condition and replacement:
            code.putln("")  # start in new line
            code.putln("#if %s" % condition)
            code.putln('"%s",' % replacement)
            code.putln("#else")
            code.putln('"%s",' % type.name)
            code.putln("#endif")
        else:
            code.put(' "%s", ' % type.name)

        if sizeof_objstruct != objstruct:
            if not condition:
                code.putln("")  # start in new line
            code.putln("#if CYTHON_COMPILING_IN_PYPY")
            code.putln('sizeof(%s),' % objstruct)
            code.putln("#else")
            code.putln('sizeof(%s),' % sizeof_objstruct)
2447
            code.putln("#endif")
2448 2449 2450 2451 2452 2453
        else:
            code.put('sizeof(%s), ' % objstruct)

        code.putln('%i); %s' % (
            not type.is_external or type.is_subclassed,
            error_code))
2454

2455 2456 2457 2458 2459 2460 2461
    def generate_type_ready_code(self, env, entry, code):
        # Generate a call to PyType_Ready for an extension
        # type defined in this module.
        type = entry.type
        typeobj_cname = type.typeobj_cname
        scope = type.scope
        if scope: # could be None if there was an error
Stefan Behnel's avatar
Stefan Behnel committed
2462
            if entry.visibility != 'extern':
2463 2464 2465 2466 2467 2468
                for slot in TypeSlots.slot_table:
                    slot.generate_dynamic_init_code(scope, code)
                code.putln(
                    "if (PyType_Ready(&%s) < 0) %s" % (
                        typeobj_cname,
                        code.error_goto(entry.pos)))
2469
                # Fix special method docstrings. This is a bit of a hack, but
2470
                # unless we let PyType_Ready create the slot wrappers we have
2471
                # a significant performance hit. (See trac #561.)
2472
                for func in entry.type.scope.pyfunc_entries:
2473 2474 2475 2476
                    is_buffer = func.name in ('__getbuffer__',
                                               '__releasebuffer__')
                    if (func.is_special and Options.docstrings and
                            func.wrapperbase_cname and not is_buffer):
2477
                        code.putln('#if CYTHON_COMPILING_IN_CPYTHON')
Stefan Behnel's avatar
Stefan Behnel committed
2478
                        code.putln("{")
2479
                        code.putln(
2480
                            'PyObject *wrapper = __Pyx_GetAttrString((PyObject *)&%s, "%s"); %s' % (
2481 2482
                                typeobj_cname,
                                func.name,
Stefan Behnel's avatar
Stefan Behnel committed
2483
                                code.error_goto_if_null('wrapper', entry.pos)))
2484
                        code.putln(
Stefan Behnel's avatar
Stefan Behnel committed
2485
                            "if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {")
2486 2487
                        code.putln(
                            "%s = *((PyWrapperDescrObject *)wrapper)->d_base;" % (
Stefan Behnel's avatar
Stefan Behnel committed
2488
                                func.wrapperbase_cname))
2489
                        code.putln(
Stefan Behnel's avatar
Stefan Behnel committed
2490
                            "%s.doc = %s;" % (func.wrapperbase_cname, func.doc_cname))
2491 2492
                        code.putln(
                            "((PyWrapperDescrObject *)wrapper)->d_base = &%s;" % (
Stefan Behnel's avatar
Stefan Behnel committed
2493 2494 2495
                                func.wrapperbase_cname))
                        code.putln("}")
                        code.putln("}")
2496
                        code.putln('#endif')
2497 2498 2499 2500 2501 2502
                if type.vtable_cname:
                    code.putln(
                        "if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
                            typeobj_cname,
                            type.vtabptr_cname,
                            code.error_goto(entry.pos)))
2503
                    code.globalstate.use_utility_code(
2504
                        UtilityCode.load_cached('SetVTable', 'ImportExport.c'))
2505 2506 2507 2508 2509 2510 2511 2512 2513 2514
                if not type.scope.is_internal and not type.scope.directives['internal']:
                    # scope.is_internal is set for types defined by
                    # Cython (such as closures), the 'internal'
                    # directive is set by users
                    code.putln(
                        'if (__Pyx_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % (
                            Naming.module_cname,
                            scope.class_name,
                            typeobj_cname,
                            code.error_goto(entry.pos)))
2515 2516 2517 2518
                weakref_entry = scope.lookup_here("__weakref__")
                if weakref_entry:
                    if weakref_entry.type is py_object_type:
                        tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname
2519 2520 2521 2522 2523
                        if type.typedef_flag:
                            objstruct = type.objstruct_cname
                        else:
                            objstruct = "struct %s" % type.objstruct_cname
                        code.putln("if (%s == 0) %s = offsetof(%s, %s);" % (
2524 2525
                            tp_weaklistoffset,
                            tp_weaklistoffset,
2526
                            objstruct,
2527 2528 2529
                            weakref_entry.cname))
                    else:
                        error(weakref_entry.pos, "__weakref__ slot must be of type 'object'")
2530

2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545
    def generate_exttype_vtable_init_code(self, entry, code):
        # Generate code to initialise the C method table of an
        # extension type.
        type = entry.type
        if type.vtable_cname:
            code.putln(
                "%s = &%s;" % (
                    type.vtabptr_cname,
                    type.vtable_cname))
            if type.base_type and type.base_type.vtabptr_cname:
                code.putln(
                    "%s.%s = *%s;" % (
                        type.vtable_cname,
                        Naming.obj_base_cname,
                        type.base_type.vtabptr_cname))
2546 2547 2548 2549

            c_method_entries = [
                entry for entry in type.scope.cfunc_entries
                if entry.func_cname ]
2550 2551 2552 2553 2554 2555 2556 2557 2558
            if c_method_entries:
                for meth_entry in c_method_entries:
                    cast = meth_entry.type.signature_cast_string()
                    code.putln(
                        "%s.%s = %s%s;" % (
                            type.vtable_cname,
                            meth_entry.cname,
                            cast,
                            meth_entry.func_cname))
2559

2560 2561 2562 2563 2564 2565 2566 2567
    def generate_typeptr_assignment_code(self, entry, code):
        # Generate code to initialise the typeptr of an extension
        # type defined in this module to point to its type object.
        type = entry.type
        if type.typeobj_cname:
            code.putln(
                "%s = &%s;" % (
                    type.typeptr_cname, type.typeobj_cname))
2568

2569
def generate_cfunction_declaration(entry, env, code, definition):
2570
    from_cy_utility = entry.used and entry.utility_code_definition
2571
    if entry.used and entry.inline_func_in_pxd or (not entry.in_cinclude and (definition
2572
            or entry.defined_in_pxd or entry.visibility == 'extern' or from_cy_utility)):
2573
        if entry.visibility == 'extern':
2574
            storage_class = Naming.extern_c_macro
2575 2576
            dll_linkage = "DL_IMPORT"
        elif entry.visibility == 'public':
2577
            storage_class = Naming.extern_c_macro
2578 2579
            dll_linkage = "DL_EXPORT"
        elif entry.visibility == 'private':
2580
            storage_class = "static"
2581 2582
            dll_linkage = None
        else:
2583
            storage_class = "static"
2584 2585 2586 2587
            dll_linkage = None
        type = entry.type

        if entry.defined_in_pxd and not definition:
2588
            storage_class = "static"
2589 2590 2591
            dll_linkage = None
            type = CPtrType(type)

2592 2593 2594 2595
        header = type.declaration_code(
            entry.cname, dll_linkage = dll_linkage)
        modifiers = code.build_function_modifiers(entry.func_modifiers)
        code.putln("%s %s%s; /*proto*/" % (
2596 2597 2598 2599
            storage_class,
            modifiers,
            header))

2600
#------------------------------------------------------------------------------------
Stefan Behnel's avatar
Stefan Behnel committed
2601 2602 2603
#
#  Runtime support code
#
2604 2605
#------------------------------------------------------------------------------------

2606 2607
streq_utility_code = UtilityCode(
proto = """
2608
static CYTHON_INLINE int __Pyx_StrEq(const char *, const char *); /*proto*/
2609 2610
""",
impl = """
2611
static CYTHON_INLINE int __Pyx_StrEq(const char *s1, const char *s2) {
2612 2613 2614 2615 2616 2617 2618
     while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; }
     return *s1 == *s2;
}
""")

#------------------------------------------------------------------------------------

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2619 2620 2621 2622 2623 2624 2625
import_star_utility_code = """

/* import_all_from is an unexposed function from ceval.c */

static int
__Pyx_import_all_from(PyObject *locals, PyObject *v)
{
Robert Bradshaw's avatar
Robert Bradshaw committed
2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642
    PyObject *all = __Pyx_GetAttrString(v, "__all__");
    PyObject *dict, *name, *value;
    int skip_leading_underscores = 0;
    int pos, err;

    if (all == NULL) {
        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
            return -1; /* Unexpected error */
        PyErr_Clear();
        dict = __Pyx_GetAttrString(v, "__dict__");
        if (dict == NULL) {
            if (!PyErr_ExceptionMatches(PyExc_AttributeError))
                return -1;
            PyErr_SetString(PyExc_ImportError,
            "from-import-* object has no __dict__ and no __all__");
            return -1;
        }
2643 2644 2645
#if PY_MAJOR_VERSION < 3
        all = PyObject_CallMethod(dict, (char *)"keys", NULL);
#else
Robert Bradshaw's avatar
Robert Bradshaw committed
2646
        all = PyMapping_Keys(dict);
2647
#endif
Robert Bradshaw's avatar
Robert Bradshaw committed
2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663
        Py_DECREF(dict);
        if (all == NULL)
            return -1;
        skip_leading_underscores = 1;
    }

    for (pos = 0, err = 0; ; pos++) {
        name = PySequence_GetItem(all, pos);
        if (name == NULL) {
            if (!PyErr_ExceptionMatches(PyExc_IndexError))
                err = -1;
            else
                PyErr_Clear();
            break;
        }
        if (skip_leading_underscores &&
2664
#if PY_MAJOR_VERSION < 3
Robert Bradshaw's avatar
Robert Bradshaw committed
2665 2666
            PyString_Check(name) &&
            PyString_AS_STRING(name)[0] == '_')
2667
#else
Robert Bradshaw's avatar
Robert Bradshaw committed
2668 2669
            PyUnicode_Check(name) &&
            PyUnicode_AS_UNICODE(name)[0] == '_')
2670
#endif
Robert Bradshaw's avatar
Robert Bradshaw committed
2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688
        {
            Py_DECREF(name);
            continue;
        }
        value = PyObject_GetAttr(v, name);
        if (value == NULL)
            err = -1;
        else if (PyDict_CheckExact(locals))
            err = PyDict_SetItem(locals, name, value);
        else
            err = PyObject_SetItem(locals, name, value);
        Py_DECREF(name);
        Py_XDECREF(value);
        if (err != 0)
            break;
    }
    Py_DECREF(all);
    return err;
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2689 2690 2691
}


2692
static int %(IMPORT_STAR)s(PyObject* m) {
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2693 2694 2695

    int i;
    int ret = -1;
2696
    char* s;
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2697 2698
    PyObject *locals = 0;
    PyObject *list = 0;
2699 2700 2701
#if PY_MAJOR_VERSION >= 3
    PyObject *utf8_name = 0;
#endif
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2702 2703
    PyObject *name;
    PyObject *item;
2704

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2705 2706 2707
    locals = PyDict_New();              if (!locals) goto bad;
    if (__Pyx_import_all_from(locals, m) < 0) goto bad;
    list = PyDict_Items(locals);        if (!list) goto bad;
2708

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2709 2710 2711
    for(i=0; i<PyList_GET_SIZE(list); i++) {
        name = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 0);
        item = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 1);
2712 2713 2714 2715 2716 2717
#if PY_MAJOR_VERSION >= 3
        utf8_name = PyUnicode_AsUTF8String(name);
        if (!utf8_name) goto bad;
        s = PyBytes_AS_STRING(utf8_name);
        if (%(IMPORT_STAR_SET)s(item, name, s) < 0) goto bad;
        Py_DECREF(utf8_name); utf8_name = 0;
2718
#else
2719
        s = PyString_AsString(name);
2720 2721
        if (!s) goto bad;
        if (%(IMPORT_STAR_SET)s(item, name, s) < 0) goto bad;
2722
#endif
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2723 2724
    }
    ret = 0;
2725

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2726 2727 2728
bad:
    Py_XDECREF(locals);
    Py_XDECREF(list);
2729 2730 2731
#if PY_MAJOR_VERSION >= 3
    Py_XDECREF(utf8_name);
#endif
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2732 2733
    return ret;
}
2734 2735
""" % {'IMPORT_STAR'     : Naming.import_star,
       'IMPORT_STAR_SET' : Naming.import_star_set }
2736

2737
refnanny_utility_code = UtilityCode.load_cached("Refnanny", "ModuleSetupCode.c")
Robert Bradshaw's avatar
Robert Bradshaw committed
2738

2739 2740
main_method = UtilityCode(
impl = """
2741 2742 2743 2744 2745
#ifdef __FreeBSD__
#include <floatingpoint.h>
#endif

#if PY_MAJOR_VERSION < 3
2746
int %(main_method)s(int argc, char** argv) {
2747
#elif defined(WIN32) || defined(MS_WINDOWS)
2748
int %(wmain_method)s(int argc, wchar_t **argv) {
2749 2750
#else
static int __Pyx_main(int argc, wchar_t **argv) {
2751
#endif
2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762
    /* 754 requires that FP exceptions run in "no stop" mode by default,
     * and until C vendors implement C99's ways to control FP exceptions,
     * Python requires non-stop mode.  Alas, some platforms enable FP
     * exceptions by default.  Here we disable them.
     */
#ifdef __FreeBSD__
    fp_except_t m;

    m = fpgetmask();
    fpsetmask(m & ~FP_X_OFL);
#endif
2763
    if (argc && argv)
2764
        Py_SetProgramName(argv[0]);
2765
    Py_Initialize();
2766
    if (argc && argv)
2767
        PySys_SetArgv(argc, argv);
2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783
    { /* init module '%(module_name)s' as '__main__' */
      PyObject* m = NULL;
      %(module_is_main)s = 1;
      #if PY_MAJOR_VERSION < 3
          init%(module_name)s();
      #else
          m = PyInit_%(module_name)s();
      #endif
      if (PyErr_Occurred()) {
          PyErr_Print(); /* This exits with the right code if SystemExit. */
          #if PY_MAJOR_VERSION < 3
          if (Py_FlushLine()) PyErr_Clear();
          #endif
          return 1;
      }
      Py_XDECREF(m);
2784
    }
2785
    Py_Finalize();
2786
    return 0;
2787
}
2788 2789 2790 2791 2792 2793 2794 2795


#if PY_MAJOR_VERSION >= 3 && !defined(WIN32) && !defined(MS_WINDOWS)
#include <locale.h>

static wchar_t*
__Pyx_char2wchar(char* arg)
{
Vitja Makarov's avatar
Vitja Makarov committed
2796
    wchar_t *res;
2797
#ifdef HAVE_BROKEN_MBSTOWCS
Vitja Makarov's avatar
Vitja Makarov committed
2798 2799 2800 2801 2802
    /* Some platforms have a broken implementation of
     * mbstowcs which does not count the characters that
     * would result from conversion.  Use an upper bound.
     */
    size_t argsize = strlen(arg);
2803
#else
Vitja Makarov's avatar
Vitja Makarov committed
2804
    size_t argsize = mbstowcs(NULL, arg, 0);
2805
#endif
Vitja Makarov's avatar
Vitja Makarov committed
2806 2807 2808
    size_t count;
    unsigned char *in;
    wchar_t *out;
2809
#ifdef HAVE_MBRTOWC
Vitja Makarov's avatar
Vitja Makarov committed
2810
    mbstate_t mbs;
2811
#endif
Vitja Makarov's avatar
Vitja Makarov committed
2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829
    if (argsize != (size_t)-1) {
        res = (wchar_t *)malloc((argsize+1)*sizeof(wchar_t));
        if (!res)
            goto oom;
        count = mbstowcs(res, arg, argsize+1);
        if (count != (size_t)-1) {
            wchar_t *tmp;
            /* Only use the result if it contains no
               surrogate characters. */
            for (tmp = res; *tmp != 0 &&
                     (*tmp < 0xd800 || *tmp > 0xdfff); tmp++)
                ;
            if (*tmp == 0)
                return res;
        }
        free(res);
    }
    /* Conversion failed. Fall back to escaping with surrogateescape. */
2830
#ifdef HAVE_MBRTOWC
Vitja Makarov's avatar
Vitja Makarov committed
2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874
    /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */

    /* Overallocate; as multi-byte characters are in the argument, the
       actual output could use less memory. */
    argsize = strlen(arg) + 1;
    res = malloc(argsize*sizeof(wchar_t));
    if (!res) goto oom;
    in = (unsigned char*)arg;
    out = res;
    memset(&mbs, 0, sizeof mbs);
    while (argsize) {
        size_t converted = mbrtowc(out, (char*)in, argsize, &mbs);
        if (converted == 0)
            /* Reached end of string; null char stored. */
            break;
        if (converted == (size_t)-2) {
            /* Incomplete character. This should never happen,
               since we provide everything that we have -
               unless there is a bug in the C library, or I
               misunderstood how mbrtowc works. */
            fprintf(stderr, "unexpected mbrtowc result -2\\n");
            return NULL;
        }
        if (converted == (size_t)-1) {
            /* Conversion error. Escape as UTF-8b, and start over
               in the initial shift state. */
            *out++ = 0xdc00 + *in++;
            argsize--;
            memset(&mbs, 0, sizeof mbs);
            continue;
        }
        if (*out >= 0xd800 && *out <= 0xdfff) {
            /* Surrogate character.  Escape the original
               byte sequence with surrogateescape. */
            argsize -= converted;
            while (converted--)
                *out++ = 0xdc00 + *in++;
            continue;
        }
        /* successfully converted some bytes */
        in += converted;
        argsize -= converted;
        out++;
    }
2875
#else
Vitja Makarov's avatar
Vitja Makarov committed
2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888
    /* Cannot use C locale for escaping; manually escape as if charset
       is ASCII (i.e. escape all bytes > 128. This will still roundtrip
       correctly in the locale's charset, which must be an ASCII superset. */
    res = malloc((strlen(arg)+1)*sizeof(wchar_t));
    if (!res) goto oom;
    in = (unsigned char*)arg;
    out = res;
    while(*in)
        if(*in < 128)
            *out++ = *in++;
        else
            *out++ = 0xdc00 + *in++;
    *out = 0;
2889
#endif
Vitja Makarov's avatar
Vitja Makarov committed
2890
    return res;
2891
oom:
Vitja Makarov's avatar
Vitja Makarov committed
2892 2893
    fprintf(stderr, "out of memory\\n");
    return NULL;
2894 2895 2896
}

int
2897
%(main_method)s(int argc, char **argv)
2898
{
2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928
    if (!argc) {
        return __Pyx_main(0, NULL);
    }
    else {
        wchar_t **argv_copy = (wchar_t **)malloc(sizeof(wchar_t*)*argc);
        /* We need a second copies, as Python might modify the first one. */
        wchar_t **argv_copy2 = (wchar_t **)malloc(sizeof(wchar_t*)*argc);
        int i, res;
        char *oldloc;
        if (!argv_copy || !argv_copy2) {
            fprintf(stderr, "out of memory\\n");
            return 1;
        }
        oldloc = strdup(setlocale(LC_ALL, NULL));
        setlocale(LC_ALL, "");
        for (i = 0; i < argc; i++) {
            argv_copy2[i] = argv_copy[i] = __Pyx_char2wchar(argv[i]);
            if (!argv_copy[i])
                return 1;
        }
        setlocale(LC_ALL, oldloc);
        free(oldloc);
        res = __Pyx_main(argc, argv_copy);
        for (i = 0; i < argc; i++) {
            free(argv_copy2[i]);
        }
        free(argv_copy);
        free(argv_copy2);
        return res;
    }
2929 2930
}
#endif
2931
""")
2932 2933 2934 2935 2936 2937 2938

packed_struct_utility_code = UtilityCode(proto="""
#if defined(__GNUC__)
#define __Pyx_PACKED __attribute__((__packed__))
#else
#define __Pyx_PACKED
#endif
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
2939
""", impl="", proto_block='utility_code_proto_before_types')
2940

2941
capsule_utility_code = UtilityCode.load("Capsule")