2 # Module parse tree node
6 cython
.declare(Naming
=object, Options
=object, PyrexTypes
=object, TypeSlots
=object,
7 error
=object, warning
=object, py_object_type
=object, UtilityCode
=object,
12 from PyrexTypes
import CPtrType
24 from Errors
import error
, warning
25 from PyrexTypes
import py_object_type
26 from Cython
.Utils
import open_new_file
, replace_suffix
, decode_filename
27 from Code
import UtilityCode
28 from StringEncoding
import EncodedString
32 def check_c_declarations_pxd(module_node
):
33 module_node
.scope
.check_c_classes_pxd()
36 def check_c_declarations(module_node
):
37 module_node
.scope
.check_c_classes()
38 module_node
.scope
.check_c_functions()
41 class ModuleNode(Nodes
.Node
, Nodes
.BlockNode
):
45 # referenced_modules [ModuleScope]
46 # full_module_name string
48 # scope The module scope.
49 # compilation_source A CompilationSource (see Main)
50 # directives Top-level compiler directives
52 child_attrs
= ["body"]
55 def merge_in(self
, tree
, scope
, merge_scope
=False):
56 # Merges in the contents of another tree, and possibly scope. With the
57 # current implementation below, this must be done right prior
60 # Note: This way of doing it seems strange -- I believe the
61 # right concept is to split ModuleNode into a ModuleNode and a
62 # CodeGenerator, and tell that CodeGenerator to generate code
63 # from multiple sources.
64 assert isinstance(self
.body
, Nodes
.StatListNode
)
65 if isinstance(tree
, Nodes
.StatListNode
):
66 self
.body
.stats
.extend(tree
.stats
)
68 self
.body
.stats
.append(tree
)
70 self
.scope
.utility_code_list
.extend(scope
.utility_code_list
)
72 def extend_if_not_in(L1
, L2
):
77 extend_if_not_in(self
.scope
.include_files
, scope
.include_files
)
78 extend_if_not_in(self
.scope
.included_files
, scope
.included_files
)
79 extend_if_not_in(self
.scope
.python_include_files
,
80 scope
.python_include_files
)
83 # Ensure that we don't generate import code for these entries!
84 for entry
in scope
.c_class_entries
:
85 entry
.type.module_name
= self
.full_module_name
86 entry
.type.scope
.directives
["internal"] = True
88 self
.scope
.merge_in(scope
)
90 def analyse_declarations(self
, env
):
91 if not Options
.docstrings
:
92 env
.doc
= self
.doc
= None
93 elif Options
.embed_pos_in_docstring
:
94 env
.doc
= EncodedString(u
'File: %s (starting at line %s)' % Nodes
.relative_position(self
.pos
))
95 if not self
.doc
is None:
96 env
.doc
= EncodedString(env
.doc
+ u
'\n' + self
.doc
)
97 env
.doc
.encoding
= self
.doc
.encoding
100 env
.directives
= self
.directives
101 self
.body
.analyse_declarations(env
)
103 def process_implementation(self
, options
, result
):
105 env
.return_type
= PyrexTypes
.c_void_type
106 self
.referenced_modules
= []
107 self
.find_referenced_modules(env
, self
.referenced_modules
, {})
108 self
.sort_cdef_classes(env
)
109 self
.generate_c_code(env
, options
, result
)
110 self
.generate_h_code(env
, options
, result
)
111 self
.generate_api_code(env
, result
)
113 def has_imported_c_functions(self
):
114 for module
in self
.referenced_modules
:
115 for entry
in module
.cfunc_entries
:
116 if entry
.defined_in_pxd
:
120 def generate_h_code(self
, env
, options
, result
):
121 def h_entries(entries
, api
=0, pxd
=0):
122 return [entry
for entry
in entries
123 if ((entry
.visibility
== 'public') or
124 (api
and entry
.api
) or
125 (pxd
and entry
.defined_in_pxd
))]
126 h_types
= h_entries(env
.type_entries
, api
=1)
127 h_vars
= h_entries(env
.var_entries
)
128 h_funcs
= h_entries(env
.cfunc_entries
)
129 h_extension_types
= h_entries(env
.c_class_entries
)
130 if (h_types
or h_vars
or h_funcs
or h_extension_types
):
131 result
.h_file
= replace_suffix(result
.c_file
, ".h")
132 h_code
= Code
.CCodeWriter()
133 Code
.GlobalState(h_code
, self
)
134 if options
.generate_pxi
:
135 result
.i_file
= replace_suffix(result
.c_file
, ".pxi")
136 i_code
= Code
.PyrexCodeWriter(result
.i_file
)
140 h_guard
= Naming
.h_guard_prefix
+ self
.api_name(env
)
141 h_code
.put_h_guard(h_guard
)
143 self
.generate_type_header_code(h_types
, h_code
)
144 if options
.capi_reexport_cincludes
:
145 self
.generate_includes(env
, [], h_code
)
147 api_guard
= Naming
.api_guard_prefix
+ self
.api_name(env
)
148 h_code
.putln("#ifndef %s" % api_guard
)
150 self
.generate_extern_c_macro_definition(h_code
)
151 if h_extension_types
:
153 for entry
in h_extension_types
:
154 self
.generate_cclass_header_code(entry
.type, h_code
)
156 self
.generate_cclass_include_code(entry
.type, i_code
)
159 for entry
in h_funcs
:
160 self
.generate_public_declaration(entry
, h_code
, i_code
)
164 self
.generate_public_declaration(entry
, h_code
, i_code
)
166 h_code
.putln("#endif /* !%s */" % api_guard
)
168 h_code
.putln("#if PY_MAJOR_VERSION < 3")
169 h_code
.putln("PyMODINIT_FUNC init%s(void);" % env
.module_name
)
170 h_code
.putln("#else")
171 h_code
.putln("PyMODINIT_FUNC PyInit_%s(void);" % env
.module_name
)
172 h_code
.putln("#endif")
174 h_code
.putln("#endif /* !%s */" % h_guard
)
176 f
= open_new_file(result
.h_file
)
182 def generate_public_declaration(self
, entry
, h_code
, i_code
):
183 h_code
.putln("%s %s;" % (
184 Naming
.extern_c_macro
,
185 entry
.type.declaration_code(
186 entry
.cname
, dll_linkage
= "DL_IMPORT")))
188 i_code
.putln("cdef extern %s" %
189 entry
.type.declaration_code(entry
.cname
, pyrex
= 1))
191 def api_name(self
, env
):
192 return env
.qualified_name
.replace(".", "__")
194 def generate_api_code(self
, env
, result
):
195 def api_entries(entries
, pxd
=0):
196 return [entry
for entry
in entries
197 if entry
.api
or (pxd
and entry
.defined_in_pxd
)]
198 api_vars
= api_entries(env
.var_entries
)
199 api_funcs
= api_entries(env
.cfunc_entries
)
200 api_extension_types
= api_entries(env
.c_class_entries
)
201 if api_vars
or api_funcs
or api_extension_types
:
202 result
.api_file
= replace_suffix(result
.c_file
, "_api.h")
203 h_code
= Code
.CCodeWriter()
204 Code
.GlobalState(h_code
, self
)
205 api_guard
= Naming
.api_guard_prefix
+ self
.api_name(env
)
206 h_code
.put_h_guard(api_guard
)
207 h_code
.putln('#include "Python.h"')
209 h_code
.putln('#include "%s"' % os
.path
.basename(result
.h_file
))
210 if api_extension_types
:
212 for entry
in api_extension_types
:
214 h_code
.putln("static PyTypeObject *%s = 0;" % type.typeptr_cname
)
215 h_code
.putln("#define %s (*%s)" % (
216 type.typeobj_cname
, type.typeptr_cname
))
219 for entry
in api_funcs
:
220 type = CPtrType(entry
.type)
221 cname
= env
.mangle(Naming
.func_prefix
, entry
.name
)
222 h_code
.putln("static %s = 0;" % type.declaration_code(cname
))
223 h_code
.putln("#define %s %s" % (entry
.name
, cname
))
226 for entry
in api_vars
:
227 type = CPtrType(entry
.type)
228 cname
= env
.mangle(Naming
.varptr_prefix
, entry
.name
)
229 h_code
.putln("static %s = 0;" % type.declaration_code(cname
))
230 h_code
.putln("#define %s (*%s)" % (entry
.name
, cname
))
231 h_code
.put(UtilityCode
.load_as_string("PyIdentifierFromString", "ImportExport.c")[0])
232 h_code
.put(UtilityCode
.load_as_string("ModuleImport", "ImportExport.c")[1])
234 h_code
.put(UtilityCode
.load_as_string("VoidPtrImport", "ImportExport.c")[1])
236 h_code
.put(UtilityCode
.load_as_string("FunctionImport", "ImportExport.c")[1])
237 if api_extension_types
:
238 h_code
.put(UtilityCode
.load_as_string("TypeImport", "ImportExport.c")[1])
240 h_code
.putln("static int import_%s(void) {" % self
.api_name(env
))
241 h_code
.putln("PyObject *module = 0;")
242 h_code
.putln('module = __Pyx_ImportModule("%s");' % env
.qualified_name
)
243 h_code
.putln("if (!module) goto bad;")
244 for entry
in api_funcs
:
245 cname
= env
.mangle(Naming
.func_prefix
, entry
.name
)
246 sig
= entry
.type.signature_string()
248 'if (__Pyx_ImportFunction(module, "%s", (void (**)(void))&%s, "%s") < 0) goto bad;'
249 % (entry
.name
, cname
, sig
))
250 for entry
in api_vars
:
251 cname
= env
.mangle(Naming
.varptr_prefix
, entry
.name
)
252 sig
= entry
.type.declaration_code("")
254 'if (__Pyx_ImportVoidPtr(module, "%s", (void **)&%s, "%s") < 0) goto bad;'
255 % (entry
.name
, cname
, sig
))
256 h_code
.putln("Py_DECREF(module); module = 0;")
257 for entry
in api_extension_types
:
258 self
.generate_type_import_call(
260 "if (!%s) goto bad;" % entry
.type.typeptr_cname
)
261 h_code
.putln("return 0;")
263 h_code
.putln("Py_XDECREF(module);")
264 h_code
.putln("return -1;")
267 h_code
.putln("#endif /* !%s */" % api_guard
)
269 f
= open_new_file(result
.api_file
)
275 def generate_cclass_header_code(self
, type, h_code
):
276 h_code
.putln("%s %s %s;" % (
277 Naming
.extern_c_macro
,
278 PyrexTypes
.public_decl("PyTypeObject", "DL_IMPORT"),
281 def generate_cclass_include_code(self
, type, i_code
):
282 i_code
.putln("cdef extern class %s.%s:" % (
283 type.module_name
, type.name
))
285 var_entries
= type.scope
.var_entries
287 for entry
in var_entries
:
288 i_code
.putln("cdef %s" %
289 entry
.type.declaration_code(entry
.cname
, pyrex
= 1))
294 def generate_c_code(self
, env
, options
, result
):
295 modules
= self
.referenced_modules
297 if Options
.annotate
or options
.annotate
:
298 emit_linenums
= False
299 rootwriter
= Annotate
.AnnotationCCodeWriter()
301 emit_linenums
= options
.emit_linenums
302 rootwriter
= Code
.CCodeWriter(emit_linenums
=emit_linenums
, c_line_in_traceback
=options
.c_line_in_traceback
)
303 globalstate
= Code
.GlobalState(rootwriter
, self
, emit_linenums
, options
.common_utility_include_dir
)
304 globalstate
.initialize_main_c_code()
305 h_code
= globalstate
['h_code']
307 self
.generate_module_preamble(env
, modules
, h_code
)
309 globalstate
.module_pos
= self
.pos
310 globalstate
.directives
= self
.directives
312 globalstate
.use_utility_code(refnanny_utility_code
)
314 code
= globalstate
['before_global_var']
315 code
.putln('#define __Pyx_MODULE_NAME "%s"' % self
.full_module_name
)
316 code
.putln("int %s%s = 0;" % (Naming
.module_is_main
, self
.full_module_name
.replace('.', '__')))
318 code
.putln("/* Implementation of '%s' */" % env
.qualified_name
)
320 code
= globalstate
['all_the_rest']
322 self
.generate_cached_builtins_decls(env
, code
)
323 self
.generate_lambda_definitions(env
, code
)
324 # generate normal variable and function definitions
325 self
.generate_variable_definitions(env
, code
)
326 self
.body
.generate_function_definitions(env
, code
)
328 self
.generate_typeobj_definitions(env
, code
)
329 self
.generate_method_table(env
, code
)
330 if env
.has_import_star
:
331 self
.generate_import_star(env
, code
)
332 self
.generate_pymoduledef_struct(env
, code
)
334 # init_globals is inserted before this
335 self
.generate_module_init_func(modules
[:-1], env
, globalstate
['init_module'])
336 self
.generate_module_cleanup_func(env
, globalstate
['cleanup_module'])
338 self
.generate_main_method(env
, globalstate
['main_method'])
339 self
.generate_filename_table(globalstate
['filename_table'])
341 self
.generate_declarations_for_modules(env
, modules
, globalstate
)
344 for utilcode
in env
.utility_code_list
[:]:
345 globalstate
.use_utility_code(utilcode
)
346 globalstate
.finalize_main_c_code()
348 f
= open_new_file(result
.c_file
)
353 result
.c_file_generated
= 1
354 if options
.gdb_debug
:
355 self
._serialize
_lineno
_map
(env
, rootwriter
)
356 if Options
.annotate
or options
.annotate
:
357 self
._generate
_annotations
(rootwriter
, result
)
359 def _generate_annotations(self
, rootwriter
, result
):
360 self
.annotate(rootwriter
)
361 rootwriter
.save_annotation(result
.main_source_file
, result
.c_file
)
363 # if we included files, additionally generate one annotation file for each
364 if not self
.scope
.included_files
:
367 search_include_file
= self
.scope
.context
.search_include_directories
368 target_dir
= os
.path
.abspath(os
.path
.dirname(result
.c_file
))
369 for included_file
in self
.scope
.included_files
:
370 target_file
= os
.path
.abspath(os
.path
.join(target_dir
, included_file
))
371 target_file_dir
= os
.path
.dirname(target_file
)
372 if not target_file_dir
.startswith(target_dir
):
373 # any other directories may not be writable => avoid trying
375 source_file
= search_include_file(included_file
, "", self
.pos
, include
=True)
378 if target_file_dir
!= target_dir
and not os
.path
.exists(target_file_dir
):
380 os
.makedirs(target_file_dir
)
383 if e
.errno
!= errno
.EEXIST
:
385 rootwriter
.save_annotation(source_file
, target_file
)
387 def _serialize_lineno_map(self
, env
, ccodewriter
):
388 tb
= env
.context
.gdb_debug_outputwriter
389 markers
= ccodewriter
.buffer.allmarkers()
392 for c_lineno
, cython_lineno
in enumerate(markers
):
393 if cython_lineno
> 0:
394 d
.setdefault(cython_lineno
, []).append(c_lineno
+ 1)
396 tb
.start('LineNumberMapping')
397 for cython_lineno
, c_linenos
in sorted(d
.iteritems()):
399 'c_linenos': ' '.join(map(str, c_linenos
)),
400 'cython_lineno': str(cython_lineno
),
402 tb
.start('LineNumber', attrs
)
404 tb
.end('LineNumberMapping')
407 def find_referenced_modules(self
, env
, module_list
, modules_seen
):
408 if env
not in modules_seen
:
409 modules_seen
[env
] = 1
410 for imported_module
in env
.cimported_modules
:
411 self
.find_referenced_modules(imported_module
, module_list
, modules_seen
)
412 module_list
.append(env
)
414 def sort_types_by_inheritance(self
, type_dict
, type_order
, getkey
):
415 # copy the types into a list moving each parent type before
418 for i
, key
in enumerate(type_order
):
419 new_entry
= type_dict
[key
]
421 # collect all base classes to check for children
425 base_type
= base
.type.base_type
428 base_key
= getkey(base_type
)
429 hierarchy
.add(base_key
)
430 base
= type_dict
.get(base_key
)
431 new_entry
.base_keys
= hierarchy
433 # find the first (sub-)subclass and insert before that
436 if key
in entry
.base_keys
:
437 type_list
.insert(j
, new_entry
)
440 type_list
.append(new_entry
)
443 def sort_type_hierarchy(self
, module_list
, env
):
444 # poor developer's OrderedDict
445 vtab_dict
, vtab_dict_order
= {}, []
446 vtabslot_dict
, vtabslot_dict_order
= {}, []
448 for module
in module_list
:
449 for entry
in module
.c_class_entries
:
450 if entry
.used
and not entry
.in_cinclude
:
452 key
= type.vtabstruct_cname
456 # FIXME: this should *never* happen, but apparently it does
457 # for Cython generated utility code
458 from Cython
.Compiler
.UtilityCode
import NonManglingModuleScope
459 assert isinstance(entry
.scope
, NonManglingModuleScope
), str(entry
.scope
)
460 assert isinstance(vtab_dict
[key
].scope
, NonManglingModuleScope
), str(vtab_dict
[key
].scope
)
462 vtab_dict
[key
] = entry
463 vtab_dict_order
.append(key
)
464 all_defined_here
= module
is env
465 for entry
in module
.type_entries
:
466 if entry
.used
and (all_defined_here
or entry
.defined_in_pxd
):
468 if type.is_extension_type
and not entry
.in_cinclude
:
470 key
= type.objstruct_cname
471 assert key
not in vtabslot_dict
, key
472 vtabslot_dict
[key
] = entry
473 vtabslot_dict_order
.append(key
)
475 def vtabstruct_cname(entry_type
):
476 return entry_type
.vtabstruct_cname
477 vtab_list
= self
.sort_types_by_inheritance(
478 vtab_dict
, vtab_dict_order
, vtabstruct_cname
)
480 def objstruct_cname(entry_type
):
481 return entry_type
.objstruct_cname
482 vtabslot_list
= self
.sort_types_by_inheritance(
483 vtabslot_dict
, vtabslot_dict_order
, objstruct_cname
)
485 return (vtab_list
, vtabslot_list
)
487 def sort_cdef_classes(self
, env
):
488 key_func
= operator
.attrgetter('objstruct_cname')
489 entry_dict
, entry_order
= {}, []
490 for entry
in env
.c_class_entries
:
491 key
= key_func(entry
.type)
492 assert key
not in entry_dict
, key
493 entry_dict
[key
] = entry
494 entry_order
.append(key
)
495 env
.c_class_entries
[:] = self
.sort_types_by_inheritance(
496 entry_dict
, entry_order
, key_func
)
498 def generate_type_definitions(self
, env
, modules
, vtab_list
, vtabslot_list
, code
):
499 # TODO: Why are these separated out?
500 for entry
in vtabslot_list
:
501 self
.generate_objstruct_predeclaration(entry
.type, code
)
502 vtabslot_entries
= set(vtabslot_list
)
503 for module
in modules
:
504 definition
= module
is env
506 type_entries
= module
.type_entries
509 for entry
in module
.type_entries
:
510 if entry
.defined_in_pxd
:
511 type_entries
.append(entry
)
512 type_entries
= [t
for t
in type_entries
if t
not in vtabslot_entries
]
513 self
.generate_type_header_code(type_entries
, code
)
514 for entry
in vtabslot_list
:
515 self
.generate_objstruct_definition(entry
.type, code
)
516 self
.generate_typeobj_predeclaration(entry
, code
)
517 for entry
in vtab_list
:
518 self
.generate_typeobj_predeclaration(entry
, code
)
519 self
.generate_exttype_vtable_struct(entry
, code
)
520 self
.generate_exttype_vtabptr_declaration(entry
, code
)
521 self
.generate_exttype_final_methods_declaration(entry
, code
)
523 def generate_declarations_for_modules(self
, env
, modules
, globalstate
):
524 typecode
= globalstate
['type_declarations']
526 typecode
.putln("/*--- Type declarations ---*/")
527 # This is to work around the fact that array.h isn't part of the C-API,
528 # but we need to declare it earlier than utility code.
529 if 'cpython.array' in [m
.qualified_name
for m
in modules
]:
530 typecode
.putln('#ifndef _ARRAYARRAY_H')
531 typecode
.putln('struct arrayobject;')
532 typecode
.putln('typedef struct arrayobject arrayobject;')
533 typecode
.putln('#endif')
534 vtab_list
, vtabslot_list
= self
.sort_type_hierarchy(modules
, env
)
535 self
.generate_type_definitions(
536 env
, modules
, vtab_list
, vtabslot_list
, typecode
)
537 modulecode
= globalstate
['module_declarations']
538 for module
in modules
:
539 defined_here
= module
is env
541 modulecode
.putln("/* Module declarations from '%s' */" % module
.qualified_name
)
542 self
.generate_c_class_declarations(module
, modulecode
, defined_here
)
543 self
.generate_cvariable_declarations(module
, modulecode
, defined_here
)
544 self
.generate_cfunction_declarations(module
, modulecode
, defined_here
)
546 def generate_module_preamble(self
, env
, cimported_modules
, code
):
547 code
.putln("/* Generated by Cython %s */" % Version
.watermark
)
549 code
.putln("#define PY_SSIZE_T_CLEAN")
551 # sizeof(PyLongObject.ob_digit[0]) may have been determined dynamically
552 # at compile time in CPython, in which case we can't know the correct
553 # storage size for an installed system. We can rely on it only if
554 # pyconfig.h defines it statically, i.e. if it was set by "configure".
555 # Once we include "Python.h", it will come up with its own idea about
556 # a suitable value, which may or may not match the real one.
557 code
.putln("#ifndef CYTHON_USE_PYLONG_INTERNALS")
558 code
.putln("#ifdef PYLONG_BITS_IN_DIGIT")
559 # assume it's an incorrect left-over
560 code
.putln("#define CYTHON_USE_PYLONG_INTERNALS 0")
562 code
.putln('#include "pyconfig.h"')
563 code
.putln("#ifdef PYLONG_BITS_IN_DIGIT")
564 code
.putln("#define CYTHON_USE_PYLONG_INTERNALS 1")
566 code
.putln("#define CYTHON_USE_PYLONG_INTERNALS 0")
571 for filename
in env
.python_include_files
:
572 code
.putln('#include "%s"' % filename
)
573 code
.putln("#ifndef Py_PYTHON_H")
574 code
.putln(" #error Python headers needed to compile C extensions, please install development version of Python.")
575 code
.putln("#elif PY_VERSION_HEX < 0x02040000")
576 code
.putln(" #error Cython requires Python 2.4+.")
578 code
.globalstate
["end"].putln("#endif /* Py_PYTHON_H */")
580 from Cython
import __version__
581 code
.putln('#define CYTHON_ABI "%s"' % __version__
.replace('.', '_'))
583 code
.put(UtilityCode
.load_as_string("CModulePreamble", "ModuleSetupCode.c")[1])
586 #if PY_MAJOR_VERSION >= 3
587 #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)
588 #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)
591 if Future
.division
in env
.context
.future_directives
:
592 code
.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)")
593 code
.putln(" #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)")
595 code
.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)")
596 code
.putln(" #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)")
600 self
.generate_extern_c_macro_definition(code
)
603 code
.putln("#if defined(WIN32) || defined(MS_WINDOWS)")
604 code
.putln("#define _USE_MATH_DEFINES")
606 code
.putln("#include <math.h>")
608 code
.putln("#define %s" % Naming
.h_guard_prefix
+ self
.api_name(env
))
609 code
.putln("#define %s" % Naming
.api_guard_prefix
+ self
.api_name(env
))
610 self
.generate_includes(env
, cimported_modules
, code
)
612 code
.putln("#ifdef PYREX_WITHOUT_ASSERTIONS")
613 code
.putln("#define CYTHON_WITHOUT_ASSERTIONS")
617 if env
.directives
['ccomplex']:
619 code
.putln("#if !defined(CYTHON_CCOMPLEX)")
620 code
.putln("#define CYTHON_CCOMPLEX 1")
623 code
.put(UtilityCode
.load_as_string("UtilityFunctionPredeclarations", "ModuleSetupCode.c")[0])
625 c_string_type
= env
.directives
['c_string_type']
626 c_string_encoding
= env
.directives
['c_string_encoding']
627 if c_string_type
not in ('bytes', 'bytearray') and not c_string_encoding
:
628 error(self
.pos
, "a default encoding must be provided if c_string_type is not a byte type")
629 code
.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII %s' % int(c_string_encoding
== 'ascii'))
630 if c_string_encoding
== 'default':
631 code
.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 1')
633 code
.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0')
634 code
.putln('#define __PYX_DEFAULT_STRING_ENCODING "%s"' % c_string_encoding
)
635 if c_string_type
== 'bytearray':
636 c_string_func_name
= 'ByteArray'
638 c_string_func_name
= c_string_type
.title()
639 code
.putln('#define __Pyx_PyObject_FromString __Pyx_Py%s_FromString' % c_string_func_name
)
640 code
.putln('#define __Pyx_PyObject_FromStringAndSize __Pyx_Py%s_FromStringAndSize' % c_string_func_name
)
641 code
.put(UtilityCode
.load_as_string("TypeConversions", "TypeConversion.c")[0])
643 # These utility functions are assumed to exist and used elsewhere.
644 PyrexTypes
.c_long_type
.create_to_py_utility_code(env
)
645 PyrexTypes
.c_long_type
.create_from_py_utility_code(env
)
646 PyrexTypes
.c_int_type
.create_from_py_utility_code(env
)
648 code
.put(Nodes
.branch_prediction_macros
)
650 code
.putln('static PyObject *%s;' % env
.module_cname
)
651 code
.putln('static PyObject *%s;' % env
.module_dict_cname
)
652 code
.putln('static PyObject *%s;' % Naming
.builtins_cname
)
653 code
.putln('static PyObject *%s;' % Naming
.empty_tuple
)
654 code
.putln('static PyObject *%s;' % Naming
.empty_bytes
)
655 if Options
.pre_import
is not None:
656 code
.putln('static PyObject *%s;' % Naming
.preimport_cname
)
657 code
.putln('static int %s;' % Naming
.lineno_cname
)
658 code
.putln('static int %s = 0;' % Naming
.clineno_cname
)
659 code
.putln('static const char * %s= %s;' % (Naming
.cfilenm_cname
, Naming
.file_c_macro
))
660 code
.putln('static const char *%s;' % Naming
.filename_cname
)
662 def generate_extern_c_macro_definition(self
, code
):
663 name
= Naming
.extern_c_macro
664 code
.putln("#ifndef %s" % name
)
665 code
.putln(" #ifdef __cplusplus")
666 code
.putln(' #define %s extern "C"' % name
)
668 code
.putln(" #define %s extern" % name
)
669 code
.putln(" #endif")
672 def generate_includes(self
, env
, cimported_modules
, code
):
674 for filename
in env
.include_files
:
675 byte_decoded_filenname
= str(filename
)
676 if byte_decoded_filenname
[0] == '<' and byte_decoded_filenname
[-1] == '>':
677 code
.putln('#include %s' % byte_decoded_filenname
)
679 code
.putln('#include "%s"' % byte_decoded_filenname
)
681 code
.putln_openmp("#include <omp.h>")
683 def generate_filename_table(self
, code
):
685 code
.putln("static const char *%s[] = {" % Naming
.filetable_cname
)
686 if code
.globalstate
.filename_list
:
687 for source_desc
in code
.globalstate
.filename_list
:
688 filename
= os
.path
.basename(source_desc
.get_filenametable_entry())
689 escaped_filename
= filename
.replace("\\", "\\\\").replace('"', r
'\"')
690 code
.putln('"%s",' % escaped_filename
)
692 # Some C compilers don't like an empty array
696 def generate_type_predeclarations(self
, env
, code
):
699 def generate_type_header_code(self
, type_entries
, code
):
700 # Generate definitions of structs/unions/enums/typedefs/objstructs.
701 #self.generate_gcc33_hack(env, code) # Is this still needed?
702 # Forward declarations
703 for entry
in type_entries
:
704 if not entry
.in_cinclude
:
705 #print "generate_type_header_code:", entry.name, repr(entry.type) ###
707 if type.is_typedef
: # Must test this first!
709 elif type.is_struct_or_union
or type.is_cpp_class
:
710 self
.generate_struct_union_predeclaration(entry
, code
)
711 elif type.is_extension_type
:
712 self
.generate_objstruct_predeclaration(type, code
)
713 # Actual declarations
714 for entry
in type_entries
:
715 if not entry
.in_cinclude
:
716 #print "generate_type_header_code:", entry.name, repr(entry.type) ###
718 if type.is_typedef
: # Must test this first!
719 self
.generate_typedef(entry
, code
)
721 self
.generate_enum_definition(entry
, code
)
722 elif type.is_struct_or_union
:
723 self
.generate_struct_union_definition(entry
, code
)
724 elif type.is_cpp_class
:
725 self
.generate_cpp_class_definition(entry
, code
)
726 elif type.is_extension_type
:
727 self
.generate_objstruct_definition(type, code
)
729 def generate_gcc33_hack(self
, env
, code
):
730 # Workaround for spurious warning generation in gcc 3.3
732 for entry
in env
.c_class_entries
:
734 if not type.typedef_flag
:
735 name
= type.objstruct_cname
736 if name
.startswith("__pyx_"):
740 code
.putln("typedef struct %s __pyx_gcc33_%s;" % (
743 def generate_typedef(self
, entry
, code
):
744 base_type
= entry
.type.typedef_base_type
745 if base_type
.is_numeric
:
747 writer
= code
.globalstate
['numeric_typedefs']
752 writer
.mark_pos(entry
.pos
)
753 writer
.putln("typedef %s;" % base_type
.declaration_code(entry
.cname
))
755 def sue_predeclaration(self
, type, kind
, name
):
756 if type.typedef_flag
:
757 return "%s %s;\ntypedef %s %s %s;" % (
761 return "%s %s;" % (kind
, name
)
763 def generate_struct_union_predeclaration(self
, entry
, code
):
765 if type.is_cpp_class
and type.templates
:
766 code
.putln("template <typename %s>" % ", typename ".join([T
.declaration_code("") for T
in type.templates
]))
767 code
.putln(self
.sue_predeclaration(type, type.kind
, type.cname
))
769 def sue_header_footer(self
, type, kind
, name
):
770 header
= "%s %s {" % (kind
, name
)
772 return header
, footer
774 def generate_struct_union_definition(self
, entry
, code
):
775 code
.mark_pos(entry
.pos
)
780 packed
= type.is_struct
and type.packed
782 kind
= "%s %s" % (type.kind
, "__Pyx_PACKED")
783 code
.globalstate
.use_utility_code(packed_struct_utility_code
)
785 self
.sue_header_footer(type, kind
, type.cname
)
787 code
.putln("#if defined(__SUNPRO_C)")
788 code
.putln(" #pragma pack(1)")
789 code
.putln("#elif !defined(__GNUC__)")
790 code
.putln(" #pragma pack(push, 1)")
793 var_entries
= scope
.var_entries
796 "Empty struct or union definition not allowed outside a"
797 " 'cdef extern from' block")
798 for attr
in var_entries
:
801 attr
.type.declaration_code(attr
.cname
))
804 code
.putln("#if defined(__SUNPRO_C)")
805 code
.putln(" #pragma pack()")
806 code
.putln("#elif !defined(__GNUC__)")
807 code
.putln(" #pragma pack(pop)")
810 def generate_cpp_class_definition(self
, entry
, code
):
811 code
.mark_pos(entry
.pos
)
816 code
.putln("template <class %s>" % ", class ".join([T
.declaration_code("") for T
in type.templates
]))
817 # Just let everything be public.
818 code
.put("struct %s" % type.cname
)
819 if type.base_classes
:
820 base_class_decl
= ", public ".join(
821 [base_class
.declaration_code("") for base_class
in type.base_classes
])
822 code
.put(" : public %s" % base_class_decl
)
824 has_virtual_methods
= False
825 has_destructor
= False
826 for attr
in scope
.var_entries
:
827 if attr
.type.is_cfunction
and attr
.name
!= "<init>":
829 has_virtual_methods
= True
830 if attr
.cname
[0] == '~':
831 has_destructor
= True
834 attr
.type.declaration_code(attr
.cname
))
835 if has_virtual_methods
and not has_destructor
:
836 code
.put("virtual ~%s() { }" % type.cname
)
839 def generate_enum_definition(self
, entry
, code
):
840 code
.mark_pos(entry
.pos
)
842 name
= entry
.cname
or entry
.name
or ""
844 self
.sue_header_footer(type, "enum", name
)
846 enum_values
= entry
.enum_values
849 "Empty enum definition not allowed outside a"
850 " 'cdef extern from' block")
852 last_entry
= enum_values
[-1]
853 # this does not really generate code, just builds the result value
854 for value_entry
in enum_values
:
855 if value_entry
.value_node
is not None:
856 value_entry
.value_node
.generate_evaluation_code(code
)
858 for value_entry
in enum_values
:
859 if value_entry
.value_node
is None:
860 value_code
= value_entry
.cname
862 value_code
= ("%s = %s" % (
864 value_entry
.value_node
.result()))
865 if value_entry
is not last_entry
:
867 code
.putln(value_code
)
869 if entry
.type.typedef_flag
:
871 code
.putln("typedef enum %s %s;" % (name
, name
))
873 def generate_typeobj_predeclaration(self
, entry
, code
):
875 name
= entry
.type.typeobj_cname
877 if entry
.visibility
== 'extern' and not entry
.in_cinclude
:
878 code
.putln("%s %s %s;" % (
879 Naming
.extern_c_macro
,
880 PyrexTypes
.public_decl("PyTypeObject", "DL_IMPORT"),
882 elif entry
.visibility
== 'public':
883 code
.putln("%s %s %s;" % (
884 Naming
.extern_c_macro
,
885 PyrexTypes
.public_decl("PyTypeObject", "DL_EXPORT"),
887 # ??? Do we really need the rest of this? ???
889 # code.putln("static PyTypeObject %s;" % name)
891 def generate_exttype_vtable_struct(self
, entry
, code
):
895 code
.mark_pos(entry
.pos
)
896 # Generate struct declaration for an extension type's vtable.
900 self
.specialize_fused_types(scope
)
902 if type.vtabstruct_cname
:
906 type.vtabstruct_cname
)
907 if type.base_type
and type.base_type
.vtabstruct_cname
:
908 code
.putln("struct %s %s;" % (
909 type.base_type
.vtabstruct_cname
,
910 Naming
.obj_base_cname
))
911 for method_entry
in scope
.cfunc_entries
:
912 if not method_entry
.is_inherited
:
914 "%s;" % method_entry
.type.declaration_code("(*%s)" % method_entry
.cname
))
918 def generate_exttype_vtabptr_declaration(self
, entry
, code
):
922 code
.mark_pos(entry
.pos
)
923 # Generate declaration of pointer to an extension type's vtable.
925 if type.vtabptr_cname
:
926 code
.putln("static struct %s *%s;" % (
927 type.vtabstruct_cname
,
930 def generate_exttype_final_methods_declaration(self
, entry
, code
):
934 code
.mark_pos(entry
.pos
)
935 # Generate final methods prototypes
937 for method_entry
in entry
.type.scope
.cfunc_entries
:
938 if not method_entry
.is_inherited
and method_entry
.final_func_cname
:
939 declaration
= method_entry
.type.declaration_code(
940 method_entry
.final_func_cname
)
941 modifiers
= code
.build_function_modifiers(method_entry
.func_modifiers
)
942 code
.putln("static %s%s;" % (modifiers
, declaration
))
944 def generate_objstruct_predeclaration(self
, type, code
):
947 code
.putln(self
.sue_predeclaration(type, "struct", type.objstruct_cname
))
949 def generate_objstruct_definition(self
, type, code
):
950 code
.mark_pos(type.pos
)
951 # Generate object struct definition for an
954 return # Forward declared but never defined
956 self
.sue_header_footer(type, "struct", type.objstruct_cname
)
958 base_type
= type.base_type
960 basestruct_cname
= base_type
.objstruct_cname
961 if basestruct_cname
== "PyTypeObject":
962 # User-defined subclasses of type are heap allocated.
963 basestruct_cname
= "PyHeapTypeObject"
966 ("struct ", "")[base_type
.typedef_flag
],
968 Naming
.obj_base_cname
))
972 if type.vtabslot_cname
and not (type.base_type
and type.base_type
.vtabslot_cname
):
975 type.vtabstruct_cname
,
976 type.vtabslot_cname
))
977 for attr
in type.scope
.var_entries
:
978 if attr
.is_declared_generic
:
979 attr_type
= py_object_type
981 attr_type
= attr
.type
984 attr_type
.declaration_code(attr
.cname
))
986 if type.objtypedef_cname
is not None:
987 # Only for exposing public typedef name.
988 code
.putln("typedef struct %s %s;" % (type.objstruct_cname
, type.objtypedef_cname
))
990 def generate_c_class_declarations(self
, env
, code
, definition
):
991 for entry
in env
.c_class_entries
:
992 if definition
or entry
.defined_in_pxd
:
993 code
.putln("static PyTypeObject *%s = 0;" %
994 entry
.type.typeptr_cname
)
996 def generate_cvariable_declarations(self
, env
, code
, definition
):
997 if env
.is_cython_builtin
:
999 for entry
in env
.var_entries
:
1000 if (entry
.in_cinclude
or entry
.in_closure
or
1001 (entry
.visibility
== 'private' and
1002 not (entry
.defined_in_pxd
or entry
.used
))):
1005 storage_class
= None
1010 if entry
.visibility
== 'extern':
1011 storage_class
= Naming
.extern_c_macro
1012 dll_linkage
= "DL_IMPORT"
1013 elif entry
.visibility
== 'public':
1014 storage_class
= Naming
.extern_c_macro
1016 dll_linkage
= "DL_EXPORT"
1018 dll_linkage
= "DL_IMPORT"
1019 elif entry
.visibility
== 'private':
1020 storage_class
= "static"
1022 if entry
.init
is not None:
1023 init
= entry
.type.literal_code(entry
.init
)
1027 if entry
.defined_in_pxd
and not definition
:
1028 storage_class
= "static"
1030 type = CPtrType(type)
1031 cname
= env
.mangle(Naming
.varptr_prefix
, entry
.name
)
1035 code
.put("%s " % storage_class
)
1036 code
.put(type.declaration_code(
1037 cname
, dll_linkage
= dll_linkage
))
1038 if init
is not None:
1039 code
.put_safe(" = %s" % init
)
1041 if entry
.cname
!= cname
:
1042 code
.putln("#define %s (*%s)" % (entry
.cname
, cname
))
1044 def generate_cfunction_declarations(self
, env
, code
, definition
):
1045 for entry
in env
.cfunc_entries
:
1046 if entry
.used
or (entry
.visibility
== 'public' or entry
.api
):
1047 generate_cfunction_declaration(entry
, env
, code
, definition
)
1049 def generate_variable_definitions(self
, env
, code
):
1050 for entry
in env
.var_entries
:
1051 if (not entry
.in_cinclude
and
1052 entry
.visibility
== "public"):
1053 code
.put(entry
.type.declaration_code(entry
.cname
))
1054 if entry
.init
is not None:
1055 init
= entry
.type.literal_code(entry
.init
)
1056 code
.put_safe(" = %s" % init
)
1059 def generate_typeobj_definitions(self
, env
, code
):
1060 full_module_name
= env
.qualified_name
1061 for entry
in env
.c_class_entries
:
1062 #print "generate_typeobj_definitions:", entry.name
1063 #print "...visibility =", entry.visibility
1064 if entry
.visibility
!= 'extern':
1067 if scope
: # could be None if there was an error
1068 self
.generate_exttype_vtable(scope
, code
)
1069 self
.generate_new_function(scope
, code
, entry
)
1070 self
.generate_dealloc_function(scope
, code
)
1071 if scope
.needs_gc():
1072 self
.generate_traverse_function(scope
, code
, entry
)
1073 if scope
.needs_tp_clear():
1074 self
.generate_clear_function(scope
, code
, entry
)
1075 if scope
.defines_any(["__getitem__"]):
1076 self
.generate_getitem_int_function(scope
, code
)
1077 if scope
.defines_any(["__setitem__", "__delitem__"]):
1078 self
.generate_ass_subscript_function(scope
, code
)
1079 if scope
.defines_any(["__getslice__", "__setslice__", "__delslice__"]):
1080 warning(self
.pos
, "__getslice__, __setslice__, and __delslice__ are not supported by Python 3, use __getitem__, __setitem__, and __delitem__ instead", 1)
1081 code
.putln("#if PY_MAJOR_VERSION >= 3")
1082 code
.putln("#error __getslice__, __setslice__, and __delslice__ not supported in Python 3.")
1083 code
.putln("#endif")
1084 if scope
.defines_any(["__setslice__", "__delslice__"]):
1085 self
.generate_ass_slice_function(scope
, code
)
1086 if scope
.defines_any(["__getattr__","__getattribute__"]):
1087 self
.generate_getattro_function(scope
, code
)
1088 if scope
.defines_any(["__setattr__", "__delattr__"]):
1089 self
.generate_setattro_function(scope
, code
)
1090 if scope
.defines_any(["__get__"]):
1091 self
.generate_descr_get_function(scope
, code
)
1092 if scope
.defines_any(["__set__", "__delete__"]):
1093 self
.generate_descr_set_function(scope
, code
)
1094 self
.generate_property_accessors(scope
, code
)
1095 self
.generate_method_table(scope
, code
)
1096 self
.generate_getset_table(scope
, code
)
1097 self
.generate_typeobj_definition(full_module_name
, entry
, code
)
1099 def generate_exttype_vtable(self
, scope
, code
):
1100 # Generate the definition of an extension type's vtable.
1101 type = scope
.parent_type
1102 if type.vtable_cname
:
1103 code
.putln("static struct %s %s;" % (
1104 type.vtabstruct_cname
,
1107 def generate_self_cast(self
, scope
, code
):
1108 type = scope
.parent_type
1111 type.declaration_code("p"),
1112 type.declaration_code("")))
1114 def generate_new_function(self
, scope
, code
, cclass_entry
):
1115 tp_slot
= TypeSlots
.ConstructorSlot("tp_new", '__new__')
1116 slot_func
= scope
.mangle_internal("tp_new")
1117 type = scope
.parent_type
1118 base_type
= type.base_type
1120 have_entries
, (py_attrs
, py_buffers
, memoryview_slices
) = \
1121 scope
.get_refcounted_entries()
1122 is_final_type
= scope
.parent_type
.is_final_type
1123 if scope
.is_internal
:
1124 # internal classes (should) never need None inits, normal zeroing will do
1126 cpp_class_attrs
= [entry
for entry
in scope
.var_entries
1127 if entry
.type.is_cpp_class
]
1129 new_func_entry
= scope
.lookup_here("__new__")
1130 if base_type
or (new_func_entry
and new_func_entry
.is_special
1131 and not new_func_entry
.trivial_signature
):
1134 unused_marker
= 'CYTHON_UNUSED '
1137 freelist_size
= 0 # not currently supported
1139 freelist_size
= scope
.directives
.get('freelist', 0)
1140 freelist_name
= scope
.mangle_internal(Naming
.freelist_name
)
1141 freecount_name
= scope
.mangle_internal(Naming
.freecount_name
)
1143 decls
= code
.globalstate
['decls']
1144 decls
.putln("static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/" %
1148 code
.putln("static %s[%d];" % (
1149 scope
.parent_type
.declaration_code(freelist_name
),
1151 code
.putln("static int %s = 0;" % freecount_name
)
1154 "static PyObject *%s(PyTypeObject *t, %sPyObject *a, %sPyObject *k) {"
1155 % (slot_func
, unused_marker
, unused_marker
))
1157 need_self_cast
= (type.vtabslot_cname
or
1158 (py_buffers
or memoryview_slices
or py_attrs
) or
1161 code
.putln("%s;" % scope
.parent_type
.declaration_code("p"))
1163 tp_new
= TypeSlots
.get_base_slot_function(scope
, tp_slot
)
1165 tp_new
= "%s->tp_new" % base_type
.typeptr_cname
1166 code
.putln("PyObject *o = %s(t, a, k);" % tp_new
)
1168 code
.putln("PyObject *o;")
1170 code
.globalstate
.use_utility_code(
1171 UtilityCode
.load_cached("IncludeStringH", "StringTools.c"))
1173 type_safety_check
= ''
1175 type_safety_check
= ' & ((t->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)) == 0)'
1176 obj_struct
= type.declaration_code("", deref
=True)
1177 code
.putln("if (CYTHON_COMPILING_IN_CPYTHON && likely((%s > 0) & (t->tp_basicsize == sizeof(%s))%s)) {" % (
1178 freecount_name
, obj_struct
, type_safety_check
))
1179 code
.putln("o = (PyObject*)%s[--%s];" % (
1180 freelist_name
, freecount_name
))
1181 code
.putln("memset(o, 0, sizeof(%s));" % obj_struct
)
1182 code
.putln("(void) PyObject_INIT(o, t);")
1183 if scope
.needs_gc():
1184 code
.putln("PyObject_GC_Track(o);")
1185 code
.putln("} else {")
1186 if not is_final_type
:
1187 code
.putln("if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {")
1188 code
.putln("o = (*t->tp_alloc)(t, 0);")
1189 if not is_final_type
:
1190 code
.putln("} else {")
1191 code
.putln("o = (PyObject *) PyBaseObject_Type.tp_new(t, %s, 0);" % Naming
.empty_tuple
)
1193 code
.putln("if (unlikely(!o)) return 0;")
1194 if freelist_size
and not base_type
:
1197 code
.putln("p = %s;" % type.cast_code("o"))
1199 # self.generate_self_cast(scope, code)
1200 if type.vtabslot_cname
:
1201 vtab_base_type
= type
1202 while vtab_base_type
.base_type
and vtab_base_type
.base_type
.vtabstruct_cname
:
1203 vtab_base_type
= vtab_base_type
.base_type
1204 if vtab_base_type
is not type:
1205 struct_type_cast
= "(struct %s*)" % vtab_base_type
.vtabstruct_cname
1207 struct_type_cast
= ""
1208 code
.putln("p->%s = %s%s;" % (
1209 type.vtabslot_cname
,
1210 struct_type_cast
, type.vtabptr_cname
))
1212 for entry
in cpp_class_attrs
:
1213 code
.putln("new((void*)&(p->%s)) %s();" %
1214 (entry
.cname
, entry
.type.declaration_code("")))
1216 for entry
in py_attrs
:
1217 code
.put_init_var_to_py_none(entry
, "p->%s", nanny
=False)
1219 for entry
in memoryview_slices
:
1220 code
.putln("p->%s.data = NULL;" % entry
.cname
)
1221 code
.putln("p->%s.memview = NULL;" % entry
.cname
)
1223 for entry
in py_buffers
:
1224 code
.putln("p->%s.obj = NULL;" % entry
.cname
)
1226 if cclass_entry
.cname
== '__pyx_memoryviewslice':
1227 code
.putln("p->from_slice.memview = NULL;")
1229 if new_func_entry
and new_func_entry
.is_special
:
1230 if new_func_entry
.trivial_signature
:
1231 cinit_args
= "o, %s, NULL" % Naming
.empty_tuple
1233 cinit_args
= "o, a, k"
1235 "if (unlikely(%s(%s) < 0)) {" %
1236 (new_func_entry
.func_cname
, cinit_args
))
1237 code
.put_decref_clear("o", py_object_type
, nanny
=False)
1245 def generate_dealloc_function(self
, scope
, code
):
1246 tp_slot
= TypeSlots
.ConstructorSlot("tp_dealloc", '__dealloc__')
1247 slot_func
= scope
.mangle_internal("tp_dealloc")
1248 base_type
= scope
.parent_type
.base_type
1249 if tp_slot
.slot_code(scope
) != slot_func
:
1252 slot_func_cname
= scope
.mangle_internal("tp_dealloc")
1255 "static void %s(PyObject *o) {" % slot_func_cname
)
1257 is_final_type
= scope
.parent_type
.is_final_type
1258 needs_gc
= scope
.needs_gc()
1260 weakref_slot
= scope
.lookup_here("__weakref__")
1261 if weakref_slot
not in scope
.var_entries
:
1264 _
, (py_attrs
, _
, memoryview_slices
) = scope
.get_refcounted_entries()
1265 cpp_class_attrs
= [entry
for entry
in scope
.var_entries
1266 if entry
.type.is_cpp_class
]
1268 if py_attrs
or cpp_class_attrs
or memoryview_slices
or weakref_slot
:
1269 self
.generate_self_cast(scope
, code
)
1271 if not is_final_type
:
1272 # in Py3.4+, call tp_finalize() as early as possible
1273 code
.putln("#if PY_VERSION_HEX >= 0x030400a1")
1275 finalised_check
= '!_PyGC_FINALIZED(o)'
1278 '(!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))')
1279 code
.putln("if (unlikely(Py_TYPE(o)->tp_finalize) && %s) {" %
1281 # if instance was resurrected by finaliser, return
1282 code
.putln("if (PyObject_CallFinalizerFromDealloc(o)) return;")
1284 code
.putln("#endif")
1287 # We must mark this object as (gc) untracked while tearing
1288 # it down, lest the garbage collection is invoked while
1289 # running this destructor.
1290 code
.putln("PyObject_GC_UnTrack(o);")
1292 # call the user's __dealloc__
1293 self
.generate_usr_dealloc_call(scope
, code
)
1296 code
.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);")
1298 for entry
in cpp_class_attrs
:
1299 code
.putln("__Pyx_call_destructor(&p->%s);" % entry
.cname
)
1301 for entry
in py_attrs
:
1302 code
.put_xdecref_clear("p->%s" % entry
.cname
, entry
.type, nanny
=False,
1303 clear_before_decref
=True)
1305 for entry
in memoryview_slices
:
1306 code
.put_xdecref_memoryviewslice("p->%s" % entry
.cname
,
1311 # The base class deallocator probably expects this to be tracked,
1312 # so undo the untracking above.
1313 if base_type
.scope
and base_type
.scope
.needs_gc():
1314 code
.putln("PyObject_GC_Track(o);")
1316 code
.putln("#if CYTHON_COMPILING_IN_CPYTHON")
1317 code
.putln("if (PyType_IS_GC(Py_TYPE(o)->tp_base))")
1318 code
.putln("#endif")
1319 code
.putln("PyObject_GC_Track(o);")
1321 tp_dealloc
= TypeSlots
.get_base_slot_function(scope
, tp_slot
)
1322 if tp_dealloc
is not None:
1323 code
.putln("%s(o);" % tp_dealloc
)
1324 elif base_type
.is_builtin_type
:
1325 code
.putln("%s->tp_dealloc(o);" % base_type
.typeptr_cname
)
1327 # This is an externally defined type. Calling through the
1328 # cimported base type pointer directly interacts badly with
1329 # the module cleanup, which may already have cleared it.
1330 # In that case, fall back to traversing the type hierarchy.
1331 base_cname
= base_type
.typeptr_cname
1332 code
.putln("if (likely(%s)) %s->tp_dealloc(o); "
1333 "else __Pyx_call_next_tp_dealloc(o, %s);" % (
1334 base_cname
, base_cname
, slot_func_cname
))
1335 code
.globalstate
.use_utility_code(
1336 UtilityCode
.load_cached("CallNextTpDealloc", "ExtensionTypes.c"))
1338 freelist_size
= scope
.directives
.get('freelist', 0)
1340 freelist_name
= scope
.mangle_internal(Naming
.freelist_name
)
1341 freecount_name
= scope
.mangle_internal(Naming
.freecount_name
)
1344 type_safety_check
= ''
1346 type_safety_check
= (
1347 ' & ((Py_TYPE(o)->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)) == 0)')
1349 type = scope
.parent_type
1350 code
.putln("if (CYTHON_COMPILING_IN_CPYTHON && ((%s < %d) & (Py_TYPE(o)->tp_basicsize == sizeof(%s))%s)) {" % (
1351 freecount_name
, freelist_size
, type.declaration_code("", deref
=True),
1353 code
.putln("%s[%s++] = %s;" % (
1354 freelist_name
, freecount_name
, type.cast_code("o")))
1355 code
.putln("} else {")
1356 code
.putln("(*Py_TYPE(o)->tp_free)(o);")
1362 def generate_usr_dealloc_call(self
, scope
, code
):
1363 entry
= scope
.lookup_here("__dealloc__")
1368 code
.putln("PyObject *etype, *eval, *etb;")
1369 code
.putln("PyErr_Fetch(&etype, &eval, &etb);")
1370 code
.putln("++Py_REFCNT(o);")
1371 code
.putln("%s(o);" % entry
.func_cname
)
1372 code
.putln("--Py_REFCNT(o);")
1373 code
.putln("PyErr_Restore(etype, eval, etb);")
1376 def generate_traverse_function(self
, scope
, code
, cclass_entry
):
1377 tp_slot
= TypeSlots
.GCDependentSlot("tp_traverse")
1378 slot_func
= scope
.mangle_internal("tp_traverse")
1379 base_type
= scope
.parent_type
.base_type
1380 if tp_slot
.slot_code(scope
) != slot_func
:
1384 "static int %s(PyObject *o, visitproc v, void *a) {"
1387 have_entries
, (py_attrs
, py_buffers
, memoryview_slices
) = (
1388 scope
.get_refcounted_entries(include_gc_simple
=False))
1390 if base_type
or py_attrs
:
1391 code
.putln("int e;")
1393 if py_attrs
or py_buffers
:
1394 self
.generate_self_cast(scope
, code
)
1397 # want to call it explicitly if possible so inlining can be performed
1398 static_call
= TypeSlots
.get_base_slot_function(scope
, tp_slot
)
1400 code
.putln("e = %s(o, v, a); if (e) return e;" % static_call
)
1401 elif base_type
.is_builtin_type
:
1402 base_cname
= base_type
.typeptr_cname
1403 code
.putln("if (!%s->tp_traverse); else { e = %s->tp_traverse(o,v,a); if (e) return e; }" % (
1404 base_cname
, base_cname
))
1406 # This is an externally defined type. Calling through the
1407 # cimported base type pointer directly interacts badly with
1408 # the module cleanup, which may already have cleared it.
1409 # In that case, fall back to traversing the type hierarchy.
1410 base_cname
= base_type
.typeptr_cname
1411 code
.putln("e = ((likely(%s)) ? ((%s->tp_traverse) ? %s->tp_traverse(o, v, a) : 0) : __Pyx_call_next_tp_traverse(o, v, a, %s)); if (e) return e;" % (
1412 base_cname
, base_cname
, base_cname
, slot_func
))
1413 code
.globalstate
.use_utility_code(
1414 UtilityCode
.load_cached("CallNextTpTraverse", "ExtensionTypes.c"))
1416 for entry
in py_attrs
:
1417 var_code
= "p->%s" % entry
.cname
1421 if entry
.type.is_extension_type
:
1422 var_code
= "((PyObject*)%s)" % var_code
1424 "e = (*v)(%s, a); if (e) return e;"
1429 # Traverse buffer exporting objects.
1430 # Note: not traversing memoryview attributes of memoryview slices!
1431 # When triggered by the GC, it would cause multiple visits (gc_refs
1432 # subtractions which is not matched by its reference count!)
1433 for entry
in py_buffers
:
1434 cname
= entry
.cname
+ ".obj"
1435 code
.putln("if (p->%s) {" % cname
)
1436 code
.putln( "e = (*v)(p->%s, a); if (e) return e;" % cname
)
1444 def generate_clear_function(self
, scope
, code
, cclass_entry
):
1445 tp_slot
= TypeSlots
.GCDependentSlot("tp_clear")
1446 slot_func
= scope
.mangle_internal("tp_clear")
1447 base_type
= scope
.parent_type
.base_type
1448 if tp_slot
.slot_code(scope
) != slot_func
:
1451 have_entries
, (py_attrs
, py_buffers
, memoryview_slices
) = (
1452 scope
.get_refcounted_entries(include_gc_simple
=False))
1454 if py_attrs
or py_buffers
or base_type
:
1457 unused
= 'CYTHON_UNUSED '
1460 code
.putln("static int %s(%sPyObject *o) {" % (slot_func
, unused
))
1462 if py_attrs
and Options
.clear_to_none
:
1463 code
.putln("PyObject* tmp;")
1465 if py_attrs
or py_buffers
:
1466 self
.generate_self_cast(scope
, code
)
1469 # want to call it explicitly if possible so inlining can be performed
1470 static_call
= TypeSlots
.get_base_slot_function(scope
, tp_slot
)
1472 code
.putln("%s(o);" % static_call
)
1473 elif base_type
.is_builtin_type
:
1474 base_cname
= base_type
.typeptr_cname
1475 code
.putln("if (!%s->tp_clear); else %s->tp_clear(o);" % (
1476 base_cname
, base_cname
))
1478 # This is an externally defined type. Calling through the
1479 # cimported base type pointer directly interacts badly with
1480 # the module cleanup, which may already have cleared it.
1481 # In that case, fall back to traversing the type hierarchy.
1482 base_cname
= base_type
.typeptr_cname
1483 code
.putln("if (likely(%s)) { if (%s->tp_clear) %s->tp_clear(o); } else __Pyx_call_next_tp_clear(o, %s);" % (
1484 base_cname
, base_cname
, base_cname
, slot_func
))
1485 code
.globalstate
.use_utility_code(
1486 UtilityCode
.load_cached("CallNextTpClear", "ExtensionTypes.c"))
1488 if Options
.clear_to_none
:
1489 for entry
in py_attrs
:
1490 name
= "p->%s" % entry
.cname
1491 code
.putln("tmp = ((PyObject*)%s);" % name
)
1492 if entry
.is_declared_generic
:
1493 code
.put_init_to_py_none(name
, py_object_type
, nanny
=False)
1495 code
.put_init_to_py_none(name
, entry
.type, nanny
=False)
1496 code
.putln("Py_XDECREF(tmp);")
1498 for entry
in py_attrs
:
1499 code
.putln("Py_CLEAR(p->%s);" % entry
.cname
)
1501 for entry
in py_buffers
:
1502 # Note: shouldn't this call __Pyx_ReleaseBuffer ??
1503 code
.putln("Py_CLEAR(p->%s.obj);" % entry
.cname
)
1505 if cclass_entry
.cname
== '__pyx_memoryviewslice':
1506 code
.putln("__PYX_XDEC_MEMVIEW(&p->from_slice, 1);")
1513 def generate_getitem_int_function(self
, scope
, code
):
1514 # This function is put into the sq_item slot when
1515 # a __getitem__ method is present. It converts its
1516 # argument to a Python integer and calls mp_subscript.
1518 "static PyObject *%s(PyObject *o, Py_ssize_t i) {" %
1519 scope
.mangle_internal("sq_item"))
1523 "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;")
1525 "r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);")
1533 def generate_ass_subscript_function(self
, scope
, code
):
1534 # Setting and deleting an item are both done through
1535 # the ass_subscript method, so we dispatch to user's __setitem__
1536 # or __delitem__, or raise an exception.
1537 base_type
= scope
.parent_type
.base_type
1538 set_entry
= scope
.lookup_here("__setitem__")
1539 del_entry
= scope
.lookup_here("__delitem__")
1542 "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
1543 scope
.mangle_internal("mp_ass_subscript"))
1548 "return %s(o, i, v);" %
1549 set_entry
.func_cname
)
1551 self
.generate_guarded_basetype_call(
1552 base_type
, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code
)
1554 "PyErr_Format(PyExc_NotImplementedError,")
1556 ' "Subscript assignment not supported by %.200s", Py_TYPE(o)->tp_name);')
1565 "return %s(o, i);" %
1566 del_entry
.func_cname
)
1568 self
.generate_guarded_basetype_call(
1569 base_type
, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code
)
1571 "PyErr_Format(PyExc_NotImplementedError,")
1573 ' "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);')
1581 def generate_guarded_basetype_call(
1582 self
, base_type
, substructure
, slot
, args
, code
):
1584 base_tpname
= base_type
.typeptr_cname
1587 "if (%s->%s && %s->%s->%s)" % (
1588 base_tpname
, substructure
, base_tpname
, substructure
, slot
))
1590 " return %s->%s->%s(%s);" % (
1591 base_tpname
, substructure
, slot
, args
))
1597 " return %s->%s(%s);" % (
1598 base_tpname
, slot
, args
))
1600 def generate_ass_slice_function(self
, scope
, code
):
1601 # Setting and deleting a slice are both done through
1602 # the ass_slice method, so we dispatch to user's __setslice__
1603 # or __delslice__, or raise an exception.
1604 base_type
= scope
.parent_type
.base_type
1605 set_entry
= scope
.lookup_here("__setslice__")
1606 del_entry
= scope
.lookup_here("__delslice__")
1609 "static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" %
1610 scope
.mangle_internal("sq_ass_slice"))
1615 "return %s(o, i, j, v);" %
1616 set_entry
.func_cname
)
1618 self
.generate_guarded_basetype_call(
1619 base_type
, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code
)
1621 "PyErr_Format(PyExc_NotImplementedError,")
1623 ' "2-element slice assignment not supported by %.200s", Py_TYPE(o)->tp_name);')
1632 "return %s(o, i, j);" %
1633 del_entry
.func_cname
)
1635 self
.generate_guarded_basetype_call(
1636 base_type
, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code
)
1638 "PyErr_Format(PyExc_NotImplementedError,")
1640 ' "2-element slice deletion not supported by %.200s", Py_TYPE(o)->tp_name);')
1648 def generate_getattro_function(self
, scope
, code
):
1649 # First try to get the attribute using __getattribute__, if defined, or
1650 # PyObject_GenericGetAttr.
1652 # If that raises an AttributeError, call the __getattr__ if defined.
1654 # In both cases, defined can be in this class, or any base class.
1655 def lookup_here_or_base(n
,type=None):
1658 type = scope
.parent_type
1659 r
= type.scope
.lookup_here(n
)
1661 type.base_type
is not None:
1662 return lookup_here_or_base(n
,type.base_type
)
1665 getattr_entry
= lookup_here_or_base("__getattr__")
1666 getattribute_entry
= lookup_here_or_base("__getattribute__")
1669 "static PyObject *%s(PyObject *o, PyObject *n) {"
1670 % scope
.mangle_internal("tp_getattro"))
1671 if getattribute_entry
is not None:
1673 "PyObject *v = %s(o, n);" %
1674 getattribute_entry
.func_cname
)
1677 "PyObject *v = PyObject_GenericGetAttr(o, n);")
1678 if getattr_entry
is not None:
1680 "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
1685 getattr_entry
.func_cname
)
1693 def generate_setattro_function(self
, scope
, code
):
1694 # Setting and deleting an attribute are both done through
1695 # the setattro method, so we dispatch to user's __setattr__
1696 # or __delattr__ or fall back on PyObject_GenericSetAttr.
1697 base_type
= scope
.parent_type
.base_type
1698 set_entry
= scope
.lookup_here("__setattr__")
1699 del_entry
= scope
.lookup_here("__delattr__")
1702 "static int %s(PyObject *o, PyObject *n, PyObject *v) {" %
1703 scope
.mangle_internal("tp_setattro"))
1708 "return %s(o, n, v);" %
1709 set_entry
.func_cname
)
1711 self
.generate_guarded_basetype_call(
1712 base_type
, None, "tp_setattro", "o, n, v", code
)
1714 "return PyObject_GenericSetAttr(o, n, v);")
1721 "return %s(o, n);" %
1722 del_entry
.func_cname
)
1724 self
.generate_guarded_basetype_call(
1725 base_type
, None, "tp_setattro", "o, n, v", code
)
1727 "return PyObject_GenericSetAttr(o, n, 0);")
1733 def generate_descr_get_function(self
, scope
, code
):
1734 # The __get__ function of a descriptor object can be
1735 # called with NULL for the second or third arguments
1736 # under some circumstances, so we replace them with
1737 # None in that case.
1738 user_get_entry
= scope
.lookup_here("__get__")
1741 "static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" %
1742 scope
.mangle_internal("tp_descr_get"))
1746 "if (!i) i = Py_None;")
1748 "if (!c) c = Py_None;")
1749 #code.put_incref("i", py_object_type)
1750 #code.put_incref("c", py_object_type)
1752 "r = %s(o, i, c);" %
1753 user_get_entry
.func_cname
)
1754 #code.put_decref("i", py_object_type)
1755 #code.put_decref("c", py_object_type)
1761 def generate_descr_set_function(self
, scope
, code
):
1762 # Setting and deleting are both done through the __set__
1763 # method of a descriptor, so we dispatch to user's __set__
1764 # or __delete__ or raise an exception.
1765 base_type
= scope
.parent_type
.base_type
1766 user_set_entry
= scope
.lookup_here("__set__")
1767 user_del_entry
= scope
.lookup_here("__delete__")
1770 "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
1771 scope
.mangle_internal("tp_descr_set"))
1776 "return %s(o, i, v);" %
1777 user_set_entry
.func_cname
)
1779 self
.generate_guarded_basetype_call(
1780 base_type
, None, "tp_descr_set", "o, i, v", code
)
1782 'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
1791 "return %s(o, i);" %
1792 user_del_entry
.func_cname
)
1794 self
.generate_guarded_basetype_call(
1795 base_type
, None, "tp_descr_set", "o, i, v", code
)
1797 'PyErr_SetString(PyExc_NotImplementedError, "__delete__");')
1805 def generate_property_accessors(self
, cclass_scope
, code
):
1806 for entry
in cclass_scope
.property_entries
:
1807 property_scope
= entry
.scope
1808 if property_scope
.defines_any(["__get__"]):
1809 self
.generate_property_get_function(entry
, code
)
1810 if property_scope
.defines_any(["__set__", "__del__"]):
1811 self
.generate_property_set_function(entry
, code
)
1813 def generate_property_get_function(self
, property_entry
, code
):
1814 property_scope
= property_entry
.scope
1815 property_entry
.getter_cname
= property_scope
.parent_scope
.mangle(
1816 Naming
.prop_get_prefix
, property_entry
.name
)
1817 get_entry
= property_scope
.lookup_here("__get__")
1820 "static PyObject *%s(PyObject *o, CYTHON_UNUSED void *x) {" %
1821 property_entry
.getter_cname
)
1824 get_entry
.func_cname
)
1828 def generate_property_set_function(self
, property_entry
, code
):
1829 property_scope
= property_entry
.scope
1830 property_entry
.setter_cname
= property_scope
.parent_scope
.mangle(
1831 Naming
.prop_set_prefix
, property_entry
.name
)
1832 set_entry
= property_scope
.lookup_here("__set__")
1833 del_entry
= property_scope
.lookup_here("__del__")
1836 "static int %s(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {" %
1837 property_entry
.setter_cname
)
1842 "return %s(o, v);" %
1843 set_entry
.func_cname
)
1846 'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
1856 del_entry
.func_cname
)
1859 'PyErr_SetString(PyExc_NotImplementedError, "__del__");')
1867 def generate_typeobj_definition(self
, modname
, entry
, code
):
1870 for suite
in TypeSlots
.substructures
:
1871 suite
.generate_substructure(scope
, code
)
1873 if entry
.visibility
== 'public':
1874 header
= "DL_EXPORT(PyTypeObject) %s = {"
1876 header
= "static PyTypeObject %s = {"
1877 #code.putln(header % scope.parent_type.typeobj_cname)
1878 code
.putln(header
% type.typeobj_cname
)
1880 "PyVarObject_HEAD_INIT(0, 0)")
1882 '__Pyx_NAMESTR("%s.%s"), /*tp_name*/' % (
1883 self
.full_module_name
, scope
.class_name
))
1884 if type.typedef_flag
:
1885 objstruct
= type.objstruct_cname
1887 objstruct
= "struct %s" % type.objstruct_cname
1889 "sizeof(%s), /*tp_basicsize*/" %
1892 "0, /*tp_itemsize*/")
1893 for slot
in TypeSlots
.slot_table
:
1894 slot
.generate(scope
, code
)
1898 def generate_method_table(self
, env
, code
):
1899 if env
.is_c_class_scope
and not env
.pyfunc_entries
:
1903 "static PyMethodDef %s[] = {" %
1904 env
.method_table_cname
)
1905 for entry
in env
.pyfunc_entries
:
1906 if not entry
.fused_cfunction
:
1907 code
.put_pymethoddef(entry
, ",")
1913 def generate_getset_table(self
, env
, code
):
1914 if env
.property_entries
:
1917 "static struct PyGetSetDef %s[] = {" %
1918 env
.getset_table_cname
)
1919 for entry
in env
.property_entries
:
1921 doc_code
= "__Pyx_DOCSTR(%s)" % code
.get_string_const(entry
.doc
)
1925 '{(char *)"%s", %s, %s, %s, 0},' % (
1927 entry
.getter_cname
or "0",
1928 entry
.setter_cname
or "0",
1935 def generate_import_star(self
, env
, code
):
1936 env
.use_utility_code(streq_utility_code
)
1938 code
.putln("static char* %s_type_names[] = {" % Naming
.import_star
)
1939 for name
, entry
in sorted(env
.entries
.items()):
1941 code
.putln('"%s",' % name
)
1945 code
.enter_cfunc_scope() # as we need labels
1946 code
.putln("static int %s(PyObject *o, PyObject* py_name, char *name) {" % Naming
.import_star_set
)
1947 code
.putln("char** type_name = %s_type_names;" % Naming
.import_star
)
1948 code
.putln("while (*type_name) {")
1949 code
.putln("if (__Pyx_StrEq(name, *type_name)) {")
1950 code
.putln('PyErr_Format(PyExc_TypeError, "Cannot overwrite C type %s", name);')
1951 code
.putln('goto bad;')
1953 code
.putln("type_name++;")
1955 old_error_label
= code
.new_error_label()
1956 code
.putln("if (0);") # so the first one can be "else if"
1957 for name
, entry
in env
.entries
.items():
1958 if entry
.is_cglobal
and entry
.used
:
1959 code
.putln('else if (__Pyx_StrEq(name, "%s")) {' % name
)
1960 if entry
.type.is_pyobject
:
1961 if entry
.type.is_extension_type
or entry
.type.is_builtin_type
:
1962 code
.putln("if (!(%s)) %s;" % (
1963 entry
.type.type_test_code("o"),
1964 code
.error_goto(entry
.pos
)))
1965 code
.putln("Py_INCREF(o);")
1966 code
.put_decref(entry
.cname
, entry
.type, nanny
=False)
1967 code
.putln("%s = %s;" % (
1969 PyrexTypes
.typecast(entry
.type, py_object_type
, "o")))
1970 elif entry
.type.from_py_function
:
1971 rhs
= "%s(o)" % entry
.type.from_py_function
1972 if entry
.type.is_enum
:
1973 rhs
= PyrexTypes
.typecast(entry
.type, PyrexTypes
.c_long_type
, rhs
)
1974 code
.putln("%s = %s; if (%s) %s;" % (
1977 entry
.type.error_condition(entry
.cname
),
1978 code
.error_goto(entry
.pos
)))
1980 code
.putln('PyErr_Format(PyExc_TypeError, "Cannot convert Python object %s to %s");' % (name
, entry
.type))
1981 code
.putln(code
.error_goto(entry
.pos
))
1983 code
.putln("else {")
1984 code
.putln("if (PyObject_SetAttr(%s, py_name, o) < 0) goto bad;" % Naming
.module_cname
)
1986 code
.putln("return 0;")
1987 if code
.label_used(code
.error_label
):
1988 code
.put_label(code
.error_label
)
1989 # This helps locate the offending name.
1990 code
.put_add_traceback(self
.full_module_name
)
1991 code
.error_label
= old_error_label
1993 code
.putln("return -1;")
1995 code
.putln(import_star_utility_code
)
1996 code
.exit_cfunc_scope() # done with labels
1998 def generate_module_init_func(self
, imported_modules
, env
, code
):
1999 code
.enter_cfunc_scope()
2001 header2
= "PyMODINIT_FUNC init%s(void)" % env
.module_name
2002 header3
= "PyMODINIT_FUNC PyInit_%s(void)" % env
.module_name
2003 code
.putln("#if PY_MAJOR_VERSION < 3")
2004 code
.putln("%s; /*proto*/" % header2
)
2007 code
.putln("%s; /*proto*/" % header3
)
2009 code
.putln("#endif")
2011 tempdecl_code
= code
.insertion_point()
2013 code
.put_declare_refcount_context()
2014 code
.putln("#if CYTHON_REFNANNY")
2015 code
.putln("__Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"refnanny\");")
2016 code
.putln("if (!__Pyx_RefNanny) {")
2017 code
.putln(" PyErr_Clear();")
2018 code
.putln(" __Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"Cython.Runtime.refnanny\");")
2019 code
.putln(" if (!__Pyx_RefNanny)")
2020 code
.putln(" Py_FatalError(\"failed to import 'refnanny' module\");")
2022 code
.putln("#endif")
2023 code
.put_setup_refcount_context(header3
)
2025 env
.use_utility_code(UtilityCode
.load("CheckBinaryVersion", "ModuleSetupCode.c"))
2026 code
.putln("if ( __Pyx_check_binary_version() < 0) %s" % code
.error_goto(self
.pos
))
2028 code
.putln("%s = PyTuple_New(0); %s" % (Naming
.empty_tuple
, code
.error_goto_if_null(Naming
.empty_tuple
, self
.pos
)))
2029 code
.putln("%s = PyBytes_FromStringAndSize(\"\", 0); %s" % (Naming
.empty_bytes
, code
.error_goto_if_null(Naming
.empty_bytes
, self
.pos
)))
2031 code
.putln("#ifdef __Pyx_CyFunction_USED")
2032 code
.putln("if (__Pyx_CyFunction_init() < 0) %s" % code
.error_goto(self
.pos
))
2033 code
.putln("#endif")
2035 code
.putln("#ifdef __Pyx_FusedFunction_USED")
2036 code
.putln("if (__pyx_FusedFunction_init() < 0) %s" % code
.error_goto(self
.pos
))
2037 code
.putln("#endif")
2039 code
.putln("#ifdef __Pyx_Generator_USED")
2040 code
.putln("if (__pyx_Generator_init() < 0) %s" % code
.error_goto(self
.pos
))
2041 code
.putln("#endif")
2043 code
.putln("/*--- Library function declarations ---*/")
2044 env
.generate_library_function_declarations(code
)
2046 code
.putln("/*--- Threads initialization code ---*/")
2047 code
.putln("#if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS")
2048 code
.putln("#ifdef WITH_THREAD /* Python build with threading support? */")
2049 code
.putln("PyEval_InitThreads();")
2050 code
.putln("#endif")
2051 code
.putln("#endif")
2053 code
.putln("/*--- Module creation code ---*/")
2054 self
.generate_module_creation_code(env
, code
)
2056 code
.putln("/*--- Initialize various global constants etc. ---*/")
2057 code
.putln(code
.error_goto_if_neg("__Pyx_InitGlobals()", self
.pos
))
2059 code
.putln("#if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)")
2060 code
.putln("if (__Pyx_init_sys_getdefaultencoding_params() < 0) %s" % code
.error_goto(self
.pos
))
2061 code
.putln("#endif")
2063 __main__name
= code
.globalstate
.get_py_string_const(
2064 EncodedString("__main__"), identifier
=True)
2065 code
.putln("if (%s%s) {" % (Naming
.module_is_main
, self
.full_module_name
.replace('.', '__')))
2067 'if (__Pyx_SetAttrString(%s, "__name__", %s) < 0) %s;' % (
2070 code
.error_goto(self
.pos
)))
2073 # set up __file__ and __path__, then add the module to sys.modules
2074 self
.generate_module_import_setup(env
, code
)
2076 if Options
.cache_builtins
:
2077 code
.putln("/*--- Builtin init code ---*/")
2078 code
.putln(code
.error_goto_if_neg("__Pyx_InitCachedBuiltins()", self
.pos
))
2080 code
.putln("/*--- Constants init code ---*/")
2081 code
.putln(code
.error_goto_if_neg("__Pyx_InitCachedConstants()", self
.pos
))
2083 code
.putln("/*--- Global init code ---*/")
2084 self
.generate_global_init_code(env
, code
)
2086 code
.putln("/*--- Variable export code ---*/")
2087 self
.generate_c_variable_export_code(env
, code
)
2089 code
.putln("/*--- Function export code ---*/")
2090 self
.generate_c_function_export_code(env
, code
)
2092 code
.putln("/*--- Type init code ---*/")
2093 self
.generate_type_init_code(env
, code
)
2095 code
.putln("/*--- Type import code ---*/")
2096 for module
in imported_modules
:
2097 self
.generate_type_import_code_for_module(module
, env
, code
)
2099 code
.putln("/*--- Variable import code ---*/")
2100 for module
in imported_modules
:
2101 self
.generate_c_variable_import_code_for_module(module
, env
, code
)
2103 code
.putln("/*--- Function import code ---*/")
2104 for module
in imported_modules
:
2105 self
.specialize_fused_types(module
)
2106 self
.generate_c_function_import_code_for_module(module
, env
, code
)
2108 code
.putln("/*--- Execution code ---*/")
2111 self
.body
.generate_execution_code(code
)
2113 if Options
.generate_cleanup_code
:
2114 code
.globalstate
.use_utility_code(
2115 UtilityCode
.load_cached("RegisterModuleCleanup", "ModuleSetupCode.c"))
2116 code
.putln("if (__Pyx_RegisterCleanup()) %s;" % code
.error_goto(self
.pos
))
2118 code
.put_goto(code
.return_label
)
2119 code
.put_label(code
.error_label
)
2120 for cname
, type in code
.funcstate
.all_managed_temps():
2121 code
.put_xdecref(cname
, type)
2122 code
.putln('if (%s) {' % env
.module_cname
)
2123 code
.put_add_traceback("init %s" % env
.qualified_name
)
2124 env
.use_utility_code(Nodes
.traceback_utility_code
)
2125 code
.put_decref_clear(env
.module_cname
, py_object_type
, nanny
=False)
2126 code
.putln('} else if (!PyErr_Occurred()) {')
2127 code
.putln('PyErr_SetString(PyExc_ImportError, "init %s");' % env
.qualified_name
)
2129 code
.put_label(code
.return_label
)
2131 code
.put_finish_refcount_context()
2133 code
.putln("#if PY_MAJOR_VERSION < 3")
2134 code
.putln("return;")
2136 code
.putln("return %s;" % env
.module_cname
)
2137 code
.putln("#endif")
2140 tempdecl_code
.put_temp_declarations(code
.funcstate
)
2142 code
.exit_cfunc_scope()
2144 def generate_module_import_setup(self
, env
, code
):
2145 module_path
= env
.directives
['set_initial_path']
2146 if module_path
== 'SOURCEFILE':
2147 module_path
= self
.pos
[0].filename
2150 code
.putln('if (__Pyx_SetAttrString(%s, "__file__", %s) < 0) %s;' % (
2152 code
.globalstate
.get_py_string_const(
2153 EncodedString(decode_filename(module_path
))).cname
,
2154 code
.error_goto(self
.pos
)))
2157 # set __path__ to mark the module as package
2158 temp
= code
.funcstate
.allocate_temp(py_object_type
, True)
2159 code
.putln('%s = Py_BuildValue("[O]", %s); %s' % (
2161 code
.globalstate
.get_py_string_const(
2162 EncodedString(decode_filename(
2163 os
.path
.dirname(module_path
)))).cname
,
2164 code
.error_goto_if_null(temp
, self
.pos
)))
2165 code
.put_gotref(temp
)
2167 'if (__Pyx_SetAttrString(%s, "__path__", %s) < 0) %s;' % (
2168 env
.module_cname
, temp
, code
.error_goto(self
.pos
)))
2169 code
.put_decref_clear(temp
, py_object_type
)
2170 code
.funcstate
.release_temp(temp
)
2172 elif env
.is_package
:
2173 # packages require __path__, so all we can do is try to figure
2174 # out the module path at runtime by rerunning the import lookup
2175 package_name
, _
= self
.full_module_name
.rsplit('.', 1)
2176 if '.' in package_name
:
2177 parent_name
= '"%s"' % (package_name
.rsplit('.', 1)[0],)
2179 parent_name
= 'NULL'
2180 code
.globalstate
.use_utility_code(UtilityCode
.load(
2181 "SetPackagePathFromImportLib", "ImportExport.c"))
2182 code
.putln(code
.error_goto_if_neg(
2183 '__Pyx_SetPackagePathFromImportLib(%s, %s)' % (
2185 code
.globalstate
.get_py_string_const(
2186 EncodedString(env
.module_name
)).cname
),
2189 # CPython may not have put us into sys.modules yet, but relative imports and reimports require it
2190 fq_module_name
= self
.full_module_name
2191 if fq_module_name
.endswith('.__init__'):
2192 fq_module_name
= fq_module_name
[:-len('.__init__')]
2193 code
.putln("#if PY_MAJOR_VERSION >= 3")
2195 code
.putln("PyObject *modules = PyImport_GetModuleDict(); %s" %
2196 code
.error_goto_if_null("modules", self
.pos
))
2197 code
.putln('if (!PyDict_GetItemString(modules, "%s")) {' % fq_module_name
)
2198 code
.putln(code
.error_goto_if_neg('PyDict_SetItemString(modules, "%s", %s)' % (
2199 fq_module_name
, env
.module_cname
), self
.pos
))
2202 code
.putln("#endif")
2204 def generate_module_cleanup_func(self
, env
, code
):
2205 if not Options
.generate_cleanup_code
:
2208 code
.putln('static void %s(CYTHON_UNUSED PyObject *self) {' %
2209 Naming
.cleanup_cname
)
2210 if Options
.generate_cleanup_code
>= 2:
2211 code
.putln("/*--- Global cleanup code ---*/")
2212 rev_entries
= list(env
.var_entries
)
2213 rev_entries
.reverse()
2214 for entry
in rev_entries
:
2215 if entry
.visibility
!= 'extern':
2216 if entry
.type.is_pyobject
and entry
.used
:
2217 code
.put_xdecref_clear(
2218 entry
.cname
, entry
.type,
2219 clear_before_decref
=True,
2221 code
.putln("__Pyx_CleanupGlobals();")
2222 if Options
.generate_cleanup_code
>= 3:
2223 code
.putln("/*--- Type import cleanup code ---*/")
2224 for ext_type
in sorted(env
.types_imported
, key
=operator
.attrgetter('typeptr_cname')):
2225 code
.put_xdecref_clear(
2226 ext_type
.typeptr_cname
, ext_type
,
2227 clear_before_decref
=True,
2229 if Options
.cache_builtins
:
2230 code
.putln("/*--- Builtin cleanup code ---*/")
2231 for entry
in env
.cached_builtins
:
2232 code
.put_xdecref_clear(
2233 entry
.cname
, PyrexTypes
.py_object_type
,
2234 clear_before_decref
=True,
2236 code
.putln("/*--- Intern cleanup code ---*/")
2237 code
.put_decref_clear(Naming
.empty_tuple
,
2238 PyrexTypes
.py_object_type
,
2239 clear_before_decref
=True,
2241 for entry
in env
.c_class_entries
:
2242 cclass_type
= entry
.type
2243 if cclass_type
.is_external
or cclass_type
.base_type
:
2245 if cclass_type
.scope
.directives
.get('freelist', 0):
2246 scope
= cclass_type
.scope
2247 freelist_name
= scope
.mangle_internal(Naming
.freelist_name
)
2248 freecount_name
= scope
.mangle_internal(Naming
.freecount_name
)
2249 code
.putln("while (%s > 0) {" % freecount_name
)
2250 code
.putln("PyObject* o = (PyObject*)%s[--%s];" % (
2251 freelist_name
, freecount_name
))
2252 code
.putln("(*Py_TYPE(o)->tp_free)(o);")
2254 # for entry in env.pynum_entries:
2255 # code.put_decref_clear(entry.cname,
2256 # PyrexTypes.py_object_type,
2258 # for entry in env.all_pystring_entries:
2259 # if entry.is_interned:
2260 # code.put_decref_clear(entry.pystring_cname,
2261 # PyrexTypes.py_object_type,
2263 # for entry in env.default_entries:
2264 # if entry.type.is_pyobject and entry.used:
2265 # code.putln("Py_DECREF(%s); %s = 0;" % (
2266 # code.entry_as_pyobject(entry), entry.cname))
2267 code
.putln('#if CYTHON_COMPILING_IN_PYPY')
2268 code
.putln('Py_CLEAR(%s);' % Naming
.builtins_cname
)
2269 code
.putln('#endif')
2270 code
.put_decref_clear(env
.module_dict_cname
, py_object_type
,
2271 nanny
=False, clear_before_decref
=True)
2273 def generate_main_method(self
, env
, code
):
2274 module_is_main
= "%s%s" % (Naming
.module_is_main
, self
.full_module_name
.replace('.', '__'))
2275 if Options
.embed
== "main":
2278 wmain
= Options
.embed
2279 code
.globalstate
.use_utility_code(
2280 main_method
.specialize(
2281 module_name
= env
.module_name
,
2282 module_is_main
= module_is_main
,
2283 main_method
= Options
.embed
,
2284 wmain_method
= wmain
))
2286 def generate_pymoduledef_struct(self
, env
, code
):
2288 doc
= "__Pyx_DOCSTR(%s)" % code
.get_string_const(env
.doc
)
2291 if Options
.generate_cleanup_code
:
2292 cleanup_func
= "(freefunc)%s" % Naming
.cleanup_cname
2294 cleanup_func
= 'NULL'
2297 code
.putln("#if PY_MAJOR_VERSION >= 3")
2298 code
.putln("static struct PyModuleDef %s = {" % Naming
.pymoduledef_cname
)
2299 code
.putln("#if PY_VERSION_HEX < 0x03020000")
2300 # fix C compiler warnings due to missing initialisers
2301 code
.putln(" { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },")
2303 code
.putln(" PyModuleDef_HEAD_INIT,")
2304 code
.putln("#endif")
2305 code
.putln(' __Pyx_NAMESTR("%s"),' % env
.module_name
)
2306 code
.putln(" %s, /* m_doc */" % doc
)
2307 code
.putln(" -1, /* m_size */")
2308 code
.putln(" %s /* m_methods */," % env
.method_table_cname
)
2309 code
.putln(" NULL, /* m_reload */")
2310 code
.putln(" NULL, /* m_traverse */")
2311 code
.putln(" NULL, /* m_clear */")
2312 code
.putln(" %s /* m_free */" % cleanup_func
)
2314 code
.putln("#endif")
2316 def generate_module_creation_code(self
, env
, code
):
2317 # Generate code to create the module object and
2318 # install the builtins.
2320 doc
= "__Pyx_DOCSTR(%s)" % code
.get_string_const(env
.doc
)
2323 code
.putln("#if PY_MAJOR_VERSION < 3")
2325 '%s = Py_InitModule4(__Pyx_NAMESTR("%s"), %s, %s, 0, PYTHON_API_VERSION); Py_XINCREF(%s);' % (
2328 env
.method_table_cname
,
2333 "%s = PyModule_Create(&%s);" % (
2335 Naming
.pymoduledef_cname
))
2336 code
.putln("#endif")
2337 code
.putln(code
.error_goto_if_null(env
.module_cname
, self
.pos
))
2339 "%s = PyModule_GetDict(%s); %s" % (
2340 env
.module_dict_cname
, env
.module_cname
,
2341 code
.error_goto_if_null(env
.module_dict_cname
, self
.pos
)))
2342 code
.put_incref(env
.module_dict_cname
, py_object_type
, nanny
=False)
2345 '%s = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); %s' % (
2346 Naming
.builtins_cname
,
2347 code
.error_goto_if_null(Naming
.builtins_cname
, self
.pos
)))
2348 code
.putln('#if CYTHON_COMPILING_IN_PYPY')
2349 code
.putln('Py_INCREF(%s);' % Naming
.builtins_cname
)
2350 code
.putln('#endif')
2352 'if (__Pyx_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % (
2354 Naming
.builtins_cname
,
2355 code
.error_goto(self
.pos
)))
2356 if Options
.pre_import
is not None:
2358 '%s = PyImport_AddModule(__Pyx_NAMESTR("%s")); %s' % (
2359 Naming
.preimport_cname
,
2361 code
.error_goto_if_null(Naming
.preimport_cname
, self
.pos
)))
2363 def generate_global_init_code(self
, env
, code
):
2364 # Generate code to initialise global PyObject *
2365 # variables to None.
2366 for entry
in env
.var_entries
:
2367 if entry
.visibility
!= 'extern':
2369 entry
.type.global_init_code(entry
, code
)
2371 def generate_c_variable_export_code(self
, env
, code
):
2372 # Generate code to create PyCFunction wrappers for exported C functions.
2374 for entry
in env
.var_entries
:
2376 or entry
.defined_in_pxd
2377 or (Options
.cimport_from_pyx
and not entry
.visibility
== 'extern')):
2378 entries
.append(entry
)
2380 env
.use_utility_code(UtilityCode
.load_cached("VoidPtrExport", "ImportExport.c"))
2381 for entry
in entries
:
2382 signature
= entry
.type.declaration_code("")
2383 name
= code
.intern_identifier(entry
.name
)
2384 code
.putln('if (__Pyx_ExportVoidPtr(%s, (void *)&%s, "%s") < 0) %s' % (
2385 name
, entry
.cname
, signature
,
2386 code
.error_goto(self
.pos
)))
2388 def generate_c_function_export_code(self
, env
, code
):
2389 # Generate code to create PyCFunction wrappers for exported C functions.
2391 for entry
in env
.cfunc_entries
:
2393 or entry
.defined_in_pxd
2394 or (Options
.cimport_from_pyx
and not entry
.visibility
== 'extern')):
2395 entries
.append(entry
)
2397 env
.use_utility_code(
2398 UtilityCode
.load_cached("FunctionExport", "ImportExport.c"))
2399 for entry
in entries
:
2400 signature
= entry
.type.signature_string()
2401 code
.putln('if (__Pyx_ExportFunction("%s", (void (*)(void))%s, "%s") < 0) %s' % (
2405 code
.error_goto(self
.pos
)))
2407 def generate_type_import_code_for_module(self
, module
, env
, code
):
2408 # Generate type import code for all exported extension types in
2409 # an imported module.
2410 #if module.c_class_entries:
2411 for entry
in module
.c_class_entries
:
2412 if entry
.defined_in_pxd
:
2413 self
.generate_type_import_code(env
, entry
.type, entry
.pos
, code
)
2415 def specialize_fused_types(self
, pxd_env
):
2417 If fused c(p)def functions are defined in an imported pxd, but not
2418 used in this implementation file, we still have fused entries and
2419 not specialized ones. This method replaces any fused entries with their
2422 for entry
in pxd_env
.cfunc_entries
[:]:
2423 if entry
.type.is_fused
:
2424 # This call modifies the cfunc_entries in-place
2425 entry
.type.get_all_specialized_function_types()
2427 def generate_c_variable_import_code_for_module(self
, module
, env
, code
):
2428 # Generate import code for all exported C functions in a cimported module.
2430 for entry
in module
.var_entries
:
2431 if entry
.defined_in_pxd
:
2432 entries
.append(entry
)
2434 env
.use_utility_code(
2435 UtilityCode
.load_cached("ModuleImport", "ImportExport.c"))
2436 env
.use_utility_code(
2437 UtilityCode
.load_cached("VoidPtrImport", "ImportExport.c"))
2438 temp
= code
.funcstate
.allocate_temp(py_object_type
, manage_ref
=True)
2440 '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % (
2442 module
.qualified_name
,
2444 code
.error_goto(self
.pos
)))
2445 for entry
in entries
:
2449 cname
= module
.mangle(Naming
.varptr_prefix
, entry
.name
)
2450 signature
= entry
.type.declaration_code("")
2452 'if (__Pyx_ImportVoidPtr(%s, "%s", (void **)&%s, "%s") < 0) %s' % (
2453 temp
, entry
.name
, cname
, signature
,
2454 code
.error_goto(self
.pos
)))
2455 code
.putln("Py_DECREF(%s); %s = 0;" % (temp
, temp
))
2457 def generate_c_function_import_code_for_module(self
, module
, env
, code
):
2458 # Generate import code for all exported C functions in a cimported module.
2460 for entry
in module
.cfunc_entries
:
2461 if entry
.defined_in_pxd
and entry
.used
:
2462 entries
.append(entry
)
2464 env
.use_utility_code(
2465 UtilityCode
.load_cached("ModuleImport", "ImportExport.c"))
2466 env
.use_utility_code(
2467 UtilityCode
.load_cached("FunctionImport", "ImportExport.c"))
2468 temp
= code
.funcstate
.allocate_temp(py_object_type
, manage_ref
=True)
2470 '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % (
2472 module
.qualified_name
,
2474 code
.error_goto(self
.pos
)))
2475 for entry
in entries
:
2477 'if (__Pyx_ImportFunction(%s, "%s", (void (**)(void))&%s, "%s") < 0) %s' % (
2481 entry
.type.signature_string(),
2482 code
.error_goto(self
.pos
)))
2483 code
.putln("Py_DECREF(%s); %s = 0;" % (temp
, temp
))
2485 def generate_type_init_code(self
, env
, code
):
2486 # Generate type import code for extern extension types
2487 # and type ready code for non-extern ones.
2488 for entry
in env
.c_class_entries
:
2489 if entry
.visibility
== 'extern' and not entry
.utility_code_definition
:
2490 self
.generate_type_import_code(env
, entry
.type, entry
.pos
, code
)
2492 self
.generate_base_type_import_code(env
, entry
, code
)
2493 self
.generate_exttype_vtable_init_code(entry
, code
)
2494 self
.generate_type_ready_code(env
, entry
, code
)
2495 self
.generate_typeptr_assignment_code(entry
, code
)
2497 def generate_base_type_import_code(self
, env
, entry
, code
):
2498 base_type
= entry
.type.base_type
2499 if (base_type
and base_type
.module_name
!= env
.qualified_name
and not
2500 base_type
.is_builtin_type
and not entry
.utility_code_definition
):
2501 self
.generate_type_import_code(env
, base_type
, self
.pos
, code
)
2503 def generate_type_import_code(self
, env
, type, pos
, code
):
2504 # If not already done, generate code to import the typeobject of an
2505 # extension type defined in another module, and extract its C method
2506 # table pointer if any.
2507 if type in env
.types_imported
:
2509 env
.use_utility_code(UtilityCode
.load_cached("TypeImport", "ImportExport.c"))
2510 self
.generate_type_import_call(type, code
,
2511 code
.error_goto_if_null(type.typeptr_cname
, pos
))
2512 if type.vtabptr_cname
:
2513 code
.globalstate
.use_utility_code(
2514 UtilityCode
.load_cached('GetVTable', 'ImportExport.c'))
2515 code
.putln("%s = (struct %s*)__Pyx_GetVtable(%s->tp_dict); %s" % (
2517 type.vtabstruct_cname
,
2519 code
.error_goto_if_null(type.vtabptr_cname
, pos
)))
2520 env
.types_imported
.add(type)
2522 py3_type_name_map
= {'str' : 'bytes', 'unicode' : 'str'}
2524 def generate_type_import_call(self
, type, code
, error_code
):
2525 if type.typedef_flag
:
2526 objstruct
= type.objstruct_cname
2528 objstruct
= "struct %s" % type.objstruct_cname
2529 sizeof_objstruct
= objstruct
2530 module_name
= type.module_name
2531 condition
= replacement
= None
2532 if module_name
not in ('__builtin__', 'builtins'):
2533 module_name
= '"%s"' % module_name
2535 module_name
= '__Pyx_BUILTIN_MODULE_NAME'
2536 if type.name
in Code
.non_portable_builtins_map
:
2537 condition
, replacement
= Code
.non_portable_builtins_map
[type.name
]
2538 if objstruct
in Code
.basicsize_builtins_map
:
2539 # Some builtin types have a tp_basicsize which differs from sizeof(...):
2540 sizeof_objstruct
= Code
.basicsize_builtins_map
[objstruct
]
2542 code
.put('%s = __Pyx_ImportType(%s,' % (
2546 if condition
and replacement
:
2547 code
.putln("") # start in new line
2548 code
.putln("#if %s" % condition
)
2549 code
.putln('"%s",' % replacement
)
2551 code
.putln('"%s",' % type.name
)
2552 code
.putln("#endif")
2554 code
.put(' "%s", ' % type.name
)
2556 if sizeof_objstruct
!= objstruct
:
2558 code
.putln("") # start in new line
2559 code
.putln("#if CYTHON_COMPILING_IN_PYPY")
2560 code
.putln('sizeof(%s),' % objstruct
)
2562 code
.putln('sizeof(%s),' % sizeof_objstruct
)
2563 code
.putln("#endif")
2565 code
.put('sizeof(%s), ' % objstruct
)
2567 code
.putln('%i); %s' % (
2568 not type.is_external
or type.is_subclassed
,
2571 def generate_type_ready_code(self
, env
, entry
, code
):
2572 # Generate a call to PyType_Ready for an extension
2573 # type defined in this module.
2575 typeobj_cname
= type.typeobj_cname
2577 if scope
: # could be None if there was an error
2578 if entry
.visibility
!= 'extern':
2579 for slot
in TypeSlots
.slot_table
:
2580 slot
.generate_dynamic_init_code(scope
, code
)
2582 "if (PyType_Ready(&%s) < 0) %s" % (
2584 code
.error_goto(entry
.pos
)))
2585 # Don't inherit tp_print from builtin types, restoring the
2586 # behavior of using tp_repr or tp_str instead.
2587 code
.putln("%s.tp_print = 0;" % typeobj_cname
)
2588 # Fix special method docstrings. This is a bit of a hack, but
2589 # unless we let PyType_Ready create the slot wrappers we have
2590 # a significant performance hit. (See trac #561.)
2591 for func
in entry
.type.scope
.pyfunc_entries
:
2592 is_buffer
= func
.name
in ('__getbuffer__',
2593 '__releasebuffer__')
2594 if (func
.is_special
and Options
.docstrings
and
2595 func
.wrapperbase_cname
and not is_buffer
):
2596 slot
= TypeSlots
.method_name_to_slot
[func
.name
]
2597 preprocessor_guard
= slot
.preprocessor_guard_code()
2598 if preprocessor_guard
:
2599 code
.putln(preprocessor_guard
)
2600 code
.putln('#if CYTHON_COMPILING_IN_CPYTHON')
2603 'PyObject *wrapper = __Pyx_GetAttrString((PyObject *)&%s, "%s"); %s' % (
2606 code
.error_goto_if_null('wrapper', entry
.pos
)))
2608 "if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {")
2610 "%s = *((PyWrapperDescrObject *)wrapper)->d_base;" % (
2611 func
.wrapperbase_cname
))
2613 "%s.doc = %s;" % (func
.wrapperbase_cname
, func
.doc_cname
))
2615 "((PyWrapperDescrObject *)wrapper)->d_base = &%s;" % (
2616 func
.wrapperbase_cname
))
2619 code
.putln('#endif')
2620 if preprocessor_guard
:
2621 code
.putln('#endif')
2622 if type.vtable_cname
:
2624 "if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
2627 code
.error_goto(entry
.pos
)))
2628 code
.globalstate
.use_utility_code(
2629 UtilityCode
.load_cached('SetVTable', 'ImportExport.c'))
2630 if not type.scope
.is_internal
and not type.scope
.directives
['internal']:
2631 # scope.is_internal is set for types defined by
2632 # Cython (such as closures), the 'internal'
2633 # directive is set by users
2635 'if (__Pyx_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % (
2636 Naming
.module_cname
,
2639 code
.error_goto(entry
.pos
)))
2640 weakref_entry
= scope
.lookup_here("__weakref__")
2642 if weakref_entry
.type is py_object_type
:
2643 tp_weaklistoffset
= "%s.tp_weaklistoffset" % typeobj_cname
2644 if type.typedef_flag
:
2645 objstruct
= type.objstruct_cname
2647 objstruct
= "struct %s" % type.objstruct_cname
2648 code
.putln("if (%s == 0) %s = offsetof(%s, %s);" % (
2652 weakref_entry
.cname
))
2654 error(weakref_entry
.pos
, "__weakref__ slot must be of type 'object'")
2656 def generate_exttype_vtable_init_code(self
, entry
, code
):
2657 # Generate code to initialise the C method table of an
2660 if type.vtable_cname
:
2665 if type.base_type
and type.base_type
.vtabptr_cname
:
2669 Naming
.obj_base_cname
,
2670 type.base_type
.vtabptr_cname
))
2672 c_method_entries
= [
2673 entry
for entry
in type.scope
.cfunc_entries
2674 if entry
.func_cname
]
2675 if c_method_entries
:
2676 for meth_entry
in c_method_entries
:
2677 cast
= meth_entry
.type.signature_cast_string()
2683 meth_entry
.func_cname
))
2685 def generate_typeptr_assignment_code(self
, entry
, code
):
2686 # Generate code to initialise the typeptr of an extension
2687 # type defined in this module to point to its type object.
2689 if type.typeobj_cname
:
2692 type.typeptr_cname
, type.typeobj_cname
))
2694 def generate_cfunction_declaration(entry
, env
, code
, definition
):
2695 from_cy_utility
= entry
.used
and entry
.utility_code_definition
2696 if entry
.used
and entry
.inline_func_in_pxd
or (not entry
.in_cinclude
and (definition
2697 or entry
.defined_in_pxd
or entry
.visibility
== 'extern' or from_cy_utility
)):
2698 if entry
.visibility
== 'extern':
2699 storage_class
= Naming
.extern_c_macro
2700 dll_linkage
= "DL_IMPORT"
2701 elif entry
.visibility
== 'public':
2702 storage_class
= Naming
.extern_c_macro
2703 dll_linkage
= "DL_EXPORT"
2704 elif entry
.visibility
== 'private':
2705 storage_class
= "static"
2708 storage_class
= "static"
2712 if entry
.defined_in_pxd
and not definition
:
2713 storage_class
= "static"
2715 type = CPtrType(type)
2717 header
= type.declaration_code(
2718 entry
.cname
, dll_linkage
= dll_linkage
)
2719 modifiers
= code
.build_function_modifiers(entry
.func_modifiers
)
2720 code
.putln("%s %s%s; /*proto*/" % (
2725 #------------------------------------------------------------------------------------
2727 # Runtime support code
2729 #------------------------------------------------------------------------------------
2731 streq_utility_code
= UtilityCode(
2733 static CYTHON_INLINE int __Pyx_StrEq(const char *, const char *); /*proto*/
2736 static CYTHON_INLINE int __Pyx_StrEq(const char *s1, const char *s2) {
2737 while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; }
2742 #------------------------------------------------------------------------------------
2744 import_star_utility_code
= """
2746 /* import_all_from is an unexposed function from ceval.c */
2749 __Pyx_import_all_from(PyObject *locals, PyObject *v)
2751 PyObject *all = __Pyx_GetAttrString(v, "__all__");
2752 PyObject *dict, *name, *value;
2753 int skip_leading_underscores = 0;
2757 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
2758 return -1; /* Unexpected error */
2760 dict = __Pyx_GetAttrString(v, "__dict__");
2762 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
2764 PyErr_SetString(PyExc_ImportError,
2765 "from-import-* object has no __dict__ and no __all__");
2768 #if PY_MAJOR_VERSION < 3
2769 all = PyObject_CallMethod(dict, (char *)"keys", NULL);
2771 all = PyMapping_Keys(dict);
2776 skip_leading_underscores = 1;
2779 for (pos = 0, err = 0; ; pos++) {
2780 name = PySequence_GetItem(all, pos);
2782 if (!PyErr_ExceptionMatches(PyExc_IndexError))
2788 if (skip_leading_underscores &&
2789 #if PY_MAJOR_VERSION < 3
2790 PyString_Check(name) &&
2791 PyString_AS_STRING(name)[0] == '_')
2793 PyUnicode_Check(name) &&
2794 PyUnicode_AS_UNICODE(name)[0] == '_')
2800 value = PyObject_GetAttr(v, name);
2803 else if (PyDict_CheckExact(locals))
2804 err = PyDict_SetItem(locals, name, value);
2806 err = PyObject_SetItem(locals, name, value);
2817 static int %(IMPORT_STAR)s(PyObject* m) {
2822 PyObject *locals = 0;
2824 #if PY_MAJOR_VERSION >= 3
2825 PyObject *utf8_name = 0;
2830 locals = PyDict_New(); if (!locals) goto bad;
2831 if (__Pyx_import_all_from(locals, m) < 0) goto bad;
2832 list = PyDict_Items(locals); if (!list) goto bad;
2834 for(i=0; i<PyList_GET_SIZE(list); i++) {
2835 name = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 0);
2836 item = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 1);
2837 #if PY_MAJOR_VERSION >= 3
2838 utf8_name = PyUnicode_AsUTF8String(name);
2839 if (!utf8_name) goto bad;
2840 s = PyBytes_AS_STRING(utf8_name);
2841 if (%(IMPORT_STAR_SET)s(item, name, s) < 0) goto bad;
2842 Py_DECREF(utf8_name); utf8_name = 0;
2844 s = PyString_AsString(name);
2846 if (%(IMPORT_STAR_SET)s(item, name, s) < 0) goto bad;
2854 #if PY_MAJOR_VERSION >= 3
2855 Py_XDECREF(utf8_name);
2859 """ % {'IMPORT_STAR' : Naming
.import_star
,
2860 'IMPORT_STAR_SET' : Naming
.import_star_set
}
2862 refnanny_utility_code
= UtilityCode
.load_cached("Refnanny", "ModuleSetupCode.c")
2864 main_method
= UtilityCode
.load("MainFunction", "Embed.c")
2866 packed_struct_utility_code
= UtilityCode(proto
="""
2867 #if defined(__GNUC__)
2868 #define __Pyx_PACKED __attribute__((__packed__))
2870 #define __Pyx_PACKED
2872 """, impl
="", proto_block
='utility_code_proto_before_types')
2874 capsule_utility_code
= UtilityCode
.load("Capsule")