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