Cython has moved to github.

cython-devel

view Cython/Compiler/ModuleNode.py @ 1362:8c0c3784245e

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