Merge circular imports stuff
[cython.git] / Cython / Compiler / ModuleNode.py
1 #
2 #   Pyrex - Module parse tree node
3 #
4
5 import os, time
6 from cStringIO import StringIO
7 from PyrexTypes import CPtrType
8
9 import Annotate
10 import Code
11 import Naming
12 import Nodes
13 import Options
14 import PyrexTypes
15 import TypeSlots
16 import Version
17
18 from Errors import error
19 from PyrexTypes import py_object_type
20 from Cython.Utils import open_new_file, replace_suffix
21
22 def recurse_vtab_check_inheritance(entry, b, dict):
23     base = entry
24     while base is not None:
25         if base.type.base_type is None or base.type.base_type.vtabstruct_cname is None:
26             return False
27         if base.type.base_type.vtabstruct_cname == b.type.vtabstruct_cname:
28             return True
29         try:
30             base = dict[base.type.base_type.vtabstruct_cname]
31         except KeyError:
32             return False
33     return False
34     
35 def recurse_vtabslot_check_inheritance(entry, b, dict):
36     base = entry
37     while base is not None:
38         if base.type.base_type is None:
39             return False
40         if base.type.base_type.objstruct_cname == b.type.objstruct_cname:
41             return True
42         try:
43             base = dict[base.type.base_type.objstruct_cname]
44         except KeyError:
45             return False
46     return False
47
48
49 class ModuleNode(Nodes.Node, Nodes.BlockNode):
50     #  doc       string or None
51     #  body      StatListNode
52     #
53     #  referenced_modules   [ModuleScope]
54     #  module_temp_cname    string
55     #  full_module_name     string
56
57     children_attrs = ["body"]
58     
59     def analyse_declarations(self, env):
60         if Options.embed_pos_in_docstring:
61             env.doc = 'File: %s (starting at line %s)'%Nodes.relative_position(self.pos)
62             if not self.doc is None:
63                 env.doc = env.doc + '\\n' + self.doc
64         else:
65             env.doc = self.doc
66         self.body.analyse_declarations(env)
67     
68     def process_implementation(self, env, options, result):
69         self.analyse_declarations(env)
70         env.check_c_classes()
71         self.body.analyse_expressions(env)
72         env.return_type = PyrexTypes.c_void_type
73         self.referenced_modules = []
74         self.find_referenced_modules(env, self.referenced_modules, {})
75         if self.has_imported_c_functions():
76             self.module_temp_cname = env.allocate_temp_pyobject()
77             env.release_temp(self.module_temp_cname)
78         self.generate_c_code(env, options, result)
79         self.generate_h_code(env, options, result)
80         self.generate_api_code(env, result)
81     
82     def has_imported_c_functions(self):
83         for module in self.referenced_modules:
84             for entry in module.cfunc_entries:
85                 if entry.defined_in_pxd:
86                     return 1
87         return 0
88     
89     def generate_h_code(self, env, options, result):
90         def h_entries(entries, pxd = 0):
91             return [entry for entry in entries
92                 if entry.visibility == 'public' or pxd and entry.defined_in_pxd]
93         h_types = h_entries(env.type_entries)
94         h_vars = h_entries(env.var_entries)
95         h_funcs = h_entries(env.cfunc_entries)
96         h_extension_types = h_entries(env.c_class_entries)
97         if h_types or h_vars or h_funcs or h_extension_types:
98             result.h_file = replace_suffix(result.c_file, ".h")
99             h_code = Code.CCodeWriter(open_new_file(result.h_file))
100             if options.generate_pxi:
101                 result.i_file = replace_suffix(result.c_file, ".pxi")
102                 i_code = Code.PyrexCodeWriter(result.i_file)
103             else:
104                 i_code = None
105             guard = Naming.h_guard_prefix + env.qualified_name.replace(".", "__")
106             h_code.put_h_guard(guard)
107             self.generate_extern_c_macro_definition(h_code)
108             self.generate_type_header_code(h_types, h_code)
109             h_code.putln("")
110             h_code.putln("#ifndef %s" % Naming.api_guard_prefix + self.api_name(env))
111             if h_vars:
112                 h_code.putln("")
113                 for entry in h_vars:
114                     self.generate_public_declaration(entry, h_code, i_code)
115             if h_funcs:
116                 h_code.putln("")
117                 for entry in h_funcs:
118                     self.generate_public_declaration(entry, h_code, i_code)
119             if h_extension_types:
120                 h_code.putln("")
121                 for entry in h_extension_types:
122                     self.generate_cclass_header_code(entry.type, h_code)
123                     if i_code:
124                         self.generate_cclass_include_code(entry.type, i_code)
125             h_code.putln("")
126             h_code.putln("#endif")
127             h_code.putln("")
128             h_code.putln("PyMODINIT_FUNC init%s(void);" % env.module_name)
129             h_code.putln("")
130             h_code.putln("#endif")
131     
132     def generate_public_declaration(self, entry, h_code, i_code):
133         h_code.putln("%s %s;" % (
134             Naming.extern_c_macro,
135             entry.type.declaration_code(
136                 entry.cname, dll_linkage = "DL_IMPORT")))
137         if i_code:
138             i_code.putln("cdef extern %s" % 
139                 entry.type.declaration_code(entry.cname, pyrex = 1))
140     
141     def api_name(self, env):
142         return env.qualified_name.replace(".", "__")
143     
144     def generate_api_code(self, env, result):
145         api_funcs = []
146         public_extension_types = []
147         has_api_extension_types = 0
148         for entry in env.cfunc_entries:
149             if entry.api:
150                 api_funcs.append(entry)
151         for entry in env.c_class_entries:
152             if entry.visibility == 'public':
153                 public_extension_types.append(entry)
154             if entry.api:
155                 has_api_extension_types = 1
156         if api_funcs or has_api_extension_types:
157             result.api_file = replace_suffix(result.c_file, "_api.h")
158             h_code = Code.CCodeWriter(open_new_file(result.api_file))
159             name = self.api_name(env)
160             guard = Naming.api_guard_prefix + name
161             h_code.put_h_guard(guard)
162             h_code.putln('#include "Python.h"')
163             if result.h_file:
164                 h_code.putln('#include "%s"' % os.path.basename(result.h_file))
165             for entry in public_extension_types:
166                 type = entry.type
167                 h_code.putln("")
168                 h_code.putln("static PyTypeObject *%s;" % type.typeptr_cname)
169                 h_code.putln("#define %s (*%s)" % (
170                     type.typeobj_cname, type.typeptr_cname))
171             if api_funcs:
172                 h_code.putln("")
173                 for entry in api_funcs:
174                     type = CPtrType(entry.type)
175                     h_code.putln("static %s;" % type.declaration_code(entry.cname))
176             h_code.putln("")
177             h_code.put_h_guard(Naming.api_func_guard + "import_module")
178             h_code.put(import_module_utility_code[1])
179             h_code.putln("")
180             h_code.putln("#endif")
181             if api_funcs:
182                 h_code.putln("")
183                 h_code.put(function_import_utility_code[1])
184             if public_extension_types:
185                 h_code.putln("")
186                 h_code.put(type_import_utility_code[1])
187             h_code.putln("")
188             h_code.putln("static int import_%s(void) {" % name)
189             h_code.putln("PyObject *module = 0;")
190             h_code.putln('module = __Pyx_ImportModule("%s");' % env.qualified_name)
191             h_code.putln("if (!module) goto bad;")
192             for entry in api_funcs:
193                 sig = entry.type.signature_string()
194                 h_code.putln(
195                     'if (__Pyx_ImportFunction(module, "%s", (void**)&%s, "%s") < 0) goto bad;' % (
196                         entry.name,
197                         entry.cname,
198                         sig))
199             h_code.putln("Py_DECREF(module); module = 0;")
200             for entry in public_extension_types:
201                 self.generate_type_import_call(
202                     entry.type, h_code,
203                     "if (!%s) goto bad;" % entry.type.typeptr_cname)
204             h_code.putln("return 0;")
205             h_code.putln("bad:")
206             h_code.putln("Py_XDECREF(module);")
207             h_code.putln("return -1;")
208             h_code.putln("}")
209             h_code.putln("")
210             h_code.putln("#endif")
211     
212     def generate_cclass_header_code(self, type, h_code):
213         h_code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
214             Naming.extern_c_macro,
215             type.typeobj_cname))
216         #self.generate_obj_struct_definition(type, h_code)
217     
218     def generate_cclass_include_code(self, type, i_code):
219         i_code.putln("cdef extern class %s.%s:" % (
220             type.module_name, type.name))
221         i_code.indent()
222         var_entries = type.scope.var_entries
223         if var_entries:
224             for entry in var_entries:
225                 i_code.putln("cdef %s" % 
226                     entry.type.declaration_code(entry.cname, pyrex = 1))
227         else:
228             i_code.putln("pass")
229         i_code.dedent()
230     
231     def generate_c_code(self, env, options, result):
232         modules = self.referenced_modules
233         if Options.annotate:
234             code = Annotate.AnnotationCCodeWriter(StringIO())
235         else:
236             code = Code.CCodeWriter(StringIO())
237         code.h = Code.CCodeWriter(StringIO())
238         code.init_labels()
239         self.generate_module_preamble(env, modules, code.h)
240
241         code.putln("")
242         code.putln("/* Implementation of %s */" % env.qualified_name)
243         self.generate_const_definitions(env, code)
244         self.generate_interned_num_decls(env, code)
245         self.generate_interned_name_decls(env, code)
246         self.generate_py_string_decls(env, code)
247         self.generate_cached_builtins_decls(env, code)
248         self.body.generate_function_definitions(env, code, options.transforms)
249         code.mark_pos(None)
250         self.generate_interned_name_table(env, code)
251         self.generate_py_string_table(env, code)
252         self.generate_typeobj_definitions(env, code)
253         self.generate_method_table(env, code)
254         self.generate_filename_init_prototype(code)
255         self.generate_module_init_func(modules[:-1], env, code)
256         code.mark_pos(None)
257         self.generate_module_cleanup_func(env, code)
258         self.generate_filename_table(code)
259         self.generate_utility_functions(env, code)
260
261         self.generate_declarations_for_modules(env, modules, code.h)
262
263
264         f = open_new_file(result.c_file)
265         f.write(code.h.f.getvalue())
266         f.write("\n")
267         f.write(code.f.getvalue())
268         f.close()
269         result.c_file_generated = 1
270         if Options.annotate:
271             self.annotate(code)
272             code.save_annotation(result.c_file[:-1] + "pyx") # change?
273     
274     def find_referenced_modules(self, env, module_list, modules_seen):
275         if env not in modules_seen:
276             modules_seen[env] = 1
277             for imported_module in env.cimported_modules:
278                 self.find_referenced_modules(imported_module, module_list, modules_seen)
279             module_list.append(env)
280
281     def generate_vtab_dict(self, module_list):
282         vtab_dict = {}
283         for module in module_list:
284             for entry in module.c_class_entries:
285                 if not entry.in_cinclude:
286                     type = entry.type
287                     scope = type.scope
288                     if type.vtabstruct_cname:
289                         vtab_dict[type.vtabstruct_cname]=entry
290         return vtab_dict
291     def generate_vtab_list(self, vtab_dict):
292         vtab_list = list()
293         for entry in vtab_dict.itervalues():
294             vtab_list.append(entry)
295         for i in range(0,len(vtab_list)):
296             for j in range(0,len(vtab_list)):
297                 if(recurse_vtab_check_inheritance(vtab_list[j],vtab_list[i], vtab_dict)==1):
298                     if i > j:
299                         vtab_list.insert(j,vtab_list[i])
300                         if i > j:
301                             vtab_list.pop(i+1)
302                         else:
303                             vtab_list.pop(i)
304         return vtab_list
305         
306     def generate_vtabslot_dict(self, module_list, env):
307         vtab_dict={}
308         type_entries=[]
309         for module in module_list:
310             definition = module is env
311             if definition:
312                 type_entries.extend( env.type_entries)
313             else:
314                 for entry in module.type_entries:
315                     if entry.defined_in_pxd:
316                         type_entries.append(entry)
317         for entry in type_entries:
318             type = entry.type
319             if type.is_extension_type:
320                 if not entry.in_cinclude:
321                     type = entry.type
322                     scope = type.scope
323                     vtab_dict[type.objstruct_cname]=entry
324         return vtab_dict
325         
326     def generate_vtabslot_list(self, vtab_dict):
327         vtab_list = list()
328         for entry in vtab_dict.itervalues():
329             vtab_list.append(entry)
330         for i in range(0,len(vtab_list)):
331             for j in range(0,len(vtab_list)):
332                 if(recurse_vtabslot_check_inheritance(vtab_list[j],vtab_list[i], vtab_dict)==1):
333                     if i > j:
334                         vtab_list.insert(j,vtab_list[i])
335                         if i > j:
336                             vtab_list.pop(i+1)
337                         else:
338                             vtab_list.pop(i)
339         return vtab_list
340         
341         
342     def generate_type_definitions(self, env, modules, vtab_list, vtabslot_list, code):
343         for module in modules:
344             definition = module is env
345             if definition:
346                 type_entries = module.type_entries
347             else:
348                 type_entries = []
349                 for entry in module.type_entries:
350                     if entry.defined_in_pxd:
351                         type_entries.append(entry)
352             for entry in type_entries:
353                 if not entry.in_cinclude:
354                     #print "generate_type_header_code:", entry.name, repr(entry.type) ###
355                     type = entry.type
356                     if type.is_typedef: # Must test this first!
357                         self.generate_typedef(entry, code)
358                     elif type.is_struct_or_union:
359                         self.generate_struct_union_definition(entry, code)
360                     elif type.is_enum:
361                         self.generate_enum_definition(entry, code)
362                     elif type.is_extension_type and (not (entry in vtabslot_list)):
363                         self.generate_obj_struct_definition(type, code)
364         for entry in vtabslot_list:
365             self.generate_obj_struct_definition(entry.type, code)
366         for entry in vtab_list:
367             self.generate_typeobject_predeclaration(entry, code)
368             self.generate_exttype_vtable_struct(entry, code)
369             self.generate_exttype_vtabptr_declaration(entry, code)
370
371     
372     def generate_declarations_for_modules(self, env, modules, code):
373         code.putln("")
374         code.putln("/* Declarations */")
375         vtab_dict = self.generate_vtab_dict(modules)
376         vtab_list = self.generate_vtab_list(vtab_dict)
377         vtabslot_dict = self.generate_vtabslot_dict(modules,env)
378         vtabslot_list = self.generate_vtabslot_list(vtabslot_dict)
379         self.generate_type_definitions(env, modules, vtab_list, vtabslot_list, code)
380         for module in modules:
381             definition = module is env
382             self.generate_global_declarations(module, code, definition)
383             self.generate_cfunction_predeclarations(module, code, definition)
384
385     def generate_module_preamble(self, env, cimported_modules, code):
386         code.putln('/* Generated by Cython %s on %s */' % (
387             Version.version, time.asctime()))
388         code.putln('')
389         code.putln('#define PY_SSIZE_T_CLEAN')
390         for filename in env.python_include_files:
391             code.putln('#include "%s"' % filename)
392         code.putln("#ifndef PY_LONG_LONG")
393         code.putln("  #define PY_LONG_LONG LONG_LONG")
394         code.putln("#endif")
395         code.putln("#if PY_VERSION_HEX < 0x02050000")
396         code.putln("  typedef int Py_ssize_t;")
397         code.putln("  #define PY_SSIZE_T_MAX INT_MAX")
398         code.putln("  #define PY_SSIZE_T_MIN INT_MIN")
399         code.putln("  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)")
400         code.putln("  #define PyInt_AsSsize_t(o)   PyInt_AsLong(o)")
401         code.putln("  #define PyNumber_Index(o)    PyNumber_Int(o)")
402         code.putln("  #define PyIndex_Check(o)     PyNumber_Check(o)")
403         code.putln("#endif")
404         code.putln("#if PY_VERSION_HEX < 0x02040000")
405         code.putln("  #define METH_COEXIST 0")
406         code.putln("#endif")
407         code.putln("#ifndef __stdcall")
408         code.putln("  #define __stdcall")
409         code.putln("#endif")
410         code.putln("#ifndef __cdecl")
411         code.putln("  #define __cdecl")
412         code.putln("#endif")
413         self.generate_extern_c_macro_definition(code)
414         code.putln("#include <math.h>")
415         self.generate_includes(env, cimported_modules, code)
416         code.putln('')
417         code.put(Nodes.utility_function_predeclarations)
418         code.put(PyrexTypes.type_conversion_predeclarations)
419         code.put(Nodes.branch_prediction_macros)
420         code.putln('')
421         code.putln('static PyObject *%s;' % env.module_cname)
422         code.putln('static PyObject *%s;' % Naming.builtins_cname)
423         code.putln('static PyObject *%s;' % Naming.empty_tuple)
424         if Options.pre_import is not None:
425             code.putln('static PyObject *%s;' % Naming.preimport_cname)
426         code.putln('static int %s;' % Naming.lineno_cname)
427         code.putln('static int %s = 0;' % Naming.clineno_cname)
428         code.putln('static char * %s= %s;' % (Naming.cfilenm_cname, Naming.file_c_macro))
429         code.putln('static char *%s;' % Naming.filename_cname)
430         code.putln('static char **%s;' % Naming.filetable_cname)
431         if env.doc:
432             code.putln('')
433             code.putln('static char %s[] = "%s";' % (env.doc_cname, env.doc))
434     
435     def generate_extern_c_macro_definition(self, code):
436         name = Naming.extern_c_macro
437         code.putln("#ifdef __cplusplus")
438         code.putln('#define %s extern "C"' % name)
439         code.putln("#else")
440         code.putln("#define %s extern" % name)
441         code.putln("#endif")
442
443     def generate_includes(self, env, cimported_modules, code):
444         includes = env.include_files[:]
445         for module in cimported_modules:
446             for filename in module.include_files:
447                 if filename not in includes:
448                     includes.append(filename)
449         for filename in includes:
450             code.putln('#include "%s"' % filename)
451     
452     def generate_filename_table(self, code):
453         code.putln("")
454         code.putln("static char *%s[] = {" % Naming.filenames_cname)
455         if code.filename_list:
456             for filename in code.filename_list:
457                 filename = os.path.basename(filename)
458                 escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"')
459                 code.putln('"%s",' % 
460                     escaped_filename)
461         else:
462             # Some C compilers don't like an empty array
463             code.putln("0")
464         code.putln("};")
465
466     def generate_type_predeclarations(self, env, code):
467         pass
468
469     def generate_type_header_code(self, type_entries, code):
470         # Generate definitions of structs/unions/enums/typedefs/objstructs.
471         #self.generate_gcc33_hack(env, code) # Is this still needed?
472         #for entry in env.type_entries:
473         for entry in type_entries:
474             if not entry.in_cinclude:
475                 #print "generate_type_header_code:", entry.name, repr(entry.type) ###
476                 type = entry.type
477                 if type.is_typedef: # Must test this first!
478                     self.generate_typedef(entry, code)
479                 elif type.is_struct_or_union:
480                     self.generate_struct_union_definition(entry, code)
481                 elif type.is_enum:
482                     self.generate_enum_definition(entry, code)
483                 elif type.is_extension_type:
484                     self.generate_obj_struct_definition(type, code)
485         
486     def generate_gcc33_hack(self, env, code):
487         # Workaround for spurious warning generation in gcc 3.3
488         code.putln("")
489         for entry in env.c_class_entries:
490             type = entry.type
491             if not type.typedef_flag:
492                 name = type.objstruct_cname
493                 if name.startswith("__pyx_"):
494                     tail = name[6:]
495                 else:
496                     tail = name
497                 code.putln("typedef struct %s __pyx_gcc33_%s;" % (
498                     name, tail))
499     
500     def generate_typedef(self, entry, code):
501         base_type = entry.type.typedef_base_type
502         code.putln("")
503         code.putln("typedef %s;" % base_type.declaration_code(entry.cname))
504
505     def sue_header_footer(self, type, kind, name):
506         if type.typedef_flag:
507             header = "typedef %s {" % kind
508             footer = "} %s;" % name
509         else:
510             header = "%s %s {" % (kind, name)
511             footer = "};"
512         return header, footer
513     
514     def generate_struct_union_definition(self, entry, code):
515         code.mark_pos(entry.pos)
516         type = entry.type
517         scope = type.scope
518         if scope:
519             header, footer = \
520                 self.sue_header_footer(type, type.kind, type.cname)
521             code.putln("")
522             code.putln(header)
523             var_entries = scope.var_entries
524             if not var_entries:
525                 error(entry.pos,
526                     "Empty struct or union definition not allowed outside a"
527                     " 'cdef extern from' block")
528             for attr in var_entries:
529                 code.putln(
530                     "%s;" %
531                         attr.type.declaration_code(attr.cname))
532             code.putln(footer)
533
534     def generate_enum_definition(self, entry, code):
535         code.mark_pos(entry.pos)
536         type = entry.type
537         name = entry.cname or entry.name or ""
538         header, footer = \
539             self.sue_header_footer(type, "enum", name)
540         code.putln("")
541         code.putln(header)
542         enum_values = entry.enum_values
543         if not enum_values:
544             error(entry.pos,
545                 "Empty enum definition not allowed outside a"
546                 " 'cdef extern from' block")
547         else:
548             last_entry = enum_values[-1]
549             for value_entry in enum_values:
550                 if value_entry.value == value_entry.name:
551                     value_code = value_entry.cname
552                 else:
553                     value_code = ("%s = %s" % (
554                         value_entry.cname,
555                         value_entry.value))
556                 if value_entry is not last_entry:
557                     value_code += ","
558                 code.putln(value_code)
559         code.putln(footer)
560     
561     def generate_typeobject_predeclaration(self, entry, code):
562         code.putln("")
563         name = entry.type.typeobj_cname
564         if name:
565             if entry.visibility == 'extern' and not entry.in_cinclude:
566                 code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
567                     Naming.extern_c_macro,
568                     name))
569             elif entry.visibility == 'public':
570                 #code.putln("DL_EXPORT(PyTypeObject) %s;" % name)
571                 code.putln("%s DL_EXPORT(PyTypeObject) %s;" % (
572                     Naming.extern_c_macro,
573                     name))
574             # ??? Do we really need the rest of this? ???
575             #else:
576             #   code.putln("staticforward PyTypeObject %s;" % name)
577     
578     def generate_exttype_vtable_struct(self, entry, code):
579         code.mark_pos(entry.pos)
580         # Generate struct declaration for an extension type's vtable.
581         type = entry.type
582         scope = type.scope
583         if type.vtabstruct_cname:
584             code.putln("")
585             code.putln(
586                 "struct %s {" %
587                     type.vtabstruct_cname)
588             if type.base_type and type.base_type.vtabstruct_cname:
589                 code.putln("struct %s %s;" % (
590                     type.base_type.vtabstruct_cname,
591                     Naming.obj_base_cname))
592             for method_entry in scope.cfunc_entries:
593                 if not method_entry.is_inherited:
594                     code.putln(
595                         "%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.name))
596             code.putln(
597                 "};")
598     
599     def generate_exttype_vtabptr_declaration(self, entry, code):
600         code.mark_pos(entry.pos)
601         # Generate declaration of pointer to an extension type's vtable.
602         type = entry.type
603         if type.vtabptr_cname:
604             code.putln("static struct %s *%s;" % (
605                 type.vtabstruct_cname,
606                 type.vtabptr_cname))
607     
608     def generate_obj_struct_definition(self, type, code):
609         code.mark_pos(type.pos)
610         # Generate object struct definition for an
611         # extension type.
612         if not type.scope:
613             return # Forward declared but never defined
614         header, footer = \
615             self.sue_header_footer(type, "struct", type.objstruct_cname)
616         code.putln("")
617         code.putln(header)
618         base_type = type.base_type
619         if base_type:
620             code.putln(
621                 "%s%s %s;" % (
622                     ("struct ", "")[base_type.typedef_flag],
623                     base_type.objstruct_cname,
624                     Naming.obj_base_cname))
625         else:
626             code.putln(
627                 "PyObject_HEAD")
628         if type.vtabslot_cname and not (type.base_type and type.base_type.vtabslot_cname):
629             code.putln(
630                 "struct %s *%s;" % (
631                     type.vtabstruct_cname,
632                     type.vtabslot_cname))
633         for attr in type.scope.var_entries:
634             code.putln(
635                 "%s;" %
636                     attr.type.declaration_code(attr.cname))
637         code.putln(footer)
638
639     def generate_global_declarations(self, env, code, definition):
640         code.putln("")
641         for entry in env.c_class_entries:
642             if definition or entry.defined_in_pxd:
643                 code.putln("static PyTypeObject *%s = 0;" % 
644                     entry.type.typeptr_cname)
645         code.put_var_declarations(env.var_entries, static = 1, 
646             dll_linkage = "DL_EXPORT", definition = definition)
647         code.put_var_declarations(env.default_entries, static = 1,
648                                   definition = definition)
649     
650     def generate_cfunction_predeclarations(self, env, code, definition):
651         for entry in env.cfunc_entries:
652             if not entry.in_cinclude and (definition
653                     or entry.defined_in_pxd or entry.visibility == 'extern'):
654                 if entry.visibility in ('public', 'extern'):
655                     dll_linkage = "DL_EXPORT"
656                 else:
657                     dll_linkage = None
658                 type = entry.type
659                 if not definition and entry.defined_in_pxd:
660                     type = CPtrType(type)
661                 header = type.declaration_code(entry.cname, 
662                     dll_linkage = dll_linkage)
663                 if entry.visibility == 'private':
664                     storage_class = "static "
665                 elif entry.visibility == 'extern':
666                     storage_class = "%s " % Naming.extern_c_macro
667                 else:
668                     storage_class = ""
669                 code.putln("%s%s; /*proto*/" % (
670                     storage_class,
671                     header))
672     
673     def generate_typeobj_definitions(self, env, code):
674         full_module_name = env.qualified_name
675         for entry in env.c_class_entries:
676             #print "generate_typeobj_definitions:", entry.name
677             #print "...visibility =", entry.visibility
678             if entry.visibility != 'extern':
679                 type = entry.type
680                 scope = type.scope
681                 if scope: # could be None if there was an error
682                     self.generate_exttype_vtable(scope, code)
683                     self.generate_new_function(scope, code)
684                     self.generate_dealloc_function(scope, code)
685                     if scope.needs_gc():
686                         self.generate_traverse_function(scope, code)
687                         self.generate_clear_function(scope, code)
688                     if scope.defines_any(["__getitem__"]):
689                         self.generate_getitem_int_function(scope, code)
690                     if scope.defines_any(["__setitem__", "__delitem__"]):
691                         self.generate_ass_subscript_function(scope, code)
692                     if scope.defines_any(["__setslice__", "__delslice__"]):
693                         self.generate_ass_slice_function(scope, code)
694                     if scope.defines_any(["__getattr__"]):
695                         self.generate_getattro_function(scope, code)
696                     if scope.defines_any(["__setattr__", "__delattr__"]):
697                         self.generate_setattro_function(scope, code)
698                     if scope.defines_any(["__get__"]):
699                         self.generate_descr_get_function(scope, code)
700                     if scope.defines_any(["__set__", "__delete__"]):
701                         self.generate_descr_set_function(scope, code)
702                     self.generate_property_accessors(scope, code)
703                     self.generate_method_table(scope, code)
704                     self.generate_member_table(scope, code)
705                     self.generate_getset_table(scope, code)
706                     self.generate_typeobj_definition(full_module_name, entry, code)
707     
708     def generate_exttype_vtable(self, scope, code):
709         # Generate the definition of an extension type's vtable.
710         type = scope.parent_type
711         if type.vtable_cname:
712             code.putln("static struct %s %s;" % (
713                 type.vtabstruct_cname,
714                 type.vtable_cname))
715         
716     def generate_self_cast(self, scope, code):
717         type = scope.parent_type
718         code.putln(
719             "%s = (%s)o;" % (
720                 type.declaration_code("p"),
721                 type.declaration_code("")))
722     
723     def generate_new_function(self, scope, code):
724         tp_slot = TypeSlots.ConstructorSlot("tp_new", '__new__')
725         slot_func = scope.mangle_internal("tp_new")
726         type = scope.parent_type
727         base_type = type.base_type
728         py_attrs = []
729         for entry in scope.var_entries:
730             if entry.type.is_pyobject:
731                 py_attrs.append(entry)
732         need_self_cast = type.vtabslot_cname or py_attrs
733         code.putln("")
734         code.putln(
735             "static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k) {"
736                 % scope.mangle_internal("tp_new"))
737         if need_self_cast:
738             code.putln(
739                 "%s;"
740                     % scope.parent_type.declaration_code("p"))
741         if base_type:
742             tp_new = TypeSlots.get_base_slot_function(scope, tp_slot)
743             if tp_new is None:
744                 tp_new = "%s->tp_new" % base_type.typeptr_cname
745             code.putln(
746                 "PyObject *o = %s(t, a, k);" % tp_new)
747         else:
748             code.putln(
749                 "PyObject *o = (*t->tp_alloc)(t, 0);")
750         code.putln(
751                 "if (!o) return 0;")
752         if need_self_cast:
753             code.putln(
754                 "p = %s;"
755                     % type.cast_code("o"))
756         #if need_self_cast:
757         #       self.generate_self_cast(scope, code)
758         if type.vtabslot_cname:
759             code.putln("*(struct %s **)&p->%s = %s;" % (
760                 type.vtabstruct_cname,
761                 type.vtabslot_cname,
762                 type.vtabptr_cname))
763         for entry in py_attrs:
764             if entry.name == "__weakref__":
765                 code.putln("p->%s = 0;" % entry.cname)
766             else:
767                 code.put_init_var_to_py_none(entry, "p->%s")
768         entry = scope.lookup_here("__new__")
769         if entry:
770             if entry.trivial_signature:
771                 cinit_args = "o, %s, NULL" % Naming.empty_tuple
772             else:
773                 cinit_args = "o, a, k"
774             code.putln(
775                 "if (%s(%s) < 0) {" % 
776                     (entry.func_cname, cinit_args))
777             code.put_decref_clear("o", py_object_type);
778             code.putln(
779                 "}")
780         code.putln(
781             "return o;")
782         code.putln(
783             "}")
784     
785     def generate_dealloc_function(self, scope, code):
786         tp_slot = TypeSlots.ConstructorSlot("tp_dealloc", '__dealloc__')
787         slot_func = scope.mangle_internal("tp_dealloc")
788         base_type = scope.parent_type.base_type
789         if tp_slot.slot_code(scope) != slot_func:
790             return # never used
791         code.putln("")
792         code.putln(
793             "static void %s(PyObject *o) {"
794                 % scope.mangle_internal("tp_dealloc"))
795         py_attrs = []
796         weakref_slot = scope.lookup_here("__weakref__")
797         for entry in scope.var_entries:
798             if entry.type.is_pyobject and entry is not weakref_slot:
799                 py_attrs.append(entry)
800         if py_attrs or weakref_slot in scope.var_entries:
801             self.generate_self_cast(scope, code)
802         self.generate_usr_dealloc_call(scope, code)
803         if weakref_slot in scope.var_entries:
804             code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);")
805         for entry in py_attrs:
806             code.put_xdecref("p->%s" % entry.cname, entry.type)
807         if base_type:
808             tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot)
809             if tp_dealloc is None:
810                 tp_dealloc = "%s->tp_dealloc" % base_type.typeptr_cname
811             code.putln(
812                     "%s(o);" % tp_dealloc)
813         else:
814             code.putln(
815                     "(*o->ob_type->tp_free)(o);")
816         code.putln(
817             "}")
818     
819     def generate_usr_dealloc_call(self, scope, code):
820         entry = scope.lookup_here("__dealloc__")
821         if entry:
822             code.putln(
823                 "{")
824             code.putln(
825                     "PyObject *etype, *eval, *etb;")
826             code.putln(
827                     "PyErr_Fetch(&etype, &eval, &etb);")
828             code.putln(
829                     "++o->ob_refcnt;")
830             code.putln(
831                     "%s(o);" % 
832                         entry.func_cname)
833             code.putln(
834                     "if (PyErr_Occurred()) PyErr_WriteUnraisable(o);")
835             code.putln(
836                     "--o->ob_refcnt;")
837             code.putln(
838                     "PyErr_Restore(etype, eval, etb);")
839             code.putln(
840                 "}")
841     
842     def generate_traverse_function(self, scope, code):
843         tp_slot = TypeSlots.GCDependentSlot("tp_traverse")
844         slot_func = scope.mangle_internal("tp_traverse")
845         base_type = scope.parent_type.base_type
846         if tp_slot.slot_code(scope) != slot_func:
847             return # never used
848         code.putln("")
849         code.putln(
850             "static int %s(PyObject *o, visitproc v, void *a) {"
851                 % slot_func)
852         py_attrs = []
853         for entry in scope.var_entries:
854             if entry.type.is_pyobject and entry.name != "__weakref__":
855                 py_attrs.append(entry)
856         if base_type or py_attrs:
857             code.putln("int e;")
858         if py_attrs:
859             self.generate_self_cast(scope, code)
860         if base_type:
861             # want to call it explicitly if possible so inlining can be performed
862             static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
863             if static_call:
864                 code.putln("e = %s(o, v, a); if (e) return e;" % static_call)
865             else:
866                 code.putln("if (%s->tp_traverse) {" % base_type.typeptr_cname)
867                 code.putln(
868                         "e = %s->tp_traverse(o, v, a); if (e) return e;" %
869                             base_type.typeptr_cname)
870                 code.putln("}")
871         for entry in py_attrs:
872             var_code = "p->%s" % entry.cname
873             code.putln(
874                     "if (%s) {"
875                         % var_code)
876             if entry.type.is_extension_type:
877                 var_code = "((PyObject*)%s)" % var_code
878             code.putln(
879                         "e = (*v)(%s, a); if (e) return e;" 
880                             % var_code)
881             code.putln(
882                     "}")
883         code.putln(
884                 "return 0;")
885         code.putln(
886             "}")
887     
888     def generate_clear_function(self, scope, code):
889         tp_slot = TypeSlots.GCDependentSlot("tp_clear")
890         slot_func = scope.mangle_internal("tp_clear")
891         base_type = scope.parent_type.base_type
892         if tp_slot.slot_code(scope) != slot_func:
893             return # never used
894         code.putln("")
895         code.putln("static int %s(PyObject *o) {" % slot_func)
896         py_attrs = []
897         for entry in scope.var_entries:
898             if entry.type.is_pyobject and entry.name != "__weakref__":
899                 py_attrs.append(entry)
900         if py_attrs:
901             self.generate_self_cast(scope, code)
902             code.putln("PyObject* tmp;")
903         if base_type:
904             # want to call it explicitly if possible so inlining can be performed
905             static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
906             if static_call:
907                 code.putln("%s(o);" % static_call)
908             else:
909                 code.putln("if (%s->tp_clear) {" % base_type.typeptr_cname)
910                 code.putln("%s->tp_clear(o);" % base_type.typeptr_cname)
911                 code.putln("}")
912         for entry in py_attrs:
913             name = "p->%s" % entry.cname
914             code.putln("tmp = ((PyObject*)%s);" % name)
915             code.put_init_to_py_none(name, entry.type)
916             code.putln("Py_XDECREF(tmp);")
917         code.putln(
918             "return 0;")
919         code.putln(
920             "}")
921             
922     def generate_getitem_int_function(self, scope, code):
923         # This function is put into the sq_item slot when
924         # a __getitem__ method is present. It converts its
925         # argument to a Python integer and calls mp_subscript.
926         code.putln(
927             "static PyObject *%s(PyObject *o, Py_ssize_t i) {" %
928                 scope.mangle_internal("sq_item"))
929         code.putln(
930                 "PyObject *r;")
931         code.putln(
932                 "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;")
933         code.putln(
934                 "r = o->ob_type->tp_as_mapping->mp_subscript(o, x);")
935         code.putln(
936                 "Py_DECREF(x);")
937         code.putln(
938                 "return r;")
939         code.putln(
940             "}")
941
942     def generate_ass_subscript_function(self, scope, code):
943         # Setting and deleting an item are both done through
944         # the ass_subscript method, so we dispatch to user's __setitem__
945         # or __delitem__, or raise an exception.
946         base_type = scope.parent_type.base_type
947         set_entry = scope.lookup_here("__setitem__")
948         del_entry = scope.lookup_here("__delitem__")
949         code.putln("")
950         code.putln(
951             "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
952                 scope.mangle_internal("mp_ass_subscript"))
953         code.putln(
954                 "if (v) {")
955         if set_entry:
956             code.putln(
957                     "return %s(o, i, v);" %
958                         set_entry.func_cname)
959         else:
960             self.generate_guarded_basetype_call(
961                 base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
962             code.putln(
963                     "PyErr_Format(PyExc_NotImplementedError,")
964             code.putln(
965                     '  "Subscript assignment not supported by %s", o->ob_type->tp_name);')
966             code.putln(
967                     "return -1;")
968         code.putln(
969                 "}")
970         code.putln(
971                 "else {")
972         if del_entry:
973             code.putln(
974                     "return %s(o, i);" %
975                         del_entry.func_cname)
976         else:
977             self.generate_guarded_basetype_call(
978                 base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
979             code.putln(
980                     "PyErr_Format(PyExc_NotImplementedError,")
981             code.putln(
982                     '  "Subscript deletion not supported by %s", o->ob_type->tp_name);')
983             code.putln(
984                     "return -1;")
985         code.putln(
986                 "}")
987         code.putln(
988             "}")
989     
990     def generate_guarded_basetype_call(
991             self, base_type, substructure, slot, args, code):
992         if base_type:
993             base_tpname = base_type.typeptr_cname
994             if substructure:
995                 code.putln(
996                     "if (%s->%s && %s->%s->%s)" % (
997                         base_tpname, substructure, base_tpname, substructure, slot))
998                 code.putln(
999                     "  return %s->%s->%s(%s);" % (
1000                         base_tpname, substructure, slot, args))
1001             else:
1002                 code.putln(
1003                     "if (%s->%s)" % (
1004                         base_tpname, slot))
1005                 code.putln(
1006                     "  return %s->%s(%s);" % (
1007                         base_tpname, slot, args))
1008
1009     def generate_ass_slice_function(self, scope, code):
1010         # Setting and deleting a slice are both done through
1011         # the ass_slice method, so we dispatch to user's __setslice__
1012         # or __delslice__, or raise an exception.
1013         base_type = scope.parent_type.base_type
1014         set_entry = scope.lookup_here("__setslice__")
1015         del_entry = scope.lookup_here("__delslice__")
1016         code.putln("")
1017         code.putln(
1018             "static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" %
1019                 scope.mangle_internal("sq_ass_slice"))
1020         code.putln(
1021                 "if (v) {")
1022         if set_entry:
1023             code.putln(
1024                     "return %s(o, i, j, v);" %
1025                         set_entry.func_cname)
1026         else:
1027             self.generate_guarded_basetype_call(
1028                 base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
1029             code.putln(
1030                     "PyErr_Format(PyExc_NotImplementedError,")
1031             code.putln(
1032                     '  "2-element slice assignment not supported by %s", o->ob_type->tp_name);')
1033             code.putln(
1034                     "return -1;")
1035         code.putln(
1036                 "}")
1037         code.putln(
1038                 "else {")
1039         if del_entry:
1040             code.putln(
1041                     "return %s(o, i, j);" %
1042                         del_entry.func_cname)
1043         else:
1044             self.generate_guarded_basetype_call(
1045                 base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
1046             code.putln(
1047                     "PyErr_Format(PyExc_NotImplementedError,")
1048             code.putln(
1049                     '  "2-element slice deletion not supported by %s", o->ob_type->tp_name);')
1050             code.putln(
1051                     "return -1;")
1052         code.putln(
1053                 "}")
1054         code.putln(
1055             "}")
1056
1057     def generate_getattro_function(self, scope, code):
1058         # First try to get the attribute using PyObject_GenericGetAttr.
1059         # If that raises an AttributeError, call the user's __getattr__
1060         # method.
1061         entry = scope.lookup_here("__getattr__")
1062         code.putln("")
1063         code.putln(
1064             "static PyObject *%s(PyObject *o, PyObject *n) {"
1065                 % scope.mangle_internal("tp_getattro"))
1066         code.putln(
1067                 "PyObject *v = PyObject_GenericGetAttr(o, n);")
1068         code.putln(
1069                 "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
1070         code.putln(
1071                     "PyErr_Clear();")
1072         code.putln(
1073                     "v = %s(o, n);" %
1074                         entry.func_cname)
1075         code.putln(
1076                 "}")
1077         code.putln(
1078                 "return v;")
1079         code.putln(
1080             "}")
1081     
1082     def generate_setattro_function(self, scope, code):
1083         # Setting and deleting an attribute are both done through
1084         # the setattro method, so we dispatch to user's __setattr__
1085         # or __delattr__ or fall back on PyObject_GenericSetAttr.
1086         base_type = scope.parent_type.base_type
1087         set_entry = scope.lookup_here("__setattr__")
1088         del_entry = scope.lookup_here("__delattr__")
1089         code.putln("")
1090         code.putln(
1091             "static int %s(PyObject *o, PyObject *n, PyObject *v) {" %
1092                 scope.mangle_internal("tp_setattro"))
1093         code.putln(
1094                 "if (v) {")
1095         if set_entry:
1096             code.putln(
1097                     "return %s(o, n, v);" %
1098                         set_entry.func_cname)
1099         else:
1100             self.generate_guarded_basetype_call(
1101                 base_type, None, "tp_setattro", "o, n, v", code)
1102             code.putln(
1103                     "return PyObject_GenericSetAttr(o, n, v);")
1104         code.putln(
1105                 "}")
1106         code.putln(
1107                 "else {")
1108         if del_entry:
1109             code.putln(
1110                     "return %s(o, n);" %
1111                         del_entry.func_cname)
1112         else:
1113             self.generate_guarded_basetype_call(
1114                 base_type, None, "tp_setattro", "o, n, v", code)
1115             code.putln(
1116                     "return PyObject_GenericSetAttr(o, n, 0);")
1117         code.putln(
1118                 "}")
1119         code.putln(
1120             "}")
1121     
1122     def generate_descr_get_function(self, scope, code):
1123         # The __get__ function of a descriptor object can be
1124         # called with NULL for the second or third arguments
1125         # under some circumstances, so we replace them with
1126         # None in that case.
1127         user_get_entry = scope.lookup_here("__get__")
1128         code.putln("")
1129         code.putln(
1130             "static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" %
1131                 scope.mangle_internal("tp_descr_get"))
1132         code.putln(
1133             "PyObject *r = 0;")
1134         code.putln(
1135             "if (!i) i = Py_None;")
1136         code.putln(
1137             "if (!c) c = Py_None;")
1138         #code.put_incref("i", py_object_type)
1139         #code.put_incref("c", py_object_type)
1140         code.putln(
1141             "r = %s(o, i, c);" %
1142                 user_get_entry.func_cname)
1143         #code.put_decref("i", py_object_type)
1144         #code.put_decref("c", py_object_type)
1145         code.putln(
1146             "return r;")
1147         code.putln(
1148             "}")
1149     
1150     def generate_descr_set_function(self, scope, code):
1151         # Setting and deleting are both done through the __set__
1152         # method of a descriptor, so we dispatch to user's __set__
1153         # or __delete__ or raise an exception.
1154         base_type = scope.parent_type.base_type
1155         user_set_entry = scope.lookup_here("__set__")
1156         user_del_entry = scope.lookup_here("__delete__")
1157         code.putln("")
1158         code.putln(
1159             "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
1160                 scope.mangle_internal("tp_descr_set"))
1161         code.putln(
1162                 "if (v) {")
1163         if user_set_entry:
1164             code.putln(
1165                     "return %s(o, i, v);" %
1166                         user_set_entry.func_cname)
1167         else:
1168             self.generate_guarded_basetype_call(
1169                 base_type, None, "tp_descr_set", "o, i, v", code)
1170             code.putln(
1171                     'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
1172             code.putln(
1173                     "return -1;")
1174         code.putln(
1175                 "}")
1176         code.putln(
1177                 "else {")
1178         if user_del_entry:
1179             code.putln(
1180                     "return %s(o, i);" %
1181                         user_del_entry.func_cname)
1182         else:
1183             self.generate_guarded_basetype_call(
1184                 base_type, None, "tp_descr_set", "o, i, v", code)
1185             code.putln(
1186                     'PyErr_SetString(PyExc_NotImplementedError, "__delete__");')
1187             code.putln(
1188                     "return -1;")
1189         code.putln(
1190                 "}")            
1191         code.putln(
1192             "}")
1193     
1194     def generate_property_accessors(self, cclass_scope, code):
1195         for entry in cclass_scope.property_entries:
1196             property_scope = entry.scope
1197             if property_scope.defines_any(["__get__"]):
1198                 self.generate_property_get_function(entry, code)
1199             if property_scope.defines_any(["__set__", "__del__"]):
1200                 self.generate_property_set_function(entry, code)
1201     
1202     def generate_property_get_function(self, property_entry, code):
1203         property_scope = property_entry.scope
1204         property_entry.getter_cname = property_scope.parent_scope.mangle(
1205             Naming.prop_get_prefix, property_entry.name)
1206         get_entry = property_scope.lookup_here("__get__")
1207         code.putln("")
1208         code.putln(
1209             "static PyObject *%s(PyObject *o, void *x) {" %
1210                 property_entry.getter_cname)
1211         code.putln(
1212                 "return %s(o);" %
1213                     get_entry.func_cname)
1214         code.putln(
1215             "}")
1216     
1217     def generate_property_set_function(self, property_entry, code):
1218         property_scope = property_entry.scope
1219         property_entry.setter_cname = property_scope.parent_scope.mangle(
1220             Naming.prop_set_prefix, property_entry.name)
1221         set_entry = property_scope.lookup_here("__set__")
1222         del_entry = property_scope.lookup_here("__del__")
1223         code.putln("")
1224         code.putln(
1225             "static int %s(PyObject *o, PyObject *v, void *x) {" %
1226                 property_entry.setter_cname)
1227         code.putln(
1228                 "if (v) {")
1229         if set_entry:
1230             code.putln(
1231                     "return %s(o, v);" %
1232                         set_entry.func_cname)
1233         else:
1234             code.putln(
1235                     'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
1236             code.putln(
1237                     "return -1;")
1238         code.putln(
1239                 "}")
1240         code.putln(
1241                 "else {")
1242         if del_entry:
1243             code.putln(
1244                     "return %s(o);" %
1245                         del_entry.func_cname)
1246         else:
1247             code.putln(
1248                     'PyErr_SetString(PyExc_NotImplementedError, "__del__");')
1249             code.putln(
1250                     "return -1;")
1251         code.putln(
1252                 "}")
1253         code.putln(
1254             "}")
1255
1256     def generate_typeobj_definition(self, modname, entry, code):
1257         type = entry.type
1258         scope = type.scope
1259         for suite in TypeSlots.substructures:
1260             suite.generate_substructure(scope, code)
1261         code.putln("")
1262         if entry.visibility == 'public':
1263             header = "DL_EXPORT(PyTypeObject) %s = {"
1264         else:
1265             #header = "statichere PyTypeObject %s = {"
1266             header = "PyTypeObject %s = {"
1267         #code.putln(header % scope.parent_type.typeobj_cname)
1268         code.putln(header % type.typeobj_cname)
1269         code.putln(
1270             "PyObject_HEAD_INIT(0)")
1271         code.putln(
1272             "0, /*ob_size*/")
1273         code.putln(
1274             '"%s.%s", /*tp_name*/' % (
1275                 self.full_module_name, scope.class_name))
1276         if type.typedef_flag:
1277             objstruct = type.objstruct_cname
1278         else:
1279             #objstruct = "struct %s" % scope.parent_type.objstruct_cname
1280             objstruct = "struct %s" % type.objstruct_cname
1281         code.putln(
1282             "sizeof(%s), /*tp_basicsize*/" %
1283                 objstruct)
1284         code.putln(
1285             "0, /*tp_itemsize*/")
1286         for slot in TypeSlots.slot_table:
1287             slot.generate(scope, code)
1288         code.putln(
1289             "};")
1290     
1291     def generate_method_table(self, env, code):
1292         code.putln("")
1293         code.putln(
1294             "static struct PyMethodDef %s[] = {" % 
1295                 env.method_table_cname)
1296         for entry in env.pyfunc_entries:
1297             code.put_pymethoddef(entry, ",")
1298         code.putln(
1299                 "{0, 0, 0, 0}")
1300         code.putln(
1301             "};")
1302     
1303     def generate_member_table(self, env, code):
1304         #print "ModuleNode.generate_member_table: scope =", env ###
1305         if env.public_attr_entries:
1306             code.putln("")
1307             code.putln(
1308                 "static struct PyMemberDef %s[] = {" %
1309                     env.member_table_cname)
1310             type = env.parent_type
1311             if type.typedef_flag:
1312                 objstruct = type.objstruct_cname
1313             else:
1314                 objstruct = "struct %s" % type.objstruct_cname
1315             for entry in env.public_attr_entries:
1316                 type_code = entry.type.pymemberdef_typecode
1317                 if entry.visibility == 'readonly':
1318                     flags = "READONLY"
1319                 else:
1320                     flags = "0"
1321                 code.putln('{"%s", %s, %s, %s, 0},' % (
1322                     entry.name,
1323                     type_code,
1324                     "offsetof(%s, %s)" % (objstruct, entry.cname),
1325                     flags))
1326             code.putln(
1327                     "{0, 0, 0, 0, 0}")
1328             code.putln(
1329                 "};")
1330     
1331     def generate_getset_table(self, env, code):
1332         if env.property_entries:
1333             code.putln("")
1334             code.putln(
1335                 "static struct PyGetSetDef %s[] = {" %
1336                     env.getset_table_cname)
1337             for entry in env.property_entries:
1338                 code.putln(
1339                     '{"%s", %s, %s, %s, 0},' % (
1340                         entry.name,
1341                         entry.getter_cname or "0",
1342                         entry.setter_cname or "0",
1343                         entry.doc_cname or "0"))
1344             code.putln(
1345                     "{0, 0, 0, 0, 0}")
1346             code.putln(
1347                 "};")
1348     
1349     def generate_interned_name_table(self, env, code):
1350         code.mark_pos(None)
1351         items = env.intern_map.items()
1352         if items:
1353             items.sort()
1354             code.putln("")
1355             code.putln(
1356                 "static __Pyx_InternTabEntry %s[] = {" %
1357                     Naming.intern_tab_cname)
1358             for (name, cname) in items:
1359                 code.putln(
1360                     '{&%s, "%s"},' % (
1361                         cname,
1362                         name))
1363             code.putln(
1364                 "{0, 0}")
1365             code.putln(
1366                 "};")
1367     
1368     def generate_py_string_table(self, env, code):
1369         entries = env.all_pystring_entries
1370         if entries:
1371             code.putln("")
1372             code.putln(
1373                 "static __Pyx_StringTabEntry %s[] = {" %
1374                     Naming.stringtab_cname)
1375             for entry in entries:
1376                 code.putln(
1377                     "{&%s, %s, sizeof(%s), %d}," % (
1378                         entry.pystring_cname,
1379                         entry.cname,
1380                         entry.cname,
1381                         entry.type.is_unicode
1382                         ))
1383             code.putln(
1384                 "{0, 0, 0, 0}")
1385             code.putln(
1386                 "};")
1387
1388
1389     def generate_filename_init_prototype(self, code):
1390         code.putln("");
1391         code.putln("static void %s(void); /*proto*/" % Naming.fileinit_cname)
1392
1393     def generate_module_init_func(self, imported_modules, env, code):
1394         code.putln("")
1395         header = "PyMODINIT_FUNC init%s(void)" % env.module_name
1396         code.putln("%s; /*proto*/" % header)
1397         code.putln("%s {" % header)
1398         code.put_var_declarations(env.temp_entries)
1399
1400         code.putln("/*--- Libary function declarations ---*/")
1401         env.generate_library_function_declarations(code)
1402         self.generate_filename_init_call(code)
1403
1404         code.putln("/*--- Module creation code ---*/")
1405         self.generate_module_creation_code(env, code)
1406
1407         code.putln("/*--- Intern code ---*/")
1408         self.generate_intern_code(env, code)
1409
1410         code.putln("/*--- String init code ---*/")
1411         self.generate_string_init_code(env, code)
1412
1413         if Options.cache_builtins:
1414             code.putln("/*--- Builtin init code ---*/")
1415             self.generate_builtin_init_code(env, code)
1416             
1417         code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos)));
1418         code.putln("%s = 0;" % Naming.skip_dispatch_cname);
1419
1420         code.putln("/*--- Global init code ---*/")
1421         self.generate_global_init_code(env, code)
1422
1423         code.putln("/*--- Function export code ---*/")
1424         self.generate_c_function_export_code(env, code)
1425
1426         code.putln("/*--- Type init code ---*/")
1427         self.generate_type_init_code(env, code)
1428
1429         code.putln("/*--- Type import code ---*/")
1430         for module in imported_modules:
1431             self.generate_type_import_code_for_module(module, env, code)
1432
1433         code.putln("/*--- Function import code ---*/")
1434         for module in imported_modules:
1435             self.generate_c_function_import_code_for_module(module, env, code)
1436
1437         code.putln("/*--- Execution code ---*/")
1438         code.mark_pos(None)
1439         self.body.generate_execution_code(code)
1440
1441         if Options.generate_cleanup_code:
1442             code.putln("if (__Pyx_RegisterCleanup()) %s;" % code.error_goto(self.pos))
1443
1444         code.putln("return;")
1445         code.put_label(code.error_label)
1446         code.put_var_xdecrefs(env.temp_entries)
1447         code.putln('__Pyx_AddTraceback("%s");' % env.qualified_name)
1448         env.use_utility_code(Nodes.traceback_utility_code)
1449         code.putln('}')
1450
1451     def generate_module_cleanup_func(self, env, code):
1452         if not Options.generate_cleanup_code:
1453             return
1454         env.use_utility_code(import_module_utility_code)
1455         env.use_utility_code(register_cleanup_utility_code)
1456         code.putln()
1457         code.putln('static PyObject* %s(PyObject *self, PyObject *unused) {' % Naming.cleanup_cname)
1458         if Options.generate_cleanup_code >= 2:
1459             code.putln("/*--- Global cleanup code ---*/")
1460             rev_entries = list(env.var_entries)
1461             rev_entries.reverse()
1462             for entry in rev_entries:
1463                 if entry.visibility != 'extern':
1464                     if entry.type.is_pyobject:
1465                         code.put_var_decref_clear(entry)
1466         if Options.generate_cleanup_code >= 3:
1467             code.putln("/*--- Type import cleanup code ---*/")
1468             for type, _ in env.types_imported.items():
1469                 code.put_decref("((PyObject*)%s)" % type.typeptr_cname, PyrexTypes.py_object_type)
1470         if Options.cache_builtins:
1471             code.putln("/*--- Builtin cleanup code ---*/")
1472             for entry in env.cached_builtins:
1473                 code.put_var_decref_clear(entry)
1474         code.putln("Py_DECREF(%s); %s = 0;" % (Naming.empty_tuple, Naming.empty_tuple));
1475         code.putln("/*--- Intern cleanup code ---*/")
1476         for entry in env.pynum_entries:
1477             code.put_var_decref_clear(entry)
1478         if env.intern_map:
1479             for name, cname in env.intern_map.items():
1480                 code.put_decref_clear(cname, PyrexTypes.py_object_type)
1481         code.putln("Py_INCREF(Py_None); return Py_None;")
1482         code.putln('}')
1483
1484     def generate_filename_init_call(self, code):
1485         code.putln("%s();" % Naming.fileinit_cname)
1486     
1487     def generate_module_creation_code(self, env, code):
1488         # Generate code to create the module object and
1489         # install the builtins.
1490         if env.doc:
1491             doc = env.doc_cname
1492         else:
1493             doc = "0"
1494         code.putln(
1495             '%s = Py_InitModule4("%s", %s, %s, 0, PYTHON_API_VERSION);' % (
1496                 env.module_cname, 
1497                 env.module_name, 
1498                 env.method_table_cname, 
1499                 doc))
1500         code.putln(
1501             "if (!%s) %s;" % (
1502                 env.module_cname,
1503                 code.error_goto(self.pos)));
1504         code.putln(
1505             '%s = PyImport_AddModule("__builtin__");' %
1506                 Naming.builtins_cname)
1507         code.putln(
1508             "if (!%s) %s;" % (
1509                 Naming.builtins_cname,
1510                 code.error_goto(self.pos)));
1511         code.putln(
1512             'if (PyObject_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % (
1513                 env.module_cname,
1514                 Naming.builtins_cname,
1515                 code.error_goto(self.pos)))
1516         if Options.pre_import is not None:
1517             code.putln(
1518                 '%s = PyImport_AddModule("%s");' % (
1519                     Naming.preimport_cname, 
1520                     Options.pre_import))
1521             code.putln(
1522                 "if (!%s) %s;" % (
1523                     Naming.preimport_cname,
1524                     code.error_goto(self.pos)));
1525     
1526     def generate_intern_code(self, env, code):
1527         for entry in env.pynum_entries:
1528             code.putln("%s = PyInt_FromLong(%s); %s;" % (
1529                 entry.cname,
1530                 entry.init,
1531                 code.error_goto_if_null(entry.cname, self.pos)))
1532         if env.intern_map:
1533             env.use_utility_code(Nodes.init_intern_tab_utility_code);
1534             code.putln(
1535                 "if (__Pyx_InternStrings(%s) < 0) %s;" % (
1536                     Naming.intern_tab_cname,
1537                     code.error_goto(self.pos)))
1538     
1539     def generate_string_init_code(self, env, code):
1540         if env.all_pystring_entries:
1541             env.use_utility_code(Nodes.init_string_tab_utility_code)
1542             code.putln(
1543                 "if (__Pyx_InitStrings(%s) < 0) %s;" % (
1544                     Naming.stringtab_cname,
1545                     code.error_goto(self.pos)))
1546
1547     def generate_builtin_init_code(self, env, code):
1548         # Lookup and cache builtin objects.
1549         if Options.cache_builtins:
1550             for entry in env.cached_builtins:
1551                 if Options.intern_names:
1552                     #assert entry.interned_cname is not None
1553                     code.putln(
1554                         '%s = __Pyx_GetName(%s, %s); if (!%s) %s' % (
1555                         entry.cname,
1556                         Naming.builtins_cname,
1557                         entry.interned_cname,
1558                         entry.cname,
1559                         code.error_goto(entry.pos)))
1560                 else:
1561                     code.putln(
1562                         '%s = __Pyx_GetName(%s, "%s"); if (!%s) %s' % (
1563                         entry.cname,
1564                         Naming.builtins_cname,
1565                         entry.name,
1566                         entry.cname, 
1567                         code.error_goto(entry.pos)))
1568     
1569     def generate_global_init_code(self, env, code):
1570         # Generate code to initialise global PyObject *
1571         # variables to None.
1572         for entry in env.var_entries:
1573             if entry.visibility != 'extern':
1574                 if entry.type.is_pyobject:
1575                     code.put_init_var_to_py_none(entry)
1576
1577     def generate_c_function_export_code(self, env, code):
1578         # Generate code to create PyCFunction wrappers for exported C functions.
1579         for entry in env.cfunc_entries:
1580             if entry.api or entry.defined_in_pxd:
1581                 env.use_utility_code(function_export_utility_code)
1582                 signature = entry.type.signature_string()
1583                 code.putln('if (__Pyx_ExportFunction("%s", (void*)%s, "%s") < 0) %s' % (
1584                     entry.name,
1585                     entry.cname,
1586                     signature, 
1587                     code.error_goto(self.pos)))
1588     
1589     def generate_type_import_code_for_module(self, module, env, code):
1590         # Generate type import code for all exported extension types in
1591         # an imported module.
1592         #if module.c_class_entries:
1593         for entry in module.c_class_entries:
1594             if entry.defined_in_pxd:
1595                 self.generate_type_import_code(env, entry.type, entry.pos, code)
1596     
1597     def generate_c_function_import_code_for_module(self, module, env, code):
1598         # Generate import code for all exported C functions in a cimported module.
1599         entries = []
1600         for entry in module.cfunc_entries:
1601             if entry.defined_in_pxd:
1602                 entries.append(entry)
1603         if entries:
1604             env.use_utility_code(import_module_utility_code)
1605             env.use_utility_code(function_import_utility_code)
1606             temp = self.module_temp_cname
1607             code.putln(
1608                 '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % (
1609                     temp,
1610                     module.qualified_name,
1611                     temp,
1612                     code.error_goto(self.pos)))
1613             for entry in entries:
1614                 code.putln(
1615                     'if (__Pyx_ImportFunction(%s, "%s", (void**)&%s, "%s") < 0) %s' % (
1616                         temp,
1617                         entry.name,
1618                         entry.cname,
1619                         entry.type.signature_string(),
1620                         code.error_goto(self.pos)))
1621             code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp))
1622     
1623     def generate_type_init_code(self, env, code):
1624         # Generate type import code for extern extension types
1625         # and type ready code for non-extern ones.
1626         for entry in env.c_class_entries:
1627             if entry.visibility == 'extern':
1628                 self.generate_type_import_code(env, entry.type, entry.pos, code)
1629             else:
1630                 self.generate_base_type_import_code(env, entry, code)
1631                 self.generate_exttype_vtable_init_code(entry, code)
1632                 self.generate_type_ready_code(env, entry, code)
1633                 self.generate_typeptr_assignment_code(entry, code)
1634
1635     def generate_base_type_import_code(self, env, entry, code):
1636         base_type = entry.type.base_type
1637         if base_type and base_type.module_name != env.qualified_name:
1638             self.generate_type_import_code(env, base_type, self.pos, code)
1639     
1640     def use_type_import_utility_code(self, env):
1641         env.use_utility_code(type_import_utility_code)
1642         env.use_utility_code(import_module_utility_code)
1643     
1644     def generate_type_import_code(self, env, type, pos, code):
1645         # If not already done, generate code to import the typeobject of an
1646         # extension type defined in another module, and extract its C method
1647         # table pointer if any.
1648         if type in env.types_imported:
1649             return
1650         if type.typedef_flag:
1651             objstruct = type.objstruct_cname
1652         else:
1653             objstruct = "struct %s" % type.objstruct_cname
1654         self.generate_type_import_call(type, code,
1655                                        code.error_goto_if_null(type.typeptr_cname, pos))
1656         self.use_type_import_utility_code(env)
1657         if type.vtabptr_cname:
1658             code.putln(
1659                 "if (__Pyx_GetVtable(%s->tp_dict, &%s) < 0) %s" % (
1660                     type.typeptr_cname,
1661                     type.vtabptr_cname,
1662                     code.error_goto(pos)))
1663             env.use_utility_code(Nodes.get_vtable_utility_code)
1664         env.types_imported[type] = 1
1665
1666     def generate_type_import_call(self, type, code, error_code):
1667         if type.typedef_flag:
1668             objstruct = type.objstruct_cname
1669         else:
1670             objstruct = "struct %s" % type.objstruct_cname
1671         code.putln('%s = __Pyx_ImportType("%s", "%s", sizeof(%s)); %s' % (
1672             type.typeptr_cname,
1673             type.module_name, 
1674             type.name,
1675             objstruct,
1676             error_code))
1677
1678     def generate_type_ready_code(self, env, entry, code):
1679         # Generate a call to PyType_Ready for an extension
1680         # type defined in this module.
1681         type = entry.type
1682         typeobj_cname = type.typeobj_cname
1683         scope = type.scope
1684         if scope: # could be None if there was an error
1685             if entry.visibility != 'extern':
1686                 for slot in TypeSlots.slot_table:
1687                     slot.generate_dynamic_init_code(scope, code)
1688                 code.putln(
1689                     "if (PyType_Ready(&%s) < 0) %s" % (
1690                         typeobj_cname,
1691                         code.error_goto(entry.pos)))
1692                 if type.vtable_cname:
1693                     code.putln(
1694                         "if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
1695                             typeobj_cname,
1696                             type.vtabptr_cname,
1697                             code.error_goto(entry.pos)))
1698                     env.use_utility_code(Nodes.set_vtable_utility_code)
1699                 code.putln(
1700                     'if (PyObject_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % (
1701                         Naming.module_cname,
1702                         scope.class_name,
1703                         typeobj_cname,
1704                         code.error_goto(entry.pos)))
1705                 weakref_entry = scope.lookup_here("__weakref__")
1706                 if weakref_entry:
1707                     if weakref_entry.type is py_object_type:
1708                         tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname
1709                         code.putln("if (%s == 0) %s = offsetof(struct %s, %s);" % (
1710                             tp_weaklistoffset,
1711                             tp_weaklistoffset,
1712                             type.objstruct_cname,
1713                             weakref_entry.cname))
1714                     else:
1715                         error(weakref_entry.pos, "__weakref__ slot must be of type 'object'")
1716     
1717     def generate_exttype_vtable_init_code(self, entry, code):
1718         # Generate code to initialise the C method table of an
1719         # extension type.
1720         type = entry.type
1721         if type.vtable_cname:
1722             code.putln(
1723                 "%s = &%s;" % (
1724                     type.vtabptr_cname,
1725                     type.vtable_cname))
1726             if type.base_type and type.base_type.vtabptr_cname:
1727                 code.putln(
1728                     "%s.%s = *%s;" % (
1729                         type.vtable_cname,
1730                         Naming.obj_base_cname,
1731                         type.base_type.vtabptr_cname))
1732             for meth_entry in type.scope.cfunc_entries:
1733                 if meth_entry.func_cname:
1734                     code.putln(
1735                         "*(void(**)(void))&%s.%s = (void(*)(void))%s;" % (
1736                             type.vtable_cname,
1737                             meth_entry.cname,
1738                             meth_entry.func_cname))
1739     
1740     def generate_typeptr_assignment_code(self, entry, code):
1741         # Generate code to initialise the typeptr of an extension
1742         # type defined in this module to point to its type object.
1743         type = entry.type
1744         if type.typeobj_cname:
1745             code.putln(
1746                 "%s = &%s;" % (
1747                     type.typeptr_cname, type.typeobj_cname))
1748     
1749     def generate_utility_functions(self, env, code):
1750         code.putln("")
1751         code.putln("/* Runtime support code */")
1752         code.putln("")
1753         code.putln("static void %s(void) {" % Naming.fileinit_cname)
1754         code.putln("%s = %s;" % 
1755             (Naming.filetable_cname, Naming.filenames_cname))
1756         code.putln("}")
1757         for utility_code in env.utility_code_used:
1758             code.h.put(utility_code[0])
1759             code.put(utility_code[1])
1760         code.put(PyrexTypes.type_conversion_functions)
1761
1762 #------------------------------------------------------------------------------------
1763 #
1764 #  Runtime support code
1765 #
1766 #------------------------------------------------------------------------------------
1767
1768 import_module_utility_code = [
1769 """
1770 static PyObject *__Pyx_ImportModule(char *name); /*proto*/
1771 ""","""
1772 #ifndef __PYX_HAVE_RT_ImportModule
1773 #define __PYX_HAVE_RT_ImportModule
1774 static PyObject *__Pyx_ImportModule(char *name) {
1775     PyObject *py_name = 0;
1776     PyObject *py_module = 0;
1777     
1778     py_name = PyString_FromString(name);
1779     if (!py_name)
1780         goto bad;
1781     py_module = PyImport_Import(py_name);
1782     Py_DECREF(py_name);
1783     return py_module;
1784 bad:
1785     Py_XDECREF(py_name);
1786     return 0;
1787 }
1788 #endif
1789 """]
1790
1791 #------------------------------------------------------------------------------------
1792
1793 type_import_utility_code = [
1794 """
1795 static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, long size);  /*proto*/
1796 ""","""
1797 #ifndef __PYX_HAVE_RT_ImportType
1798 #define __PYX_HAVE_RT_ImportType
1799 static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name,
1800     long size)
1801 {
1802     PyObject *py_module = 0;
1803     PyObject *result = 0;
1804     PyObject *py_name = 0;
1805     
1806     py_name = PyString_FromString(module_name);
1807     if (!py_name)
1808         goto bad;
1809
1810     py_module = __Pyx_ImportModule(module_name);
1811     if (!py_module)
1812         goto bad;
1813     result = PyObject_GetAttrString(py_module, class_name);
1814     if (!result)
1815         goto bad;
1816     if (!PyType_Check(result)) {
1817         PyErr_Format(PyExc_TypeError, 
1818             "%s.%s is not a type object",
1819             module_name, class_name);
1820         goto bad;
1821     }
1822     if (((PyTypeObject *)result)->tp_basicsize != size) {
1823         PyErr_Format(PyExc_ValueError, 
1824             "%s.%s does not appear to be the correct type object",
1825             module_name, class_name);
1826         goto bad;
1827     }
1828     return (PyTypeObject *)result;
1829 bad:
1830     Py_XDECREF(py_name);
1831     Py_XDECREF(result);
1832     return 0;
1833 }
1834 #endif
1835 """]
1836
1837 #------------------------------------------------------------------------------------
1838
1839 function_export_utility_code = [
1840 """
1841 static int __Pyx_ExportFunction(char *name, void *f, char *sig); /*proto*/
1842 """,r"""
1843 static int __Pyx_ExportFunction(char *name, void *f, char *sig) {
1844     PyObject *d = 0;
1845     PyObject *p = 0;
1846     d = PyObject_GetAttrString(%(MODULE)s, "%(API)s");
1847     if (!d) {
1848         PyErr_Clear();
1849         d = PyDict_New();
1850         if (!d)
1851             goto bad;
1852         Py_INCREF(d);
1853         if (PyModule_AddObject(%(MODULE)s, "%(API)s", d) < 0)
1854             goto bad;
1855     }
1856     p = PyCObject_FromVoidPtrAndDesc(f, sig, 0);
1857     if (!p)
1858         goto bad;
1859     if (PyDict_SetItemString(d, name, p) < 0)
1860         goto bad;
1861     Py_DECREF(d);
1862     return 0;
1863 bad:
1864     Py_XDECREF(p);
1865     Py_XDECREF(d);
1866     return -1;
1867 }
1868 """ % {'MODULE': Naming.module_cname, 'API': Naming.api_name}]
1869
1870 #------------------------------------------------------------------------------------
1871
1872 function_import_utility_code = [
1873 """
1874 static int __Pyx_ImportFunction(PyObject *module, char *funcname, void **f, char *sig); /*proto*/
1875 ""","""
1876 #ifndef __PYX_HAVE_RT_ImportFunction
1877 #define __PYX_HAVE_RT_ImportFunction
1878 static int __Pyx_ImportFunction(PyObject *module, char *funcname, void **f, char *sig) {
1879     PyObject *d = 0;
1880     PyObject *cobj = 0;
1881     char *desc;
1882     
1883     d = PyObject_GetAttrString(module, "%(API)s");
1884     if (!d)
1885         goto bad;
1886     cobj = PyDict_GetItemString(d, funcname);
1887     if (!cobj) {
1888         PyErr_Format(PyExc_ImportError,
1889             "%%s does not export expected C function %%s",
1890                 PyModule_GetName(module), funcname);
1891         goto bad;
1892     }
1893     desc = (char *)PyCObject_GetDesc(cobj);
1894     if (!desc)
1895         goto bad;
1896     if (strcmp(desc, sig) != 0) {
1897         PyErr_Format(PyExc_TypeError,
1898             "C function %%s.%%s has wrong signature (expected %%s, got %%s)",
1899                 PyModule_GetName(module), funcname, sig, desc);
1900         goto bad;
1901     }
1902     *f = PyCObject_AsVoidPtr(cobj);
1903     Py_DECREF(d);
1904     return 0;
1905 bad:
1906     Py_XDECREF(d);
1907     return -1;
1908 }
1909 #endif
1910 """ % dict(API = Naming.api_name)]
1911
1912 register_cleanup_utility_code = [
1913 """
1914 static int __Pyx_RegisterCleanup(void); /*proto*/
1915 static PyObject* __pyx_module_cleanup(PyObject *self, PyObject *unused); /*proto*/
1916 static PyMethodDef cleanup_def = {"__cleanup", (PyCFunction)&__pyx_module_cleanup, METH_NOARGS, 0};
1917 ""","""
1918 static int __Pyx_RegisterCleanup(void) {
1919     /* Don't use Py_AtExit because that has a 32-call limit 
1920      * and is called after python finalization. 
1921      */
1922
1923     PyObject *cleanup_func = 0;
1924     PyObject *atexit = 0;
1925     PyObject *reg = 0;
1926     PyObject *args = 0;
1927     PyObject *res = 0;
1928     int ret = -1;
1929     
1930     cleanup_func = PyCFunction_New(&cleanup_def, 0);
1931     args = PyTuple_New(1);
1932     if (!cleanup_func || !args)
1933         goto bad;
1934     PyTuple_SET_ITEM(args, 0, cleanup_func);
1935     cleanup_func = 0;
1936
1937     atexit = __Pyx_ImportModule("atexit");
1938     if (!atexit)
1939         goto bad;
1940     reg = PyObject_GetAttrString(atexit, "register");
1941     if (!reg)
1942         goto bad;
1943     res = PyObject_CallObject(reg, args);
1944     if (!res)
1945         goto bad;
1946     ret = 0;
1947 bad:
1948     Py_XDECREF(cleanup_func);
1949     Py_XDECREF(atexit);
1950     Py_XDECREF(reg);
1951     Py_XDECREF(args);
1952     Py_XDECREF(res);
1953     return ret;
1954 }
1955 """]