Cython has moved to github.
cython-devel
view Cython/Compiler/ModuleNode.py @ 1751:df64cbd751ac
enable refnanny for module init function (by Lisandro)
| author | Stefan Behnel <scoder@users.berlios.de> |
|---|---|
| date | Sun Feb 22 11:24:54 2009 +0100 (3 years ago) |
| parents | b25f64a0d940 |
| children | c4b922517f10 |
line source
1 #
2 # Pyrex - Module parse tree node
3 #
5 import os, time
6 from PyrexTypes import CPtrType
7 import Future
9 try:
10 set
11 except NameError: # Python 2.3
12 from sets import Set as set
14 import Annotate
15 import Code
16 import Naming
17 import Nodes
18 import Options
19 import PyrexTypes
20 import TypeSlots
21 import Version
22 import DebugFlags
24 from Errors import error, warning
25 from PyrexTypes import py_object_type
26 from Cython.Utils import open_new_file, replace_suffix, UtilityCode
27 from StringEncoding import escape_byte_string, EncodedString
30 def check_c_declarations(module_node):
31 module_node.scope.check_c_classes()
32 module_node.scope.check_c_functions()
33 return module_node
35 class ModuleNode(Nodes.Node, Nodes.BlockNode):
36 # doc string or None
37 # body StatListNode
38 #
39 # referenced_modules [ModuleScope]
40 # module_temp_cname string
41 # full_module_name string
42 #
43 # scope The module scope.
44 # compilation_source A CompilationSource (see Main)
45 # directives Top-level compiler directives
47 child_attrs = ["body"]
48 directives = None
50 def analyse_declarations(self, env):
51 if Options.embed_pos_in_docstring:
52 env.doc = EncodedString(u'File: %s (starting at line %s)' % Nodes.relative_position(self.pos))
53 if not self.doc is None:
54 env.doc = EncodedString(env.doc + u'\n' + self.doc)
55 env.doc.encoding = self.doc.encoding
56 else:
57 env.doc = self.doc
58 env.directives = self.directives
59 self.body.analyse_declarations(env)
61 def process_implementation(self, options, result):
62 env = self.scope
63 env.return_type = PyrexTypes.c_void_type
64 self.referenced_modules = []
65 self.find_referenced_modules(env, self.referenced_modules, {})
66 if self.has_imported_c_functions():
67 self.module_temp_cname = env.allocate_temp_pyobject()
68 env.release_temp(self.module_temp_cname)
69 if options.recursive:
70 self.generate_dep_file(env, result)
71 self.generate_c_code(env, options, result)
72 self.generate_h_code(env, options, result)
73 self.generate_api_code(env, result)
75 def has_imported_c_functions(self):
76 for module in self.referenced_modules:
77 for entry in module.cfunc_entries:
78 if entry.defined_in_pxd:
79 return 1
80 return 0
82 def generate_dep_file(self, env, result):
83 modules = self.referenced_modules
84 if len(modules) > 1 or env.included_files:
85 dep_file = replace_suffix(result.c_file, ".dep")
86 f = open(dep_file, "w")
87 try:
88 for module in modules:
89 if module is not env:
90 f.write("cimport %s\n" % module.qualified_name)
91 for path in module.included_files:
92 f.write("include %s\n" % path)
93 finally:
94 f.close()
96 def generate_h_code(self, env, options, result):
97 def h_entries(entries, pxd = 0):
98 return [entry for entry in entries
99 if entry.visibility == 'public' or pxd and entry.defined_in_pxd]
100 h_types = h_entries(env.type_entries)
101 h_vars = h_entries(env.var_entries)
102 h_funcs = h_entries(env.cfunc_entries)
103 h_extension_types = h_entries(env.c_class_entries)
104 if h_types or h_vars or h_funcs or h_extension_types:
105 result.h_file = replace_suffix(result.c_file, ".h")
106 h_code = Code.CCodeWriter()
107 if options.generate_pxi:
108 result.i_file = replace_suffix(result.c_file, ".pxi")
109 i_code = Code.PyrexCodeWriter(result.i_file)
110 else:
111 i_code = None
112 guard = Naming.h_guard_prefix + env.qualified_name.replace(".", "__")
113 h_code.put_h_guard(guard)
114 self.generate_extern_c_macro_definition(h_code)
115 self.generate_type_header_code(h_types, h_code)
116 h_code.putln("")
117 h_code.putln("#ifndef %s" % Naming.api_guard_prefix + self.api_name(env))
118 if h_vars:
119 h_code.putln("")
120 for entry in h_vars:
121 self.generate_public_declaration(entry, h_code, i_code)
122 if h_funcs:
123 h_code.putln("")
124 for entry in h_funcs:
125 self.generate_public_declaration(entry, h_code, i_code)
126 if h_extension_types:
127 h_code.putln("")
128 for entry in h_extension_types:
129 self.generate_cclass_header_code(entry.type, h_code)
130 if i_code:
131 self.generate_cclass_include_code(entry.type, i_code)
132 h_code.putln("")
133 h_code.putln("#endif")
134 h_code.putln("")
135 h_code.putln("PyMODINIT_FUNC init%s(void);" % env.module_name)
136 h_code.putln("")
137 h_code.putln("#endif")
139 h_code.copyto(open_new_file(result.h_file))
141 def generate_public_declaration(self, entry, h_code, i_code):
142 h_code.putln("%s %s;" % (
143 Naming.extern_c_macro,
144 entry.type.declaration_code(
145 entry.cname, dll_linkage = "DL_IMPORT")))
146 if i_code:
147 i_code.putln("cdef extern %s" %
148 entry.type.declaration_code(entry.cname, pyrex = 1))
150 def api_name(self, env):
151 return env.qualified_name.replace(".", "__")
153 def generate_api_code(self, env, result):
154 api_funcs = []
155 public_extension_types = []
156 has_api_extension_types = 0
157 for entry in env.cfunc_entries:
158 if entry.api:
159 api_funcs.append(entry)
160 for entry in env.c_class_entries:
161 if entry.visibility == 'public':
162 public_extension_types.append(entry)
163 if entry.api:
164 has_api_extension_types = 1
165 if api_funcs or has_api_extension_types:
166 result.api_file = replace_suffix(result.c_file, "_api.h")
167 h_code = Code.CCodeWriter()
168 name = self.api_name(env)
169 guard = Naming.api_guard_prefix + name
170 h_code.put_h_guard(guard)
171 h_code.putln('#include "Python.h"')
172 if result.h_file:
173 h_code.putln('#include "%s"' % os.path.basename(result.h_file))
174 for entry in public_extension_types:
175 type = entry.type
176 h_code.putln("")
177 h_code.putln("static PyTypeObject *%s;" % type.typeptr_cname)
178 h_code.putln("#define %s (*%s)" % (
179 type.typeobj_cname, type.typeptr_cname))
180 if api_funcs:
181 h_code.putln("")
182 for entry in api_funcs:
183 type = CPtrType(entry.type)
184 h_code.putln("static %s;" % type.declaration_code(entry.cname))
185 h_code.putln("")
186 h_code.put_h_guard(Naming.api_func_guard + "import_module")
187 h_code.put(import_module_utility_code.impl)
188 h_code.putln("")
189 h_code.putln("#endif")
190 if api_funcs:
191 h_code.putln("")
192 h_code.put(function_import_utility_code.impl)
193 if public_extension_types:
194 h_code.putln("")
195 h_code.put(type_import_utility_code.impl)
196 h_code.putln("")
197 h_code.putln("static int import_%s(void) {" % name)
198 h_code.putln("PyObject *module = 0;")
199 h_code.putln('module = __Pyx_ImportModule("%s");' % env.qualified_name)
200 h_code.putln("if (!module) goto bad;")
201 for entry in api_funcs:
202 sig = entry.type.signature_string()
203 h_code.putln(
204 'if (__Pyx_ImportFunction(module, "%s", (void**)&%s, "%s") < 0) goto bad;' % (
205 entry.name,
206 entry.cname,
207 sig))
208 h_code.putln("Py_DECREF(module); module = 0;")
209 for entry in public_extension_types:
210 self.generate_type_import_call(
211 entry.type, h_code,
212 "if (!%s) goto bad;" % entry.type.typeptr_cname)
213 h_code.putln("return 0;")
214 h_code.putln("bad:")
215 h_code.putln("Py_XDECREF(module);")
216 h_code.putln("return -1;")
217 h_code.putln("}")
218 h_code.putln("")
219 h_code.putln("#endif")
221 h_code.copyto(open_new_file(result.api_file))
223 def generate_cclass_header_code(self, type, h_code):
224 h_code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
225 Naming.extern_c_macro,
226 type.typeobj_cname))
227 #self.generate_obj_struct_definition(type, h_code)
229 def generate_cclass_include_code(self, type, i_code):
230 i_code.putln("cdef extern class %s.%s:" % (
231 type.module_name, type.name))
232 i_code.indent()
233 var_entries = type.scope.var_entries
234 if var_entries:
235 for entry in var_entries:
236 i_code.putln("cdef %s" %
237 entry.type.declaration_code(entry.cname, pyrex = 1))
238 else:
239 i_code.putln("pass")
240 i_code.dedent()
242 def generate_c_code(self, env, options, result):
243 modules = self.referenced_modules
244 if Options.annotate or options.annotate:
245 code = Annotate.AnnotationCCodeWriter()
246 else:
247 code = Code.CCodeWriter(emit_linenums=options.emit_linenums)
248 h_code = code.insertion_point()
249 self.generate_module_preamble(env, modules, h_code)
251 code.globalstate.module_pos = self.pos
252 code.globalstate.directives = self.directives
254 code.globalstate.use_utility_code(refcount_utility_code)
256 code.putln("")
257 code.putln("/* Implementation of %s */" % env.qualified_name)
258 self.generate_const_definitions(env, code)
259 self.generate_interned_num_decls(env, code)
260 self.generate_interned_string_decls(env, code)
261 self.generate_py_string_decls(env, code)
263 code.globalstate.insert_global_var_declarations_into(code)
265 self.generate_cached_builtins_decls(env, code)
266 self.body.generate_function_definitions(env, code)
267 code.mark_pos(None)
268 self.generate_typeobj_definitions(env, code)
269 self.generate_method_table(env, code)
270 self.generate_filename_init_prototype(code)
271 if env.has_import_star:
272 self.generate_import_star(env, code)
273 self.generate_pymoduledef_struct(env, code)
274 self.generate_module_init_func(modules[:-1], env, code)
275 code.mark_pos(None)
276 self.generate_module_cleanup_func(env, code)
277 self.generate_filename_table(code)
278 self.generate_utility_functions(env, code, h_code)
280 self.generate_declarations_for_modules(env, modules, h_code)
281 h_code.write('\n')
283 code.globalstate.close_global_decls()
285 f = open_new_file(result.c_file)
286 code.copyto(f)
287 f.close()
288 result.c_file_generated = 1
289 if Options.annotate or options.annotate:
290 self.annotate(code)
291 code.save_annotation(result.main_source_file, result.c_file)
293 def find_referenced_modules(self, env, module_list, modules_seen):
294 if env not in modules_seen:
295 modules_seen[env] = 1
296 for imported_module in env.cimported_modules:
297 self.find_referenced_modules(imported_module, module_list, modules_seen)
298 module_list.append(env)
300 def sort_types_by_inheritance(self, type_dict, getkey):
301 # copy the types into a list moving each parent type before
302 # its first child
303 type_items = type_dict.items()
304 type_list = []
305 for i, item in enumerate(type_items):
306 key, new_entry = item
308 # collect all base classes to check for children
309 hierarchy = set()
310 base = new_entry
311 while base:
312 base_type = base.type.base_type
313 if not base_type:
314 break
315 base_key = getkey(base_type)
316 hierarchy.add(base_key)
317 base = type_dict.get(base_key)
318 new_entry.base_keys = hierarchy
320 # find the first (sub-)subclass and insert before that
321 for j in range(i):
322 entry = type_list[j]
323 if key in entry.base_keys:
324 type_list.insert(j, new_entry)
325 break
326 else:
327 type_list.append(new_entry)
328 return type_list
330 def sort_type_hierarchy(self, module_list, env):
331 vtab_dict = {}
332 vtabslot_dict = {}
333 for module in module_list:
334 for entry in module.c_class_entries:
335 if not entry.in_cinclude:
336 type = entry.type
337 if type.vtabstruct_cname:
338 vtab_dict[type.vtabstruct_cname] = entry
339 all_defined_here = module is env
340 for entry in module.type_entries:
341 if all_defined_here or entry.defined_in_pxd:
342 type = entry.type
343 if type.is_extension_type and not entry.in_cinclude:
344 type = entry.type
345 vtabslot_dict[type.objstruct_cname] = entry
347 def vtabstruct_cname(entry_type):
348 return entry_type.vtabstruct_cname
349 vtab_list = self.sort_types_by_inheritance(
350 vtab_dict, vtabstruct_cname)
352 def objstruct_cname(entry_type):
353 return entry_type.objstruct_cname
354 vtabslot_list = self.sort_types_by_inheritance(
355 vtabslot_dict, objstruct_cname)
357 return (vtab_list, vtabslot_list)
359 def generate_type_definitions(self, env, modules, vtab_list, vtabslot_list, code):
360 vtabslot_entries = set(vtabslot_list)
361 for module in modules:
362 definition = module is env
363 if definition:
364 type_entries = module.type_entries
365 else:
366 type_entries = []
367 for entry in module.type_entries:
368 if entry.defined_in_pxd:
369 type_entries.append(entry)
370 for entry in type_entries:
371 if not entry.in_cinclude:
372 #print "generate_type_header_code:", entry.name, repr(entry.type) ###
373 type = entry.type
374 if type.is_typedef: # Must test this first!
375 self.generate_typedef(entry, code)
376 elif type.is_struct_or_union:
377 self.generate_struct_union_definition(entry, code)
378 elif type.is_enum:
379 self.generate_enum_definition(entry, code)
380 elif type.is_extension_type and entry not in vtabslot_entries:
381 self.generate_obj_struct_definition(type, code)
382 for entry in vtabslot_list:
383 self.generate_obj_struct_definition(entry.type, code)
384 for entry in vtab_list:
385 self.generate_typeobject_predeclaration(entry, code)
386 self.generate_exttype_vtable_struct(entry, code)
387 self.generate_exttype_vtabptr_declaration(entry, code)
389 def generate_declarations_for_modules(self, env, modules, code):
390 code.putln("")
391 code.putln("/* Type declarations */")
392 vtab_list, vtabslot_list = self.sort_type_hierarchy(modules, env)
393 self.generate_type_definitions(
394 env, modules, vtab_list, vtabslot_list, code)
395 for module in modules:
396 defined_here = module is env
397 code.putln("/* Module declarations from %s */" %
398 module.qualified_name.encode("ASCII", "ignore"))
399 self.generate_global_declarations(module, code, defined_here)
400 self.generate_cfunction_predeclarations(module, code, defined_here)
402 def generate_module_preamble(self, env, cimported_modules, code):
403 code.putln('/* Generated by Cython %s on %s */' % (
404 Version.version, time.asctime()))
405 code.putln('')
406 code.putln('#define PY_SSIZE_T_CLEAN')
407 for filename in env.python_include_files:
408 code.putln('#include "%s"' % filename)
409 code.putln("#ifndef PY_LONG_LONG")
410 code.putln(" #define PY_LONG_LONG LONG_LONG")
411 code.putln("#endif")
412 code.putln("#ifndef DL_EXPORT")
413 code.putln(" #define DL_EXPORT(t) t")
414 code.putln("#endif")
415 code.putln("#if PY_VERSION_HEX < 0x02040000")
416 code.putln(" #define METH_COEXIST 0")
417 code.putln(" #define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type)")
418 code.putln("#endif")
420 code.putln("#if PY_VERSION_HEX < 0x02050000")
421 code.putln(" typedef int Py_ssize_t;")
422 code.putln(" #define PY_SSIZE_T_MAX INT_MAX")
423 code.putln(" #define PY_SSIZE_T_MIN INT_MIN")
424 code.putln(" #define PyInt_FromSsize_t(z) PyInt_FromLong(z)")
425 code.putln(" #define PyInt_AsSsize_t(o) PyInt_AsLong(o)")
426 code.putln(" #define PyNumber_Index(o) PyNumber_Int(o)")
427 code.putln(" #define PyIndex_Check(o) PyNumber_Check(o)")
428 code.putln("#endif")
430 code.putln("#if PY_VERSION_HEX < 0x02060000")
431 code.putln(" #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)")
432 code.putln(" #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)")
433 code.putln(" #define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)")
434 code.putln(" #define PyVarObject_HEAD_INIT(type, size) \\")
435 code.putln(" PyObject_HEAD_INIT(type) size,")
436 code.putln(" #define PyType_Modified(t)")
437 code.putln("")
438 code.putln(" typedef struct {")
439 code.putln(" void *buf;")
440 code.putln(" PyObject *obj;")
441 code.putln(" Py_ssize_t len;")
442 code.putln(" Py_ssize_t itemsize;")
443 code.putln(" int readonly;")
444 code.putln(" int ndim;")
445 code.putln(" char *format;")
446 code.putln(" Py_ssize_t *shape;")
447 code.putln(" Py_ssize_t *strides;")
448 code.putln(" Py_ssize_t *suboffsets;")
449 code.putln(" void *internal;")
450 code.putln(" } Py_buffer;")
451 code.putln("")
452 code.putln(" #define PyBUF_SIMPLE 0")
453 code.putln(" #define PyBUF_WRITABLE 0x0001")
454 code.putln(" #define PyBUF_FORMAT 0x0004")
455 code.putln(" #define PyBUF_ND 0x0008")
456 code.putln(" #define PyBUF_STRIDES (0x0010 | PyBUF_ND)")
457 code.putln(" #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)")
458 code.putln(" #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)")
459 code.putln(" #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)")
460 code.putln(" #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)")
461 code.putln("")
462 code.putln("#endif")
464 code.put(builtin_module_name_utility_code.proto)
466 code.putln("#if PY_MAJOR_VERSION >= 3")
467 code.putln(" #define Py_TPFLAGS_CHECKTYPES 0")
468 code.putln(" #define Py_TPFLAGS_HAVE_INDEX 0")
469 code.putln("#endif")
471 code.putln("#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)")
472 code.putln(" #define Py_TPFLAGS_HAVE_NEWBUFFER 0")
473 code.putln("#endif")
475 code.putln("#if PY_MAJOR_VERSION >= 3")
476 code.putln(" #define PyBaseString_Type PyUnicode_Type")
477 code.putln(" #define PyString_Type PyBytes_Type")
478 code.putln(" #define PyString_CheckExact PyBytes_CheckExact")
479 code.putln(" #define PyInt_Type PyLong_Type")
480 code.putln(" #define PyInt_Check(op) PyLong_Check(op)")
481 code.putln(" #define PyInt_CheckExact(op) PyLong_CheckExact(op)")
482 code.putln(" #define PyInt_FromString PyLong_FromString")
483 code.putln(" #define PyInt_FromUnicode PyLong_FromUnicode")
484 code.putln(" #define PyInt_FromLong PyLong_FromLong")
485 code.putln(" #define PyInt_FromSize_t PyLong_FromSize_t")
486 code.putln(" #define PyInt_FromSsize_t PyLong_FromSsize_t")
487 code.putln(" #define PyInt_AsLong PyLong_AsLong")
488 code.putln(" #define PyInt_AS_LONG PyLong_AS_LONG")
489 code.putln(" #define PyInt_AsSsize_t PyLong_AsSsize_t")
490 code.putln(" #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask")
491 code.putln(" #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask")
492 code.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)")
493 code.putln("#else")
494 if Future.division in env.context.future_directives:
495 code.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)")
496 else:
497 code.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)")
498 code.putln(" #define PyBytes_Type PyString_Type")
499 code.putln("#endif")
501 code.putln("#if PY_MAJOR_VERSION >= 3")
502 code.putln(" #define PyMethod_New(func, self, klass) PyInstanceMethod_New(func)")
503 code.putln("#endif")
505 code.putln("#if !defined(WIN32) && !defined(MS_WINDOWS)")
506 code.putln(" #ifndef __stdcall")
507 code.putln(" #define __stdcall")
508 code.putln(" #endif")
509 code.putln(" #ifndef __cdecl")
510 code.putln(" #define __cdecl")
511 code.putln(" #endif")
512 code.putln("#else")
513 code.putln(" #define _USE_MATH_DEFINES")
514 code.putln("#endif")
516 code.putln("#if PY_VERSION_HEX < 0x02050000")
517 code.putln(" #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),((char *)(n)))")
518 code.putln(" #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))")
519 code.putln(" #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),((char *)(n)))")
520 code.putln("#else")
521 code.putln(" #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),(n))")
522 code.putln(" #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))")
523 code.putln(" #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),(n))")
524 code.putln("#endif")
526 code.putln("#if PY_VERSION_HEX < 0x02050000")
527 code.putln(" #define __Pyx_NAMESTR(n) ((char *)(n))")
528 code.putln(" #define __Pyx_DOCSTR(n) ((char *)(n))")
529 code.putln("#else")
530 code.putln(" #define __Pyx_NAMESTR(n) (n)")
531 code.putln(" #define __Pyx_DOCSTR(n) (n)")
532 code.putln("#endif")
534 self.generate_extern_c_macro_definition(code)
535 code.putln("#include <math.h>")
536 code.putln("#define %s" % Naming.api_guard_prefix + self.api_name(env))
537 self.generate_includes(env, cimported_modules, code)
538 code.putln('')
539 code.put(Nodes.utility_function_predeclarations)
540 code.put(PyrexTypes.type_conversion_predeclarations)
541 code.put(Nodes.branch_prediction_macros)
542 code.putln('')
543 code.putln('static PyObject *%s;' % env.module_cname)
544 code.putln('static PyObject *%s;' % Naming.builtins_cname)
545 code.putln('static PyObject *%s;' % Naming.empty_tuple)
546 if Options.pre_import is not None:
547 code.putln('static PyObject *%s;' % Naming.preimport_cname)
548 code.putln('static int %s;' % Naming.lineno_cname)
549 code.putln('static int %s = 0;' % Naming.clineno_cname)
550 code.putln('static const char * %s= %s;' % (Naming.cfilenm_cname, Naming.file_c_macro))
551 code.putln('static const char *%s;' % Naming.filename_cname)
552 code.putln('static const char **%s;' % Naming.filetable_cname)
553 if env.doc:
554 docstr = env.doc
555 if not isinstance(docstr, str):
556 docstr = docstr.utf8encode()
557 code.putln('')
558 code.putln('static char %s[] = "%s";' % (
559 env.doc_cname, escape_byte_string(docstr)))
561 def generate_extern_c_macro_definition(self, code):
562 name = Naming.extern_c_macro
563 code.putln("#ifdef __cplusplus")
564 code.putln('#define %s extern "C"' % name)
565 code.putln("#else")
566 code.putln("#define %s extern" % name)
567 code.putln("#endif")
569 def generate_includes(self, env, cimported_modules, code):
570 includes = []
571 for filename in env.include_files:
572 code.putln('#include "%s"' % filename)
574 def generate_filename_table(self, code):
575 code.putln("")
576 code.putln("static const char *%s[] = {" % Naming.filenames_cname)
577 if code.globalstate.filename_list:
578 for source_desc in code.globalstate.filename_list:
579 filename = os.path.basename(source_desc.get_filenametable_entry())
580 escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"')
581 code.putln('"%s",' %
582 escaped_filename)
583 else:
584 # Some C compilers don't like an empty array
585 code.putln("0")
586 code.putln("};")
588 def generate_type_predeclarations(self, env, code):
589 pass
591 def generate_type_header_code(self, type_entries, code):
592 # Generate definitions of structs/unions/enums/typedefs/objstructs.
593 #self.generate_gcc33_hack(env, code) # Is this still needed?
594 #for entry in env.type_entries:
595 for entry in type_entries:
596 if not entry.in_cinclude:
597 #print "generate_type_header_code:", entry.name, repr(entry.type) ###
598 type = entry.type
599 if type.is_typedef: # Must test this first!
600 self.generate_typedef(entry, code)
601 elif type.is_struct_or_union:
602 self.generate_struct_union_definition(entry, code)
603 elif type.is_enum:
604 self.generate_enum_definition(entry, code)
605 elif type.is_extension_type:
606 self.generate_obj_struct_definition(type, code)
608 def generate_gcc33_hack(self, env, code):
609 # Workaround for spurious warning generation in gcc 3.3
610 code.putln("")
611 for entry in env.c_class_entries:
612 type = entry.type
613 if not type.typedef_flag:
614 name = type.objstruct_cname
615 if name.startswith("__pyx_"):
616 tail = name[6:]
617 else:
618 tail = name
619 code.putln("typedef struct %s __pyx_gcc33_%s;" % (
620 name, tail))
622 def generate_typedef(self, entry, code):
623 base_type = entry.type.typedef_base_type
624 code.putln("")
625 code.putln("typedef %s;" % base_type.declaration_code(entry.cname))
627 def sue_header_footer(self, type, kind, name):
628 if type.typedef_flag:
629 header = "typedef %s {" % kind
630 footer = "} %s;" % name
631 else:
632 header = "%s %s {" % (kind, name)
633 footer = "};"
634 return header, footer
636 def generate_struct_union_definition(self, entry, code):
637 code.mark_pos(entry.pos)
638 type = entry.type
639 scope = type.scope
640 if scope:
641 header, footer = \
642 self.sue_header_footer(type, type.kind, type.cname)
643 code.putln("")
644 code.putln(header)
645 var_entries = scope.var_entries
646 if not var_entries:
647 error(entry.pos,
648 "Empty struct or union definition not allowed outside a"
649 " 'cdef extern from' block")
650 for attr in var_entries:
651 code.putln(
652 "%s;" %
653 attr.type.declaration_code(attr.cname))
654 code.putln(footer)
656 def generate_enum_definition(self, entry, code):
657 code.mark_pos(entry.pos)
658 type = entry.type
659 name = entry.cname or entry.name or ""
660 header, footer = \
661 self.sue_header_footer(type, "enum", name)
662 code.putln("")
663 code.putln(header)
664 enum_values = entry.enum_values
665 if not enum_values:
666 error(entry.pos,
667 "Empty enum definition not allowed outside a"
668 " 'cdef extern from' block")
669 else:
670 last_entry = enum_values[-1]
671 for value_entry in enum_values:
672 if value_entry.value == value_entry.name:
673 value_code = value_entry.cname
674 else:
675 value_code = ("%s = %s" % (
676 value_entry.cname,
677 value_entry.value))
678 if value_entry is not last_entry:
679 value_code += ","
680 code.putln(value_code)
681 code.putln(footer)
683 def generate_typeobject_predeclaration(self, entry, code):
684 code.putln("")
685 name = entry.type.typeobj_cname
686 if name:
687 if entry.visibility == 'extern' and not entry.in_cinclude:
688 code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
689 Naming.extern_c_macro,
690 name))
691 elif entry.visibility == 'public':
692 #code.putln("DL_EXPORT(PyTypeObject) %s;" % name)
693 code.putln("%s DL_EXPORT(PyTypeObject) %s;" % (
694 Naming.extern_c_macro,
695 name))
696 # ??? Do we really need the rest of this? ???
697 #else:
698 # code.putln("staticforward PyTypeObject %s;" % name)
700 def generate_exttype_vtable_struct(self, entry, code):
701 code.mark_pos(entry.pos)
702 # Generate struct declaration for an extension type's vtable.
703 type = entry.type
704 scope = type.scope
705 if type.vtabstruct_cname:
706 code.putln("")
707 code.putln(
708 "struct %s {" %
709 type.vtabstruct_cname)
710 if type.base_type and type.base_type.vtabstruct_cname:
711 code.putln("struct %s %s;" % (
712 type.base_type.vtabstruct_cname,
713 Naming.obj_base_cname))
714 for method_entry in scope.cfunc_entries:
715 if not method_entry.is_inherited:
716 code.putln(
717 "%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.name))
718 code.putln(
719 "};")
721 def generate_exttype_vtabptr_declaration(self, entry, code):
722 code.mark_pos(entry.pos)
723 # Generate declaration of pointer to an extension type's vtable.
724 type = entry.type
725 if type.vtabptr_cname:
726 code.putln("static struct %s *%s;" % (
727 type.vtabstruct_cname,
728 type.vtabptr_cname))
730 def generate_obj_struct_definition(self, type, code):
731 code.mark_pos(type.pos)
732 # Generate object struct definition for an
733 # extension type.
734 if not type.scope:
735 return # Forward declared but never defined
736 header, footer = \
737 self.sue_header_footer(type, "struct", type.objstruct_cname)
738 code.putln("")
739 code.putln(header)
740 base_type = type.base_type
741 if base_type:
742 code.putln(
743 "%s%s %s;" % (
744 ("struct ", "")[base_type.typedef_flag],
745 base_type.objstruct_cname,
746 Naming.obj_base_cname))
747 else:
748 code.putln(
749 "PyObject_HEAD")
750 if type.vtabslot_cname and not (type.base_type and type.base_type.vtabslot_cname):
751 code.putln(
752 "struct %s *%s;" % (
753 type.vtabstruct_cname,
754 type.vtabslot_cname))
755 for attr in type.scope.var_entries:
756 code.putln(
757 "%s;" %
758 attr.type.declaration_code(attr.cname))
759 code.putln(footer)
761 def generate_global_declarations(self, env, code, definition):
762 code.putln("")
763 for entry in env.c_class_entries:
764 if definition or entry.defined_in_pxd:
765 code.putln("static PyTypeObject *%s = 0;" %
766 entry.type.typeptr_cname)
767 code.put_var_declarations(env.var_entries, static = 1,
768 dll_linkage = "DL_EXPORT", definition = definition)
769 if definition:
770 code.put_var_declarations(env.default_entries, static = 1,
771 definition = definition)
773 def generate_cfunction_predeclarations(self, env, code, definition):
774 for entry in env.cfunc_entries:
775 if entry.inline_func_in_pxd or (not entry.in_cinclude and (definition
776 or entry.defined_in_pxd or entry.visibility == 'extern')):
777 if entry.visibility in ('public', 'extern'):
778 dll_linkage = "DL_EXPORT"
779 else:
780 dll_linkage = None
781 type = entry.type
782 if not definition and entry.defined_in_pxd:
783 type = CPtrType(type)
784 header = type.declaration_code(entry.cname,
785 dll_linkage = dll_linkage)
786 if entry.visibility == 'private':
787 storage_class = "static "
788 elif entry.visibility == 'public':
789 storage_class = ""
790 else:
791 storage_class = "%s " % Naming.extern_c_macro
792 if entry.func_modifiers:
793 modifiers = '%s ' % ' '.join([
794 modifier.upper() for modifier in entry.func_modifiers])
795 else:
796 modifiers = ''
797 code.putln("%s%s%s; /*proto*/" % (
798 storage_class,
799 modifiers,
800 header))
802 def generate_typeobj_definitions(self, env, code):
803 full_module_name = env.qualified_name
804 for entry in env.c_class_entries:
805 #print "generate_typeobj_definitions:", entry.name
806 #print "...visibility =", entry.visibility
807 if entry.visibility != 'extern':
808 type = entry.type
809 scope = type.scope
810 if scope: # could be None if there was an error
811 self.generate_exttype_vtable(scope, code)
812 self.generate_new_function(scope, code)
813 self.generate_dealloc_function(scope, code)
814 if scope.needs_gc():
815 self.generate_traverse_function(scope, code)
816 self.generate_clear_function(scope, code)
817 if scope.defines_any(["__getitem__"]):
818 self.generate_getitem_int_function(scope, code)
819 if scope.defines_any(["__setitem__", "__delitem__"]):
820 self.generate_ass_subscript_function(scope, code)
821 if scope.defines_any(["__setslice__", "__delslice__"]):
822 warning(self.pos, "__setslice__ and __delslice__ are not supported by Python 3", 1)
823 self.generate_ass_slice_function(scope, code)
824 if scope.defines_any(["__getattr__","__getattribute__"]):
825 self.generate_getattro_function(scope, code)
826 if scope.defines_any(["__setattr__", "__delattr__"]):
827 self.generate_setattro_function(scope, code)
828 if scope.defines_any(["__get__"]):
829 self.generate_descr_get_function(scope, code)
830 if scope.defines_any(["__set__", "__delete__"]):
831 self.generate_descr_set_function(scope, code)
832 self.generate_property_accessors(scope, code)
833 self.generate_method_table(scope, code)
834 self.generate_member_table(scope, code)
835 self.generate_getset_table(scope, code)
836 self.generate_typeobj_definition(full_module_name, entry, code)
838 def generate_exttype_vtable(self, scope, code):
839 # Generate the definition of an extension type's vtable.
840 type = scope.parent_type
841 if type.vtable_cname:
842 code.putln("static struct %s %s;" % (
843 type.vtabstruct_cname,
844 type.vtable_cname))
846 def generate_self_cast(self, scope, code):
847 type = scope.parent_type
848 code.putln(
849 "%s = (%s)o;" % (
850 type.declaration_code("p"),
851 type.declaration_code("")))
853 def generate_new_function(self, scope, code):
854 tp_slot = TypeSlots.ConstructorSlot("tp_new", '__new__')
855 slot_func = scope.mangle_internal("tp_new")
856 type = scope.parent_type
857 base_type = type.base_type
858 py_attrs = []
859 for entry in scope.var_entries:
860 if entry.type.is_pyobject:
861 py_attrs.append(entry)
862 need_self_cast = type.vtabslot_cname or py_attrs
863 code.putln("")
864 code.putln(
865 "static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k) {"
866 % scope.mangle_internal("tp_new"))
867 if need_self_cast:
868 code.putln(
869 "%s;"
870 % scope.parent_type.declaration_code("p"))
871 if base_type:
872 tp_new = TypeSlots.get_base_slot_function(scope, tp_slot)
873 if tp_new is None:
874 tp_new = "%s->tp_new" % base_type.typeptr_cname
875 code.putln(
876 "PyObject *o = %s(t, a, k);" % tp_new)
877 else:
878 code.putln(
879 "PyObject *o = (*t->tp_alloc)(t, 0);")
880 code.putln(
881 "if (!o) return 0;")
882 if need_self_cast:
883 code.putln(
884 "p = %s;"
885 % type.cast_code("o"))
886 #if need_self_cast:
887 # self.generate_self_cast(scope, code)
888 if type.vtabslot_cname:
889 vtab_base_type = type
890 while vtab_base_type.base_type and vtab_base_type.base_type.vtabstruct_cname:
891 vtab_base_type = vtab_base_type.base_type
892 if vtab_base_type is not type:
893 struct_type_cast = "(struct %s*)" % vtab_base_type.vtabstruct_cname
894 else:
895 struct_type_cast = ""
896 code.putln("p->%s = %s%s;" % (
897 type.vtabslot_cname,
898 struct_type_cast, type.vtabptr_cname))
899 for entry in py_attrs:
900 if entry.name == "__weakref__":
901 code.putln("p->%s = 0;" % entry.cname)
902 else:
903 code.put_init_var_to_py_none(entry, "p->%s", nanny=False)
904 entry = scope.lookup_here("__new__")
905 if entry and entry.is_special:
906 if entry.trivial_signature:
907 cinit_args = "o, %s, NULL" % Naming.empty_tuple
908 else:
909 cinit_args = "o, a, k"
910 code.putln(
911 "if (%s(%s) < 0) {" %
912 (entry.func_cname, cinit_args))
913 code.put_decref_clear("o", py_object_type, nanny=False);
914 code.putln(
915 "}")
916 code.putln(
917 "return o;")
918 code.putln(
919 "}")
921 def generate_dealloc_function(self, scope, code):
922 tp_slot = TypeSlots.ConstructorSlot("tp_dealloc", '__dealloc__')
923 slot_func = scope.mangle_internal("tp_dealloc")
924 base_type = scope.parent_type.base_type
925 if tp_slot.slot_code(scope) != slot_func:
926 return # never used
927 code.putln("")
928 code.putln(
929 "static void %s(PyObject *o) {"
930 % scope.mangle_internal("tp_dealloc"))
931 py_attrs = []
932 weakref_slot = scope.lookup_here("__weakref__")
933 for entry in scope.var_entries:
934 if entry.type.is_pyobject and entry is not weakref_slot:
935 py_attrs.append(entry)
936 if py_attrs or weakref_slot in scope.var_entries:
937 self.generate_self_cast(scope, code)
938 self.generate_usr_dealloc_call(scope, code)
939 if weakref_slot in scope.var_entries:
940 code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);")
941 for entry in py_attrs:
942 code.put_xdecref("p->%s" % entry.cname, entry.type, nanny=False)
943 if base_type:
944 tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot)
945 if tp_dealloc is None:
946 tp_dealloc = "%s->tp_dealloc" % base_type.typeptr_cname
947 code.putln(
948 "%s(o);" % tp_dealloc)
949 else:
950 code.putln(
951 "(*Py_TYPE(o)->tp_free)(o);")
952 code.putln(
953 "}")
955 def generate_usr_dealloc_call(self, scope, code):
956 entry = scope.lookup_here("__dealloc__")
957 if entry:
958 code.putln(
959 "{")
960 code.putln(
961 "PyObject *etype, *eval, *etb;")
962 code.putln(
963 "PyErr_Fetch(&etype, &eval, &etb);")
964 code.putln(
965 "++Py_REFCNT(o);")
966 code.putln(
967 "%s(o);" %
968 entry.func_cname)
969 code.putln(
970 "if (PyErr_Occurred()) PyErr_WriteUnraisable(o);")
971 code.putln(
972 "--Py_REFCNT(o);")
973 code.putln(
974 "PyErr_Restore(etype, eval, etb);")
975 code.putln(
976 "}")
978 def generate_traverse_function(self, scope, code):
979 tp_slot = TypeSlots.GCDependentSlot("tp_traverse")
980 slot_func = scope.mangle_internal("tp_traverse")
981 base_type = scope.parent_type.base_type
982 if tp_slot.slot_code(scope) != slot_func:
983 return # never used
984 code.putln("")
985 code.putln(
986 "static int %s(PyObject *o, visitproc v, void *a) {"
987 % slot_func)
988 py_attrs = []
989 for entry in scope.var_entries:
990 if entry.type.is_pyobject and entry.name != "__weakref__":
991 py_attrs.append(entry)
992 if base_type or py_attrs:
993 code.putln("int e;")
994 if py_attrs:
995 self.generate_self_cast(scope, code)
996 if base_type:
997 # want to call it explicitly if possible so inlining can be performed
998 static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
999 if static_call:
1000 code.putln("e = %s(o, v, a); if (e) return e;" % static_call)
1001 else:
1002 code.putln("if (%s->tp_traverse) {" % base_type.typeptr_cname)
1003 code.putln(
1004 "e = %s->tp_traverse(o, v, a); if (e) return e;" %
1005 base_type.typeptr_cname)
1006 code.putln("}")
1007 for entry in py_attrs:
1008 var_code = "p->%s" % entry.cname
1009 code.putln(
1010 "if (%s) {"
1011 % var_code)
1012 if entry.type.is_extension_type:
1013 var_code = "((PyObject*)%s)" % var_code
1014 code.putln(
1015 "e = (*v)(%s, a); if (e) return e;"
1016 % var_code)
1017 code.putln(
1018 "}")
1019 code.putln(
1020 "return 0;")
1021 code.putln(
1022 "}")
1024 def generate_clear_function(self, scope, code):
1025 tp_slot = TypeSlots.GCDependentSlot("tp_clear")
1026 slot_func = scope.mangle_internal("tp_clear")
1027 base_type = scope.parent_type.base_type
1028 if tp_slot.slot_code(scope) != slot_func:
1029 return # never used
1030 code.putln("")
1031 code.putln("static int %s(PyObject *o) {" % slot_func)
1032 py_attrs = []
1033 for entry in scope.var_entries:
1034 if entry.type.is_pyobject and entry.name != "__weakref__":
1035 py_attrs.append(entry)
1036 if py_attrs:
1037 self.generate_self_cast(scope, code)
1038 code.putln("PyObject* tmp;")
1039 if base_type:
1040 # want to call it explicitly if possible so inlining can be performed
1041 static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
1042 if static_call:
1043 code.putln("%s(o);" % static_call)
1044 else:
1045 code.putln("if (%s->tp_clear) {" % base_type.typeptr_cname)
1046 code.putln("%s->tp_clear(o);" % base_type.typeptr_cname)
1047 code.putln("}")
1048 for entry in py_attrs:
1049 name = "p->%s" % entry.cname
1050 code.putln("tmp = ((PyObject*)%s);" % name)
1051 code.put_init_to_py_none(name, entry.type, nanny=False)
1052 code.putln("Py_XDECREF(tmp);")
1053 code.putln(
1054 "return 0;")
1055 code.putln(
1056 "}")
1058 def generate_getitem_int_function(self, scope, code):
1059 # This function is put into the sq_item slot when
1060 # a __getitem__ method is present. It converts its
1061 # argument to a Python integer and calls mp_subscript.
1062 code.putln(
1063 "static PyObject *%s(PyObject *o, Py_ssize_t i) {" %
1064 scope.mangle_internal("sq_item"))
1065 code.putln(
1066 "PyObject *r;")
1067 code.putln(
1068 "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;")
1069 code.putln(
1070 "r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);")
1071 code.putln(
1072 "Py_DECREF(x);")
1073 code.putln(
1074 "return r;")
1075 code.putln(
1076 "}")
1078 def generate_ass_subscript_function(self, scope, code):
1079 # Setting and deleting an item are both done through
1080 # the ass_subscript method, so we dispatch to user's __setitem__
1081 # or __delitem__, or raise an exception.
1082 base_type = scope.parent_type.base_type
1083 set_entry = scope.lookup_here("__setitem__")
1084 del_entry = scope.lookup_here("__delitem__")
1085 code.putln("")
1086 code.putln(
1087 "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
1088 scope.mangle_internal("mp_ass_subscript"))
1089 code.putln(
1090 "if (v) {")
1091 if set_entry:
1092 code.putln(
1093 "return %s(o, i, v);" %
1094 set_entry.func_cname)
1095 else:
1096 self.generate_guarded_basetype_call(
1097 base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
1098 code.putln(
1099 "PyErr_Format(PyExc_NotImplementedError,")
1100 code.putln(
1101 ' "Subscript assignment not supported by %s", Py_TYPE(o)->tp_name);')
1102 code.putln(
1103 "return -1;")
1104 code.putln(
1105 "}")
1106 code.putln(
1107 "else {")
1108 if del_entry:
1109 code.putln(
1110 "return %s(o, i);" %
1111 del_entry.func_cname)
1112 else:
1113 self.generate_guarded_basetype_call(
1114 base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
1115 code.putln(
1116 "PyErr_Format(PyExc_NotImplementedError,")
1117 code.putln(
1118 ' "Subscript deletion not supported by %s", Py_TYPE(o)->tp_name);')
1119 code.putln(
1120 "return -1;")
1121 code.putln(
1122 "}")
1123 code.putln(
1124 "}")
1126 def generate_guarded_basetype_call(
1127 self, base_type, substructure, slot, args, code):
1128 if base_type:
1129 base_tpname = base_type.typeptr_cname
1130 if substructure:
1131 code.putln(
1132 "if (%s->%s && %s->%s->%s)" % (
1133 base_tpname, substructure, base_tpname, substructure, slot))
1134 code.putln(
1135 " return %s->%s->%s(%s);" % (
1136 base_tpname, substructure, slot, args))
1137 else:
1138 code.putln(
1139 "if (%s->%s)" % (
1140 base_tpname, slot))
1141 code.putln(
1142 " return %s->%s(%s);" % (
1143 base_tpname, slot, args))
1145 def generate_ass_slice_function(self, scope, code):
1146 # Setting and deleting a slice are both done through
1147 # the ass_slice method, so we dispatch to user's __setslice__
1148 # or __delslice__, or raise an exception.
1149 base_type = scope.parent_type.base_type
1150 set_entry = scope.lookup_here("__setslice__")
1151 del_entry = scope.lookup_here("__delslice__")
1152 code.putln("")
1153 code.putln(
1154 "static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" %
1155 scope.mangle_internal("sq_ass_slice"))
1156 code.putln(
1157 "if (v) {")
1158 if set_entry:
1159 code.putln(
1160 "return %s(o, i, j, v);" %
1161 set_entry.func_cname)
1162 else:
1163 self.generate_guarded_basetype_call(
1164 base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
1165 code.putln(
1166 "PyErr_Format(PyExc_NotImplementedError,")
1167 code.putln(
1168 ' "2-element slice assignment not supported by %s", Py_TYPE(o)->tp_name);')
1169 code.putln(
1170 "return -1;")
1171 code.putln(
1172 "}")
1173 code.putln(
1174 "else {")
1175 if del_entry:
1176 code.putln(
1177 "return %s(o, i, j);" %
1178 del_entry.func_cname)
1179 else:
1180 self.generate_guarded_basetype_call(
1181 base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
1182 code.putln(
1183 "PyErr_Format(PyExc_NotImplementedError,")
1184 code.putln(
1185 ' "2-element slice deletion not supported by %s", Py_TYPE(o)->tp_name);')
1186 code.putln(
1187 "return -1;")
1188 code.putln(
1189 "}")
1190 code.putln(
1191 "}")
1193 def generate_getattro_function(self, scope, code):
1194 # First try to get the attribute using __getattribute__, if defined, or
1195 # PyObject_GenericGetAttr.
1196 #
1197 # If that raises an AttributeError, call the __getattr__ if defined.
1198 #
1199 # In both cases, defined can be in this class, or any base class.
1200 def lookup_here_or_base(n,type=None):
1201 # Recursive lookup
1202 if type is None:
1203 type = scope.parent_type
1204 r = type.scope.lookup_here(n)
1205 if r is None and \
1206 type.base_type is not None:
1207 return lookup_here_or_base(n,type.base_type)
1208 else:
1209 return r
1210 getattr_entry = lookup_here_or_base("__getattr__")
1211 getattribute_entry = lookup_here_or_base("__getattribute__")
1212 code.putln("")
1213 code.putln(
1214 "static PyObject *%s(PyObject *o, PyObject *n) {"
1215 % scope.mangle_internal("tp_getattro"))
1216 if getattribute_entry is not None:
1217 code.putln(
1218 "PyObject *v = %s(o, n);" %
1219 getattribute_entry.func_cname)
1220 else:
1221 code.putln(
1222 "PyObject *v = PyObject_GenericGetAttr(o, n);")
1223 if getattr_entry is not None:
1224 code.putln(
1225 "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
1226 code.putln(
1227 "PyErr_Clear();")
1228 code.putln(
1229 "v = %s(o, n);" %
1230 getattr_entry.func_cname)
1231 code.putln(
1232 "}")
1233 code.putln(
1234 "return v;")
1235 code.putln(
1236 "}")
1238 def generate_setattro_function(self, scope, code):
1239 # Setting and deleting an attribute are both done through
1240 # the setattro method, so we dispatch to user's __setattr__
1241 # or __delattr__ or fall back on PyObject_GenericSetAttr.
1242 base_type = scope.parent_type.base_type
1243 set_entry = scope.lookup_here("__setattr__")
1244 del_entry = scope.lookup_here("__delattr__")
1245 code.putln("")
1246 code.putln(
1247 "static int %s(PyObject *o, PyObject *n, PyObject *v) {" %
1248 scope.mangle_internal("tp_setattro"))
1249 code.putln(
1250 "if (v) {")
1251 if set_entry:
1252 code.putln(
1253 "return %s(o, n, v);" %
1254 set_entry.func_cname)
1255 else:
1256 self.generate_guarded_basetype_call(
1257 base_type, None, "tp_setattro", "o, n, v", code)
1258 code.putln(
1259 "return PyObject_GenericSetAttr(o, n, v);")
1260 code.putln(
1261 "}")
1262 code.putln(
1263 "else {")
1264 if del_entry:
1265 code.putln(
1266 "return %s(o, n);" %
1267 del_entry.func_cname)
1268 else:
1269 self.generate_guarded_basetype_call(
1270 base_type, None, "tp_setattro", "o, n, v", code)
1271 code.putln(
1272 "return PyObject_GenericSetAttr(o, n, 0);")
1273 code.putln(
1274 "}")
1275 code.putln(
1276 "}")
1278 def generate_descr_get_function(self, scope, code):
1279 # The __get__ function of a descriptor object can be
1280 # called with NULL for the second or third arguments
1281 # under some circumstances, so we replace them with
1282 # None in that case.
1283 user_get_entry = scope.lookup_here("__get__")
1284 code.putln("")
1285 code.putln(
1286 "static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" %
1287 scope.mangle_internal("tp_descr_get"))
1288 code.putln(
1289 "PyObject *r = 0;")
1290 code.putln(
1291 "if (!i) i = Py_None;")
1292 code.putln(
1293 "if (!c) c = Py_None;")
1294 #code.put_incref("i", py_object_type)
1295 #code.put_incref("c", py_object_type)
1296 code.putln(
1297 "r = %s(o, i, c);" %
1298 user_get_entry.func_cname)
1299 #code.put_decref("i", py_object_type)
1300 #code.put_decref("c", py_object_type)
1301 code.putln(
1302 "return r;")
1303 code.putln(
1304 "}")
1306 def generate_descr_set_function(self, scope, code):
1307 # Setting and deleting are both done through the __set__
1308 # method of a descriptor, so we dispatch to user's __set__
1309 # or __delete__ or raise an exception.
1310 base_type = scope.parent_type.base_type
1311 user_set_entry = scope.lookup_here("__set__")
1312 user_del_entry = scope.lookup_here("__delete__")
1313 code.putln("")
1314 code.putln(
1315 "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
1316 scope.mangle_internal("tp_descr_set"))
1317 code.putln(
1318 "if (v) {")
1319 if user_set_entry:
1320 code.putln(
1321 "return %s(o, i, v);" %
1322 user_set_entry.func_cname)
1323 else:
1324 self.generate_guarded_basetype_call(
1325 base_type, None, "tp_descr_set", "o, i, v", code)
1326 code.putln(
1327 'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
1328 code.putln(
1329 "return -1;")
1330 code.putln(
1331 "}")
1332 code.putln(
1333 "else {")
1334 if user_del_entry:
1335 code.putln(
1336 "return %s(o, i);" %
1337 user_del_entry.func_cname)
1338 else:
1339 self.generate_guarded_basetype_call(
1340 base_type, None, "tp_descr_set", "o, i, v", code)
1341 code.putln(
1342 'PyErr_SetString(PyExc_NotImplementedError, "__delete__");')
1343 code.putln(
1344 "return -1;")
1345 code.putln(
1346 "}")
1347 code.putln(
1348 "}")
1350 def generate_property_accessors(self, cclass_scope, code):
1351 for entry in cclass_scope.property_entries:
1352 property_scope = entry.scope
1353 if property_scope.defines_any(["__get__"]):
1354 self.generate_property_get_function(entry, code)
1355 if property_scope.defines_any(["__set__", "__del__"]):
1356 self.generate_property_set_function(entry, code)
1358 def generate_property_get_function(self, property_entry, code):
1359 property_scope = property_entry.scope
1360 property_entry.getter_cname = property_scope.parent_scope.mangle(
1361 Naming.prop_get_prefix, property_entry.name)
1362 get_entry = property_scope.lookup_here("__get__")
1363 code.putln("")
1364 code.putln(
1365 "static PyObject *%s(PyObject *o, void *x) {" %
1366 property_entry.getter_cname)
1367 code.putln(
1368 "return %s(o);" %
1369 get_entry.func_cname)
1370 code.putln(
1371 "}")
1373 def generate_property_set_function(self, property_entry, code):
1374 property_scope = property_entry.scope
1375 property_entry.setter_cname = property_scope.parent_scope.mangle(
1376 Naming.prop_set_prefix, property_entry.name)
1377 set_entry = property_scope.lookup_here("__set__")
1378 del_entry = property_scope.lookup_here("__del__")
1379 code.putln("")
1380 code.putln(
1381 "static int %s(PyObject *o, PyObject *v, void *x) {" %
1382 property_entry.setter_cname)
1383 code.putln(
1384 "if (v) {")
1385 if set_entry:
1386 code.putln(
1387 "return %s(o, v);" %
1388 set_entry.func_cname)
1389 else:
1390 code.putln(
1391 'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
1392 code.putln(
1393 "return -1;")
1394 code.putln(
1395 "}")
1396 code.putln(
1397 "else {")
1398 if del_entry:
1399 code.putln(
1400 "return %s(o);" %
1401 del_entry.func_cname)
1402 else:
1403 code.putln(
1404 'PyErr_SetString(PyExc_NotImplementedError, "__del__");')
1405 code.putln(
1406 "return -1;")
1407 code.putln(
1408 "}")
1409 code.putln(
1410 "}")
1412 def generate_typeobj_definition(self, modname, entry, code):
1413 type = entry.type
1414 scope = type.scope
1415 for suite in TypeSlots.substructures:
1416 suite.generate_substructure(scope, code)
1417 code.putln("")
1418 if entry.visibility == 'public':
1419 header = "DL_EXPORT(PyTypeObject) %s = {"
1420 else:
1421 #header = "statichere PyTypeObject %s = {"
1422 header = "PyTypeObject %s = {"
1423 #code.putln(header % scope.parent_type.typeobj_cname)
1424 code.putln(header % type.typeobj_cname)
1425 code.putln(
1426 "PyVarObject_HEAD_INIT(0, 0)")
1427 code.putln(
1428 '__Pyx_NAMESTR("%s.%s"), /*tp_name*/' % (
1429 self.full_module_name, scope.class_name))
1430 if type.typedef_flag:
1431 objstruct = type.objstruct_cname
1432 else:
1433 #objstruct = "struct %s" % scope.parent_type.objstruct_cname
1434 objstruct = "struct %s" % type.objstruct_cname
1435 code.putln(
1436 "sizeof(%s), /*tp_basicsize*/" %
1437 objstruct)
1438 code.putln(
1439 "0, /*tp_itemsize*/")
1440 for slot in TypeSlots.slot_table:
1441 slot.generate(scope, code)
1442 code.putln(
1443 "};")
1445 def generate_method_table(self, env, code):
1446 code.putln("")
1447 code.putln(
1448 "static struct PyMethodDef %s[] = {" %
1449 env.method_table_cname)
1450 for entry in env.pyfunc_entries:
1451 code.put_pymethoddef(entry, ",")
1452 code.putln(
1453 "{0, 0, 0, 0}")
1454 code.putln(
1455 "};")
1457 def generate_member_table(self, env, code):
1458 #print "ModuleNode.generate_member_table: scope =", env ###
1459 if env.public_attr_entries:
1460 code.putln("")
1461 code.putln(
1462 "static struct PyMemberDef %s[] = {" %
1463 env.member_table_cname)
1464 type = env.parent_type
1465 if type.typedef_flag:
1466 objstruct = type.objstruct_cname
1467 else:
1468 objstruct = "struct %s" % type.objstruct_cname
1469 for entry in env.public_attr_entries:
1470 type_code = entry.type.pymemberdef_typecode
1471 if entry.visibility == 'readonly':
1472 flags = "READONLY"
1473 else:
1474 flags = "0"
1475 code.putln('{(char *)"%s", %s, %s, %s, 0},' % (
1476 entry.name,
1477 type_code,
1478 "offsetof(%s, %s)" % (objstruct, entry.cname),
1479 flags))
1480 code.putln(
1481 "{0, 0, 0, 0, 0}")
1482 code.putln(
1483 "};")
1485 def generate_getset_table(self, env, code):
1486 if env.property_entries:
1487 code.putln("")
1488 code.putln(
1489 "static struct PyGetSetDef %s[] = {" %
1490 env.getset_table_cname)
1491 for entry in env.property_entries:
1492 code.putln(
1493 '{(char *)"%s", %s, %s, %s, 0},' % (
1494 entry.name,
1495 entry.getter_cname or "0",
1496 entry.setter_cname or "0",
1497 entry.doc_cname or "0"))
1498 code.putln(
1499 "{0, 0, 0, 0, 0}")
1500 code.putln(
1501 "};")
1503 def generate_filename_init_prototype(self, code):
1504 code.putln("");
1505 code.putln("static void %s(void); /*proto*/" % Naming.fileinit_cname)
1507 def generate_import_star(self, env, code):
1508 code.putln()
1509 code.putln("char* %s_type_names[] = {" % Naming.import_star)
1510 for name, entry in env.entries.items():
1511 if entry.is_type:
1512 code.putln('"%s",' % name)
1513 code.putln("0")
1514 code.putln("};")
1515 code.putln()
1516 code.enter_cfunc_scope() # as we need labels
1517 code.putln("static int %s(PyObject *o, PyObject* py_name, char *name) {" % Naming.import_star_set)
1518 code.putln("char** type_name = %s_type_names;" % Naming.import_star)
1519 code.putln("while (*type_name) {")
1520 code.putln("if (!strcmp(name, *type_name)) {")
1521 code.putln('PyErr_Format(PyExc_TypeError, "Cannot overwrite C type %s", name);')
1522 code.putln('goto bad;')
1523 code.putln("}")
1524 code.putln("type_name++;")
1525 code.putln("}")
1526 old_error_label = code.new_error_label()
1527 code.putln("if (0);") # so the first one can be "else if"
1528 for name, entry in env.entries.items():
1529 if entry.is_cglobal and entry.used:
1530 code.putln('else if (!strcmp(name, "%s")) {' % name)
1531 if entry.type.is_pyobject:
1532 if entry.type.is_extension_type or entry.type.is_builtin_type:
1533 code.putln("if (!(%s)) %s;" % (
1534 entry.type.type_test_code("o"),
1535 code.error_goto(entry.pos)))
1536 code.put_var_decref(entry)
1537 code.putln("%s = %s;" % (
1538 entry.cname,
1539 PyrexTypes.typecast(entry.type, py_object_type, "o")))
1540 elif entry.type.from_py_function:
1541 rhs = "%s(o)" % entry.type.from_py_function
1542 if entry.type.is_enum:
1543 rhs = typecast(entry.type, c_long_type, rhs)
1544 code.putln("%s = %s; if (%s) %s;" % (
1545 entry.cname,
1546 rhs,
1547 entry.type.error_condition(entry.cname),
1548 code.error_goto(entry.pos)))
1549 code.putln("Py_DECREF(o);")
1550 else:
1551 code.putln('PyErr_Format(PyExc_TypeError, "Cannot convert Python object %s to %s");' % (name, entry.type))
1552 code.putln(code.error_goto(entry.pos))
1553 code.putln("}")
1554 code.putln("else {")
1555 code.putln("if (PyObject_SetAttr(%s, py_name, o) < 0) goto bad;" % Naming.module_cname)
1556 code.putln("}")
1557 code.putln("return 0;")
1558 code.put_label(code.error_label)
1559 # This helps locate the offending name.
1560 code.putln('__Pyx_AddTraceback("%s");' % self.full_module_name);
1561 code.error_label = old_error_label
1562 code.putln("bad:")
1563 code.putln("Py_DECREF(o);")
1564 code.putln("return -1;")
1565 code.putln("}")
1566 code.putln(import_star_utility_code)
1567 code.exit_cfunc_scope() # done with labels
1569 def generate_module_init_func(self, imported_modules, env, code):
1570 # Insert code stream of __Pyx_InitGlobals()
1571 code.globalstate.insert_initcode_into(code)
1573 code.enter_cfunc_scope()
1574 code.putln("")
1575 header2 = "PyMODINIT_FUNC init%s(void)" % env.module_name
1576 header3 = "PyMODINIT_FUNC PyInit_%s(void)" % env.module_name
1577 code.putln("#if PY_MAJOR_VERSION < 3")
1578 code.putln("%s; /*proto*/" % header2)
1579 code.putln(header2)
1580 code.putln("#else")
1581 code.putln("%s; /*proto*/" % header3)
1582 code.putln(header3)
1583 code.putln("#endif")
1584 code.putln("{")
1585 code.putln("PyObject* %s;" % Naming.retval_cname)
1586 tempdecl_code = code.insertion_point()
1588 code.putln("#ifdef CYTHON_REFNANNY")
1589 code.putln("void* __pyx_refchk = NULL;")
1590 code.putln("__Pyx_Refnanny = __Pyx_ImportRefcountAPI(\"refnanny\");")
1591 code.putln("if (!__Pyx_Refnanny) {")
1592 code.putln(" PyErr_Clear();")
1593 code.putln(" __Pyx_Refnanny = __Pyx_ImportRefcountAPI(\"Cython.Runtime.refnanny\");")
1594 code.putln(" if (!__Pyx_Refnanny)")
1595 code.putln(" Py_FatalError(\"failed to import refnanny module\");")
1596 code.putln("}")
1597 code.putln("__pyx_refchk = __Pyx_Refnanny->NewContext(\"%s\", __LINE__, __FILE__);"% header3)
1598 code.putln("#endif")
1600 code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos)));
1602 code.putln("/*--- Library function declarations ---*/")
1603 env.generate_library_function_declarations(code)
1604 self.generate_filename_init_call(code)
1606 code.putln("/*--- Initialize various global constants etc. ---*/")
1607 code.putln(code.error_goto_if_neg("__Pyx_InitGlobals()", self.pos))
1609 code.putln("/*--- Module creation code ---*/")
1610 self.generate_module_creation_code(env, code)
1612 if Options.cache_builtins:
1613 code.putln("/*--- Builtin init code ---*/")
1614 code.putln(code.error_goto_if_neg("__Pyx_InitCachedBuiltins()",
1615 self.pos))
1617 code.putln("%s = 0;" % Naming.skip_dispatch_cname);
1619 code.putln("/*--- Global init code ---*/")
1620 self.generate_global_init_code(env, code)
1622 code.putln("/*--- Function export code ---*/")
1623 self.generate_c_function_export_code(env, code)
1625 code.putln("/*--- Type init code ---*/")
1626 self.generate_type_init_code(env, code)
1628 code.putln("/*--- Type import code ---*/")
1629 for module in imported_modules:
1630 self.generate_type_import_code_for_module(module, env, code)
1632 code.putln("/*--- Function import code ---*/")
1633 for module in imported_modules:
1634 self.generate_c_function_import_code_for_module(module, env, code)
1636 code.putln("/*--- Execution code ---*/")
1637 code.mark_pos(None)
1639 self.body.generate_execution_code(code)
1641 if Options.generate_cleanup_code:
1642 # this should be replaced by the module's tp_clear in Py3
1643 env.use_utility_code(import_module_utility_code)
1644 code.putln("if (__Pyx_RegisterCleanup()) %s;" % code.error_goto(self.pos))
1646 code.putln("%s = %s;" % (Naming.retval_cname, env.module_cname))
1647 code.put_goto(code.return_label)
1648 code.put_label(code.error_label)
1649 code.put_var_xdecrefs(env.temp_entries)
1650 code.putln('__Pyx_AddTraceback("%s");' % env.qualified_name)
1651 env.use_utility_code(Nodes.traceback_utility_code)
1652 code.putln("%s = NULL;" % Naming.retval_cname)
1653 code.put_label(code.return_label)
1655 code.put_finish_refcount_context()
1657 code.putln("#if PY_MAJOR_VERSION < 3")
1658 code.putln("return;")
1659 code.putln("#else")
1660 code.putln("return %s;" % Naming.retval_cname)
1661 code.putln("#endif")
1662 code.putln('}')
1664 tempdecl_code.put_var_declarations(env.temp_entries)
1665 tempdecl_code.put_temp_declarations(code.funcstate)
1667 code.exit_cfunc_scope()
1669 def generate_module_cleanup_func(self, env, code):
1670 if not Options.generate_cleanup_code:
1671 return
1672 env.use_utility_code(register_cleanup_utility_code)
1673 # Insert code stream of __Pyx_CleanupGlobals()
1674 code.globalstate.insert_cleanupcode_into(code)
1675 code.putln()
1676 code.putln('static PyObject* %s(PyObject *self, PyObject *unused) {' % Naming.cleanup_cname)
1677 if Options.generate_cleanup_code >= 2:
1678 code.putln("/*--- Global cleanup code ---*/")
1679 rev_entries = list(env.var_entries)
1680 rev_entries.reverse()
1681 for entry in rev_entries:
1682 if entry.visibility != 'extern':
1683 if entry.type.is_pyobject and entry.used:
1684 code.putln("Py_DECREF(%s); %s = 0;" % (
1685 code.entry_as_pyobject(entry), entry.cname))
1686 code.putln("__Pyx_CleanupGlobals();")
1687 if Options.generate_cleanup_code >= 3:
1688 code.putln("/*--- Type import cleanup code ---*/")
1689 for type, _ in env.types_imported.items():
1690 code.putln("Py_DECREF((PyObject *)%s); %s = 0;" % (
1691 type.typeptr_cname, type.typeptr_cname))
1692 if Options.cache_builtins:
1693 code.putln("/*--- Builtin cleanup code ---*/")
1694 for entry in env.cached_builtins:
1695 code.put_decref_clear(entry.cname,
1696 PyrexTypes.py_object_type,
1697 nanny=False)
1698 code.putln("/*--- Intern cleanup code ---*/")
1699 code.put_decref_clear(Naming.empty_tuple,
1700 PyrexTypes.py_object_type,
1701 nanny=False)
1702 for entry in env.pynum_entries:
1703 code.put_decref_clear(entry.cname,
1704 PyrexTypes.py_object_type,
1705 nanny=False)
1706 for entry in env.all_pystring_entries:
1707 if entry.is_interned:
1708 code.put_decref_clear(entry.pystring_cname,
1709 PyrexTypes.py_object_type,
1710 nanny=False)
1711 code.putln("Py_INCREF(Py_None); return Py_None;")
1712 code.putln('}')
1714 def generate_filename_init_call(self, code):
1715 code.putln("%s();" % Naming.fileinit_cname)
1717 def generate_pymoduledef_struct(self, env, code):
1718 if env.doc:
1719 doc = env.doc_cname
1720 else:
1721 doc = "0"
1722 code.putln("")
1723 code.putln("#if PY_MAJOR_VERSION >= 3")
1724 code.putln("static struct PyModuleDef %s = {" % Naming.pymoduledef_cname)
1725 code.putln(" PyModuleDef_HEAD_INIT,")
1726 code.putln(' "%s",' % env.module_name)
1727 code.putln(" %s, /* m_doc */" % doc)
1728 code.putln(" -1, /* m_size */")
1729 code.putln(" %s /* m_methods */," % env.method_table_cname)
1730 code.putln(" NULL, /* m_reload */")
1731 code.putln(" NULL, /* m_traverse */")
1732 code.putln(" NULL, /* m_clear */")
1733 code.putln(" NULL /* m_free */")
1734 code.putln("};")
1735 code.putln("#endif")
1737 def generate_module_creation_code(self, env, code):
1738 # Generate code to create the module object and
1739 # install the builtins.
1740 if env.doc:
1741 doc = env.doc_cname
1742 else:
1743 doc = "0"
1744 code.putln("#if PY_MAJOR_VERSION < 3")
1745 code.putln(
1746 '%s = Py_InitModule4(__Pyx_NAMESTR("%s"), %s, %s, 0, PYTHON_API_VERSION);' % (
1747 env.module_cname,
1748 env.module_name,
1749 env.method_table_cname,
1750 doc))
1751 code.putln("#else")
1752 code.putln(
1753 "%s = PyModule_Create(&%s);" % (
1754 env.module_cname,
1755 Naming.pymoduledef_cname))
1756 code.putln("#endif")
1757 code.putln(
1758 "if (!%s) %s;" % (
1759 env.module_cname,
1760 code.error_goto(self.pos)));
1761 code.putln("#if PY_MAJOR_VERSION < 3")
1762 code.putln(
1763 "Py_INCREF(%s);" %
1764 env.module_cname)
1765 code.putln("#endif")
1766 code.putln(
1767 '%s = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME));' %
1768 Naming.builtins_cname)
1769 code.putln(
1770 "if (!%s) %s;" % (
1771 Naming.builtins_cname,
1772 code.error_goto(self.pos)));
1773 code.putln(
1774 'if (__Pyx_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % (
1775 env.module_cname,
1776 Naming.builtins_cname,
1777 code.error_goto(self.pos)))
1778 if Options.pre_import is not None:
1779 code.putln(
1780 '%s = PyImport_AddModule(__Pyx_NAMESTR("%s"));' % (
1781 Naming.preimport_cname,
1782 Options.pre_import))
1783 code.putln(
1784 "if (!%s) %s;" % (
1785 Naming.preimport_cname,
1786 code.error_goto(self.pos)));
1788 def generate_global_init_code(self, env, code):
1789 # Generate code to initialise global PyObject *
1790 # variables to None.
1791 for entry in env.var_entries:
1792 if entry.visibility != 'extern':
1793 if entry.type.is_pyobject and entry.used:
1794 code.put_init_var_to_py_none(entry, nanny=False)
1796 def generate_c_function_export_code(self, env, code):
1797 # Generate code to create PyCFunction wrappers for exported C functions.
1798 for entry in env.cfunc_entries:
1799 if entry.api or entry.defined_in_pxd:
1800 env.use_utility_code(function_export_utility_code)
1801 signature = entry.type.signature_string()
1802 code.putln('if (__Pyx_ExportFunction("%s", (void*)%s, "%s") < 0) %s' % (
1803 entry.name,
1804 entry.cname,
1805 signature,
1806 code.error_goto(self.pos)))
1808 def generate_type_import_code_for_module(self, module, env, code):
1809 # Generate type import code for all exported extension types in
1810 # an imported module.
1811 #if module.c_class_entries:
1812 for entry in module.c_class_entries:
1813 if entry.defined_in_pxd:
1814 self.generate_type_import_code(env, entry.type, entry.pos, code)
1816 def generate_c_function_import_code_for_module(self, module, env, code):
1817 # Generate import code for all exported C functions in a cimported module.
1818 entries = []
1819 for entry in module.cfunc_entries:
1820 if entry.defined_in_pxd:
1821 entries.append(entry)
1822 if entries:
1823 env.use_utility_code(import_module_utility_code)
1824 env.use_utility_code(function_import_utility_code)
1825 temp = self.module_temp_cname
1826 code.putln(
1827 '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % (
1828 temp,
1829 module.qualified_name,
1830 temp,
1831 code.error_goto(self.pos)))
1832 for entry in entries:
1833 code.putln(
1834 'if (__Pyx_ImportFunction(%s, "%s", (void**)&%s, "%s") < 0) %s' % (
1835 temp,
1836 entry.name,
1837 entry.cname,
1838 entry.type.signature_string(),
1839 code.error_goto(self.pos)))
1840 code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp))
1842 def generate_type_init_code(self, env, code):
1843 # Generate type import code for extern extension types
1844 # and type ready code for non-extern ones.
1845 for entry in env.c_class_entries:
1846 if entry.visibility == 'extern':
1847 self.generate_type_import_code(env, entry.type, entry.pos, code)
1848 else:
1849 self.generate_base_type_import_code(env, entry, code)
1850 self.generate_exttype_vtable_init_code(entry, code)
1851 self.generate_type_ready_code(env, entry, code)
1852 self.generate_typeptr_assignment_code(entry, code)
1854 def generate_base_type_import_code(self, env, entry, code):
1855 base_type = entry.type.base_type
1856 if base_type and base_type.module_name != env.qualified_name:
1857 self.generate_type_import_code(env, base_type, self.pos, code)
1859 def use_type_import_utility_code(self, env):
1860 env.use_utility_code(type_import_utility_code)
1861 env.use_utility_code(import_module_utility_code)
1863 def generate_type_import_code(self, env, type, pos, code):
1864 # If not already done, generate code to import the typeobject of an
1865 # extension type defined in another module, and extract its C method
1866 # table pointer if any.
1867 if type in env.types_imported:
1868 return
1869 if type.typedef_flag:
1870 objstruct = type.objstruct_cname
1871 else:
1872 objstruct = "struct %s" % type.objstruct_cname
1873 self.generate_type_import_call(type, code,
1874 code.error_goto_if_null(type.typeptr_cname, pos))
1875 self.use_type_import_utility_code(env)
1876 if type.vtabptr_cname:
1877 code.putln(
1878 "if (__Pyx_GetVtable(%s->tp_dict, &%s) < 0) %s" % (
1879 type.typeptr_cname,
1880 type.vtabptr_cname,
1881 code.error_goto(pos)))
1882 env.use_utility_code(Nodes.get_vtable_utility_code)
1883 env.types_imported[type] = 1
1885 py3_type_name_map = {'str' : 'bytes', 'unicode' : 'str'}
1887 def generate_type_import_call(self, type, code, error_code):
1888 if type.typedef_flag:
1889 objstruct = type.objstruct_cname
1890 else:
1891 objstruct = "struct %s" % type.objstruct_cname
1892 module_name = type.module_name
1893 if module_name not in ('__builtin__', 'builtins'):
1894 module_name = '"%s"' % module_name
1895 else:
1896 module_name = '__Pyx_BUILTIN_MODULE_NAME'
1897 if type.name in self.py3_type_name_map:
1898 code.putln("#if PY_MAJOR_VERSION >= 3")
1899 code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s)); %s' % (
1900 type.typeptr_cname,
1901 module_name,
1902 self.py3_type_name_map[type.name],
1903 objstruct,
1904 error_code))
1905 code.putln("#else")
1906 code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s)); %s' % (
1907 type.typeptr_cname,
1908 module_name,
1909 type.name,
1910 objstruct,
1911 error_code))
1912 if type.name in self.py3_type_name_map:
1913 code.putln("#endif")
1915 def generate_type_ready_code(self, env, entry, code):
1916 # Generate a call to PyType_Ready for an extension
1917 # type defined in this module.
1918 type = entry.type
1919 typeobj_cname = type.typeobj_cname
1920 scope = type.scope
1921 if scope: # could be None if there was an error
1922 if entry.visibility != 'extern':
1923 for slot in TypeSlots.slot_table:
1924 slot.generate_dynamic_init_code(scope, code)
1925 code.putln(
1926 "if (PyType_Ready(&%s) < 0) %s" % (
1927 typeobj_cname,
1928 code.error_goto(entry.pos)))
1929 if type.vtable_cname:
1930 code.putln(
1931 "if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
1932 typeobj_cname,
1933 type.vtabptr_cname,
1934 code.error_goto(entry.pos)))
1935 env.use_utility_code(Nodes.set_vtable_utility_code)
1936 code.putln(
1937 'if (__Pyx_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % (
1938 Naming.module_cname,
1939 scope.class_name,
1940 typeobj_cname,
1941 code.error_goto(entry.pos)))
1942 weakref_entry = scope.lookup_here("__weakref__")
1943 if weakref_entry:
1944 if weakref_entry.type is py_object_type:
1945 tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname
1946 code.putln("if (%s == 0) %s = offsetof(struct %s, %s);" % (
1947 tp_weaklistoffset,
1948 tp_weaklistoffset,
1949 type.objstruct_cname,
1950 weakref_entry.cname))
1951 else:
1952 error(weakref_entry.pos, "__weakref__ slot must be of type 'object'")
1954 def generate_exttype_vtable_init_code(self, entry, code):
1955 # Generate code to initialise the C method table of an
1956 # extension type.
1957 type = entry.type
1958 if type.vtable_cname:
1959 code.putln(
1960 "%s = &%s;" % (
1961 type.vtabptr_cname,
1962 type.vtable_cname))
1963 if type.base_type and type.base_type.vtabptr_cname:
1964 code.putln(
1965 "%s.%s = *%s;" % (
1966 type.vtable_cname,
1967 Naming.obj_base_cname,
1968 type.base_type.vtabptr_cname))
1969 for meth_entry in type.scope.cfunc_entries:
1970 if meth_entry.func_cname:
1971 code.putln(
1972 "*(void(**)(void))&%s.%s = (void(*)(void))%s;" % (
1973 type.vtable_cname,
1974 meth_entry.cname,
1975 meth_entry.func_cname))
1977 def generate_typeptr_assignment_code(self, entry, code):
1978 # Generate code to initialise the typeptr of an extension
1979 # type defined in this module to point to its type object.
1980 type = entry.type
1981 if type.typeobj_cname:
1982 code.putln(
1983 "%s = &%s;" % (
1984 type.typeptr_cname, type.typeobj_cname))
1986 def generate_utility_functions(self, env, code, h_code):
1987 for codetup, name in env.utility_code_list:
1988 code.globalstate.use_utility_code(codetup, name)
1990 code.globalstate.put_utility_code_protos(h_code)
1991 code.putln("")
1992 code.putln("/* Runtime support code */")
1993 code.putln("")
1994 code.putln("static void %s(void) {" % Naming.fileinit_cname)
1995 code.putln("%s = %s;" %
1996 (Naming.filetable_cname, Naming.filenames_cname))
1997 code.putln("}")
1998 code.globalstate.put_utility_code_defs(code)
1999 code.put(PyrexTypes.type_conversion_functions)
2000 code.putln("")
2002 #------------------------------------------------------------------------------------
2003 #
2004 # Runtime support code
2005 #
2006 #------------------------------------------------------------------------------------
2008 builtin_module_name_utility_code = UtilityCode(
2009 proto = """\
2010 #if PY_MAJOR_VERSION < 3
2011 #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
2012 #else
2013 #define __Pyx_BUILTIN_MODULE_NAME "builtins"
2014 #endif
2015 """)
2017 import_module_utility_code = UtilityCode(
2018 proto = """
2019 static PyObject *__Pyx_ImportModule(const char *name); /*proto*/
2020 """,
2021 impl = """
2022 #ifndef __PYX_HAVE_RT_ImportModule
2023 #define __PYX_HAVE_RT_ImportModule
2024 static PyObject *__Pyx_ImportModule(const char *name) {
2025 PyObject *py_name = 0;
2026 PyObject *py_module = 0;
2028 #if PY_MAJOR_VERSION < 3
2029 py_name = PyString_FromString(name);
2030 #else
2031 py_name = PyUnicode_FromString(name);
2032 #endif
2033 if (!py_name)
2034 goto bad;
2035 py_module = PyImport_Import(py_name);
2036 Py_DECREF(py_name);
2037 return py_module;
2038 bad:
2039 Py_XDECREF(py_name);
2040 return 0;
2041 }
2042 #endif
2043 """)
2045 #------------------------------------------------------------------------------------
2047 type_import_utility_code = UtilityCode(
2048 proto = """
2049 static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, long size); /*proto*/
2050 """,
2051 impl = """
2052 #ifndef __PYX_HAVE_RT_ImportType
2053 #define __PYX_HAVE_RT_ImportType
2054 static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
2055 long size)
2056 {
2057 PyObject *py_module = 0;
2058 PyObject *result = 0;
2059 PyObject *py_name = 0;
2061 py_module = __Pyx_ImportModule(module_name);
2062 if (!py_module)
2063 goto bad;
2064 #if PY_MAJOR_VERSION < 3
2065 py_name = PyString_FromString(class_name);
2066 #else
2067 py_name = PyUnicode_FromString(class_name);
2068 #endif
2069 if (!py_name)
2070 goto bad;
2071 result = PyObject_GetAttr(py_module, py_name);
2072 Py_DECREF(py_name);
2073 py_name = 0;
2074 Py_DECREF(py_module);
2075 py_module = 0;
2076 if (!result)
2077 goto bad;
2078 if (!PyType_Check(result)) {
2079 PyErr_Format(PyExc_TypeError,
2080 "%s.%s is not a type object",
2081 module_name, class_name);
2082 goto bad;
2083 }
2084 if (((PyTypeObject *)result)->tp_basicsize != size) {
2085 PyErr_Format(PyExc_ValueError,
2086 "%s.%s does not appear to be the correct type object",
2087 module_name, class_name);
2088 goto bad;
2089 }
2090 return (PyTypeObject *)result;
2091 bad:
2092 Py_XDECREF(py_module);
2093 Py_XDECREF(result);
2094 return 0;
2095 }
2096 #endif
2097 """)
2099 #------------------------------------------------------------------------------------
2101 function_export_utility_code = UtilityCode(
2102 proto = """
2103 static int __Pyx_ExportFunction(const char *name, void *f, const char *sig); /*proto*/
2104 """,
2105 impl = r"""
2106 static int __Pyx_ExportFunction(const char *name, void *f, const char *sig) {
2107 #if PY_VERSION_HEX < 0x02050000
2108 char *api = (char *)"%(API)s";
2109 #else
2110 const char *api = "%(API)s";
2111 #endif
2112 PyObject *d = 0;
2113 PyObject *p = 0;
2115 d = PyObject_GetAttrString(%(MODULE)s, api);
2116 if (!d) {
2117 PyErr_Clear();
2118 d = PyDict_New();
2119 if (!d)
2120 goto bad;
2121 Py_INCREF(d);
2122 if (PyModule_AddObject(%(MODULE)s, api, d) < 0)
2123 goto bad;
2124 }
2125 p = PyCObject_FromVoidPtrAndDesc(f, (void *)sig, 0);
2126 if (!p)
2127 goto bad;
2128 if (PyDict_SetItemString(d, name, p) < 0)
2129 goto bad;
2130 Py_DECREF(d);
2131 return 0;
2132 bad:
2133 Py_XDECREF(p);
2134 Py_XDECREF(d);
2135 return -1;
2136 }
2137 """ % {'MODULE': Naming.module_cname, 'API': Naming.api_name}
2138 )
2140 #------------------------------------------------------------------------------------
2142 function_import_utility_code = UtilityCode(
2143 proto = """
2144 static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void **f, const char *sig); /*proto*/
2145 """,
2146 impl = """
2147 #ifndef __PYX_HAVE_RT_ImportFunction
2148 #define __PYX_HAVE_RT_ImportFunction
2149 static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void **f, const char *sig) {
2150 #if PY_VERSION_HEX < 0x02050000
2151 char *api = (char *)"%(API)s";
2152 #else
2153 const char *api = "%(API)s";
2154 #endif
2155 PyObject *d = 0;
2156 PyObject *cobj = 0;
2157 char *desc;
2159 d = PyObject_GetAttrString(module, api);
2160 if (!d)
2161 goto bad;
2162 cobj = PyDict_GetItemString(d, funcname);
2163 if (!cobj) {
2164 PyErr_Format(PyExc_ImportError,
2165 "%%s does not export expected C function %%s",
2166 PyModule_GetName(module), funcname);
2167 goto bad;
2168 }
2169 desc = (char *)PyCObject_GetDesc(cobj);
2170 if (!desc)
2171 goto bad;
2172 if (strcmp(desc, sig) != 0) {
2173 PyErr_Format(PyExc_TypeError,
2174 "C function %%s.%%s has wrong signature (expected %%s, got %%s)",
2175 PyModule_GetName(module), funcname, sig, desc);
2176 goto bad;
2177 }
2178 *f = PyCObject_AsVoidPtr(cobj);
2179 Py_DECREF(d);
2180 return 0;
2181 bad:
2182 Py_XDECREF(d);
2183 return -1;
2184 }
2185 #endif
2186 """ % dict(API = Naming.api_name)
2187 )
2189 register_cleanup_utility_code = UtilityCode(
2190 proto = """
2191 static int __Pyx_RegisterCleanup(void); /*proto*/
2192 static PyObject* __pyx_module_cleanup(PyObject *self, PyObject *unused); /*proto*/
2193 static PyMethodDef cleanup_def = {__Pyx_NAMESTR("__cleanup"), (PyCFunction)&__pyx_module_cleanup, METH_NOARGS, 0};
2194 """,
2195 impl = """
2196 static int __Pyx_RegisterCleanup(void) {
2197 /* Don't use Py_AtExit because that has a 32-call limit
2198 * and is called after python finalization.
2199 */
2201 PyObject *cleanup_func = 0;
2202 PyObject *atexit = 0;
2203 PyObject *reg = 0;
2204 PyObject *args = 0;
2205 PyObject *res = 0;
2206 int ret = -1;
2208 cleanup_func = PyCFunction_New(&cleanup_def, 0);
2209 args = PyTuple_New(1);
2210 if (!cleanup_func || !args)
2211 goto bad;
2212 PyTuple_SET_ITEM(args, 0, cleanup_func);
2213 cleanup_func = 0;
2215 atexit = __Pyx_ImportModule("atexit");
2216 if (!atexit)
2217 goto bad;
2218 reg = __Pyx_GetAttrString(atexit, "register");
2219 if (!reg)
2220 goto bad;
2221 res = PyObject_CallObject(reg, args);
2222 if (!res)
2223 goto bad;
2224 ret = 0;
2225 bad:
2226 Py_XDECREF(cleanup_func);
2227 Py_XDECREF(atexit);
2228 Py_XDECREF(reg);
2229 Py_XDECREF(args);
2230 Py_XDECREF(res);
2231 return ret;
2232 }
2233 """)
2235 import_star_utility_code = """
2237 /* import_all_from is an unexposed function from ceval.c */
2239 static int
2240 __Pyx_import_all_from(PyObject *locals, PyObject *v)
2241 {
2242 PyObject *all = __Pyx_GetAttrString(v, "__all__");
2243 PyObject *dict, *name, *value;
2244 int skip_leading_underscores = 0;
2245 int pos, err;
2247 if (all == NULL) {
2248 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
2249 return -1; /* Unexpected error */
2250 PyErr_Clear();
2251 dict = __Pyx_GetAttrString(v, "__dict__");
2252 if (dict == NULL) {
2253 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
2254 return -1;
2255 PyErr_SetString(PyExc_ImportError,
2256 "from-import-* object has no __dict__ and no __all__");
2257 return -1;
2258 }
2259 all = PyMapping_Keys(dict);
2260 Py_DECREF(dict);
2261 if (all == NULL)
2262 return -1;
2263 skip_leading_underscores = 1;
2264 }
2266 for (pos = 0, err = 0; ; pos++) {
2267 name = PySequence_GetItem(all, pos);
2268 if (name == NULL) {
2269 if (!PyErr_ExceptionMatches(PyExc_IndexError))
2270 err = -1;
2271 else
2272 PyErr_Clear();
2273 break;
2274 }
2275 if (skip_leading_underscores &&
2276 #if PY_MAJOR_VERSION < 3
2277 PyString_Check(name) &&
2278 PyString_AS_STRING(name)[0] == '_')
2279 #else
2280 PyUnicode_Check(name) &&
2281 PyUnicode_AS_UNICODE(name)[0] == '_')
2282 #endif
2283 {
2284 Py_DECREF(name);
2285 continue;
2286 }
2287 value = PyObject_GetAttr(v, name);
2288 if (value == NULL)
2289 err = -1;
2290 else if (PyDict_CheckExact(locals))
2291 err = PyDict_SetItem(locals, name, value);
2292 else
2293 err = PyObject_SetItem(locals, name, value);
2294 Py_DECREF(name);
2295 Py_XDECREF(value);
2296 if (err != 0)
2297 break;
2298 }
2299 Py_DECREF(all);
2300 return err;
2301 }
2304 static int %(IMPORT_STAR)s(PyObject* m) {
2306 int i;
2307 int ret = -1;
2308 char* s;
2309 PyObject *locals = 0;
2310 PyObject *list = 0;
2311 PyObject *name;
2312 PyObject *item;
2314 locals = PyDict_New(); if (!locals) goto bad;
2315 if (__Pyx_import_all_from(locals, m) < 0) goto bad;
2316 list = PyDict_Items(locals); if (!list) goto bad;
2318 for(i=0; i<PyList_GET_SIZE(list); i++) {
2319 name = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 0);
2320 item = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 1);
2321 #if PY_MAJOR_VERSION < 3
2322 s = PyString_AsString(name);
2323 #else
2324 s = PyUnicode_AsString(name);
2325 #endif
2326 if (!s) goto bad;
2327 if (%(IMPORT_STAR_SET)s(item, name, s) < 0) goto bad;
2328 }
2329 ret = 0;
2331 bad:
2332 Py_XDECREF(locals);
2333 Py_XDECREF(list);
2334 return ret;
2335 }
2336 """ % {'IMPORT_STAR' : Naming.import_star,
2337 'IMPORT_STAR_SET' : Naming.import_star_set }
2339 refcount_utility_code = UtilityCode(proto="""
2340 #ifdef CYTHON_REFNANNY
2341 typedef struct {
2342 void (*INCREF)(void*, PyObject*, int);
2343 void (*DECREF)(void*, PyObject*, int);
2344 void (*GOTREF)(void*, PyObject*, int);
2345 void (*GIVEREF)(void*, PyObject*, int);
2346 void* (*NewContext)(const char*, int, const char*);
2347 void (*FinishContext)(void**);
2348 } __Pyx_RefnannyAPIStruct;
2349 static __Pyx_RefnannyAPIStruct *__Pyx_Refnanny = NULL;
2350 #define __Pyx_ImportRefcountAPI(name) \
2351 (__Pyx_RefnannyAPIStruct *) PyCObject_Import((char *)name, (char *)\"RefnannyAPI\")
2352 #define __Pyx_INCREF(r) __Pyx_Refnanny->INCREF(__pyx_refchk, (PyObject *)(r), __LINE__)
2353 #define __Pyx_DECREF(r) __Pyx_Refnanny->DECREF(__pyx_refchk, (PyObject *)(r), __LINE__)
2354 #define __Pyx_GOTREF(r) __Pyx_Refnanny->GOTREF(__pyx_refchk, (PyObject *)(r), __LINE__)
2355 #define __Pyx_GIVEREF(r) __Pyx_Refnanny->GIVEREF(__pyx_refchk, (PyObject *)(r), __LINE__)
2356 #define __Pyx_XDECREF(r) if((r) == NULL) ; else __Pyx_DECREF(r)
2357 #define __Pyx_SetupRefcountContext(name) \
2358 void* __pyx_refchk = __Pyx_Refnanny->NewContext((name), __LINE__, __FILE__)
2359 #define __Pyx_FinishRefcountContext() \
2360 __Pyx_Refnanny->FinishContext(&__pyx_refchk)
2361 #else
2362 #define __Pyx_INCREF(r) Py_INCREF(r)
2363 #define __Pyx_DECREF(r) Py_DECREF(r)
2364 #define __Pyx_GOTREF(r)
2365 #define __Pyx_GIVEREF(r)
2366 #define __Pyx_XDECREF(r) Py_XDECREF(r)
2367 #define __Pyx_SetupRefcountContext(name)
2368 #define __Pyx_FinishRefcountContext()
2369 #endif /* CYTHON_REFNANNY */
2370 #define __Pyx_XGIVEREF(r) if((r) == NULL) ; else __Pyx_GIVEREF(r)
2371 #define __Pyx_XGOTREF(r) if((r) == NULL) ; else __Pyx_GOTREF(r)
2372 """)
