Cython has moved to github.

cython-devel

view Cython/Compiler/ModuleNode.py @ 1617:84a34fc5c19e

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