Cython has moved to github.

cython-devel

view Cython/Compiler/ModuleNode.py @ 1875:9a1f6f7c260a

thread initialisation when using with gil/nogil (by Lisandro)
author Stefan Behnel <scoder@users.berlios.de>
date Thu Mar 19 10:50:40 2009 +0100 (3 years ago)
parents 838a6b7cae62
children 0bd3bfd487a5
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 (**)(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 env.use_utility_code(streq_utility_code)
563 def generate_extern_c_macro_definition(self, code):
564 name = Naming.extern_c_macro
565 code.putln("#ifdef __cplusplus")
566 code.putln('#define %s extern "C"' % name)
567 code.putln("#else")
568 code.putln("#define %s extern" % name)
569 code.putln("#endif")
571 def generate_includes(self, env, cimported_modules, code):
572 includes = []
573 for filename in env.include_files:
574 code.putln('#include "%s"' % filename)
576 def generate_filename_table(self, code):
577 code.putln("")
578 code.putln("static const char *%s[] = {" % Naming.filenames_cname)
579 if code.globalstate.filename_list:
580 for source_desc in code.globalstate.filename_list:
581 filename = os.path.basename(source_desc.get_filenametable_entry())
582 escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"')
583 code.putln('"%s",' %
584 escaped_filename)
585 else:
586 # Some C compilers don't like an empty array
587 code.putln("0")
588 code.putln("};")
590 def generate_type_predeclarations(self, env, code):
591 pass
593 def generate_type_header_code(self, type_entries, code):
594 # Generate definitions of structs/unions/enums/typedefs/objstructs.
595 #self.generate_gcc33_hack(env, code) # Is this still needed?
596 #for entry in env.type_entries:
597 for entry in type_entries:
598 if not entry.in_cinclude:
599 #print "generate_type_header_code:", entry.name, repr(entry.type) ###
600 type = entry.type
601 if type.is_typedef: # Must test this first!
602 self.generate_typedef(entry, code)
603 elif type.is_struct_or_union:
604 self.generate_struct_union_definition(entry, code)
605 elif type.is_enum:
606 self.generate_enum_definition(entry, code)
607 elif type.is_extension_type:
608 self.generate_obj_struct_definition(type, code)
610 def generate_gcc33_hack(self, env, code):
611 # Workaround for spurious warning generation in gcc 3.3
612 code.putln("")
613 for entry in env.c_class_entries:
614 type = entry.type
615 if not type.typedef_flag:
616 name = type.objstruct_cname
617 if name.startswith("__pyx_"):
618 tail = name[6:]
619 else:
620 tail = name
621 code.putln("typedef struct %s __pyx_gcc33_%s;" % (
622 name, tail))
624 def generate_typedef(self, entry, code):
625 base_type = entry.type.typedef_base_type
626 code.putln("")
627 code.putln("typedef %s;" % base_type.declaration_code(entry.cname))
629 def sue_header_footer(self, type, kind, name):
630 if type.typedef_flag:
631 header = "typedef %s {" % kind
632 footer = "} %s;" % name
633 else:
634 header = "%s %s {" % (kind, name)
635 footer = "};"
636 return header, footer
638 def generate_struct_union_definition(self, entry, code):
639 code.mark_pos(entry.pos)
640 type = entry.type
641 scope = type.scope
642 if scope:
643 header, footer = \
644 self.sue_header_footer(type, type.kind, type.cname)
645 code.putln("")
646 code.putln(header)
647 var_entries = scope.var_entries
648 if not var_entries:
649 error(entry.pos,
650 "Empty struct or union definition not allowed outside a"
651 " 'cdef extern from' block")
652 for attr in var_entries:
653 code.putln(
654 "%s;" %
655 attr.type.declaration_code(attr.cname))
656 code.putln(footer)
658 def generate_enum_definition(self, entry, code):
659 code.mark_pos(entry.pos)
660 type = entry.type
661 name = entry.cname or entry.name or ""
662 header, footer = \
663 self.sue_header_footer(type, "enum", name)
664 code.putln("")
665 code.putln(header)
666 enum_values = entry.enum_values
667 if not enum_values:
668 error(entry.pos,
669 "Empty enum definition not allowed outside a"
670 " 'cdef extern from' block")
671 else:
672 last_entry = enum_values[-1]
673 for value_entry in enum_values:
674 if value_entry.value == value_entry.name:
675 value_code = value_entry.cname
676 else:
677 value_code = ("%s = %s" % (
678 value_entry.cname,
679 value_entry.value))
680 if value_entry is not last_entry:
681 value_code += ","
682 code.putln(value_code)
683 code.putln(footer)
685 def generate_typeobject_predeclaration(self, entry, code):
686 code.putln("")
687 name = entry.type.typeobj_cname
688 if name:
689 if entry.visibility == 'extern' and not entry.in_cinclude:
690 code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
691 Naming.extern_c_macro,
692 name))
693 elif entry.visibility == 'public':
694 #code.putln("DL_EXPORT(PyTypeObject) %s;" % name)
695 code.putln("%s DL_EXPORT(PyTypeObject) %s;" % (
696 Naming.extern_c_macro,
697 name))
698 # ??? Do we really need the rest of this? ???
699 #else:
700 # code.putln("staticforward PyTypeObject %s;" % name)
702 def generate_exttype_vtable_struct(self, entry, code):
703 code.mark_pos(entry.pos)
704 # Generate struct declaration for an extension type's vtable.
705 type = entry.type
706 scope = type.scope
707 if type.vtabstruct_cname:
708 code.putln("")
709 code.putln(
710 "struct %s {" %
711 type.vtabstruct_cname)
712 if type.base_type and type.base_type.vtabstruct_cname:
713 code.putln("struct %s %s;" % (
714 type.base_type.vtabstruct_cname,
715 Naming.obj_base_cname))
716 for method_entry in scope.cfunc_entries:
717 if not method_entry.is_inherited:
718 code.putln(
719 "%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.name))
720 code.putln(
721 "};")
723 def generate_exttype_vtabptr_declaration(self, entry, code):
724 code.mark_pos(entry.pos)
725 # Generate declaration of pointer to an extension type's vtable.
726 type = entry.type
727 if type.vtabptr_cname:
728 code.putln("static struct %s *%s;" % (
729 type.vtabstruct_cname,
730 type.vtabptr_cname))
732 def generate_obj_struct_definition(self, type, code):
733 code.mark_pos(type.pos)
734 # Generate object struct definition for an
735 # extension type.
736 if not type.scope:
737 return # Forward declared but never defined
738 header, footer = \
739 self.sue_header_footer(type, "struct", type.objstruct_cname)
740 code.putln("")
741 code.putln(header)
742 base_type = type.base_type
743 if base_type:
744 code.putln(
745 "%s%s %s;" % (
746 ("struct ", "")[base_type.typedef_flag],
747 base_type.objstruct_cname,
748 Naming.obj_base_cname))
749 else:
750 code.putln(
751 "PyObject_HEAD")
752 if type.vtabslot_cname and not (type.base_type and type.base_type.vtabslot_cname):
753 code.putln(
754 "struct %s *%s;" % (
755 type.vtabstruct_cname,
756 type.vtabslot_cname))
757 for attr in type.scope.var_entries:
758 code.putln(
759 "%s;" %
760 attr.type.declaration_code(attr.cname))
761 code.putln(footer)
763 def generate_global_declarations(self, env, code, definition):
764 code.putln("")
765 for entry in env.c_class_entries:
766 if definition or entry.defined_in_pxd:
767 code.putln("static PyTypeObject *%s = 0;" %
768 entry.type.typeptr_cname)
769 code.put_var_declarations(env.var_entries, static = 1,
770 dll_linkage = "DL_EXPORT", definition = definition)
771 if definition:
772 code.put_var_declarations(env.default_entries, static = 1,
773 definition = definition)
775 def generate_cfunction_predeclarations(self, env, code, definition):
776 for entry in env.cfunc_entries:
777 if entry.inline_func_in_pxd or (not entry.in_cinclude and (definition
778 or entry.defined_in_pxd or entry.visibility == 'extern')):
779 if entry.visibility in ('public', 'extern'):
780 dll_linkage = "DL_EXPORT"
781 else:
782 dll_linkage = None
783 type = entry.type
784 if not definition and entry.defined_in_pxd:
785 type = CPtrType(type)
786 header = type.declaration_code(entry.cname,
787 dll_linkage = dll_linkage)
788 if entry.visibility == 'private':
789 storage_class = "static "
790 elif entry.visibility == 'public':
791 storage_class = ""
792 else:
793 storage_class = "%s " % Naming.extern_c_macro
794 if entry.func_modifiers:
795 modifiers = '%s ' % ' '.join([
796 modifier.upper() for modifier in entry.func_modifiers])
797 else:
798 modifiers = ''
799 code.putln("%s%s%s; /*proto*/" % (
800 storage_class,
801 modifiers,
802 header))
804 def generate_typeobj_definitions(self, env, code):
805 full_module_name = env.qualified_name
806 for entry in env.c_class_entries:
807 #print "generate_typeobj_definitions:", entry.name
808 #print "...visibility =", entry.visibility
809 if entry.visibility != 'extern':
810 type = entry.type
811 scope = type.scope
812 if scope: # could be None if there was an error
813 self.generate_exttype_vtable(scope, code)
814 self.generate_new_function(scope, code)
815 self.generate_dealloc_function(scope, code)
816 if scope.needs_gc():
817 self.generate_traverse_function(scope, code)
818 self.generate_clear_function(scope, code)
819 if scope.defines_any(["__getitem__"]):
820 self.generate_getitem_int_function(scope, code)
821 if scope.defines_any(["__setitem__", "__delitem__"]):
822 self.generate_ass_subscript_function(scope, code)
823 if scope.defines_any(["__setslice__", "__delslice__"]):
824 warning(self.pos, "__setslice__ and __delslice__ are not supported by Python 3", 1)
825 self.generate_ass_slice_function(scope, code)
826 if scope.defines_any(["__getattr__","__getattribute__"]):
827 self.generate_getattro_function(scope, code)
828 if scope.defines_any(["__setattr__", "__delattr__"]):
829 self.generate_setattro_function(scope, code)
830 if scope.defines_any(["__get__"]):
831 self.generate_descr_get_function(scope, code)
832 if scope.defines_any(["__set__", "__delete__"]):
833 self.generate_descr_set_function(scope, code)
834 self.generate_property_accessors(scope, code)
835 self.generate_method_table(scope, code)
836 self.generate_member_table(scope, code)
837 self.generate_getset_table(scope, code)
838 self.generate_typeobj_definition(full_module_name, entry, code)
840 def generate_exttype_vtable(self, scope, code):
841 # Generate the definition of an extension type's vtable.
842 type = scope.parent_type
843 if type.vtable_cname:
844 code.putln("static struct %s %s;" % (
845 type.vtabstruct_cname,
846 type.vtable_cname))
848 def generate_self_cast(self, scope, code):
849 type = scope.parent_type
850 code.putln(
851 "%s = (%s)o;" % (
852 type.declaration_code("p"),
853 type.declaration_code("")))
855 def generate_new_function(self, scope, code):
856 tp_slot = TypeSlots.ConstructorSlot("tp_new", '__new__')
857 slot_func = scope.mangle_internal("tp_new")
858 type = scope.parent_type
859 base_type = type.base_type
860 py_attrs = []
861 for entry in scope.var_entries:
862 if entry.type.is_pyobject:
863 py_attrs.append(entry)
864 need_self_cast = type.vtabslot_cname or py_attrs
865 code.putln("")
866 code.putln(
867 "static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k) {"
868 % scope.mangle_internal("tp_new"))
869 if need_self_cast:
870 code.putln(
871 "%s;"
872 % scope.parent_type.declaration_code("p"))
873 if base_type:
874 tp_new = TypeSlots.get_base_slot_function(scope, tp_slot)
875 if tp_new is None:
876 tp_new = "%s->tp_new" % base_type.typeptr_cname
877 code.putln(
878 "PyObject *o = %s(t, a, k);" % tp_new)
879 else:
880 code.putln(
881 "PyObject *o = (*t->tp_alloc)(t, 0);")
882 code.putln(
883 "if (!o) return 0;")
884 if need_self_cast:
885 code.putln(
886 "p = %s;"
887 % type.cast_code("o"))
888 #if need_self_cast:
889 # self.generate_self_cast(scope, code)
890 if type.vtabslot_cname:
891 vtab_base_type = type
892 while vtab_base_type.base_type and vtab_base_type.base_type.vtabstruct_cname:
893 vtab_base_type = vtab_base_type.base_type
894 if vtab_base_type is not type:
895 struct_type_cast = "(struct %s*)" % vtab_base_type.vtabstruct_cname
896 else:
897 struct_type_cast = ""
898 code.putln("p->%s = %s%s;" % (
899 type.vtabslot_cname,
900 struct_type_cast, type.vtabptr_cname))
901 for entry in py_attrs:
902 if entry.name == "__weakref__":
903 code.putln("p->%s = 0;" % entry.cname)
904 else:
905 code.put_init_var_to_py_none(entry, "p->%s", nanny=False)
906 entry = scope.lookup_here("__new__")
907 if entry and entry.is_special:
908 if entry.trivial_signature:
909 cinit_args = "o, %s, NULL" % Naming.empty_tuple
910 else:
911 cinit_args = "o, a, k"
912 code.putln(
913 "if (%s(%s) < 0) {" %
914 (entry.func_cname, cinit_args))
915 code.put_decref_clear("o", py_object_type, nanny=False);
916 code.putln(
917 "}")
918 code.putln(
919 "return o;")
920 code.putln(
921 "}")
923 def generate_dealloc_function(self, scope, code):
924 tp_slot = TypeSlots.ConstructorSlot("tp_dealloc", '__dealloc__')
925 slot_func = scope.mangle_internal("tp_dealloc")
926 base_type = scope.parent_type.base_type
927 if tp_slot.slot_code(scope) != slot_func:
928 return # never used
929 code.putln("")
930 code.putln(
931 "static void %s(PyObject *o) {"
932 % scope.mangle_internal("tp_dealloc"))
933 py_attrs = []
934 weakref_slot = scope.lookup_here("__weakref__")
935 for entry in scope.var_entries:
936 if entry.type.is_pyobject and entry is not weakref_slot:
937 py_attrs.append(entry)
938 if py_attrs or weakref_slot in scope.var_entries:
939 self.generate_self_cast(scope, code)
940 self.generate_usr_dealloc_call(scope, code)
941 if weakref_slot in scope.var_entries:
942 code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);")
943 for entry in py_attrs:
944 code.put_xdecref("p->%s" % entry.cname, entry.type, nanny=False)
945 if base_type:
946 tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot)
947 if tp_dealloc is None:
948 tp_dealloc = "%s->tp_dealloc" % base_type.typeptr_cname
949 code.putln(
950 "%s(o);" % tp_dealloc)
951 else:
952 code.putln(
953 "(*Py_TYPE(o)->tp_free)(o);")
954 code.putln(
955 "}")
957 def generate_usr_dealloc_call(self, scope, code):
958 entry = scope.lookup_here("__dealloc__")
959 if entry:
960 code.putln(
961 "{")
962 code.putln(
963 "PyObject *etype, *eval, *etb;")
964 code.putln(
965 "PyErr_Fetch(&etype, &eval, &etb);")
966 code.putln(
967 "++Py_REFCNT(o);")
968 code.putln(
969 "%s(o);" %
970 entry.func_cname)
971 code.putln(
972 "if (PyErr_Occurred()) PyErr_WriteUnraisable(o);")
973 code.putln(
974 "--Py_REFCNT(o);")
975 code.putln(
976 "PyErr_Restore(etype, eval, etb);")
977 code.putln(
978 "}")
980 def generate_traverse_function(self, scope, code):
981 tp_slot = TypeSlots.GCDependentSlot("tp_traverse")
982 slot_func = scope.mangle_internal("tp_traverse")
983 base_type = scope.parent_type.base_type
984 if tp_slot.slot_code(scope) != slot_func:
985 return # never used
986 code.putln("")
987 code.putln(
988 "static int %s(PyObject *o, visitproc v, void *a) {"
989 % slot_func)
990 py_attrs = []
991 for entry in scope.var_entries:
992 if entry.type.is_pyobject and entry.name != "__weakref__":
993 py_attrs.append(entry)
994 if base_type or py_attrs:
995 code.putln("int e;")
996 if py_attrs:
997 self.generate_self_cast(scope, code)
998 if base_type:
999 # want to call it explicitly if possible so inlining can be performed
1000 static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
1001 if static_call:
1002 code.putln("e = %s(o, v, a); if (e) return e;" % static_call)
1003 else:
1004 code.putln("if (%s->tp_traverse) {" % base_type.typeptr_cname)
1005 code.putln(
1006 "e = %s->tp_traverse(o, v, a); if (e) return e;" %
1007 base_type.typeptr_cname)
1008 code.putln("}")
1009 for entry in py_attrs:
1010 var_code = "p->%s" % entry.cname
1011 code.putln(
1012 "if (%s) {"
1013 % var_code)
1014 if entry.type.is_extension_type:
1015 var_code = "((PyObject*)%s)" % var_code
1016 code.putln(
1017 "e = (*v)(%s, a); if (e) return e;"
1018 % var_code)
1019 code.putln(
1020 "}")
1021 code.putln(
1022 "return 0;")
1023 code.putln(
1024 "}")
1026 def generate_clear_function(self, scope, code):
1027 tp_slot = TypeSlots.GCDependentSlot("tp_clear")
1028 slot_func = scope.mangle_internal("tp_clear")
1029 base_type = scope.parent_type.base_type
1030 if tp_slot.slot_code(scope) != slot_func:
1031 return # never used
1032 code.putln("")
1033 code.putln("static int %s(PyObject *o) {" % slot_func)
1034 py_attrs = []
1035 for entry in scope.var_entries:
1036 if entry.type.is_pyobject and entry.name != "__weakref__":
1037 py_attrs.append(entry)
1038 if py_attrs:
1039 self.generate_self_cast(scope, code)
1040 code.putln("PyObject* tmp;")
1041 if base_type:
1042 # want to call it explicitly if possible so inlining can be performed
1043 static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
1044 if static_call:
1045 code.putln("%s(o);" % static_call)
1046 else:
1047 code.putln("if (%s->tp_clear) {" % base_type.typeptr_cname)
1048 code.putln("%s->tp_clear(o);" % base_type.typeptr_cname)
1049 code.putln("}")
1050 for entry in py_attrs:
1051 name = "p->%s" % entry.cname
1052 code.putln("tmp = ((PyObject*)%s);" % name)
1053 code.put_init_to_py_none(name, entry.type, nanny=False)
1054 code.putln("Py_XDECREF(tmp);")
1055 code.putln(
1056 "return 0;")
1057 code.putln(
1058 "}")
1060 def generate_getitem_int_function(self, scope, code):
1061 # This function is put into the sq_item slot when
1062 # a __getitem__ method is present. It converts its
1063 # argument to a Python integer and calls mp_subscript.
1064 code.putln(
1065 "static PyObject *%s(PyObject *o, Py_ssize_t i) {" %
1066 scope.mangle_internal("sq_item"))
1067 code.putln(
1068 "PyObject *r;")
1069 code.putln(
1070 "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;")
1071 code.putln(
1072 "r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);")
1073 code.putln(
1074 "Py_DECREF(x);")
1075 code.putln(
1076 "return r;")
1077 code.putln(
1078 "}")
1080 def generate_ass_subscript_function(self, scope, code):
1081 # Setting and deleting an item are both done through
1082 # the ass_subscript method, so we dispatch to user's __setitem__
1083 # or __delitem__, or raise an exception.
1084 base_type = scope.parent_type.base_type
1085 set_entry = scope.lookup_here("__setitem__")
1086 del_entry = scope.lookup_here("__delitem__")
1087 code.putln("")
1088 code.putln(
1089 "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
1090 scope.mangle_internal("mp_ass_subscript"))
1091 code.putln(
1092 "if (v) {")
1093 if set_entry:
1094 code.putln(
1095 "return %s(o, i, v);" %
1096 set_entry.func_cname)
1097 else:
1098 self.generate_guarded_basetype_call(
1099 base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
1100 code.putln(
1101 "PyErr_Format(PyExc_NotImplementedError,")
1102 code.putln(
1103 ' "Subscript assignment not supported by %s", Py_TYPE(o)->tp_name);')
1104 code.putln(
1105 "return -1;")
1106 code.putln(
1107 "}")
1108 code.putln(
1109 "else {")
1110 if del_entry:
1111 code.putln(
1112 "return %s(o, i);" %
1113 del_entry.func_cname)
1114 else:
1115 self.generate_guarded_basetype_call(
1116 base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
1117 code.putln(
1118 "PyErr_Format(PyExc_NotImplementedError,")
1119 code.putln(
1120 ' "Subscript deletion not supported by %s", Py_TYPE(o)->tp_name);')
1121 code.putln(
1122 "return -1;")
1123 code.putln(
1124 "}")
1125 code.putln(
1126 "}")
1128 def generate_guarded_basetype_call(
1129 self, base_type, substructure, slot, args, code):
1130 if base_type:
1131 base_tpname = base_type.typeptr_cname
1132 if substructure:
1133 code.putln(
1134 "if (%s->%s && %s->%s->%s)" % (
1135 base_tpname, substructure, base_tpname, substructure, slot))
1136 code.putln(
1137 " return %s->%s->%s(%s);" % (
1138 base_tpname, substructure, slot, args))
1139 else:
1140 code.putln(
1141 "if (%s->%s)" % (
1142 base_tpname, slot))
1143 code.putln(
1144 " return %s->%s(%s);" % (
1145 base_tpname, slot, args))
1147 def generate_ass_slice_function(self, scope, code):
1148 # Setting and deleting a slice are both done through
1149 # the ass_slice method, so we dispatch to user's __setslice__
1150 # or __delslice__, or raise an exception.
1151 base_type = scope.parent_type.base_type
1152 set_entry = scope.lookup_here("__setslice__")
1153 del_entry = scope.lookup_here("__delslice__")
1154 code.putln("")
1155 code.putln(
1156 "static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" %
1157 scope.mangle_internal("sq_ass_slice"))
1158 code.putln(
1159 "if (v) {")
1160 if set_entry:
1161 code.putln(
1162 "return %s(o, i, j, v);" %
1163 set_entry.func_cname)
1164 else:
1165 self.generate_guarded_basetype_call(
1166 base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
1167 code.putln(
1168 "PyErr_Format(PyExc_NotImplementedError,")
1169 code.putln(
1170 ' "2-element slice assignment not supported by %s", Py_TYPE(o)->tp_name);')
1171 code.putln(
1172 "return -1;")
1173 code.putln(
1174 "}")
1175 code.putln(
1176 "else {")
1177 if del_entry:
1178 code.putln(
1179 "return %s(o, i, j);" %
1180 del_entry.func_cname)
1181 else:
1182 self.generate_guarded_basetype_call(
1183 base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
1184 code.putln(
1185 "PyErr_Format(PyExc_NotImplementedError,")
1186 code.putln(
1187 ' "2-element slice deletion not supported by %s", Py_TYPE(o)->tp_name);')
1188 code.putln(
1189 "return -1;")
1190 code.putln(
1191 "}")
1192 code.putln(
1193 "}")
1195 def generate_getattro_function(self, scope, code):
1196 # First try to get the attribute using __getattribute__, if defined, or
1197 # PyObject_GenericGetAttr.
1199 # If that raises an AttributeError, call the __getattr__ if defined.
1201 # In both cases, defined can be in this class, or any base class.
1202 def lookup_here_or_base(n,type=None):
1203 # Recursive lookup
1204 if type is None:
1205 type = scope.parent_type
1206 r = type.scope.lookup_here(n)
1207 if r is None and \
1208 type.base_type is not None:
1209 return lookup_here_or_base(n,type.base_type)
1210 else:
1211 return r
1212 getattr_entry = lookup_here_or_base("__getattr__")
1213 getattribute_entry = lookup_here_or_base("__getattribute__")
1214 code.putln("")
1215 code.putln(
1216 "static PyObject *%s(PyObject *o, PyObject *n) {"
1217 % scope.mangle_internal("tp_getattro"))
1218 if getattribute_entry is not None:
1219 code.putln(
1220 "PyObject *v = %s(o, n);" %
1221 getattribute_entry.func_cname)
1222 else:
1223 code.putln(
1224 "PyObject *v = PyObject_GenericGetAttr(o, n);")
1225 if getattr_entry is not None:
1226 code.putln(
1227 "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
1228 code.putln(
1229 "PyErr_Clear();")
1230 code.putln(
1231 "v = %s(o, n);" %
1232 getattr_entry.func_cname)
1233 code.putln(
1234 "}")
1235 code.putln(
1236 "return v;")
1237 code.putln(
1238 "}")
1240 def generate_setattro_function(self, scope, code):
1241 # Setting and deleting an attribute are both done through
1242 # the setattro method, so we dispatch to user's __setattr__
1243 # or __delattr__ or fall back on PyObject_GenericSetAttr.
1244 base_type = scope.parent_type.base_type
1245 set_entry = scope.lookup_here("__setattr__")
1246 del_entry = scope.lookup_here("__delattr__")
1247 code.putln("")
1248 code.putln(
1249 "static int %s(PyObject *o, PyObject *n, PyObject *v) {" %
1250 scope.mangle_internal("tp_setattro"))
1251 code.putln(
1252 "if (v) {")
1253 if set_entry:
1254 code.putln(
1255 "return %s(o, n, v);" %
1256 set_entry.func_cname)
1257 else:
1258 self.generate_guarded_basetype_call(
1259 base_type, None, "tp_setattro", "o, n, v", code)
1260 code.putln(
1261 "return PyObject_GenericSetAttr(o, n, v);")
1262 code.putln(
1263 "}")
1264 code.putln(
1265 "else {")
1266 if del_entry:
1267 code.putln(
1268 "return %s(o, n);" %
1269 del_entry.func_cname)
1270 else:
1271 self.generate_guarded_basetype_call(
1272 base_type, None, "tp_setattro", "o, n, v", code)
1273 code.putln(
1274 "return PyObject_GenericSetAttr(o, n, 0);")
1275 code.putln(
1276 "}")
1277 code.putln(
1278 "}")
1280 def generate_descr_get_function(self, scope, code):
1281 # The __get__ function of a descriptor object can be
1282 # called with NULL for the second or third arguments
1283 # under some circumstances, so we replace them with
1284 # None in that case.
1285 user_get_entry = scope.lookup_here("__get__")
1286 code.putln("")
1287 code.putln(
1288 "static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" %
1289 scope.mangle_internal("tp_descr_get"))
1290 code.putln(
1291 "PyObject *r = 0;")
1292 code.putln(
1293 "if (!i) i = Py_None;")
1294 code.putln(
1295 "if (!c) c = Py_None;")
1296 #code.put_incref("i", py_object_type)
1297 #code.put_incref("c", py_object_type)
1298 code.putln(
1299 "r = %s(o, i, c);" %
1300 user_get_entry.func_cname)
1301 #code.put_decref("i", py_object_type)
1302 #code.put_decref("c", py_object_type)
1303 code.putln(
1304 "return r;")
1305 code.putln(
1306 "}")
1308 def generate_descr_set_function(self, scope, code):
1309 # Setting and deleting are both done through the __set__
1310 # method of a descriptor, so we dispatch to user's __set__
1311 # or __delete__ or raise an exception.
1312 base_type = scope.parent_type.base_type
1313 user_set_entry = scope.lookup_here("__set__")
1314 user_del_entry = scope.lookup_here("__delete__")
1315 code.putln("")
1316 code.putln(
1317 "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
1318 scope.mangle_internal("tp_descr_set"))
1319 code.putln(
1320 "if (v) {")
1321 if user_set_entry:
1322 code.putln(
1323 "return %s(o, i, v);" %
1324 user_set_entry.func_cname)
1325 else:
1326 self.generate_guarded_basetype_call(
1327 base_type, None, "tp_descr_set", "o, i, v", code)
1328 code.putln(
1329 'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
1330 code.putln(
1331 "return -1;")
1332 code.putln(
1333 "}")
1334 code.putln(
1335 "else {")
1336 if user_del_entry:
1337 code.putln(
1338 "return %s(o, i);" %
1339 user_del_entry.func_cname)
1340 else:
1341 self.generate_guarded_basetype_call(
1342 base_type, None, "tp_descr_set", "o, i, v", code)
1343 code.putln(
1344 'PyErr_SetString(PyExc_NotImplementedError, "__delete__");')
1345 code.putln(
1346 "return -1;")
1347 code.putln(
1348 "}")
1349 code.putln(
1350 "}")
1352 def generate_property_accessors(self, cclass_scope, code):
1353 for entry in cclass_scope.property_entries:
1354 property_scope = entry.scope
1355 if property_scope.defines_any(["__get__"]):
1356 self.generate_property_get_function(entry, code)
1357 if property_scope.defines_any(["__set__", "__del__"]):
1358 self.generate_property_set_function(entry, code)
1360 def generate_property_get_function(self, property_entry, code):
1361 property_scope = property_entry.scope
1362 property_entry.getter_cname = property_scope.parent_scope.mangle(
1363 Naming.prop_get_prefix, property_entry.name)
1364 get_entry = property_scope.lookup_here("__get__")
1365 code.putln("")
1366 code.putln(
1367 "static PyObject *%s(PyObject *o, void *x) {" %
1368 property_entry.getter_cname)
1369 code.putln(
1370 "return %s(o);" %
1371 get_entry.func_cname)
1372 code.putln(
1373 "}")
1375 def generate_property_set_function(self, property_entry, code):
1376 property_scope = property_entry.scope
1377 property_entry.setter_cname = property_scope.parent_scope.mangle(
1378 Naming.prop_set_prefix, property_entry.name)
1379 set_entry = property_scope.lookup_here("__set__")
1380 del_entry = property_scope.lookup_here("__del__")
1381 code.putln("")
1382 code.putln(
1383 "static int %s(PyObject *o, PyObject *v, void *x) {" %
1384 property_entry.setter_cname)
1385 code.putln(
1386 "if (v) {")
1387 if set_entry:
1388 code.putln(
1389 "return %s(o, v);" %
1390 set_entry.func_cname)
1391 else:
1392 code.putln(
1393 'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
1394 code.putln(
1395 "return -1;")
1396 code.putln(
1397 "}")
1398 code.putln(
1399 "else {")
1400 if del_entry:
1401 code.putln(
1402 "return %s(o);" %
1403 del_entry.func_cname)
1404 else:
1405 code.putln(
1406 'PyErr_SetString(PyExc_NotImplementedError, "__del__");')
1407 code.putln(
1408 "return -1;")
1409 code.putln(
1410 "}")
1411 code.putln(
1412 "}")
1414 def generate_typeobj_definition(self, modname, entry, code):
1415 type = entry.type
1416 scope = type.scope
1417 for suite in TypeSlots.substructures:
1418 suite.generate_substructure(scope, code)
1419 code.putln("")
1420 if entry.visibility == 'public':
1421 header = "DL_EXPORT(PyTypeObject) %s = {"
1422 else:
1423 #header = "statichere PyTypeObject %s = {"
1424 header = "PyTypeObject %s = {"
1425 #code.putln(header % scope.parent_type.typeobj_cname)
1426 code.putln(header % type.typeobj_cname)
1427 code.putln(
1428 "PyVarObject_HEAD_INIT(0, 0)")
1429 code.putln(
1430 '__Pyx_NAMESTR("%s.%s"), /*tp_name*/' % (
1431 self.full_module_name, scope.class_name))
1432 if type.typedef_flag:
1433 objstruct = type.objstruct_cname
1434 else:
1435 #objstruct = "struct %s" % scope.parent_type.objstruct_cname
1436 objstruct = "struct %s" % type.objstruct_cname
1437 code.putln(
1438 "sizeof(%s), /*tp_basicsize*/" %
1439 objstruct)
1440 code.putln(
1441 "0, /*tp_itemsize*/")
1442 for slot in TypeSlots.slot_table:
1443 slot.generate(scope, code)
1444 code.putln(
1445 "};")
1447 def generate_method_table(self, env, code):
1448 code.putln("")
1449 code.putln(
1450 "static struct PyMethodDef %s[] = {" %
1451 env.method_table_cname)
1452 for entry in env.pyfunc_entries:
1453 code.put_pymethoddef(entry, ",")
1454 code.putln(
1455 "{0, 0, 0, 0}")
1456 code.putln(
1457 "};")
1459 def generate_member_table(self, env, code):
1460 #print "ModuleNode.generate_member_table: scope =", env ###
1461 if env.public_attr_entries:
1462 code.putln("")
1463 code.putln(
1464 "static struct PyMemberDef %s[] = {" %
1465 env.member_table_cname)
1466 type = env.parent_type
1467 if type.typedef_flag:
1468 objstruct = type.objstruct_cname
1469 else:
1470 objstruct = "struct %s" % type.objstruct_cname
1471 for entry in env.public_attr_entries:
1472 type_code = entry.type.pymemberdef_typecode
1473 if entry.visibility == 'readonly':
1474 flags = "READONLY"
1475 else:
1476 flags = "0"
1477 code.putln('{(char *)"%s", %s, %s, %s, 0},' % (
1478 entry.name,
1479 type_code,
1480 "offsetof(%s, %s)" % (objstruct, entry.cname),
1481 flags))
1482 code.putln(
1483 "{0, 0, 0, 0, 0}")
1484 code.putln(
1485 "};")
1487 def generate_getset_table(self, env, code):
1488 if env.property_entries:
1489 code.putln("")
1490 code.putln(
1491 "static struct PyGetSetDef %s[] = {" %
1492 env.getset_table_cname)
1493 for entry in env.property_entries:
1494 code.putln(
1495 '{(char *)"%s", %s, %s, %s, 0},' % (
1496 entry.name,
1497 entry.getter_cname or "0",
1498 entry.setter_cname or "0",
1499 entry.doc_cname or "0"))
1500 code.putln(
1501 "{0, 0, 0, 0, 0}")
1502 code.putln(
1503 "};")
1505 def generate_filename_init_prototype(self, code):
1506 code.putln("");
1507 code.putln("static void %s(void); /*proto*/" % Naming.fileinit_cname)
1509 def generate_import_star(self, env, code):
1510 code.putln()
1511 code.putln("char* %s_type_names[] = {" % Naming.import_star)
1512 for name, entry in env.entries.items():
1513 if entry.is_type:
1514 code.putln('"%s",' % name)
1515 code.putln("0")
1516 code.putln("};")
1517 code.putln()
1518 code.enter_cfunc_scope() # as we need labels
1519 code.putln("static int %s(PyObject *o, PyObject* py_name, char *name) {" % Naming.import_star_set)
1520 code.putln("char** type_name = %s_type_names;" % Naming.import_star)
1521 code.putln("while (*type_name) {")
1522 code.putln("if (__Pyx_StrEq(name, *type_name)) {")
1523 code.putln('PyErr_Format(PyExc_TypeError, "Cannot overwrite C type %s", name);')
1524 code.putln('goto bad;')
1525 code.putln("}")
1526 code.putln("type_name++;")
1527 code.putln("}")
1528 old_error_label = code.new_error_label()
1529 code.putln("if (0);") # so the first one can be "else if"
1530 for name, entry in env.entries.items():
1531 if entry.is_cglobal and entry.used:
1532 code.putln('else if (__Pyx_StrEq(name, "%s")) {' % name)
1533 if entry.type.is_pyobject:
1534 if entry.type.is_extension_type or entry.type.is_builtin_type:
1535 code.putln("if (!(%s)) %s;" % (
1536 entry.type.type_test_code("o"),
1537 code.error_goto(entry.pos)))
1538 code.put_var_decref(entry)
1539 code.putln("%s = %s;" % (
1540 entry.cname,
1541 PyrexTypes.typecast(entry.type, py_object_type, "o")))
1542 elif entry.type.from_py_function:
1543 rhs = "%s(o)" % entry.type.from_py_function
1544 if entry.type.is_enum:
1545 rhs = typecast(entry.type, c_long_type, rhs)
1546 code.putln("%s = %s; if (%s) %s;" % (
1547 entry.cname,
1548 rhs,
1549 entry.type.error_condition(entry.cname),
1550 code.error_goto(entry.pos)))
1551 code.putln("Py_DECREF(o);")
1552 else:
1553 code.putln('PyErr_Format(PyExc_TypeError, "Cannot convert Python object %s to %s");' % (name, entry.type))
1554 code.putln(code.error_goto(entry.pos))
1555 code.putln("}")
1556 code.putln("else {")
1557 code.putln("if (PyObject_SetAttr(%s, py_name, o) < 0) goto bad;" % Naming.module_cname)
1558 code.putln("}")
1559 code.putln("return 0;")
1560 code.put_label(code.error_label)
1561 # This helps locate the offending name.
1562 code.putln('__Pyx_AddTraceback("%s");' % self.full_module_name);
1563 code.error_label = old_error_label
1564 code.putln("bad:")
1565 code.putln("Py_DECREF(o);")
1566 code.putln("return -1;")
1567 code.putln("}")
1568 code.putln(import_star_utility_code)
1569 code.exit_cfunc_scope() # done with labels
1571 def generate_module_init_func(self, imported_modules, env, code):
1572 # Insert code stream of __Pyx_InitGlobals()
1573 code.globalstate.insert_initcode_into(code)
1575 code.enter_cfunc_scope()
1576 code.putln("")
1577 header2 = "PyMODINIT_FUNC init%s(void)" % env.module_name
1578 header3 = "PyMODINIT_FUNC PyInit_%s(void)" % env.module_name
1579 code.putln("#if PY_MAJOR_VERSION < 3")
1580 code.putln("%s; /*proto*/" % header2)
1581 code.putln(header2)
1582 code.putln("#else")
1583 code.putln("%s; /*proto*/" % header3)
1584 code.putln(header3)
1585 code.putln("#endif")
1586 code.putln("{")
1587 tempdecl_code = code.insertion_point()
1589 code.putln("#ifdef CYTHON_REFNANNY")
1590 code.putln("void* __pyx_refchk = NULL;")
1591 code.putln("__Pyx_Refnanny = __Pyx_ImportRefcountAPI(\"refnanny\");")
1592 code.putln("if (!__Pyx_Refnanny) {")
1593 code.putln(" PyErr_Clear();")
1594 code.putln(" __Pyx_Refnanny = __Pyx_ImportRefcountAPI(\"Cython.Runtime.refnanny\");")
1595 code.putln(" if (!__Pyx_Refnanny)")
1596 code.putln(" Py_FatalError(\"failed to import refnanny module\");")
1597 code.putln("}")
1598 code.putln("__pyx_refchk = __Pyx_Refnanny->NewContext(\"%s\", __LINE__, __FILE__);"% header3)
1599 code.putln("#endif")
1601 code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos)));
1603 code.putln("/*--- Library function declarations ---*/")
1604 env.generate_library_function_declarations(code)
1605 self.generate_filename_init_call(code)
1607 code.putln("/*--- Threads initialization code ---*/")
1608 code.putln("#if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS")
1609 code.putln("#ifdef WITH_THREAD")
1610 code.putln("PyEval_InitThreads();")
1611 code.putln("#endif")
1612 code.putln("#endif")
1614 code.putln("/*--- Initialize various global constants etc. ---*/")
1615 code.putln(code.error_goto_if_neg("__Pyx_InitGlobals()", self.pos))
1617 code.putln("/*--- Module creation code ---*/")
1618 self.generate_module_creation_code(env, code)
1620 if Options.cache_builtins:
1621 code.putln("/*--- Builtin init code ---*/")
1622 code.putln(code.error_goto_if_neg("__Pyx_InitCachedBuiltins()",
1623 self.pos))
1625 code.putln("%s = 0;" % Naming.skip_dispatch_cname);
1627 code.putln("/*--- Global init code ---*/")
1628 self.generate_global_init_code(env, code)
1630 code.putln("/*--- Function export code ---*/")
1631 self.generate_c_function_export_code(env, code)
1633 code.putln("/*--- Type init code ---*/")
1634 self.generate_type_init_code(env, code)
1636 code.putln("/*--- Type import code ---*/")
1637 for module in imported_modules:
1638 self.generate_type_import_code_for_module(module, env, code)
1640 code.putln("/*--- Function import code ---*/")
1641 for module in imported_modules:
1642 self.generate_c_function_import_code_for_module(module, env, code)
1644 code.putln("/*--- Execution code ---*/")
1645 code.mark_pos(None)
1647 self.body.generate_execution_code(code)
1649 if Options.generate_cleanup_code:
1650 # this should be replaced by the module's tp_clear in Py3
1651 env.use_utility_code(import_module_utility_code)
1652 code.putln("if (__Pyx_RegisterCleanup()) %s;" % code.error_goto(self.pos))
1654 code.put_goto(code.return_label)
1655 code.put_label(code.error_label)
1656 code.put_var_xdecrefs(env.temp_entries)
1657 code.putln('__Pyx_AddTraceback("%s");' % env.qualified_name)
1658 env.use_utility_code(Nodes.traceback_utility_code)
1659 code.put_decref_clear(env.module_cname, py_object_type, nanny=False)
1660 code.put_label(code.return_label)
1662 code.put_finish_refcount_context()
1664 code.putln("#if PY_MAJOR_VERSION < 3")
1665 code.putln("return;")
1666 code.putln("#else")
1667 code.putln("return %s;" % env.module_cname)
1668 code.putln("#endif")
1669 code.putln('}')
1671 tempdecl_code.put_var_declarations(env.temp_entries)
1672 tempdecl_code.put_temp_declarations(code.funcstate)
1674 code.exit_cfunc_scope()
1676 def generate_module_cleanup_func(self, env, code):
1677 if not Options.generate_cleanup_code:
1678 return
1679 env.use_utility_code(register_cleanup_utility_code)
1680 # Insert code stream of __Pyx_CleanupGlobals()
1681 code.globalstate.insert_cleanupcode_into(code)
1682 code.putln()
1683 code.putln('static PyObject* %s(PyObject *self, PyObject *unused) {' % Naming.cleanup_cname)
1684 if Options.generate_cleanup_code >= 2:
1685 code.putln("/*--- Global cleanup code ---*/")
1686 rev_entries = list(env.var_entries)
1687 rev_entries.reverse()
1688 for entry in rev_entries:
1689 if entry.visibility != 'extern':
1690 if entry.type.is_pyobject and entry.used:
1691 code.putln("Py_DECREF(%s); %s = 0;" % (
1692 code.entry_as_pyobject(entry), entry.cname))
1693 code.putln("__Pyx_CleanupGlobals();")
1694 if Options.generate_cleanup_code >= 3:
1695 code.putln("/*--- Type import cleanup code ---*/")
1696 for type, _ in env.types_imported.items():
1697 code.putln("Py_DECREF((PyObject *)%s);" % type.typeptr_cname)
1698 if Options.cache_builtins:
1699 code.putln("/*--- Builtin cleanup code ---*/")
1700 for entry in env.cached_builtins:
1701 code.put_decref_clear(entry.cname,
1702 PyrexTypes.py_object_type,
1703 nanny=False)
1704 code.putln("/*--- Intern cleanup code ---*/")
1705 code.put_decref_clear(Naming.empty_tuple,
1706 PyrexTypes.py_object_type,
1707 nanny=False)
1708 for entry in env.pynum_entries:
1709 code.put_decref_clear(entry.cname,
1710 PyrexTypes.py_object_type,
1711 nanny=False)
1712 for entry in env.all_pystring_entries:
1713 if entry.is_interned:
1714 code.put_decref_clear(entry.pystring_cname,
1715 PyrexTypes.py_object_type,
1716 nanny=False)
1717 for entry in env.default_entries:
1718 if entry.type.is_pyobject and entry.used:
1719 code.putln("Py_DECREF(%s); %s = 0;" % (
1720 code.entry_as_pyobject(entry), entry.cname))
1721 code.putln("Py_INCREF(Py_None); return Py_None;")
1722 code.putln('}')
1724 def generate_filename_init_call(self, code):
1725 code.putln("%s();" % Naming.fileinit_cname)
1727 def generate_pymoduledef_struct(self, env, code):
1728 if env.doc:
1729 doc = "__Pyx_DOCSTR(%s)" % env.doc_cname
1730 else:
1731 doc = "0"
1732 code.putln("")
1733 code.putln("#if PY_MAJOR_VERSION >= 3")
1734 code.putln("static struct PyModuleDef %s = {" % Naming.pymoduledef_cname)
1735 code.putln(" PyModuleDef_HEAD_INIT,")
1736 code.putln(' __Pyx_NAMESTR("%s"),' % env.module_name)
1737 code.putln(" %s, /* m_doc */" % doc)
1738 code.putln(" -1, /* m_size */")
1739 code.putln(" %s /* m_methods */," % env.method_table_cname)
1740 code.putln(" NULL, /* m_reload */")
1741 code.putln(" NULL, /* m_traverse */")
1742 code.putln(" NULL, /* m_clear */")
1743 code.putln(" NULL /* m_free */")
1744 code.putln("};")
1745 code.putln("#endif")
1747 def generate_module_creation_code(self, env, code):
1748 # Generate code to create the module object and
1749 # install the builtins.
1750 if env.doc:
1751 doc = env.doc_cname
1752 else:
1753 doc = "0"
1754 code.putln("#if PY_MAJOR_VERSION < 3")
1755 code.putln(
1756 '%s = Py_InitModule4(__Pyx_NAMESTR("%s"), %s, %s, 0, PYTHON_API_VERSION);' % (
1757 env.module_cname,
1758 env.module_name,
1759 env.method_table_cname,
1760 doc))
1761 code.putln("#else")
1762 code.putln(
1763 "%s = PyModule_Create(&%s);" % (
1764 env.module_cname,
1765 Naming.pymoduledef_cname))
1766 code.putln("#endif")
1767 code.putln(
1768 "if (!%s) %s;" % (
1769 env.module_cname,
1770 code.error_goto(self.pos)));
1771 code.putln("#if PY_MAJOR_VERSION < 3")
1772 code.putln(
1773 "Py_INCREF(%s);" %
1774 env.module_cname)
1775 code.putln("#endif")
1776 code.putln(
1777 '%s = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME));' %
1778 Naming.builtins_cname)
1779 code.putln(
1780 "if (!%s) %s;" % (
1781 Naming.builtins_cname,
1782 code.error_goto(self.pos)));
1783 code.putln(
1784 'if (__Pyx_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % (
1785 env.module_cname,
1786 Naming.builtins_cname,
1787 code.error_goto(self.pos)))
1788 if Options.pre_import is not None:
1789 code.putln(
1790 '%s = PyImport_AddModule(__Pyx_NAMESTR("%s"));' % (
1791 Naming.preimport_cname,
1792 Options.pre_import))
1793 code.putln(
1794 "if (!%s) %s;" % (
1795 Naming.preimport_cname,
1796 code.error_goto(self.pos)));
1798 def generate_global_init_code(self, env, code):
1799 # Generate code to initialise global PyObject *
1800 # variables to None.
1801 for entry in env.var_entries:
1802 if entry.visibility != 'extern':
1803 if entry.type.is_pyobject and entry.used:
1804 code.put_init_var_to_py_none(entry, nanny=False)
1806 def generate_c_function_export_code(self, env, code):
1807 # Generate code to create PyCFunction wrappers for exported C functions.
1808 for entry in env.cfunc_entries:
1809 if entry.api or entry.defined_in_pxd:
1810 env.use_utility_code(function_export_utility_code)
1811 signature = entry.type.signature_string()
1812 code.putln('if (__Pyx_ExportFunction("%s", (void (*)(void))%s, "%s") < 0) %s' % (
1813 entry.name,
1814 entry.cname,
1815 signature,
1816 code.error_goto(self.pos)))
1818 def generate_type_import_code_for_module(self, module, env, code):
1819 # Generate type import code for all exported extension types in
1820 # an imported module.
1821 #if module.c_class_entries:
1822 for entry in module.c_class_entries:
1823 if entry.defined_in_pxd:
1824 self.generate_type_import_code(env, entry.type, entry.pos, code)
1826 def generate_c_function_import_code_for_module(self, module, env, code):
1827 # Generate import code for all exported C functions in a cimported module.
1828 entries = []
1829 for entry in module.cfunc_entries:
1830 if entry.defined_in_pxd:
1831 entries.append(entry)
1832 if entries:
1833 env.use_utility_code(import_module_utility_code)
1834 env.use_utility_code(function_import_utility_code)
1835 temp = self.module_temp_cname
1836 code.putln(
1837 '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % (
1838 temp,
1839 module.qualified_name,
1840 temp,
1841 code.error_goto(self.pos)))
1842 for entry in entries:
1843 code.putln(
1844 'if (__Pyx_ImportFunction(%s, "%s", (void (**)(void))&%s, "%s") < 0) %s' % (
1845 temp,
1846 entry.name,
1847 entry.cname,
1848 entry.type.signature_string(),
1849 code.error_goto(self.pos)))
1850 code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp))
1852 def generate_type_init_code(self, env, code):
1853 # Generate type import code for extern extension types
1854 # and type ready code for non-extern ones.
1855 for entry in env.c_class_entries:
1856 if entry.visibility == 'extern':
1857 self.generate_type_import_code(env, entry.type, entry.pos, code)
1858 else:
1859 self.generate_base_type_import_code(env, entry, code)
1860 self.generate_exttype_vtable_init_code(entry, code)
1861 self.generate_type_ready_code(env, entry, code)
1862 self.generate_typeptr_assignment_code(entry, code)
1864 def generate_base_type_import_code(self, env, entry, code):
1865 base_type = entry.type.base_type
1866 if base_type and base_type.module_name != env.qualified_name:
1867 self.generate_type_import_code(env, base_type, self.pos, code)
1869 def use_type_import_utility_code(self, env):
1870 env.use_utility_code(type_import_utility_code)
1871 env.use_utility_code(import_module_utility_code)
1873 def generate_type_import_code(self, env, type, pos, code):
1874 # If not already done, generate code to import the typeobject of an
1875 # extension type defined in another module, and extract its C method
1876 # table pointer if any.
1877 if type in env.types_imported:
1878 return
1879 if type.typedef_flag:
1880 objstruct = type.objstruct_cname
1881 else:
1882 objstruct = "struct %s" % type.objstruct_cname
1883 self.generate_type_import_call(type, code,
1884 code.error_goto_if_null(type.typeptr_cname, pos))
1885 self.use_type_import_utility_code(env)
1886 if type.vtabptr_cname:
1887 code.putln(
1888 "if (__Pyx_GetVtable(%s->tp_dict, &%s) < 0) %s" % (
1889 type.typeptr_cname,
1890 type.vtabptr_cname,
1891 code.error_goto(pos)))
1892 env.use_utility_code(Nodes.get_vtable_utility_code)
1893 env.types_imported[type] = 1
1895 py3_type_name_map = {'str' : 'bytes', 'unicode' : 'str'}
1897 def generate_type_import_call(self, type, code, error_code):
1898 if type.typedef_flag:
1899 objstruct = type.objstruct_cname
1900 else:
1901 objstruct = "struct %s" % type.objstruct_cname
1902 module_name = type.module_name
1903 if module_name not in ('__builtin__', 'builtins'):
1904 module_name = '"%s"' % module_name
1905 else:
1906 module_name = '__Pyx_BUILTIN_MODULE_NAME'
1907 if type.name in self.py3_type_name_map:
1908 code.putln("#if PY_MAJOR_VERSION >= 3")
1909 code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s)); %s' % (
1910 type.typeptr_cname,
1911 module_name,
1912 self.py3_type_name_map[type.name],
1913 objstruct,
1914 error_code))
1915 code.putln("#else")
1916 code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s)); %s' % (
1917 type.typeptr_cname,
1918 module_name,
1919 type.name,
1920 objstruct,
1921 error_code))
1922 if type.name in self.py3_type_name_map:
1923 code.putln("#endif")
1925 def generate_type_ready_code(self, env, entry, code):
1926 # Generate a call to PyType_Ready for an extension
1927 # type defined in this module.
1928 type = entry.type
1929 typeobj_cname = type.typeobj_cname
1930 scope = type.scope
1931 if scope: # could be None if there was an error
1932 if entry.visibility != 'extern':
1933 for slot in TypeSlots.slot_table:
1934 slot.generate_dynamic_init_code(scope, code)
1935 code.putln(
1936 "if (PyType_Ready(&%s) < 0) %s" % (
1937 typeobj_cname,
1938 code.error_goto(entry.pos)))
1939 if type.vtable_cname:
1940 code.putln(
1941 "if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
1942 typeobj_cname,
1943 type.vtabptr_cname,
1944 code.error_goto(entry.pos)))
1945 env.use_utility_code(Nodes.set_vtable_utility_code)
1946 code.putln(
1947 'if (__Pyx_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % (
1948 Naming.module_cname,
1949 scope.class_name,
1950 typeobj_cname,
1951 code.error_goto(entry.pos)))
1952 weakref_entry = scope.lookup_here("__weakref__")
1953 if weakref_entry:
1954 if weakref_entry.type is py_object_type:
1955 tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname
1956 code.putln("if (%s == 0) %s = offsetof(struct %s, %s);" % (
1957 tp_weaklistoffset,
1958 tp_weaklistoffset,
1959 type.objstruct_cname,
1960 weakref_entry.cname))
1961 else:
1962 error(weakref_entry.pos, "__weakref__ slot must be of type 'object'")
1964 def generate_exttype_vtable_init_code(self, entry, code):
1965 # Generate code to initialise the C method table of an
1966 # extension type.
1967 type = entry.type
1968 if type.vtable_cname:
1969 code.putln(
1970 "%s = &%s;" % (
1971 type.vtabptr_cname,
1972 type.vtable_cname))
1973 if type.base_type and type.base_type.vtabptr_cname:
1974 code.putln(
1975 "%s.%s = *%s;" % (
1976 type.vtable_cname,
1977 Naming.obj_base_cname,
1978 type.base_type.vtabptr_cname))
1980 c_method_entries = [
1981 entry for entry in type.scope.cfunc_entries
1982 if entry.func_cname ]
1983 if c_method_entries:
1984 code.putln('#if PY_MAJOR_VERSION >= 3')
1985 for meth_entry in c_method_entries:
1986 cast = meth_entry.type.signature_cast_string()
1987 code.putln(
1988 "%s.%s = %s%s;" % (
1989 type.vtable_cname,
1990 meth_entry.cname,
1991 cast,
1992 meth_entry.func_cname))
1993 code.putln('#else')
1994 for meth_entry in c_method_entries:
1995 code.putln(
1996 "*(void(**)(void))&%s.%s = (void(*)(void))%s;" % (
1997 type.vtable_cname,
1998 meth_entry.cname,
1999 meth_entry.func_cname))
2000 code.putln('#endif')
2002 def generate_typeptr_assignment_code(self, entry, code):
2003 # Generate code to initialise the typeptr of an extension
2004 # type defined in this module to point to its type object.
2005 type = entry.type
2006 if type.typeobj_cname:
2007 code.putln(
2008 "%s = &%s;" % (
2009 type.typeptr_cname, type.typeobj_cname))
2011 def generate_utility_functions(self, env, code, h_code):
2012 for codetup, name in env.utility_code_list:
2013 code.globalstate.use_utility_code(codetup, name)
2015 code.globalstate.put_utility_code_protos(h_code)
2016 code.putln("")
2017 code.putln("/* Runtime support code */")
2018 code.putln("")
2019 code.putln("static void %s(void) {" % Naming.fileinit_cname)
2020 code.putln("%s = %s;" %
2021 (Naming.filetable_cname, Naming.filenames_cname))
2022 code.putln("}")
2023 code.globalstate.put_utility_code_defs(code)
2024 code.put(PyrexTypes.type_conversion_functions)
2025 code.putln("")
2027 #------------------------------------------------------------------------------------
2029 # Runtime support code
2031 #------------------------------------------------------------------------------------
2033 builtin_module_name_utility_code = UtilityCode(
2034 proto = """\
2035 #if PY_MAJOR_VERSION < 3
2036 #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
2037 #else
2038 #define __Pyx_BUILTIN_MODULE_NAME "builtins"
2039 #endif
2040 """)
2042 #------------------------------------------------------------------------------------
2044 streq_utility_code = UtilityCode(
2045 proto = """
2046 static INLINE int __Pyx_StrEq(const char *, const char *); /*proto*/
2047 """,
2048 impl = """
2049 static INLINE int __Pyx_StrEq(const char *s1, const char *s2) {
2050 while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; }
2051 return *s1 == *s2;
2053 """)
2055 #------------------------------------------------------------------------------------
2057 import_module_utility_code = UtilityCode(
2058 proto = """
2059 static PyObject *__Pyx_ImportModule(const char *name); /*proto*/
2060 """,
2061 impl = """
2062 #ifndef __PYX_HAVE_RT_ImportModule
2063 #define __PYX_HAVE_RT_ImportModule
2064 static PyObject *__Pyx_ImportModule(const char *name) {
2065 PyObject *py_name = 0;
2066 PyObject *py_module = 0;
2068 #if PY_MAJOR_VERSION < 3
2069 py_name = PyString_FromString(name);
2070 #else
2071 py_name = PyUnicode_FromString(name);
2072 #endif
2073 if (!py_name)
2074 goto bad;
2075 py_module = PyImport_Import(py_name);
2076 Py_DECREF(py_name);
2077 return py_module;
2078 bad:
2079 Py_XDECREF(py_name);
2080 return 0;
2082 #endif
2083 """)
2085 #------------------------------------------------------------------------------------
2087 type_import_utility_code = UtilityCode(
2088 proto = """
2089 static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, long size); /*proto*/
2090 """,
2091 impl = """
2092 #ifndef __PYX_HAVE_RT_ImportType
2093 #define __PYX_HAVE_RT_ImportType
2094 static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
2095 long size)
2097 PyObject *py_module = 0;
2098 PyObject *result = 0;
2099 PyObject *py_name = 0;
2101 py_module = __Pyx_ImportModule(module_name);
2102 if (!py_module)
2103 goto bad;
2104 #if PY_MAJOR_VERSION < 3
2105 py_name = PyString_FromString(class_name);
2106 #else
2107 py_name = PyUnicode_FromString(class_name);
2108 #endif
2109 if (!py_name)
2110 goto bad;
2111 result = PyObject_GetAttr(py_module, py_name);
2112 Py_DECREF(py_name);
2113 py_name = 0;
2114 Py_DECREF(py_module);
2115 py_module = 0;
2116 if (!result)
2117 goto bad;
2118 if (!PyType_Check(result)) {
2119 PyErr_Format(PyExc_TypeError,
2120 "%s.%s is not a type object",
2121 module_name, class_name);
2122 goto bad;
2124 if (((PyTypeObject *)result)->tp_basicsize != size) {
2125 PyErr_Format(PyExc_ValueError,
2126 "%s.%s does not appear to be the correct type object",
2127 module_name, class_name);
2128 goto bad;
2130 return (PyTypeObject *)result;
2131 bad:
2132 Py_XDECREF(py_module);
2133 Py_XDECREF(result);
2134 return 0;
2136 #endif
2137 """)
2139 #------------------------------------------------------------------------------------
2141 function_export_utility_code = UtilityCode(
2142 proto = """
2143 static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *sig); /*proto*/
2144 """,
2145 impl = r"""
2146 static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *sig) {
2147 #if PY_VERSION_HEX < 0x02050000
2148 char *api = (char *)"%(API)s";
2149 #else
2150 const char *api = "%(API)s";
2151 #endif
2152 PyObject *d = 0;
2153 PyObject *cobj = 0;
2154 union {
2155 void (*fp)(void);
2156 void *p;
2157 } tmp;
2160 d = PyObject_GetAttrString(%(MODULE)s, api);
2161 if (!d) {
2162 PyErr_Clear();
2163 d = PyDict_New();
2164 if (!d)
2165 goto bad;
2166 Py_INCREF(d);
2167 if (PyModule_AddObject(%(MODULE)s, api, d) < 0)
2168 goto bad;
2170 tmp.fp = f;
2171 cobj = PyCObject_FromVoidPtrAndDesc(tmp.p, (void *)sig, 0);
2172 if (!cobj)
2173 goto bad;
2174 if (PyDict_SetItemString(d, name, cobj) < 0)
2175 goto bad;
2176 Py_DECREF(cobj);
2177 Py_DECREF(d);
2178 return 0;
2179 bad:
2180 Py_XDECREF(cobj);
2181 Py_XDECREF(d);
2182 return -1;
2184 """ % {'MODULE': Naming.module_cname, 'API': Naming.api_name}
2187 #------------------------------------------------------------------------------------
2189 function_import_utility_code = UtilityCode(
2190 proto = """
2191 static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig); /*proto*/
2192 """,
2193 impl = """
2194 #ifndef __PYX_HAVE_RT_ImportFunction
2195 #define __PYX_HAVE_RT_ImportFunction
2196 static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig) {
2197 #if PY_VERSION_HEX < 0x02050000
2198 char *api = (char *)"%(API)s";
2199 #else
2200 const char *api = "%(API)s";
2201 #endif
2202 PyObject *d = 0;
2203 PyObject *cobj = 0;
2204 const char *desc;
2205 const char *s1, *s2;
2206 union {
2207 void (*fp)(void);
2208 void *p;
2209 } tmp;
2211 d = PyObject_GetAttrString(module, api);
2212 if (!d)
2213 goto bad;
2214 cobj = PyDict_GetItemString(d, funcname);
2215 if (!cobj) {
2216 PyErr_Format(PyExc_ImportError,
2217 "%%s does not export expected C function %%s",
2218 PyModule_GetName(module), funcname);
2219 goto bad;
2221 desc = (const char *)PyCObject_GetDesc(cobj);
2222 if (!desc)
2223 goto bad;
2224 s1 = desc; s2 = sig;
2225 while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; }
2226 if (*s1 != *s2) {
2227 PyErr_Format(PyExc_TypeError,
2228 "C function %%s.%%s has wrong signature (expected %%s, got %%s)",
2229 PyModule_GetName(module), funcname, sig, desc);
2230 goto bad;
2232 tmp.p = PyCObject_AsVoidPtr(cobj);
2233 *f = tmp.fp;
2234 Py_DECREF(d);
2235 return 0;
2236 bad:
2237 Py_XDECREF(d);
2238 return -1;
2240 #endif
2241 """ % dict(API = Naming.api_name)
2244 register_cleanup_utility_code = UtilityCode(
2245 proto = """
2246 static int __Pyx_RegisterCleanup(void); /*proto*/
2247 static PyObject* __pyx_module_cleanup(PyObject *self, PyObject *unused); /*proto*/
2248 static PyMethodDef cleanup_def = {__Pyx_NAMESTR("__cleanup"), (PyCFunction)&__pyx_module_cleanup, METH_NOARGS, 0};
2249 """,
2250 impl = """
2251 static int __Pyx_RegisterCleanup(void) {
2252 /* Don't use Py_AtExit because that has a 32-call limit
2253 * and is called after python finalization.
2254 */
2256 PyObject *cleanup_func = 0;
2257 PyObject *atexit = 0;
2258 PyObject *reg = 0;
2259 PyObject *args = 0;
2260 PyObject *res = 0;
2261 int ret = -1;
2263 cleanup_func = PyCFunction_New(&cleanup_def, 0);
2264 args = PyTuple_New(1);
2265 if (!cleanup_func || !args)
2266 goto bad;
2267 PyTuple_SET_ITEM(args, 0, cleanup_func);
2268 cleanup_func = 0;
2270 atexit = __Pyx_ImportModule("atexit");
2271 if (!atexit)
2272 goto bad;
2273 reg = __Pyx_GetAttrString(atexit, "register");
2274 if (!reg)
2275 goto bad;
2276 res = PyObject_CallObject(reg, args);
2277 if (!res)
2278 goto bad;
2279 ret = 0;
2280 bad:
2281 Py_XDECREF(cleanup_func);
2282 Py_XDECREF(atexit);
2283 Py_XDECREF(reg);
2284 Py_XDECREF(args);
2285 Py_XDECREF(res);
2286 return ret;
2288 """)
2290 import_star_utility_code = """
2292 /* import_all_from is an unexposed function from ceval.c */
2294 static int
2295 __Pyx_import_all_from(PyObject *locals, PyObject *v)
2297 PyObject *all = __Pyx_GetAttrString(v, "__all__");
2298 PyObject *dict, *name, *value;
2299 int skip_leading_underscores = 0;
2300 int pos, err;
2302 if (all == NULL) {
2303 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
2304 return -1; /* Unexpected error */
2305 PyErr_Clear();
2306 dict = __Pyx_GetAttrString(v, "__dict__");
2307 if (dict == NULL) {
2308 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
2309 return -1;
2310 PyErr_SetString(PyExc_ImportError,
2311 "from-import-* object has no __dict__ and no __all__");
2312 return -1;
2314 all = PyMapping_Keys(dict);
2315 Py_DECREF(dict);
2316 if (all == NULL)
2317 return -1;
2318 skip_leading_underscores = 1;
2321 for (pos = 0, err = 0; ; pos++) {
2322 name = PySequence_GetItem(all, pos);
2323 if (name == NULL) {
2324 if (!PyErr_ExceptionMatches(PyExc_IndexError))
2325 err = -1;
2326 else
2327 PyErr_Clear();
2328 break;
2330 if (skip_leading_underscores &&
2331 #if PY_MAJOR_VERSION < 3
2332 PyString_Check(name) &&
2333 PyString_AS_STRING(name)[0] == '_')
2334 #else
2335 PyUnicode_Check(name) &&
2336 PyUnicode_AS_UNICODE(name)[0] == '_')
2337 #endif
2339 Py_DECREF(name);
2340 continue;
2342 value = PyObject_GetAttr(v, name);
2343 if (value == NULL)
2344 err = -1;
2345 else if (PyDict_CheckExact(locals))
2346 err = PyDict_SetItem(locals, name, value);
2347 else
2348 err = PyObject_SetItem(locals, name, value);
2349 Py_DECREF(name);
2350 Py_XDECREF(value);
2351 if (err != 0)
2352 break;
2354 Py_DECREF(all);
2355 return err;
2359 static int %(IMPORT_STAR)s(PyObject* m) {
2361 int i;
2362 int ret = -1;
2363 char* s;
2364 PyObject *locals = 0;
2365 PyObject *list = 0;
2366 PyObject *name;
2367 PyObject *item;
2369 locals = PyDict_New(); if (!locals) goto bad;
2370 if (__Pyx_import_all_from(locals, m) < 0) goto bad;
2371 list = PyDict_Items(locals); if (!list) goto bad;
2373 for(i=0; i<PyList_GET_SIZE(list); i++) {
2374 name = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 0);
2375 item = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 1);
2376 #if PY_MAJOR_VERSION < 3
2377 s = PyString_AsString(name);
2378 #else
2379 s = PyUnicode_AsString(name);
2380 #endif
2381 if (!s) goto bad;
2382 if (%(IMPORT_STAR_SET)s(item, name, s) < 0) goto bad;
2384 ret = 0;
2386 bad:
2387 Py_XDECREF(locals);
2388 Py_XDECREF(list);
2389 return ret;
2391 """ % {'IMPORT_STAR' : Naming.import_star,
2392 'IMPORT_STAR_SET' : Naming.import_star_set }
2394 refcount_utility_code = UtilityCode(proto="""
2395 #ifdef CYTHON_REFNANNY
2396 typedef struct {
2397 void (*INCREF)(void*, PyObject*, int);
2398 void (*DECREF)(void*, PyObject*, int);
2399 void (*GOTREF)(void*, PyObject*, int);
2400 void (*GIVEREF)(void*, PyObject*, int);
2401 void* (*NewContext)(const char*, int, const char*);
2402 void (*FinishContext)(void**);
2403 } __Pyx_RefnannyAPIStruct;
2404 static __Pyx_RefnannyAPIStruct *__Pyx_Refnanny = NULL;
2405 #define __Pyx_ImportRefcountAPI(name) \
2406 (__Pyx_RefnannyAPIStruct *) PyCObject_Import((char *)name, (char *)\"RefnannyAPI\")
2407 #define __Pyx_INCREF(r) __Pyx_Refnanny->INCREF(__pyx_refchk, (PyObject *)(r), __LINE__)
2408 #define __Pyx_DECREF(r) __Pyx_Refnanny->DECREF(__pyx_refchk, (PyObject *)(r), __LINE__)
2409 #define __Pyx_GOTREF(r) __Pyx_Refnanny->GOTREF(__pyx_refchk, (PyObject *)(r), __LINE__)
2410 #define __Pyx_GIVEREF(r) __Pyx_Refnanny->GIVEREF(__pyx_refchk, (PyObject *)(r), __LINE__)
2411 #define __Pyx_XDECREF(r) if((r) == NULL) ; else __Pyx_DECREF(r)
2412 #define __Pyx_SetupRefcountContext(name) \
2413 void* __pyx_refchk = __Pyx_Refnanny->NewContext((name), __LINE__, __FILE__)
2414 #define __Pyx_FinishRefcountContext() \
2415 __Pyx_Refnanny->FinishContext(&__pyx_refchk)
2416 #else
2417 #define __Pyx_INCREF(r) Py_INCREF(r)
2418 #define __Pyx_DECREF(r) Py_DECREF(r)
2419 #define __Pyx_GOTREF(r)
2420 #define __Pyx_GIVEREF(r)
2421 #define __Pyx_XDECREF(r) Py_XDECREF(r)
2422 #define __Pyx_SetupRefcountContext(name)
2423 #define __Pyx_FinishRefcountContext()
2424 #endif /* CYTHON_REFNANNY */
2425 #define __Pyx_XGIVEREF(r) if((r) == NULL) ; else __Pyx_GIVEREF(r)
2426 #define __Pyx_XGOTREF(r) if((r) == NULL) ; else __Pyx_GOTREF(r)
2427 """)