Cython has moved to github.

cython-devel

view Cython/Compiler/ModuleNode.py @ 834:4695bbb3a785

Better integer literal parsing.

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