Cython has moved to github.

cython

view Cython/Compiler/ModuleNode.py @ 1149:7b8970eb4837

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