Cython has moved to github.

cython-devel

view Cython/Compiler/ModuleNode.py @ 1928:3aa127500ce9

Fix #271
author Dag Sverre Seljebotn <dagss@student.matnat.uio.no>
date Tue Mar 31 23:07:13 2009 +0200 (3 years ago)
parents 413a75b92fc0
children ecc2df83945e 5a03cdbbb82f
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('const char *%s = "%s";' % (Naming.modulename_cname, self.full_module_name))
257 code.putln("")
258 code.putln("/* Implementation of %s */" % env.qualified_name)
259 self.generate_const_definitions(env, code)
260 self.generate_interned_num_decls(env, code)
261 self.generate_interned_string_decls(env, code)
262 self.generate_py_string_decls(env, code)
264 code.globalstate.insert_global_var_declarations_into(code)
266 self.generate_cached_builtins_decls(env, code)
267 self.body.generate_function_definitions(env, code)
268 code.mark_pos(None)
269 self.generate_typeobj_definitions(env, code)
270 self.generate_method_table(env, code)
271 self.generate_filename_init_prototype(code)
272 if env.has_import_star:
273 self.generate_import_star(env, code)
274 self.generate_pymoduledef_struct(env, code)
275 self.generate_module_init_func(modules[:-1], env, code)
276 code.mark_pos(None)
277 self.generate_module_cleanup_func(env, code)
278 self.generate_filename_table(code)
279 self.generate_utility_functions(env, code, h_code)
281 self.generate_declarations_for_modules(env, modules, h_code)
282 h_code.write('\n')
284 code.globalstate.close_global_decls()
286 f = open_new_file(result.c_file)
287 code.copyto(f)
288 f.close()
289 result.c_file_generated = 1
290 if Options.annotate or options.annotate:
291 self.annotate(code)
292 code.save_annotation(result.main_source_file, result.c_file)
294 def find_referenced_modules(self, env, module_list, modules_seen):
295 if env not in modules_seen:
296 modules_seen[env] = 1
297 for imported_module in env.cimported_modules:
298 self.find_referenced_modules(imported_module, module_list, modules_seen)
299 module_list.append(env)
301 def sort_types_by_inheritance(self, type_dict, getkey):
302 # copy the types into a list moving each parent type before
303 # its first child
304 type_items = type_dict.items()
305 type_list = []
306 for i, item in enumerate(type_items):
307 key, new_entry = item
309 # collect all base classes to check for children
310 hierarchy = set()
311 base = new_entry
312 while base:
313 base_type = base.type.base_type
314 if not base_type:
315 break
316 base_key = getkey(base_type)
317 hierarchy.add(base_key)
318 base = type_dict.get(base_key)
319 new_entry.base_keys = hierarchy
321 # find the first (sub-)subclass and insert before that
322 for j in range(i):
323 entry = type_list[j]
324 if key in entry.base_keys:
325 type_list.insert(j, new_entry)
326 break
327 else:
328 type_list.append(new_entry)
329 return type_list
331 def sort_type_hierarchy(self, module_list, env):
332 vtab_dict = {}
333 vtabslot_dict = {}
334 for module in module_list:
335 for entry in module.c_class_entries:
336 if not entry.in_cinclude:
337 type = entry.type
338 if type.vtabstruct_cname:
339 vtab_dict[type.vtabstruct_cname] = entry
340 all_defined_here = module is env
341 for entry in module.type_entries:
342 if all_defined_here or entry.defined_in_pxd:
343 type = entry.type
344 if type.is_extension_type and not entry.in_cinclude:
345 type = entry.type
346 vtabslot_dict[type.objstruct_cname] = entry
348 def vtabstruct_cname(entry_type):
349 return entry_type.vtabstruct_cname
350 vtab_list = self.sort_types_by_inheritance(
351 vtab_dict, vtabstruct_cname)
353 def objstruct_cname(entry_type):
354 return entry_type.objstruct_cname
355 vtabslot_list = self.sort_types_by_inheritance(
356 vtabslot_dict, objstruct_cname)
358 return (vtab_list, vtabslot_list)
360 def generate_type_definitions(self, env, modules, vtab_list, vtabslot_list, code):
361 vtabslot_entries = set(vtabslot_list)
362 for module in modules:
363 definition = module is env
364 if definition:
365 type_entries = module.type_entries
366 else:
367 type_entries = []
368 for entry in module.type_entries:
369 if entry.defined_in_pxd:
370 type_entries.append(entry)
371 for entry in type_entries:
372 if not entry.in_cinclude:
373 #print "generate_type_header_code:", entry.name, repr(entry.type) ###
374 type = entry.type
375 if type.is_typedef: # Must test this first!
376 self.generate_typedef(entry, code)
377 elif type.is_struct_or_union:
378 self.generate_struct_union_definition(entry, code)
379 elif type.is_enum:
380 self.generate_enum_definition(entry, code)
381 elif type.is_extension_type and entry not in vtabslot_entries:
382 self.generate_obj_struct_definition(type, code)
383 for entry in vtabslot_list:
384 self.generate_obj_struct_definition(entry.type, code)
385 for entry in vtab_list:
386 self.generate_typeobject_predeclaration(entry, code)
387 self.generate_exttype_vtable_struct(entry, code)
388 self.generate_exttype_vtabptr_declaration(entry, code)
390 def generate_declarations_for_modules(self, env, modules, code):
391 code.putln("")
392 code.putln("/* Type declarations */")
393 vtab_list, vtabslot_list = self.sort_type_hierarchy(modules, env)
394 self.generate_type_definitions(
395 env, modules, vtab_list, vtabslot_list, code)
396 for module in modules:
397 defined_here = module is env
398 code.putln("/* Module declarations from %s */" %
399 module.qualified_name.encode("ASCII", "ignore"))
400 self.generate_global_declarations(module, code, defined_here)
401 self.generate_cfunction_predeclarations(module, code, defined_here)
403 def generate_module_preamble(self, env, cimported_modules, code):
404 code.putln('/* Generated by Cython %s on %s */' % (
405 Version.version, time.asctime()))
406 code.putln('')
407 code.putln('#define PY_SSIZE_T_CLEAN')
408 for filename in env.python_include_files:
409 code.putln('#include "%s"' % filename)
410 code.putln("#ifndef Py_PYTHON_H")
411 code.putln(" #error Python headers needed to compile C extensions, please install development version of Python.")
412 code.putln("#endif")
413 code.putln("#ifndef PY_LONG_LONG")
414 code.putln(" #define PY_LONG_LONG LONG_LONG")
415 code.putln("#endif")
416 code.putln("#ifndef DL_EXPORT")
417 code.putln(" #define DL_EXPORT(t) t")
418 code.putln("#endif")
419 code.putln("#if PY_VERSION_HEX < 0x02040000")
420 code.putln(" #define METH_COEXIST 0")
421 code.putln(" #define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type)")
422 code.putln("#endif")
424 code.putln("#if PY_VERSION_HEX < 0x02050000")
425 code.putln(" typedef int Py_ssize_t;")
426 code.putln(" #define PY_SSIZE_T_MAX INT_MAX")
427 code.putln(" #define PY_SSIZE_T_MIN INT_MIN")
428 code.putln(" #define PyInt_FromSsize_t(z) PyInt_FromLong(z)")
429 code.putln(" #define PyInt_AsSsize_t(o) PyInt_AsLong(o)")
430 code.putln(" #define PyNumber_Index(o) PyNumber_Int(o)")
431 code.putln(" #define PyIndex_Check(o) PyNumber_Check(o)")
432 code.putln("#endif")
434 code.putln("#if PY_VERSION_HEX < 0x02060000")
435 code.putln(" #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)")
436 code.putln(" #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)")
437 code.putln(" #define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)")
438 code.putln(" #define PyVarObject_HEAD_INIT(type, size) \\")
439 code.putln(" PyObject_HEAD_INIT(type) size,")
440 code.putln(" #define PyType_Modified(t)")
441 code.putln("")
442 code.putln(" typedef struct {")
443 code.putln(" void *buf;")
444 code.putln(" PyObject *obj;")
445 code.putln(" Py_ssize_t len;")
446 code.putln(" Py_ssize_t itemsize;")
447 code.putln(" int readonly;")
448 code.putln(" int ndim;")
449 code.putln(" char *format;")
450 code.putln(" Py_ssize_t *shape;")
451 code.putln(" Py_ssize_t *strides;")
452 code.putln(" Py_ssize_t *suboffsets;")
453 code.putln(" void *internal;")
454 code.putln(" } Py_buffer;")
455 code.putln("")
456 code.putln(" #define PyBUF_SIMPLE 0")
457 code.putln(" #define PyBUF_WRITABLE 0x0001")
458 code.putln(" #define PyBUF_FORMAT 0x0004")
459 code.putln(" #define PyBUF_ND 0x0008")
460 code.putln(" #define PyBUF_STRIDES (0x0010 | PyBUF_ND)")
461 code.putln(" #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)")
462 code.putln(" #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)")
463 code.putln(" #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)")
464 code.putln(" #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)")
465 code.putln("")
466 code.putln("#endif")
468 code.put(builtin_module_name_utility_code.proto)
470 code.putln("#if PY_MAJOR_VERSION >= 3")
471 code.putln(" #define Py_TPFLAGS_CHECKTYPES 0")
472 code.putln(" #define Py_TPFLAGS_HAVE_INDEX 0")
473 code.putln("#endif")
475 code.putln("#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)")
476 code.putln(" #define Py_TPFLAGS_HAVE_NEWBUFFER 0")
477 code.putln("#endif")
479 code.putln("#if PY_MAJOR_VERSION >= 3")
480 code.putln(" #define PyBaseString_Type PyUnicode_Type")
481 code.putln(" #define PyString_Type PyBytes_Type")
482 code.putln(" #define PyString_CheckExact PyBytes_CheckExact")
483 code.putln(" #define PyInt_Type PyLong_Type")
484 code.putln(" #define PyInt_Check(op) PyLong_Check(op)")
485 code.putln(" #define PyInt_CheckExact(op) PyLong_CheckExact(op)")
486 code.putln(" #define PyInt_FromString PyLong_FromString")
487 code.putln(" #define PyInt_FromUnicode PyLong_FromUnicode")
488 code.putln(" #define PyInt_FromLong PyLong_FromLong")
489 code.putln(" #define PyInt_FromSize_t PyLong_FromSize_t")
490 code.putln(" #define PyInt_FromSsize_t PyLong_FromSsize_t")
491 code.putln(" #define PyInt_AsLong PyLong_AsLong")
492 code.putln(" #define PyInt_AS_LONG PyLong_AS_LONG")
493 code.putln(" #define PyInt_AsSsize_t PyLong_AsSsize_t")
494 code.putln(" #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask")
495 code.putln(" #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask")
496 code.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)")
497 code.putln("#else")
498 if Future.division in env.context.future_directives:
499 code.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)")
500 else:
501 code.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)")
502 code.putln(" #define PyBytes_Type PyString_Type")
503 code.putln("#endif")
505 code.putln("#if PY_MAJOR_VERSION >= 3")
506 code.putln(" #define PyMethod_New(func, self, klass) PyInstanceMethod_New(func)")
507 code.putln("#endif")
509 code.putln("#if !defined(WIN32) && !defined(MS_WINDOWS)")
510 code.putln(" #ifndef __stdcall")
511 code.putln(" #define __stdcall")
512 code.putln(" #endif")
513 code.putln(" #ifndef __cdecl")
514 code.putln(" #define __cdecl")
515 code.putln(" #endif")
516 code.putln("#else")
517 code.putln(" #define _USE_MATH_DEFINES")
518 code.putln("#endif")
520 code.putln("#if PY_VERSION_HEX < 0x02050000")
521 code.putln(" #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),((char *)(n)))")
522 code.putln(" #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))")
523 code.putln(" #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),((char *)(n)))")
524 code.putln("#else")
525 code.putln(" #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),(n))")
526 code.putln(" #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))")
527 code.putln(" #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),(n))")
528 code.putln("#endif")
530 code.putln("#if PY_VERSION_HEX < 0x02050000")
531 code.putln(" #define __Pyx_NAMESTR(n) ((char *)(n))")
532 code.putln(" #define __Pyx_DOCSTR(n) ((char *)(n))")
533 code.putln("#else")
534 code.putln(" #define __Pyx_NAMESTR(n) (n)")
535 code.putln(" #define __Pyx_DOCSTR(n) (n)")
536 code.putln("#endif")
538 self.generate_extern_c_macro_definition(code)
539 code.putln("#include <math.h>")
540 code.putln("#define %s" % Naming.api_guard_prefix + self.api_name(env))
541 self.generate_includes(env, cimported_modules, code)
542 code.putln('')
543 code.put(Nodes.utility_function_predeclarations)
544 code.put(PyrexTypes.type_conversion_predeclarations)
545 code.put(Nodes.branch_prediction_macros)
546 code.putln('')
547 code.putln('static PyObject *%s;' % env.module_cname)
548 code.putln('static PyObject *%s;' % Naming.builtins_cname)
549 code.putln('static PyObject *%s;' % Naming.empty_tuple)
550 if Options.pre_import is not None:
551 code.putln('static PyObject *%s;' % Naming.preimport_cname)
552 code.putln('static int %s;' % Naming.lineno_cname)
553 code.putln('static int %s = 0;' % Naming.clineno_cname)
554 code.putln('static const char * %s= %s;' % (Naming.cfilenm_cname, Naming.file_c_macro))
555 code.putln('static const char *%s;' % Naming.filename_cname)
556 code.putln('static const char **%s;' % Naming.filetable_cname)
557 if env.doc:
558 docstr = env.doc
559 if not isinstance(docstr, str):
560 docstr = docstr.utf8encode()
561 code.putln('')
562 code.putln('static char %s[] = "%s";' % (
563 env.doc_cname, escape_byte_string(docstr)))
565 env.use_utility_code(streq_utility_code)
567 def generate_extern_c_macro_definition(self, code):
568 name = Naming.extern_c_macro
569 code.putln("#ifdef __cplusplus")
570 code.putln('#define %s extern "C"' % name)
571 code.putln("#else")
572 code.putln("#define %s extern" % name)
573 code.putln("#endif")
575 def generate_includes(self, env, cimported_modules, code):
576 includes = []
577 for filename in env.include_files:
578 code.putln('#include "%s"' % filename)
580 def generate_filename_table(self, code):
581 code.putln("")
582 code.putln("static const char *%s[] = {" % Naming.filenames_cname)
583 if code.globalstate.filename_list:
584 for source_desc in code.globalstate.filename_list:
585 filename = os.path.basename(source_desc.get_filenametable_entry())
586 escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"')
587 code.putln('"%s",' %
588 escaped_filename)
589 else:
590 # Some C compilers don't like an empty array
591 code.putln("0")
592 code.putln("};")
594 def generate_type_predeclarations(self, env, code):
595 pass
597 def generate_type_header_code(self, type_entries, code):
598 # Generate definitions of structs/unions/enums/typedefs/objstructs.
599 #self.generate_gcc33_hack(env, code) # Is this still needed?
600 #for entry in env.type_entries:
601 for entry in type_entries:
602 if not entry.in_cinclude:
603 #print "generate_type_header_code:", entry.name, repr(entry.type) ###
604 type = entry.type
605 if type.is_typedef: # Must test this first!
606 self.generate_typedef(entry, code)
607 elif type.is_struct_or_union:
608 self.generate_struct_union_definition(entry, code)
609 elif type.is_enum:
610 self.generate_enum_definition(entry, code)
611 elif type.is_extension_type:
612 self.generate_obj_struct_definition(type, code)
614 def generate_gcc33_hack(self, env, code):
615 # Workaround for spurious warning generation in gcc 3.3
616 code.putln("")
617 for entry in env.c_class_entries:
618 type = entry.type
619 if not type.typedef_flag:
620 name = type.objstruct_cname
621 if name.startswith("__pyx_"):
622 tail = name[6:]
623 else:
624 tail = name
625 code.putln("typedef struct %s __pyx_gcc33_%s;" % (
626 name, tail))
628 def generate_typedef(self, entry, code):
629 base_type = entry.type.typedef_base_type
630 code.putln("")
631 code.putln("typedef %s;" % base_type.declaration_code(entry.cname))
633 def sue_header_footer(self, type, kind, name):
634 if type.typedef_flag:
635 header = "typedef %s {" % kind
636 footer = "} %s;" % name
637 else:
638 header = "%s %s {" % (kind, name)
639 footer = "};"
640 return header, footer
642 def generate_struct_union_definition(self, entry, code):
643 code.mark_pos(entry.pos)
644 type = entry.type
645 scope = type.scope
646 if scope:
647 header, footer = \
648 self.sue_header_footer(type, type.kind, type.cname)
649 code.putln("")
650 code.putln(header)
651 var_entries = scope.var_entries
652 if not var_entries:
653 error(entry.pos,
654 "Empty struct or union definition not allowed outside a"
655 " 'cdef extern from' block")
656 for attr in var_entries:
657 code.putln(
658 "%s;" %
659 attr.type.declaration_code(attr.cname))
660 code.putln(footer)
662 def generate_enum_definition(self, entry, code):
663 code.mark_pos(entry.pos)
664 type = entry.type
665 name = entry.cname or entry.name or ""
666 header, footer = \
667 self.sue_header_footer(type, "enum", name)
668 code.putln("")
669 code.putln(header)
670 enum_values = entry.enum_values
671 if not enum_values:
672 error(entry.pos,
673 "Empty enum definition not allowed outside a"
674 " 'cdef extern from' block")
675 else:
676 last_entry = enum_values[-1]
677 for value_entry in enum_values:
678 if value_entry.value == value_entry.name:
679 value_code = value_entry.cname
680 else:
681 value_code = ("%s = %s" % (
682 value_entry.cname,
683 value_entry.value))
684 if value_entry is not last_entry:
685 value_code += ","
686 code.putln(value_code)
687 code.putln(footer)
689 def generate_typeobject_predeclaration(self, entry, code):
690 code.putln("")
691 name = entry.type.typeobj_cname
692 if name:
693 if entry.visibility == 'extern' and not entry.in_cinclude:
694 code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
695 Naming.extern_c_macro,
696 name))
697 elif entry.visibility == 'public':
698 #code.putln("DL_EXPORT(PyTypeObject) %s;" % name)
699 code.putln("%s DL_EXPORT(PyTypeObject) %s;" % (
700 Naming.extern_c_macro,
701 name))
702 # ??? Do we really need the rest of this? ???
703 #else:
704 # code.putln("staticforward PyTypeObject %s;" % name)
706 def generate_exttype_vtable_struct(self, entry, code):
707 code.mark_pos(entry.pos)
708 # Generate struct declaration for an extension type's vtable.
709 type = entry.type
710 scope = type.scope
711 if type.vtabstruct_cname:
712 code.putln("")
713 code.putln(
714 "struct %s {" %
715 type.vtabstruct_cname)
716 if type.base_type and type.base_type.vtabstruct_cname:
717 code.putln("struct %s %s;" % (
718 type.base_type.vtabstruct_cname,
719 Naming.obj_base_cname))
720 for method_entry in scope.cfunc_entries:
721 if not method_entry.is_inherited:
722 code.putln(
723 "%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.name))
724 code.putln(
725 "};")
727 def generate_exttype_vtabptr_declaration(self, entry, code):
728 code.mark_pos(entry.pos)
729 # Generate declaration of pointer to an extension type's vtable.
730 type = entry.type
731 if type.vtabptr_cname:
732 code.putln("static struct %s *%s;" % (
733 type.vtabstruct_cname,
734 type.vtabptr_cname))
736 def generate_obj_struct_definition(self, type, code):
737 code.mark_pos(type.pos)
738 # Generate object struct definition for an
739 # extension type.
740 if not type.scope:
741 return # Forward declared but never defined
742 header, footer = \
743 self.sue_header_footer(type, "struct", type.objstruct_cname)
744 code.putln("")
745 code.putln(header)
746 base_type = type.base_type
747 if base_type:
748 code.putln(
749 "%s%s %s;" % (
750 ("struct ", "")[base_type.typedef_flag],
751 base_type.objstruct_cname,
752 Naming.obj_base_cname))
753 else:
754 code.putln(
755 "PyObject_HEAD")
756 if type.vtabslot_cname and not (type.base_type and type.base_type.vtabslot_cname):
757 code.putln(
758 "struct %s *%s;" % (
759 type.vtabstruct_cname,
760 type.vtabslot_cname))
761 for attr in type.scope.var_entries:
762 code.putln(
763 "%s;" %
764 attr.type.declaration_code(attr.cname))
765 code.putln(footer)
767 def generate_global_declarations(self, env, code, definition):
768 code.putln("")
769 for entry in env.c_class_entries:
770 if definition or entry.defined_in_pxd:
771 code.putln("static PyTypeObject *%s = 0;" %
772 entry.type.typeptr_cname)
773 code.put_var_declarations(env.var_entries, static = 1,
774 dll_linkage = "DL_EXPORT", definition = definition)
775 if definition:
776 code.put_var_declarations(env.default_entries, static = 1,
777 definition = definition)
779 def generate_cfunction_predeclarations(self, env, code, definition):
780 for entry in env.cfunc_entries:
781 if entry.inline_func_in_pxd or (not entry.in_cinclude and (definition
782 or entry.defined_in_pxd or entry.visibility == 'extern')):
783 if entry.visibility in ('public', 'extern'):
784 dll_linkage = "DL_EXPORT"
785 else:
786 dll_linkage = None
787 type = entry.type
788 if not definition and entry.defined_in_pxd:
789 type = CPtrType(type)
790 header = type.declaration_code(entry.cname,
791 dll_linkage = dll_linkage)
792 if entry.visibility == 'private':
793 storage_class = "static "
794 elif entry.visibility == 'public':
795 storage_class = ""
796 else:
797 storage_class = "%s " % Naming.extern_c_macro
798 if entry.func_modifiers:
799 modifiers = '%s ' % ' '.join([
800 modifier.upper() for modifier in entry.func_modifiers])
801 else:
802 modifiers = ''
803 code.putln("%s%s%s; /*proto*/" % (
804 storage_class,
805 modifiers,
806 header))
808 def generate_typeobj_definitions(self, env, code):
809 full_module_name = env.qualified_name
810 for entry in env.c_class_entries:
811 #print "generate_typeobj_definitions:", entry.name
812 #print "...visibility =", entry.visibility
813 if entry.visibility != 'extern':
814 type = entry.type
815 scope = type.scope
816 if scope: # could be None if there was an error
817 self.generate_exttype_vtable(scope, code)
818 self.generate_new_function(scope, code)
819 self.generate_dealloc_function(scope, code)
820 if scope.needs_gc():
821 self.generate_traverse_function(scope, code)
822 self.generate_clear_function(scope, code)
823 if scope.defines_any(["__getitem__"]):
824 self.generate_getitem_int_function(scope, code)
825 if scope.defines_any(["__setitem__", "__delitem__"]):
826 self.generate_ass_subscript_function(scope, code)
827 if scope.defines_any(["__setslice__", "__delslice__"]):
828 warning(self.pos, "__setslice__ and __delslice__ are not supported by Python 3", 1)
829 self.generate_ass_slice_function(scope, code)
830 if scope.defines_any(["__getattr__","__getattribute__"]):
831 self.generate_getattro_function(scope, code)
832 if scope.defines_any(["__setattr__", "__delattr__"]):
833 self.generate_setattro_function(scope, code)
834 if scope.defines_any(["__get__"]):
835 self.generate_descr_get_function(scope, code)
836 if scope.defines_any(["__set__", "__delete__"]):
837 self.generate_descr_set_function(scope, code)
838 self.generate_property_accessors(scope, code)
839 self.generate_method_table(scope, code)
840 self.generate_member_table(scope, code)
841 self.generate_getset_table(scope, code)
842 self.generate_typeobj_definition(full_module_name, entry, code)
844 def generate_exttype_vtable(self, scope, code):
845 # Generate the definition of an extension type's vtable.
846 type = scope.parent_type
847 if type.vtable_cname:
848 code.putln("static struct %s %s;" % (
849 type.vtabstruct_cname,
850 type.vtable_cname))
852 def generate_self_cast(self, scope, code):
853 type = scope.parent_type
854 code.putln(
855 "%s = (%s)o;" % (
856 type.declaration_code("p"),
857 type.declaration_code("")))
859 def generate_new_function(self, scope, code):
860 tp_slot = TypeSlots.ConstructorSlot("tp_new", '__new__')
861 slot_func = scope.mangle_internal("tp_new")
862 type = scope.parent_type
863 base_type = type.base_type
864 py_attrs = []
865 for entry in scope.var_entries:
866 if entry.type.is_pyobject:
867 py_attrs.append(entry)
868 need_self_cast = type.vtabslot_cname or py_attrs
869 code.putln("")
870 code.putln(
871 "static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k) {"
872 % scope.mangle_internal("tp_new"))
873 if need_self_cast:
874 code.putln(
875 "%s;"
876 % scope.parent_type.declaration_code("p"))
877 if base_type:
878 tp_new = TypeSlots.get_base_slot_function(scope, tp_slot)
879 if tp_new is None:
880 tp_new = "%s->tp_new" % base_type.typeptr_cname
881 code.putln(
882 "PyObject *o = %s(t, a, k);" % tp_new)
883 else:
884 code.putln(
885 "PyObject *o = (*t->tp_alloc)(t, 0);")
886 code.putln(
887 "if (!o) return 0;")
888 if need_self_cast:
889 code.putln(
890 "p = %s;"
891 % type.cast_code("o"))
892 #if need_self_cast:
893 # self.generate_self_cast(scope, code)
894 if type.vtabslot_cname:
895 vtab_base_type = type
896 while vtab_base_type.base_type and vtab_base_type.base_type.vtabstruct_cname:
897 vtab_base_type = vtab_base_type.base_type
898 if vtab_base_type is not type:
899 struct_type_cast = "(struct %s*)" % vtab_base_type.vtabstruct_cname
900 else:
901 struct_type_cast = ""
902 code.putln("p->%s = %s%s;" % (
903 type.vtabslot_cname,
904 struct_type_cast, type.vtabptr_cname))
905 for entry in py_attrs:
906 if entry.name == "__weakref__":
907 code.putln("p->%s = 0;" % entry.cname)
908 else:
909 code.put_init_var_to_py_none(entry, "p->%s", nanny=False)
910 entry = scope.lookup_here("__new__")
911 if entry and entry.is_special:
912 if entry.trivial_signature:
913 cinit_args = "o, %s, NULL" % Naming.empty_tuple
914 else:
915 cinit_args = "o, a, k"
916 code.putln(
917 "if (%s(%s) < 0) {" %
918 (entry.func_cname, cinit_args))
919 code.put_decref_clear("o", py_object_type, nanny=False);
920 code.putln(
921 "}")
922 code.putln(
923 "return o;")
924 code.putln(
925 "}")
927 def generate_dealloc_function(self, scope, code):
928 tp_slot = TypeSlots.ConstructorSlot("tp_dealloc", '__dealloc__')
929 slot_func = scope.mangle_internal("tp_dealloc")
930 base_type = scope.parent_type.base_type
931 if tp_slot.slot_code(scope) != slot_func:
932 return # never used
933 code.putln("")
934 code.putln(
935 "static void %s(PyObject *o) {"
936 % scope.mangle_internal("tp_dealloc"))
937 py_attrs = []
938 weakref_slot = scope.lookup_here("__weakref__")
939 for entry in scope.var_entries:
940 if entry.type.is_pyobject and entry is not weakref_slot:
941 py_attrs.append(entry)
942 if py_attrs or weakref_slot in scope.var_entries:
943 self.generate_self_cast(scope, code)
944 self.generate_usr_dealloc_call(scope, code)
945 if weakref_slot in scope.var_entries:
946 code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);")
947 for entry in py_attrs:
948 code.put_xdecref("p->%s" % entry.cname, entry.type, nanny=False)
949 if base_type:
950 tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot)
951 if tp_dealloc is None:
952 tp_dealloc = "%s->tp_dealloc" % base_type.typeptr_cname
953 code.putln(
954 "%s(o);" % tp_dealloc)
955 else:
956 code.putln(
957 "(*Py_TYPE(o)->tp_free)(o);")
958 code.putln(
959 "}")
961 def generate_usr_dealloc_call(self, scope, code):
962 entry = scope.lookup_here("__dealloc__")
963 if entry:
964 code.putln(
965 "{")
966 code.putln(
967 "PyObject *etype, *eval, *etb;")
968 code.putln(
969 "PyErr_Fetch(&etype, &eval, &etb);")
970 code.putln(
971 "++Py_REFCNT(o);")
972 code.putln(
973 "%s(o);" %
974 entry.func_cname)
975 code.putln(
976 "if (PyErr_Occurred()) PyErr_WriteUnraisable(o);")
977 code.putln(
978 "--Py_REFCNT(o);")
979 code.putln(
980 "PyErr_Restore(etype, eval, etb);")
981 code.putln(
982 "}")
984 def generate_traverse_function(self, scope, code):
985 tp_slot = TypeSlots.GCDependentSlot("tp_traverse")
986 slot_func = scope.mangle_internal("tp_traverse")
987 base_type = scope.parent_type.base_type
988 if tp_slot.slot_code(scope) != slot_func:
989 return # never used
990 code.putln("")
991 code.putln(
992 "static int %s(PyObject *o, visitproc v, void *a) {"
993 % slot_func)
994 py_attrs = []
995 for entry in scope.var_entries:
996 if entry.type.is_pyobject and entry.name != "__weakref__":
997 py_attrs.append(entry)
998 if base_type or py_attrs:
999 code.putln("int e;")
1000 if py_attrs:
1001 self.generate_self_cast(scope, code)
1002 if base_type:
1003 # want to call it explicitly if possible so inlining can be performed
1004 static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
1005 if static_call:
1006 code.putln("e = %s(o, v, a); if (e) return e;" % static_call)
1007 else:
1008 code.putln("if (%s->tp_traverse) {" % base_type.typeptr_cname)
1009 code.putln(
1010 "e = %s->tp_traverse(o, v, a); if (e) return e;" %
1011 base_type.typeptr_cname)
1012 code.putln("}")
1013 for entry in py_attrs:
1014 var_code = "p->%s" % entry.cname
1015 code.putln(
1016 "if (%s) {"
1017 % var_code)
1018 if entry.type.is_extension_type:
1019 var_code = "((PyObject*)%s)" % var_code
1020 code.putln(
1021 "e = (*v)(%s, a); if (e) return e;"
1022 % var_code)
1023 code.putln(
1024 "}")
1025 code.putln(
1026 "return 0;")
1027 code.putln(
1028 "}")
1030 def generate_clear_function(self, scope, code):
1031 tp_slot = TypeSlots.GCDependentSlot("tp_clear")
1032 slot_func = scope.mangle_internal("tp_clear")
1033 base_type = scope.parent_type.base_type
1034 if tp_slot.slot_code(scope) != slot_func:
1035 return # never used
1036 code.putln("")
1037 code.putln("static int %s(PyObject *o) {" % slot_func)
1038 py_attrs = []
1039 for entry in scope.var_entries:
1040 if entry.type.is_pyobject and entry.name != "__weakref__":
1041 py_attrs.append(entry)
1042 if py_attrs:
1043 self.generate_self_cast(scope, code)
1044 code.putln("PyObject* tmp;")
1045 if base_type:
1046 # want to call it explicitly if possible so inlining can be performed
1047 static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
1048 if static_call:
1049 code.putln("%s(o);" % static_call)
1050 else:
1051 code.putln("if (%s->tp_clear) {" % base_type.typeptr_cname)
1052 code.putln("%s->tp_clear(o);" % base_type.typeptr_cname)
1053 code.putln("}")
1054 for entry in py_attrs:
1055 name = "p->%s" % entry.cname
1056 code.putln("tmp = ((PyObject*)%s);" % name)
1057 code.put_init_to_py_none(name, entry.type, nanny=False)
1058 code.putln("Py_XDECREF(tmp);")
1059 code.putln(
1060 "return 0;")
1061 code.putln(
1062 "}")
1064 def generate_getitem_int_function(self, scope, code):
1065 # This function is put into the sq_item slot when
1066 # a __getitem__ method is present. It converts its
1067 # argument to a Python integer and calls mp_subscript.
1068 code.putln(
1069 "static PyObject *%s(PyObject *o, Py_ssize_t i) {" %
1070 scope.mangle_internal("sq_item"))
1071 code.putln(
1072 "PyObject *r;")
1073 code.putln(
1074 "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;")
1075 code.putln(
1076 "r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);")
1077 code.putln(
1078 "Py_DECREF(x);")
1079 code.putln(
1080 "return r;")
1081 code.putln(
1082 "}")
1084 def generate_ass_subscript_function(self, scope, code):
1085 # Setting and deleting an item are both done through
1086 # the ass_subscript method, so we dispatch to user's __setitem__
1087 # or __delitem__, or raise an exception.
1088 base_type = scope.parent_type.base_type
1089 set_entry = scope.lookup_here("__setitem__")
1090 del_entry = scope.lookup_here("__delitem__")
1091 code.putln("")
1092 code.putln(
1093 "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
1094 scope.mangle_internal("mp_ass_subscript"))
1095 code.putln(
1096 "if (v) {")
1097 if set_entry:
1098 code.putln(
1099 "return %s(o, i, v);" %
1100 set_entry.func_cname)
1101 else:
1102 self.generate_guarded_basetype_call(
1103 base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
1104 code.putln(
1105 "PyErr_Format(PyExc_NotImplementedError,")
1106 code.putln(
1107 ' "Subscript assignment not supported by %s", Py_TYPE(o)->tp_name);')
1108 code.putln(
1109 "return -1;")
1110 code.putln(
1111 "}")
1112 code.putln(
1113 "else {")
1114 if del_entry:
1115 code.putln(
1116 "return %s(o, i);" %
1117 del_entry.func_cname)
1118 else:
1119 self.generate_guarded_basetype_call(
1120 base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
1121 code.putln(
1122 "PyErr_Format(PyExc_NotImplementedError,")
1123 code.putln(
1124 ' "Subscript deletion not supported by %s", Py_TYPE(o)->tp_name);')
1125 code.putln(
1126 "return -1;")
1127 code.putln(
1128 "}")
1129 code.putln(
1130 "}")
1132 def generate_guarded_basetype_call(
1133 self, base_type, substructure, slot, args, code):
1134 if base_type:
1135 base_tpname = base_type.typeptr_cname
1136 if substructure:
1137 code.putln(
1138 "if (%s->%s && %s->%s->%s)" % (
1139 base_tpname, substructure, base_tpname, substructure, slot))
1140 code.putln(
1141 " return %s->%s->%s(%s);" % (
1142 base_tpname, substructure, slot, args))
1143 else:
1144 code.putln(
1145 "if (%s->%s)" % (
1146 base_tpname, slot))
1147 code.putln(
1148 " return %s->%s(%s);" % (
1149 base_tpname, slot, args))
1151 def generate_ass_slice_function(self, scope, code):
1152 # Setting and deleting a slice are both done through
1153 # the ass_slice method, so we dispatch to user's __setslice__
1154 # or __delslice__, or raise an exception.
1155 base_type = scope.parent_type.base_type
1156 set_entry = scope.lookup_here("__setslice__")
1157 del_entry = scope.lookup_here("__delslice__")
1158 code.putln("")
1159 code.putln(
1160 "static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" %
1161 scope.mangle_internal("sq_ass_slice"))
1162 code.putln(
1163 "if (v) {")
1164 if set_entry:
1165 code.putln(
1166 "return %s(o, i, j, v);" %
1167 set_entry.func_cname)
1168 else:
1169 self.generate_guarded_basetype_call(
1170 base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
1171 code.putln(
1172 "PyErr_Format(PyExc_NotImplementedError,")
1173 code.putln(
1174 ' "2-element slice assignment not supported by %s", Py_TYPE(o)->tp_name);')
1175 code.putln(
1176 "return -1;")
1177 code.putln(
1178 "}")
1179 code.putln(
1180 "else {")
1181 if del_entry:
1182 code.putln(
1183 "return %s(o, i, j);" %
1184 del_entry.func_cname)
1185 else:
1186 self.generate_guarded_basetype_call(
1187 base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
1188 code.putln(
1189 "PyErr_Format(PyExc_NotImplementedError,")
1190 code.putln(
1191 ' "2-element slice deletion not supported by %s", Py_TYPE(o)->tp_name);')
1192 code.putln(
1193 "return -1;")
1194 code.putln(
1195 "}")
1196 code.putln(
1197 "}")
1199 def generate_getattro_function(self, scope, code):
1200 # First try to get the attribute using __getattribute__, if defined, or
1201 # PyObject_GenericGetAttr.
1203 # If that raises an AttributeError, call the __getattr__ if defined.
1205 # In both cases, defined can be in this class, or any base class.
1206 def lookup_here_or_base(n,type=None):
1207 # Recursive lookup
1208 if type is None:
1209 type = scope.parent_type
1210 r = type.scope.lookup_here(n)
1211 if r is None and \
1212 type.base_type is not None:
1213 return lookup_here_or_base(n,type.base_type)
1214 else:
1215 return r
1216 getattr_entry = lookup_here_or_base("__getattr__")
1217 getattribute_entry = lookup_here_or_base("__getattribute__")
1218 code.putln("")
1219 code.putln(
1220 "static PyObject *%s(PyObject *o, PyObject *n) {"
1221 % scope.mangle_internal("tp_getattro"))
1222 if getattribute_entry is not None:
1223 code.putln(
1224 "PyObject *v = %s(o, n);" %
1225 getattribute_entry.func_cname)
1226 else:
1227 code.putln(
1228 "PyObject *v = PyObject_GenericGetAttr(o, n);")
1229 if getattr_entry is not None:
1230 code.putln(
1231 "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
1232 code.putln(
1233 "PyErr_Clear();")
1234 code.putln(
1235 "v = %s(o, n);" %
1236 getattr_entry.func_cname)
1237 code.putln(
1238 "}")
1239 code.putln(
1240 "return v;")
1241 code.putln(
1242 "}")
1244 def generate_setattro_function(self, scope, code):
1245 # Setting and deleting an attribute are both done through
1246 # the setattro method, so we dispatch to user's __setattr__
1247 # or __delattr__ or fall back on PyObject_GenericSetAttr.
1248 base_type = scope.parent_type.base_type
1249 set_entry = scope.lookup_here("__setattr__")
1250 del_entry = scope.lookup_here("__delattr__")
1251 code.putln("")
1252 code.putln(
1253 "static int %s(PyObject *o, PyObject *n, PyObject *v) {" %
1254 scope.mangle_internal("tp_setattro"))
1255 code.putln(
1256 "if (v) {")
1257 if set_entry:
1258 code.putln(
1259 "return %s(o, n, v);" %
1260 set_entry.func_cname)
1261 else:
1262 self.generate_guarded_basetype_call(
1263 base_type, None, "tp_setattro", "o, n, v", code)
1264 code.putln(
1265 "return PyObject_GenericSetAttr(o, n, v);")
1266 code.putln(
1267 "}")
1268 code.putln(
1269 "else {")
1270 if del_entry:
1271 code.putln(
1272 "return %s(o, n);" %
1273 del_entry.func_cname)
1274 else:
1275 self.generate_guarded_basetype_call(
1276 base_type, None, "tp_setattro", "o, n, v", code)
1277 code.putln(
1278 "return PyObject_GenericSetAttr(o, n, 0);")
1279 code.putln(
1280 "}")
1281 code.putln(
1282 "}")
1284 def generate_descr_get_function(self, scope, code):
1285 # The __get__ function of a descriptor object can be
1286 # called with NULL for the second or third arguments
1287 # under some circumstances, so we replace them with
1288 # None in that case.
1289 user_get_entry = scope.lookup_here("__get__")
1290 code.putln("")
1291 code.putln(
1292 "static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" %
1293 scope.mangle_internal("tp_descr_get"))
1294 code.putln(
1295 "PyObject *r = 0;")
1296 code.putln(
1297 "if (!i) i = Py_None;")
1298 code.putln(
1299 "if (!c) c = Py_None;")
1300 #code.put_incref("i", py_object_type)
1301 #code.put_incref("c", py_object_type)
1302 code.putln(
1303 "r = %s(o, i, c);" %
1304 user_get_entry.func_cname)
1305 #code.put_decref("i", py_object_type)
1306 #code.put_decref("c", py_object_type)
1307 code.putln(
1308 "return r;")
1309 code.putln(
1310 "}")
1312 def generate_descr_set_function(self, scope, code):
1313 # Setting and deleting are both done through the __set__
1314 # method of a descriptor, so we dispatch to user's __set__
1315 # or __delete__ or raise an exception.
1316 base_type = scope.parent_type.base_type
1317 user_set_entry = scope.lookup_here("__set__")
1318 user_del_entry = scope.lookup_here("__delete__")
1319 code.putln("")
1320 code.putln(
1321 "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
1322 scope.mangle_internal("tp_descr_set"))
1323 code.putln(
1324 "if (v) {")
1325 if user_set_entry:
1326 code.putln(
1327 "return %s(o, i, v);" %
1328 user_set_entry.func_cname)
1329 else:
1330 self.generate_guarded_basetype_call(
1331 base_type, None, "tp_descr_set", "o, i, v", code)
1332 code.putln(
1333 'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
1334 code.putln(
1335 "return -1;")
1336 code.putln(
1337 "}")
1338 code.putln(
1339 "else {")
1340 if user_del_entry:
1341 code.putln(
1342 "return %s(o, i);" %
1343 user_del_entry.func_cname)
1344 else:
1345 self.generate_guarded_basetype_call(
1346 base_type, None, "tp_descr_set", "o, i, v", code)
1347 code.putln(
1348 'PyErr_SetString(PyExc_NotImplementedError, "__delete__");')
1349 code.putln(
1350 "return -1;")
1351 code.putln(
1352 "}")
1353 code.putln(
1354 "}")
1356 def generate_property_accessors(self, cclass_scope, code):
1357 for entry in cclass_scope.property_entries:
1358 property_scope = entry.scope
1359 if property_scope.defines_any(["__get__"]):
1360 self.generate_property_get_function(entry, code)
1361 if property_scope.defines_any(["__set__", "__del__"]):
1362 self.generate_property_set_function(entry, code)
1364 def generate_property_get_function(self, property_entry, code):
1365 property_scope = property_entry.scope
1366 property_entry.getter_cname = property_scope.parent_scope.mangle(
1367 Naming.prop_get_prefix, property_entry.name)
1368 get_entry = property_scope.lookup_here("__get__")
1369 code.putln("")
1370 code.putln(
1371 "static PyObject *%s(PyObject *o, void *x) {" %
1372 property_entry.getter_cname)
1373 code.putln(
1374 "return %s(o);" %
1375 get_entry.func_cname)
1376 code.putln(
1377 "}")
1379 def generate_property_set_function(self, property_entry, code):
1380 property_scope = property_entry.scope
1381 property_entry.setter_cname = property_scope.parent_scope.mangle(
1382 Naming.prop_set_prefix, property_entry.name)
1383 set_entry = property_scope.lookup_here("__set__")
1384 del_entry = property_scope.lookup_here("__del__")
1385 code.putln("")
1386 code.putln(
1387 "static int %s(PyObject *o, PyObject *v, void *x) {" %
1388 property_entry.setter_cname)
1389 code.putln(
1390 "if (v) {")
1391 if set_entry:
1392 code.putln(
1393 "return %s(o, v);" %
1394 set_entry.func_cname)
1395 else:
1396 code.putln(
1397 'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
1398 code.putln(
1399 "return -1;")
1400 code.putln(
1401 "}")
1402 code.putln(
1403 "else {")
1404 if del_entry:
1405 code.putln(
1406 "return %s(o);" %
1407 del_entry.func_cname)
1408 else:
1409 code.putln(
1410 'PyErr_SetString(PyExc_NotImplementedError, "__del__");')
1411 code.putln(
1412 "return -1;")
1413 code.putln(
1414 "}")
1415 code.putln(
1416 "}")
1418 def generate_typeobj_definition(self, modname, entry, code):
1419 type = entry.type
1420 scope = type.scope
1421 for suite in TypeSlots.substructures:
1422 suite.generate_substructure(scope, code)
1423 code.putln("")
1424 if entry.visibility == 'public':
1425 header = "DL_EXPORT(PyTypeObject) %s = {"
1426 else:
1427 #header = "statichere PyTypeObject %s = {"
1428 header = "PyTypeObject %s = {"
1429 #code.putln(header % scope.parent_type.typeobj_cname)
1430 code.putln(header % type.typeobj_cname)
1431 code.putln(
1432 "PyVarObject_HEAD_INIT(0, 0)")
1433 code.putln(
1434 '__Pyx_NAMESTR("%s.%s"), /*tp_name*/' % (
1435 self.full_module_name, scope.class_name))
1436 if type.typedef_flag:
1437 objstruct = type.objstruct_cname
1438 else:
1439 #objstruct = "struct %s" % scope.parent_type.objstruct_cname
1440 objstruct = "struct %s" % type.objstruct_cname
1441 code.putln(
1442 "sizeof(%s), /*tp_basicsize*/" %
1443 objstruct)
1444 code.putln(
1445 "0, /*tp_itemsize*/")
1446 for slot in TypeSlots.slot_table:
1447 slot.generate(scope, code)
1448 code.putln(
1449 "};")
1451 def generate_method_table(self, env, code):
1452 code.putln("")
1453 code.putln(
1454 "static struct PyMethodDef %s[] = {" %
1455 env.method_table_cname)
1456 for entry in env.pyfunc_entries:
1457 code.put_pymethoddef(entry, ",")
1458 code.putln(
1459 "{0, 0, 0, 0}")
1460 code.putln(
1461 "};")
1463 def generate_member_table(self, env, code):
1464 #print "ModuleNode.generate_member_table: scope =", env ###
1465 if env.public_attr_entries:
1466 code.putln("")
1467 code.putln(
1468 "static struct PyMemberDef %s[] = {" %
1469 env.member_table_cname)
1470 type = env.parent_type
1471 if type.typedef_flag:
1472 objstruct = type.objstruct_cname
1473 else:
1474 objstruct = "struct %s" % type.objstruct_cname
1475 for entry in env.public_attr_entries:
1476 type_code = entry.type.pymemberdef_typecode
1477 if entry.visibility == 'readonly':
1478 flags = "READONLY"
1479 else:
1480 flags = "0"
1481 code.putln('{(char *)"%s", %s, %s, %s, 0},' % (
1482 entry.name,
1483 type_code,
1484 "offsetof(%s, %s)" % (objstruct, entry.cname),
1485 flags))
1486 code.putln(
1487 "{0, 0, 0, 0, 0}")
1488 code.putln(
1489 "};")
1491 def generate_getset_table(self, env, code):
1492 if env.property_entries:
1493 code.putln("")
1494 code.putln(
1495 "static struct PyGetSetDef %s[] = {" %
1496 env.getset_table_cname)
1497 for entry in env.property_entries:
1498 code.putln(
1499 '{(char *)"%s", %s, %s, %s, 0},' % (
1500 entry.name,
1501 entry.getter_cname or "0",
1502 entry.setter_cname or "0",
1503 entry.doc_cname or "0"))
1504 code.putln(
1505 "{0, 0, 0, 0, 0}")
1506 code.putln(
1507 "};")
1509 def generate_filename_init_prototype(self, code):
1510 code.putln("");
1511 code.putln("static void %s(void); /*proto*/" % Naming.fileinit_cname)
1513 def generate_import_star(self, env, code):
1514 code.putln()
1515 code.putln("char* %s_type_names[] = {" % Naming.import_star)
1516 for name, entry in env.entries.items():
1517 if entry.is_type:
1518 code.putln('"%s",' % name)
1519 code.putln("0")
1520 code.putln("};")
1521 code.putln()
1522 code.enter_cfunc_scope() # as we need labels
1523 code.putln("static int %s(PyObject *o, PyObject* py_name, char *name) {" % Naming.import_star_set)
1524 code.putln("char** type_name = %s_type_names;" % Naming.import_star)
1525 code.putln("while (*type_name) {")
1526 code.putln("if (__Pyx_StrEq(name, *type_name)) {")
1527 code.putln('PyErr_Format(PyExc_TypeError, "Cannot overwrite C type %s", name);')
1528 code.putln('goto bad;')
1529 code.putln("}")
1530 code.putln("type_name++;")
1531 code.putln("}")
1532 old_error_label = code.new_error_label()
1533 code.putln("if (0);") # so the first one can be "else if"
1534 for name, entry in env.entries.items():
1535 if entry.is_cglobal and entry.used:
1536 code.putln('else if (__Pyx_StrEq(name, "%s")) {' % name)
1537 if entry.type.is_pyobject:
1538 if entry.type.is_extension_type or entry.type.is_builtin_type:
1539 code.putln("if (!(%s)) %s;" % (
1540 entry.type.type_test_code("o"),
1541 code.error_goto(entry.pos)))
1542 code.put_var_decref(entry)
1543 code.putln("%s = %s;" % (
1544 entry.cname,
1545 PyrexTypes.typecast(entry.type, py_object_type, "o")))
1546 elif entry.type.from_py_function:
1547 rhs = "%s(o)" % entry.type.from_py_function
1548 if entry.type.is_enum:
1549 rhs = typecast(entry.type, c_long_type, rhs)
1550 code.putln("%s = %s; if (%s) %s;" % (
1551 entry.cname,
1552 rhs,
1553 entry.type.error_condition(entry.cname),
1554 code.error_goto(entry.pos)))
1555 code.putln("Py_DECREF(o);")
1556 else:
1557 code.putln('PyErr_Format(PyExc_TypeError, "Cannot convert Python object %s to %s");' % (name, entry.type))
1558 code.putln(code.error_goto(entry.pos))
1559 code.putln("}")
1560 code.putln("else {")
1561 code.putln("if (PyObject_SetAttr(%s, py_name, o) < 0) goto bad;" % Naming.module_cname)
1562 code.putln("}")
1563 code.putln("return 0;")
1564 code.put_label(code.error_label)
1565 # This helps locate the offending name.
1566 code.putln('__Pyx_AddTraceback("%s");' % self.full_module_name);
1567 code.error_label = old_error_label
1568 code.putln("bad:")
1569 code.putln("Py_DECREF(o);")
1570 code.putln("return -1;")
1571 code.putln("}")
1572 code.putln(import_star_utility_code)
1573 code.exit_cfunc_scope() # done with labels
1575 def generate_module_init_func(self, imported_modules, env, code):
1576 # Insert code stream of __Pyx_InitGlobals()
1577 code.globalstate.insert_initcode_into(code)
1579 code.enter_cfunc_scope()
1580 code.putln("")
1581 header2 = "PyMODINIT_FUNC init%s(void)" % env.module_name
1582 header3 = "PyMODINIT_FUNC PyInit_%s(void)" % env.module_name
1583 code.putln("#if PY_MAJOR_VERSION < 3")
1584 code.putln("%s; /*proto*/" % header2)
1585 code.putln(header2)
1586 code.putln("#else")
1587 code.putln("%s; /*proto*/" % header3)
1588 code.putln(header3)
1589 code.putln("#endif")
1590 code.putln("{")
1591 tempdecl_code = code.insertion_point()
1593 code.putln("#ifdef CYTHON_REFNANNY")
1594 code.putln("void* __pyx_refchk = NULL;")
1595 code.putln("__Pyx_Refnanny = __Pyx_ImportRefcountAPI(\"refnanny\");")
1596 code.putln("if (!__Pyx_Refnanny) {")
1597 code.putln(" PyErr_Clear();")
1598 code.putln(" __Pyx_Refnanny = __Pyx_ImportRefcountAPI(\"Cython.Runtime.refnanny\");")
1599 code.putln(" if (!__Pyx_Refnanny)")
1600 code.putln(" Py_FatalError(\"failed to import refnanny module\");")
1601 code.putln("}")
1602 code.putln("__pyx_refchk = __Pyx_Refnanny->NewContext(\"%s\", __LINE__, __FILE__);"% header3)
1603 code.putln("#endif")
1605 code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos)));
1607 code.putln("/*--- Library function declarations ---*/")
1608 env.generate_library_function_declarations(code)
1609 self.generate_filename_init_call(code)
1611 code.putln("/*--- Threads initialization code ---*/")
1612 code.putln("#if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS")
1613 code.putln("#ifdef WITH_THREAD /* Python build with threading support? */")
1614 code.putln("PyEval_InitThreads();")
1615 code.putln("#endif")
1616 code.putln("#endif")
1618 code.putln("/*--- Initialize various global constants etc. ---*/")
1619 code.putln(code.error_goto_if_neg("__Pyx_InitGlobals()", self.pos))
1621 code.putln("/*--- Module creation code ---*/")
1622 self.generate_module_creation_code(env, code)
1624 if Options.cache_builtins:
1625 code.putln("/*--- Builtin init code ---*/")
1626 code.putln(code.error_goto_if_neg("__Pyx_InitCachedBuiltins()",
1627 self.pos))
1629 code.putln("%s = 0;" % Naming.skip_dispatch_cname);
1631 code.putln("/*--- Global init code ---*/")
1632 self.generate_global_init_code(env, code)
1634 code.putln("/*--- Function export code ---*/")
1635 self.generate_c_function_export_code(env, code)
1637 code.putln("/*--- Type init code ---*/")
1638 self.generate_type_init_code(env, code)
1640 code.putln("/*--- Type import code ---*/")
1641 for module in imported_modules:
1642 self.generate_type_import_code_for_module(module, env, code)
1644 code.putln("/*--- Function import code ---*/")
1645 for module in imported_modules:
1646 self.generate_c_function_import_code_for_module(module, env, code)
1648 code.putln("/*--- Execution code ---*/")
1649 code.mark_pos(None)
1651 self.body.generate_execution_code(code)
1653 if Options.generate_cleanup_code:
1654 # this should be replaced by the module's tp_clear in Py3
1655 env.use_utility_code(import_module_utility_code)
1656 code.putln("if (__Pyx_RegisterCleanup()) %s;" % code.error_goto(self.pos))
1658 code.put_goto(code.return_label)
1659 code.put_label(code.error_label)
1660 code.put_var_xdecrefs(env.temp_entries)
1661 for cname, type in code.funcstate.all_managed_temps():
1662 code.put_xdecref(cname, type)
1663 code.putln('__Pyx_AddTraceback("%s");' % env.qualified_name)
1664 env.use_utility_code(Nodes.traceback_utility_code)
1665 code.put_decref_clear(env.module_cname, py_object_type, nanny=False)
1666 code.put_label(code.return_label)
1668 code.put_finish_refcount_context()
1670 code.putln("#if PY_MAJOR_VERSION < 3")
1671 code.putln("return;")
1672 code.putln("#else")
1673 code.putln("return %s;" % env.module_cname)
1674 code.putln("#endif")
1675 code.putln('}')
1677 tempdecl_code.put_var_declarations(env.temp_entries)
1678 tempdecl_code.put_temp_declarations(code.funcstate)
1680 code.exit_cfunc_scope()
1682 def generate_module_cleanup_func(self, env, code):
1683 if not Options.generate_cleanup_code:
1684 return
1685 env.use_utility_code(register_cleanup_utility_code)
1686 # Insert code stream of __Pyx_CleanupGlobals()
1687 code.globalstate.insert_cleanupcode_into(code)
1688 code.putln()
1689 code.putln('static PyObject* %s(PyObject *self, PyObject *unused) {' % Naming.cleanup_cname)
1690 if Options.generate_cleanup_code >= 2:
1691 code.putln("/*--- Global cleanup code ---*/")
1692 rev_entries = list(env.var_entries)
1693 rev_entries.reverse()
1694 for entry in rev_entries:
1695 if entry.visibility != 'extern':
1696 if entry.type.is_pyobject and entry.used:
1697 code.putln("Py_DECREF(%s); %s = 0;" % (
1698 code.entry_as_pyobject(entry), entry.cname))
1699 code.putln("__Pyx_CleanupGlobals();")
1700 if Options.generate_cleanup_code >= 3:
1701 code.putln("/*--- Type import cleanup code ---*/")
1702 for type, _ in env.types_imported.items():
1703 code.putln("Py_DECREF((PyObject *)%s);" % type.typeptr_cname)
1704 if Options.cache_builtins:
1705 code.putln("/*--- Builtin cleanup code ---*/")
1706 for entry in env.cached_builtins:
1707 code.put_decref_clear(entry.cname,
1708 PyrexTypes.py_object_type,
1709 nanny=False)
1710 code.putln("/*--- Intern cleanup code ---*/")
1711 code.put_decref_clear(Naming.empty_tuple,
1712 PyrexTypes.py_object_type,
1713 nanny=False)
1714 for entry in env.pynum_entries:
1715 code.put_decref_clear(entry.cname,
1716 PyrexTypes.py_object_type,
1717 nanny=False)
1718 for entry in env.all_pystring_entries:
1719 if entry.is_interned:
1720 code.put_decref_clear(entry.pystring_cname,
1721 PyrexTypes.py_object_type,
1722 nanny=False)
1723 for entry in env.default_entries:
1724 if entry.type.is_pyobject and entry.used:
1725 code.putln("Py_DECREF(%s); %s = 0;" % (
1726 code.entry_as_pyobject(entry), entry.cname))
1727 code.putln("Py_INCREF(Py_None); return Py_None;")
1728 code.putln('}')
1730 def generate_filename_init_call(self, code):
1731 code.putln("%s();" % Naming.fileinit_cname)
1733 def generate_pymoduledef_struct(self, env, code):
1734 if env.doc:
1735 doc = "__Pyx_DOCSTR(%s)" % env.doc_cname
1736 else:
1737 doc = "0"
1738 code.putln("")
1739 code.putln("#if PY_MAJOR_VERSION >= 3")
1740 code.putln("static struct PyModuleDef %s = {" % Naming.pymoduledef_cname)
1741 code.putln(" PyModuleDef_HEAD_INIT,")
1742 code.putln(' __Pyx_NAMESTR("%s"),' % env.module_name)
1743 code.putln(" %s, /* m_doc */" % doc)
1744 code.putln(" -1, /* m_size */")
1745 code.putln(" %s /* m_methods */," % env.method_table_cname)
1746 code.putln(" NULL, /* m_reload */")
1747 code.putln(" NULL, /* m_traverse */")
1748 code.putln(" NULL, /* m_clear */")
1749 code.putln(" NULL /* m_free */")
1750 code.putln("};")
1751 code.putln("#endif")
1753 def generate_module_creation_code(self, env, code):
1754 # Generate code to create the module object and
1755 # install the builtins.
1756 if env.doc:
1757 doc = env.doc_cname
1758 else:
1759 doc = "0"
1760 code.putln("#if PY_MAJOR_VERSION < 3")
1761 code.putln(
1762 '%s = Py_InitModule4(__Pyx_NAMESTR("%s"), %s, %s, 0, PYTHON_API_VERSION);' % (
1763 env.module_cname,
1764 env.module_name,
1765 env.method_table_cname,
1766 doc))
1767 code.putln("#else")
1768 code.putln(
1769 "%s = PyModule_Create(&%s);" % (
1770 env.module_cname,
1771 Naming.pymoduledef_cname))
1772 code.putln("#endif")
1773 code.putln(
1774 "if (!%s) %s;" % (
1775 env.module_cname,
1776 code.error_goto(self.pos)));
1777 code.putln("#if PY_MAJOR_VERSION < 3")
1778 code.putln(
1779 "Py_INCREF(%s);" %
1780 env.module_cname)
1781 code.putln("#endif")
1782 code.putln(
1783 '%s = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME));' %
1784 Naming.builtins_cname)
1785 code.putln(
1786 "if (!%s) %s;" % (
1787 Naming.builtins_cname,
1788 code.error_goto(self.pos)));
1789 code.putln(
1790 'if (__Pyx_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % (
1791 env.module_cname,
1792 Naming.builtins_cname,
1793 code.error_goto(self.pos)))
1794 if Options.pre_import is not None:
1795 code.putln(
1796 '%s = PyImport_AddModule(__Pyx_NAMESTR("%s"));' % (
1797 Naming.preimport_cname,
1798 Options.pre_import))
1799 code.putln(
1800 "if (!%s) %s;" % (
1801 Naming.preimport_cname,
1802 code.error_goto(self.pos)));
1804 def generate_global_init_code(self, env, code):
1805 # Generate code to initialise global PyObject *
1806 # variables to None.
1807 for entry in env.var_entries:
1808 if entry.visibility != 'extern':
1809 if entry.type.is_pyobject and entry.used:
1810 code.put_init_var_to_py_none(entry, nanny=False)
1812 def generate_c_function_export_code(self, env, code):
1813 # Generate code to create PyCFunction wrappers for exported C functions.
1814 for entry in env.cfunc_entries:
1815 if entry.api or entry.defined_in_pxd:
1816 env.use_utility_code(function_export_utility_code)
1817 signature = entry.type.signature_string()
1818 code.putln('if (__Pyx_ExportFunction("%s", (void (*)(void))%s, "%s") < 0) %s' % (
1819 entry.name,
1820 entry.cname,
1821 signature,
1822 code.error_goto(self.pos)))
1824 def generate_type_import_code_for_module(self, module, env, code):
1825 # Generate type import code for all exported extension types in
1826 # an imported module.
1827 #if module.c_class_entries:
1828 for entry in module.c_class_entries:
1829 if entry.defined_in_pxd:
1830 self.generate_type_import_code(env, entry.type, entry.pos, code)
1832 def generate_c_function_import_code_for_module(self, module, env, code):
1833 # Generate import code for all exported C functions in a cimported module.
1834 entries = []
1835 for entry in module.cfunc_entries:
1836 if entry.defined_in_pxd:
1837 entries.append(entry)
1838 if entries:
1839 env.use_utility_code(import_module_utility_code)
1840 env.use_utility_code(function_import_utility_code)
1841 temp = self.module_temp_cname
1842 code.putln(
1843 '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % (
1844 temp,
1845 module.qualified_name,
1846 temp,
1847 code.error_goto(self.pos)))
1848 for entry in entries:
1849 code.putln(
1850 'if (__Pyx_ImportFunction(%s, "%s", (void (**)(void))&%s, "%s") < 0) %s' % (
1851 temp,
1852 entry.name,
1853 entry.cname,
1854 entry.type.signature_string(),
1855 code.error_goto(self.pos)))
1856 code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp))
1858 def generate_type_init_code(self, env, code):
1859 # Generate type import code for extern extension types
1860 # and type ready code for non-extern ones.
1861 for entry in env.c_class_entries:
1862 if entry.visibility == 'extern':
1863 self.generate_type_import_code(env, entry.type, entry.pos, code)
1864 else:
1865 self.generate_base_type_import_code(env, entry, code)
1866 self.generate_exttype_vtable_init_code(entry, code)
1867 self.generate_type_ready_code(env, entry, code)
1868 self.generate_typeptr_assignment_code(entry, code)
1870 def generate_base_type_import_code(self, env, entry, code):
1871 base_type = entry.type.base_type
1872 if base_type and base_type.module_name != env.qualified_name:
1873 self.generate_type_import_code(env, base_type, self.pos, code)
1875 def use_type_import_utility_code(self, env):
1876 env.use_utility_code(type_import_utility_code)
1877 env.use_utility_code(import_module_utility_code)
1879 def generate_type_import_code(self, env, type, pos, code):
1880 # If not already done, generate code to import the typeobject of an
1881 # extension type defined in another module, and extract its C method
1882 # table pointer if any.
1883 if type in env.types_imported:
1884 return
1885 if type.typedef_flag:
1886 objstruct = type.objstruct_cname
1887 else:
1888 objstruct = "struct %s" % type.objstruct_cname
1889 self.generate_type_import_call(type, code,
1890 code.error_goto_if_null(type.typeptr_cname, pos))
1891 self.use_type_import_utility_code(env)
1892 if type.vtabptr_cname:
1893 code.putln(
1894 "if (__Pyx_GetVtable(%s->tp_dict, &%s) < 0) %s" % (
1895 type.typeptr_cname,
1896 type.vtabptr_cname,
1897 code.error_goto(pos)))
1898 env.use_utility_code(Nodes.get_vtable_utility_code)
1899 env.types_imported[type] = 1
1901 py3_type_name_map = {'str' : 'bytes', 'unicode' : 'str'}
1903 def generate_type_import_call(self, type, code, error_code):
1904 if type.typedef_flag:
1905 objstruct = type.objstruct_cname
1906 else:
1907 objstruct = "struct %s" % type.objstruct_cname
1908 module_name = type.module_name
1909 if module_name not in ('__builtin__', 'builtins'):
1910 module_name = '"%s"' % module_name
1911 else:
1912 module_name = '__Pyx_BUILTIN_MODULE_NAME'
1913 if type.name in self.py3_type_name_map:
1914 code.putln("#if PY_MAJOR_VERSION >= 3")
1915 code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s)); %s' % (
1916 type.typeptr_cname,
1917 module_name,
1918 self.py3_type_name_map[type.name],
1919 objstruct,
1920 error_code))
1921 code.putln("#else")
1922 code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s)); %s' % (
1923 type.typeptr_cname,
1924 module_name,
1925 type.name,
1926 objstruct,
1927 error_code))
1928 if type.name in self.py3_type_name_map:
1929 code.putln("#endif")
1931 def generate_type_ready_code(self, env, entry, code):
1932 # Generate a call to PyType_Ready for an extension
1933 # type defined in this module.
1934 type = entry.type
1935 typeobj_cname = type.typeobj_cname
1936 scope = type.scope
1937 if scope: # could be None if there was an error
1938 if entry.visibility != 'extern':
1939 for slot in TypeSlots.slot_table:
1940 slot.generate_dynamic_init_code(scope, code)
1941 code.putln(
1942 "if (PyType_Ready(&%s) < 0) %s" % (
1943 typeobj_cname,
1944 code.error_goto(entry.pos)))
1945 if type.vtable_cname:
1946 code.putln(
1947 "if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
1948 typeobj_cname,
1949 type.vtabptr_cname,
1950 code.error_goto(entry.pos)))
1951 env.use_utility_code(Nodes.set_vtable_utility_code)
1952 code.putln(
1953 'if (__Pyx_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % (
1954 Naming.module_cname,
1955 scope.class_name,
1956 typeobj_cname,
1957 code.error_goto(entry.pos)))
1958 weakref_entry = scope.lookup_here("__weakref__")
1959 if weakref_entry:
1960 if weakref_entry.type is py_object_type:
1961 tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname
1962 code.putln("if (%s == 0) %s = offsetof(struct %s, %s);" % (
1963 tp_weaklistoffset,
1964 tp_weaklistoffset,
1965 type.objstruct_cname,
1966 weakref_entry.cname))
1967 else:
1968 error(weakref_entry.pos, "__weakref__ slot must be of type 'object'")
1970 def generate_exttype_vtable_init_code(self, entry, code):
1971 # Generate code to initialise the C method table of an
1972 # extension type.
1973 type = entry.type
1974 if type.vtable_cname:
1975 code.putln(
1976 "%s = &%s;" % (
1977 type.vtabptr_cname,
1978 type.vtable_cname))
1979 if type.base_type and type.base_type.vtabptr_cname:
1980 code.putln(
1981 "%s.%s = *%s;" % (
1982 type.vtable_cname,
1983 Naming.obj_base_cname,
1984 type.base_type.vtabptr_cname))
1986 c_method_entries = [
1987 entry for entry in type.scope.cfunc_entries
1988 if entry.func_cname ]
1989 if c_method_entries:
1990 code.putln('#if PY_MAJOR_VERSION >= 3')
1991 for meth_entry in c_method_entries:
1992 cast = meth_entry.type.signature_cast_string()
1993 code.putln(
1994 "%s.%s = %s%s;" % (
1995 type.vtable_cname,
1996 meth_entry.cname,
1997 cast,
1998 meth_entry.func_cname))
1999 code.putln('#else')
2000 for meth_entry in c_method_entries:
2001 code.putln(
2002 "*(void(**)(void))&%s.%s = (void(*)(void))%s;" % (
2003 type.vtable_cname,
2004 meth_entry.cname,
2005 meth_entry.func_cname))
2006 code.putln('#endif')
2008 def generate_typeptr_assignment_code(self, entry, code):
2009 # Generate code to initialise the typeptr of an extension
2010 # type defined in this module to point to its type object.
2011 type = entry.type
2012 if type.typeobj_cname:
2013 code.putln(
2014 "%s = &%s;" % (
2015 type.typeptr_cname, type.typeobj_cname))
2017 def generate_utility_functions(self, env, code, h_code):
2018 for codetup, name in env.utility_code_list:
2019 code.globalstate.use_utility_code(codetup, name)
2021 code.globalstate.put_utility_code_protos(h_code)
2022 code.putln("")
2023 code.putln("/* Runtime support code */")
2024 code.putln("")
2025 code.putln("static void %s(void) {" % Naming.fileinit_cname)
2026 code.putln("%s = %s;" %
2027 (Naming.filetable_cname, Naming.filenames_cname))
2028 code.putln("}")
2029 code.globalstate.put_utility_code_defs(code)
2030 code.put(PyrexTypes.type_conversion_functions)
2031 code.putln("")
2033 #------------------------------------------------------------------------------------
2035 # Runtime support code
2037 #------------------------------------------------------------------------------------
2039 builtin_module_name_utility_code = UtilityCode(
2040 proto = """\
2041 #if PY_MAJOR_VERSION < 3
2042 #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
2043 #else
2044 #define __Pyx_BUILTIN_MODULE_NAME "builtins"
2045 #endif
2046 """)
2048 #------------------------------------------------------------------------------------
2050 streq_utility_code = UtilityCode(
2051 proto = """
2052 static INLINE int __Pyx_StrEq(const char *, const char *); /*proto*/
2053 """,
2054 impl = """
2055 static INLINE int __Pyx_StrEq(const char *s1, const char *s2) {
2056 while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; }
2057 return *s1 == *s2;
2059 """)
2061 #------------------------------------------------------------------------------------
2063 import_module_utility_code = UtilityCode(
2064 proto = """
2065 static PyObject *__Pyx_ImportModule(const char *name); /*proto*/
2066 """,
2067 impl = """
2068 #ifndef __PYX_HAVE_RT_ImportModule
2069 #define __PYX_HAVE_RT_ImportModule
2070 static PyObject *__Pyx_ImportModule(const char *name) {
2071 PyObject *py_name = 0;
2072 PyObject *py_module = 0;
2074 #if PY_MAJOR_VERSION < 3
2075 py_name = PyString_FromString(name);
2076 #else
2077 py_name = PyUnicode_FromString(name);
2078 #endif
2079 if (!py_name)
2080 goto bad;
2081 py_module = PyImport_Import(py_name);
2082 Py_DECREF(py_name);
2083 return py_module;
2084 bad:
2085 Py_XDECREF(py_name);
2086 return 0;
2088 #endif
2089 """)
2091 #------------------------------------------------------------------------------------
2093 type_import_utility_code = UtilityCode(
2094 proto = """
2095 static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, long size); /*proto*/
2096 """,
2097 impl = """
2098 #ifndef __PYX_HAVE_RT_ImportType
2099 #define __PYX_HAVE_RT_ImportType
2100 static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
2101 long size)
2103 PyObject *py_module = 0;
2104 PyObject *result = 0;
2105 PyObject *py_name = 0;
2107 py_module = __Pyx_ImportModule(module_name);
2108 if (!py_module)
2109 goto bad;
2110 #if PY_MAJOR_VERSION < 3
2111 py_name = PyString_FromString(class_name);
2112 #else
2113 py_name = PyUnicode_FromString(class_name);
2114 #endif
2115 if (!py_name)
2116 goto bad;
2117 result = PyObject_GetAttr(py_module, py_name);
2118 Py_DECREF(py_name);
2119 py_name = 0;
2120 Py_DECREF(py_module);
2121 py_module = 0;
2122 if (!result)
2123 goto bad;
2124 if (!PyType_Check(result)) {
2125 PyErr_Format(PyExc_TypeError,
2126 "%s.%s is not a type object",
2127 module_name, class_name);
2128 goto bad;
2130 if (((PyTypeObject *)result)->tp_basicsize != size) {
2131 PyErr_Format(PyExc_ValueError,
2132 "%s.%s does not appear to be the correct type object",
2133 module_name, class_name);
2134 goto bad;
2136 return (PyTypeObject *)result;
2137 bad:
2138 Py_XDECREF(py_module);
2139 Py_XDECREF(result);
2140 return 0;
2142 #endif
2143 """)
2145 #------------------------------------------------------------------------------------
2147 function_export_utility_code = UtilityCode(
2148 proto = """
2149 static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *sig); /*proto*/
2150 """,
2151 impl = r"""
2152 static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *sig) {
2153 #if PY_VERSION_HEX < 0x02050000
2154 char *api = (char *)"%(API)s";
2155 #else
2156 const char *api = "%(API)s";
2157 #endif
2158 PyObject *d = 0;
2159 PyObject *cobj = 0;
2160 union {
2161 void (*fp)(void);
2162 void *p;
2163 } tmp;
2166 d = PyObject_GetAttrString(%(MODULE)s, api);
2167 if (!d) {
2168 PyErr_Clear();
2169 d = PyDict_New();
2170 if (!d)
2171 goto bad;
2172 Py_INCREF(d);
2173 if (PyModule_AddObject(%(MODULE)s, api, d) < 0)
2174 goto bad;
2176 tmp.fp = f;
2177 cobj = PyCObject_FromVoidPtrAndDesc(tmp.p, (void *)sig, 0);
2178 if (!cobj)
2179 goto bad;
2180 if (PyDict_SetItemString(d, name, cobj) < 0)
2181 goto bad;
2182 Py_DECREF(cobj);
2183 Py_DECREF(d);
2184 return 0;
2185 bad:
2186 Py_XDECREF(cobj);
2187 Py_XDECREF(d);
2188 return -1;
2190 """ % {'MODULE': Naming.module_cname, 'API': Naming.api_name}
2193 #------------------------------------------------------------------------------------
2195 function_import_utility_code = UtilityCode(
2196 proto = """
2197 static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig); /*proto*/
2198 """,
2199 impl = """
2200 #ifndef __PYX_HAVE_RT_ImportFunction
2201 #define __PYX_HAVE_RT_ImportFunction
2202 static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig) {
2203 #if PY_VERSION_HEX < 0x02050000
2204 char *api = (char *)"%(API)s";
2205 #else
2206 const char *api = "%(API)s";
2207 #endif
2208 PyObject *d = 0;
2209 PyObject *cobj = 0;
2210 const char *desc;
2211 const char *s1, *s2;
2212 union {
2213 void (*fp)(void);
2214 void *p;
2215 } tmp;
2217 d = PyObject_GetAttrString(module, api);
2218 if (!d)
2219 goto bad;
2220 cobj = PyDict_GetItemString(d, funcname);
2221 if (!cobj) {
2222 PyErr_Format(PyExc_ImportError,
2223 "%%s does not export expected C function %%s",
2224 PyModule_GetName(module), funcname);
2225 goto bad;
2227 desc = (const char *)PyCObject_GetDesc(cobj);
2228 if (!desc)
2229 goto bad;
2230 s1 = desc; s2 = sig;
2231 while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; }
2232 if (*s1 != *s2) {
2233 PyErr_Format(PyExc_TypeError,
2234 "C function %%s.%%s has wrong signature (expected %%s, got %%s)",
2235 PyModule_GetName(module), funcname, sig, desc);
2236 goto bad;
2238 tmp.p = PyCObject_AsVoidPtr(cobj);
2239 *f = tmp.fp;
2240 Py_DECREF(d);
2241 return 0;
2242 bad:
2243 Py_XDECREF(d);
2244 return -1;
2246 #endif
2247 """ % dict(API = Naming.api_name)
2250 register_cleanup_utility_code = UtilityCode(
2251 proto = """
2252 static int __Pyx_RegisterCleanup(void); /*proto*/
2253 static PyObject* __pyx_module_cleanup(PyObject *self, PyObject *unused); /*proto*/
2254 static PyMethodDef cleanup_def = {__Pyx_NAMESTR("__cleanup"), (PyCFunction)&__pyx_module_cleanup, METH_NOARGS, 0};
2255 """,
2256 impl = """
2257 static int __Pyx_RegisterCleanup(void) {
2258 /* Don't use Py_AtExit because that has a 32-call limit
2259 * and is called after python finalization.
2260 */
2262 PyObject *cleanup_func = 0;
2263 PyObject *atexit = 0;
2264 PyObject *reg = 0;
2265 PyObject *args = 0;
2266 PyObject *res = 0;
2267 int ret = -1;
2269 cleanup_func = PyCFunction_New(&cleanup_def, 0);
2270 args = PyTuple_New(1);
2271 if (!cleanup_func || !args)
2272 goto bad;
2273 PyTuple_SET_ITEM(args, 0, cleanup_func);
2274 cleanup_func = 0;
2276 atexit = __Pyx_ImportModule("atexit");
2277 if (!atexit)
2278 goto bad;
2279 reg = __Pyx_GetAttrString(atexit, "register");
2280 if (!reg)
2281 goto bad;
2282 res = PyObject_CallObject(reg, args);
2283 if (!res)
2284 goto bad;
2285 ret = 0;
2286 bad:
2287 Py_XDECREF(cleanup_func);
2288 Py_XDECREF(atexit);
2289 Py_XDECREF(reg);
2290 Py_XDECREF(args);
2291 Py_XDECREF(res);
2292 return ret;
2294 """)
2296 import_star_utility_code = """
2298 /* import_all_from is an unexposed function from ceval.c */
2300 static int
2301 __Pyx_import_all_from(PyObject *locals, PyObject *v)
2303 PyObject *all = __Pyx_GetAttrString(v, "__all__");
2304 PyObject *dict, *name, *value;
2305 int skip_leading_underscores = 0;
2306 int pos, err;
2308 if (all == NULL) {
2309 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
2310 return -1; /* Unexpected error */
2311 PyErr_Clear();
2312 dict = __Pyx_GetAttrString(v, "__dict__");
2313 if (dict == NULL) {
2314 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
2315 return -1;
2316 PyErr_SetString(PyExc_ImportError,
2317 "from-import-* object has no __dict__ and no __all__");
2318 return -1;
2320 all = PyMapping_Keys(dict);
2321 Py_DECREF(dict);
2322 if (all == NULL)
2323 return -1;
2324 skip_leading_underscores = 1;
2327 for (pos = 0, err = 0; ; pos++) {
2328 name = PySequence_GetItem(all, pos);
2329 if (name == NULL) {
2330 if (!PyErr_ExceptionMatches(PyExc_IndexError))
2331 err = -1;
2332 else
2333 PyErr_Clear();
2334 break;
2336 if (skip_leading_underscores &&
2337 #if PY_MAJOR_VERSION < 3
2338 PyString_Check(name) &&
2339 PyString_AS_STRING(name)[0] == '_')
2340 #else
2341 PyUnicode_Check(name) &&
2342 PyUnicode_AS_UNICODE(name)[0] == '_')
2343 #endif
2345 Py_DECREF(name);
2346 continue;
2348 value = PyObject_GetAttr(v, name);
2349 if (value == NULL)
2350 err = -1;
2351 else if (PyDict_CheckExact(locals))
2352 err = PyDict_SetItem(locals, name, value);
2353 else
2354 err = PyObject_SetItem(locals, name, value);
2355 Py_DECREF(name);
2356 Py_XDECREF(value);
2357 if (err != 0)
2358 break;
2360 Py_DECREF(all);
2361 return err;
2365 static int %(IMPORT_STAR)s(PyObject* m) {
2367 int i;
2368 int ret = -1;
2369 char* s;
2370 PyObject *locals = 0;
2371 PyObject *list = 0;
2372 PyObject *name;
2373 PyObject *item;
2375 locals = PyDict_New(); if (!locals) goto bad;
2376 if (__Pyx_import_all_from(locals, m) < 0) goto bad;
2377 list = PyDict_Items(locals); if (!list) goto bad;
2379 for(i=0; i<PyList_GET_SIZE(list); i++) {
2380 name = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 0);
2381 item = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 1);
2382 #if PY_MAJOR_VERSION < 3
2383 s = PyString_AsString(name);
2384 #else
2385 s = PyUnicode_AsString(name);
2386 #endif
2387 if (!s) goto bad;
2388 if (%(IMPORT_STAR_SET)s(item, name, s) < 0) goto bad;
2390 ret = 0;
2392 bad:
2393 Py_XDECREF(locals);
2394 Py_XDECREF(list);
2395 return ret;
2397 """ % {'IMPORT_STAR' : Naming.import_star,
2398 'IMPORT_STAR_SET' : Naming.import_star_set }
2400 refcount_utility_code = UtilityCode(proto="""
2401 #ifdef CYTHON_REFNANNY
2402 typedef struct {
2403 void (*INCREF)(void*, PyObject*, int);
2404 void (*DECREF)(void*, PyObject*, int);
2405 void (*GOTREF)(void*, PyObject*, int);
2406 void (*GIVEREF)(void*, PyObject*, int);
2407 void* (*NewContext)(const char*, int, const char*);
2408 void (*FinishContext)(void**);
2409 } __Pyx_RefnannyAPIStruct;
2410 static __Pyx_RefnannyAPIStruct *__Pyx_Refnanny = NULL;
2411 #define __Pyx_ImportRefcountAPI(name) \
2412 (__Pyx_RefnannyAPIStruct *) PyCObject_Import((char *)name, (char *)\"RefnannyAPI\")
2413 #define __Pyx_INCREF(r) __Pyx_Refnanny->INCREF(__pyx_refchk, (PyObject *)(r), __LINE__)
2414 #define __Pyx_DECREF(r) __Pyx_Refnanny->DECREF(__pyx_refchk, (PyObject *)(r), __LINE__)
2415 #define __Pyx_GOTREF(r) __Pyx_Refnanny->GOTREF(__pyx_refchk, (PyObject *)(r), __LINE__)
2416 #define __Pyx_GIVEREF(r) __Pyx_Refnanny->GIVEREF(__pyx_refchk, (PyObject *)(r), __LINE__)
2417 #define __Pyx_XDECREF(r) if((r) == NULL) ; else __Pyx_DECREF(r)
2418 #define __Pyx_SetupRefcountContext(name) \
2419 void* __pyx_refchk = __Pyx_Refnanny->NewContext((name), __LINE__, __FILE__)
2420 #define __Pyx_FinishRefcountContext() \
2421 __Pyx_Refnanny->FinishContext(&__pyx_refchk)
2422 #else
2423 #define __Pyx_INCREF(r) Py_INCREF(r)
2424 #define __Pyx_DECREF(r) Py_DECREF(r)
2425 #define __Pyx_GOTREF(r)
2426 #define __Pyx_GIVEREF(r)
2427 #define __Pyx_XDECREF(r) Py_XDECREF(r)
2428 #define __Pyx_SetupRefcountContext(name)
2429 #define __Pyx_FinishRefcountContext()
2430 #endif /* CYTHON_REFNANNY */
2431 #define __Pyx_XGIVEREF(r) if((r) == NULL) ; else __Pyx_GIVEREF(r)
2432 #define __Pyx_XGOTREF(r) if((r) == NULL) ; else __Pyx_GOTREF(r)
2433 """)