1# 2# Module parse tree node 3# 4 5from __future__ import absolute_import 6 7import cython 8cython.declare(Naming=object, Options=object, PyrexTypes=object, TypeSlots=object, 9 error=object, warning=object, py_object_type=object, UtilityCode=object, 10 EncodedString=object, re=object) 11 12from collections import defaultdict 13import json 14import operator 15import os 16import re 17import sys 18 19from .PyrexTypes import CPtrType 20from . import Future 21from . import Annotate 22from . import Code 23from . import Naming 24from . import Nodes 25from . import Options 26from . import TypeSlots 27from . import PyrexTypes 28from . import Pythran 29 30from .Errors import error, warning, CompileError 31from .PyrexTypes import py_object_type 32from ..Utils import open_new_file, replace_suffix, decode_filename, build_hex_version, is_cython_generated_file 33from .Code import UtilityCode, IncludeCode, TempitaUtilityCode 34from .StringEncoding import EncodedString, encoded_string_or_bytes_literal 35from .Pythran import has_np_pythran 36 37 38def replace_suffix_encoded(path, newsuf): 39 # calls replace suffix and returns a EncodedString or BytesLiteral with the encoding set 40 newpath = replace_suffix(path, newsuf) 41 return as_encoded_filename(newpath) 42 43def as_encoded_filename(path): 44 # wraps the path with either EncodedString or BytesLiteral (depending on its input type) 45 # and sets the encoding to the file system encoding 46 return encoded_string_or_bytes_literal(path, sys.getfilesystemencoding()) 47 48 49def check_c_declarations_pxd(module_node): 50 module_node.scope.check_c_classes_pxd() 51 return module_node 52 53 54def check_c_declarations(module_node): 55 module_node.scope.check_c_classes() 56 module_node.scope.check_c_functions() 57 return module_node 58 59 60def generate_c_code_config(env, options): 61 if Options.annotate or options.annotate: 62 emit_linenums = False 63 else: 64 emit_linenums = options.emit_linenums 65 66 if hasattr(options, "emit_code_comments"): 67 print('Warning: option emit_code_comments is deprecated. ' 68 'Instead, use compiler directive emit_code_comments.') 69 70 return Code.CCodeConfig( 71 emit_linenums=emit_linenums, 72 emit_code_comments=env.directives['emit_code_comments'], 73 c_line_in_traceback=options.c_line_in_traceback) 74 75# The code required to generate one comparison from another. 76# The keys are (from, to). 77# The comparison operator always goes first, with equality possibly second. 78# The first value specifies if the comparison is inverted. The second is the 79# logic op to use, and the third is if the equality is inverted or not. 80TOTAL_ORDERING = { 81 # a > b from (not a < b) and (a != b) 82 ('__lt__', '__gt__'): (True, '&&', True), 83 # a <= b from (a < b) or (a == b) 84 ('__lt__', '__le__'): (False, '||', False), 85 # a >= b from (not a < b). 86 ('__lt__', '__ge__'): (True, '', None), 87 88 # a >= b from (not a <= b) or (a == b) 89 ('__le__', '__ge__'): (True, '||', False), 90 # a < b, from (a <= b) and (a != b) 91 ('__le__', '__lt__'): (False, '&&', True), 92 # a > b from (not a <= b) 93 ('__le__', '__gt__'): (True, '', None), 94 95 # a < b from (not a > b) and (a != b) 96 ('__gt__', '__lt__'): (True, '&&', True), 97 # a >= b from (a > b) or (a == b) 98 ('__gt__', '__ge__'): (False, '||', False), 99 # a <= b from (not a > b) 100 ('__gt__', '__le__'): (True, '', None), 101 102 # Return a <= b from (not a >= b) or (a == b) 103 ('__ge__', '__le__'): (True, '||', False), 104 # a > b from (a >= b) and (a != b) 105 ('__ge__', '__gt__'): (False, '&&', True), 106 # a < b from (not a >= b) 107 ('__ge__', '__lt__'): (True, '', None), 108} 109 110 111class ModuleNode(Nodes.Node, Nodes.BlockNode): 112 # doc string or None 113 # body StatListNode 114 # 115 # referenced_modules [ModuleScope] 116 # full_module_name string 117 # 118 # scope The module scope. 119 # compilation_source A CompilationSource (see Main) 120 # directives Top-level compiler directives 121 122 child_attrs = ["body"] 123 directives = None 124 125 def merge_in(self, tree, scope, merge_scope=False): 126 # Merges in the contents of another tree, and possibly scope. With the 127 # current implementation below, this must be done right prior 128 # to code generation. 129 # 130 # Note: This way of doing it seems strange -- I believe the 131 # right concept is to split ModuleNode into a ModuleNode and a 132 # CodeGenerator, and tell that CodeGenerator to generate code 133 # from multiple sources. 134 assert isinstance(self.body, Nodes.StatListNode) 135 if scope.directives != self.scope.directives: 136 # merged in nodes should keep their original compiler directives 137 # (for example inline cdef functions) 138 tree = Nodes.CompilerDirectivesNode(tree.pos, body=tree, directives=scope.directives) 139 if isinstance(tree, Nodes.StatListNode): 140 self.body.stats.extend(tree.stats) 141 else: 142 self.body.stats.append(tree) 143 144 self.scope.utility_code_list.extend(scope.utility_code_list) 145 146 for inc in scope.c_includes.values(): 147 self.scope.process_include(inc) 148 149 def extend_if_not_in(L1, L2): 150 for x in L2: 151 if x not in L1: 152 L1.append(x) 153 154 extend_if_not_in(self.scope.included_files, scope.included_files) 155 156 if merge_scope: 157 # Ensure that we don't generate import code for these entries! 158 for entry in scope.c_class_entries: 159 entry.type.module_name = self.full_module_name 160 entry.type.scope.directives["internal"] = True 161 162 self.scope.merge_in(scope) 163 164 def with_compiler_directives(self): 165 # When merging a utility code module into the user code we need to preserve 166 # the original compiler directives. This returns the body of the module node, 167 # wrapped in its set of directives. 168 body = Nodes.CompilerDirectivesNode(self.pos, directives=self.directives, body=self.body) 169 return body 170 171 def analyse_declarations(self, env): 172 if has_np_pythran(env): 173 Pythran.include_pythran_generic(env) 174 if self.directives: 175 env.old_style_globals = self.directives['old_style_globals'] 176 if not Options.docstrings: 177 env.doc = self.doc = None 178 elif Options.embed_pos_in_docstring: 179 env.doc = EncodedString(u'File: %s (starting at line %s)' % Nodes.relative_position(self.pos)) 180 if self.doc is not None: 181 env.doc = EncodedString(env.doc + u'\n' + self.doc) 182 env.doc.encoding = self.doc.encoding 183 else: 184 env.doc = self.doc 185 env.directives = self.directives 186 187 self.body.analyse_declarations(env) 188 189 def prepare_utility_code(self): 190 # prepare any utility code that must be created before code generation 191 # specifically: CythonUtilityCode 192 env = self.scope 193 if env.has_import_star: 194 self.create_import_star_conversion_utility_code(env) 195 for name, entry in sorted(env.entries.items()): 196 if (entry.create_wrapper and entry.scope is env 197 and entry.is_type and (entry.type.is_enum or entry.type.is_cpp_enum)): 198 entry.type.create_type_wrapper(env) 199 200 def process_implementation(self, options, result): 201 env = self.scope 202 env.return_type = PyrexTypes.c_void_type 203 self.referenced_modules = [] 204 self.find_referenced_modules(env, self.referenced_modules, {}) 205 self.sort_cdef_classes(env) 206 self.generate_c_code(env, options, result) 207 self.generate_h_code(env, options, result) 208 self.generate_api_code(env, options, result) 209 210 def has_imported_c_functions(self): 211 for module in self.referenced_modules: 212 for entry in module.cfunc_entries: 213 if entry.defined_in_pxd: 214 return 1 215 return 0 216 217 def assure_safe_target(self, path, allow_failed=False): 218 # Check for a common gotcha for new users: naming your .pyx file after the .c file you want to wrap 219 if not is_cython_generated_file(path, allow_failed=allow_failed, if_not_found=True): 220 # Raising a fatal CompileError instead of calling error() to prevent castrating an existing file. 221 raise CompileError( 222 self.pos, 'The output file already exists and does not look like it was generated by Cython: "%s"' % 223 os.path.basename(path)) 224 225 def generate_h_code(self, env, options, result): 226 def h_entries(entries, api=0, pxd=0): 227 return [entry for entry in entries 228 if ((entry.visibility == 'public') or 229 (api and entry.api) or 230 (pxd and entry.defined_in_pxd))] 231 h_types = h_entries(env.type_entries, api=1) 232 h_vars = h_entries(env.var_entries) 233 h_funcs = h_entries(env.cfunc_entries) 234 h_extension_types = h_entries(env.c_class_entries) 235 236 if h_types or h_vars or h_funcs or h_extension_types: 237 result.h_file = replace_suffix_encoded(result.c_file, ".h") 238 self.assure_safe_target(result.h_file) 239 240 h_code_writer = Code.CCodeWriter() 241 c_code_config = generate_c_code_config(env, options) 242 globalstate = Code.GlobalState(h_code_writer, self, c_code_config) 243 globalstate.initialize_main_h_code() # in-case utility code is used in the header 244 h_code_start = globalstate.parts['h_code'] 245 h_code_main = globalstate.parts['type_declarations'] 246 h_code_end = globalstate.parts['end'] 247 if options.generate_pxi: 248 result.i_file = replace_suffix_encoded(result.c_file, ".pxi") 249 i_code = Code.PyrexCodeWriter(result.i_file) 250 else: 251 i_code = None 252 253 h_code_start.put_generated_by() 254 h_guard = self.api_name(Naming.h_guard_prefix, env) 255 h_code_start.put_h_guard(h_guard) 256 h_code_start.putln("") 257 h_code_start.putln('#include "Python.h"') 258 self.generate_type_header_code(h_types, h_code_start) 259 if options.capi_reexport_cincludes: 260 self.generate_includes(env, [], h_code_start) 261 h_code_start.putln("") 262 api_guard = self.api_name(Naming.api_guard_prefix, env) 263 h_code_start.putln("#ifndef %s" % api_guard) 264 h_code_start.putln("") 265 self.generate_extern_c_macro_definition(h_code_start) 266 h_code_start.putln("") 267 self.generate_dl_import_macro(h_code_start) 268 if h_extension_types: 269 h_code_main.putln("") 270 for entry in h_extension_types: 271 self.generate_cclass_header_code(entry.type, h_code_main) 272 if i_code: 273 self.generate_cclass_include_code(entry.type, i_code) 274 if h_funcs: 275 h_code_main.putln("") 276 for entry in h_funcs: 277 self.generate_public_declaration(entry, h_code_main, i_code) 278 if h_vars: 279 h_code_main.putln("") 280 for entry in h_vars: 281 self.generate_public_declaration(entry, h_code_main, i_code) 282 h_code_main.putln("") 283 h_code_main.putln("#endif /* !%s */" % api_guard) 284 h_code_main.putln("") 285 h_code_main.putln("/* WARNING: the interface of the module init function changed in CPython 3.5. */") 286 h_code_main.putln("/* It now returns a PyModuleDef instance instead of a PyModule instance. */") 287 h_code_main.putln("") 288 h_code_main.putln("#if PY_MAJOR_VERSION < 3") 289 if env.module_name.isascii(): 290 py2_mod_name = env.module_name 291 else: 292 py2_mod_name = env.module_name.encode("ascii", errors="ignore").decode("utf-8") 293 h_code_main.putln('#error "Unicode module names are not supported in Python 2";') 294 h_code_main.putln("PyMODINIT_FUNC init%s(void);" % py2_mod_name) 295 h_code_main.putln("#else") 296 py3_mod_func_name = self.mod_init_func_cname('PyInit', env) 297 warning_string = EncodedString('Use PyImport_AppendInittab("%s", %s) instead of calling %s directly.' % ( 298 py2_mod_name, py3_mod_func_name, py3_mod_func_name)) 299 h_code_main.putln('/* WARNING: %s from Python 3.5 */' % warning_string.rstrip('.')) 300 h_code_main.putln("PyMODINIT_FUNC %s(void);" % py3_mod_func_name) 301 h_code_main.putln("") 302 h_code_main.putln("#if PY_VERSION_HEX >= 0x03050000 " 303 "&& (defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER) " 304 "|| (defined(__cplusplus) && __cplusplus >= 201402L))") 305 h_code_main.putln("#if defined(__cplusplus) && __cplusplus >= 201402L") 306 h_code_main.putln("[[deprecated(%s)]] inline" % warning_string.as_c_string_literal()) 307 h_code_main.putln("#elif defined(__GNUC__) || defined(__clang__)") 308 h_code_main.putln('__attribute__ ((__deprecated__(%s), __unused__)) __inline__' % ( 309 warning_string.as_c_string_literal())) 310 h_code_main.putln("#elif defined(_MSC_VER)") 311 h_code_main.putln('__declspec(deprecated(%s)) __inline' % ( 312 warning_string.as_c_string_literal())) 313 h_code_main.putln('#endif') 314 h_code_main.putln("static PyObject* __PYX_WARN_IF_%s_INIT_CALLED(PyObject* res) {" % py3_mod_func_name) 315 h_code_main.putln("return res;") 316 h_code_main.putln("}") 317 # Function call is converted to warning macro; uncalled (pointer) is not 318 h_code_main.putln('#define %s() __PYX_WARN_IF_%s_INIT_CALLED(%s())' % ( 319 py3_mod_func_name, py3_mod_func_name, py3_mod_func_name)) 320 h_code_main.putln('#endif') 321 h_code_main.putln('#endif') 322 323 h_code_end.putln("") 324 h_code_end.putln("#endif /* !%s */" % h_guard) 325 326 with open_new_file(result.h_file) as f: 327 h_code_writer.copyto(f) 328 329 def generate_public_declaration(self, entry, h_code, i_code): 330 h_code.putln("%s %s;" % ( 331 Naming.extern_c_macro, 332 entry.type.declaration_code(entry.cname))) 333 if i_code: 334 i_code.putln("cdef extern %s" % ( 335 entry.type.declaration_code(entry.cname, pyrex=1))) 336 337 def api_name(self, prefix, env): 338 api_name = self.punycode_module_name(prefix, env.qualified_name) 339 return api_name.replace(".", "__") 340 341 def generate_api_code(self, env, options, result): 342 def api_entries(entries, pxd=0): 343 return [entry for entry in entries 344 if entry.api or (pxd and entry.defined_in_pxd)] 345 api_vars = api_entries(env.var_entries) 346 api_funcs = api_entries(env.cfunc_entries) 347 api_extension_types = api_entries(env.c_class_entries) 348 349 if api_vars or api_funcs or api_extension_types: 350 result.api_file = replace_suffix_encoded(result.c_file, "_api.h") 351 self.assure_safe_target(result.api_file) 352 353 h_code = Code.CCodeWriter() 354 c_code_config = generate_c_code_config(env, options) 355 Code.GlobalState(h_code, self, c_code_config) 356 h_code.put_generated_by() 357 api_guard = self.api_name(Naming.api_guard_prefix, env) 358 h_code.put_h_guard(api_guard) 359 # Work around https://bugs.python.org/issue4709 360 h_code.putln('#ifdef __MINGW64__') 361 h_code.putln('#define MS_WIN64') 362 h_code.putln('#endif') 363 364 h_code.putln('#include "Python.h"') 365 if result.h_file: 366 h_filename = os.path.basename(result.h_file) 367 h_filename = as_encoded_filename(h_filename) 368 h_code.putln('#include %s' % h_filename.as_c_string_literal()) 369 if api_extension_types: 370 h_code.putln("") 371 for entry in api_extension_types: 372 type = entry.type 373 h_code.putln("static PyTypeObject *%s = 0;" % type.typeptr_cname) 374 h_code.putln("#define %s (*%s)" % ( 375 type.typeobj_cname, type.typeptr_cname)) 376 if api_funcs: 377 h_code.putln("") 378 for entry in api_funcs: 379 type = CPtrType(entry.type) 380 cname = env.mangle(Naming.func_prefix_api, entry.name) 381 h_code.putln("static %s = 0;" % type.declaration_code(cname)) 382 h_code.putln("#define %s %s" % (entry.name, cname)) 383 if api_vars: 384 h_code.putln("") 385 for entry in api_vars: 386 type = CPtrType(entry.type) 387 cname = env.mangle(Naming.varptr_prefix_api, entry.name) 388 h_code.putln("static %s = 0;" % type.declaration_code(cname)) 389 h_code.putln("#define %s (*%s)" % (entry.name, cname)) 390 h_code.put(UtilityCode.load_as_string("PyIdentifierFromString", "ImportExport.c")[0]) 391 if api_vars: 392 h_code.put(UtilityCode.load_as_string("VoidPtrImport", "ImportExport.c")[1]) 393 if api_funcs: 394 h_code.put(UtilityCode.load_as_string("FunctionImport", "ImportExport.c")[1]) 395 if api_extension_types: 396 h_code.put(UtilityCode.load_as_string("TypeImport", "ImportExport.c")[0]) 397 h_code.put(UtilityCode.load_as_string("TypeImport", "ImportExport.c")[1]) 398 h_code.putln("") 399 h_code.putln("static int %s(void) {" % self.api_name("import", env)) 400 h_code.putln("PyObject *module = 0;") 401 h_code.putln('module = PyImport_ImportModule(%s);' % env.qualified_name.as_c_string_literal()) 402 h_code.putln("if (!module) goto bad;") 403 for entry in api_funcs: 404 cname = env.mangle(Naming.func_prefix_api, entry.name) 405 sig = entry.type.signature_string() 406 h_code.putln( 407 'if (__Pyx_ImportFunction(module, %s, (void (**)(void))&%s, "%s") < 0) goto bad;' 408 % (entry.name.as_c_string_literal(), cname, sig)) 409 for entry in api_vars: 410 cname = env.mangle(Naming.varptr_prefix_api, entry.name) 411 sig = entry.type.empty_declaration_code() 412 h_code.putln( 413 'if (__Pyx_ImportVoidPtr(module, %s, (void **)&%s, "%s") < 0) goto bad;' 414 % (entry.name.as_c_string_literal(), cname, sig)) 415 with ModuleImportGenerator(h_code, imported_modules={env.qualified_name: 'module'}) as import_generator: 416 for entry in api_extension_types: 417 self.generate_type_import_call(entry.type, h_code, import_generator, error_code="goto bad;") 418 h_code.putln("Py_DECREF(module); module = 0;") 419 h_code.putln("return 0;") 420 h_code.putln("bad:") 421 h_code.putln("Py_XDECREF(module);") 422 h_code.putln("return -1;") 423 h_code.putln("}") 424 h_code.putln("") 425 h_code.putln("#endif /* !%s */" % api_guard) 426 427 f = open_new_file(result.api_file) 428 try: 429 h_code.copyto(f) 430 finally: 431 f.close() 432 433 def generate_cclass_header_code(self, type, h_code): 434 h_code.putln("%s %s %s;" % ( 435 Naming.extern_c_macro, 436 PyrexTypes.public_decl("PyTypeObject", "DL_IMPORT"), 437 type.typeobj_cname)) 438 439 def generate_cclass_include_code(self, type, i_code): 440 i_code.putln("cdef extern class %s.%s:" % ( 441 type.module_name, type.name)) 442 i_code.indent() 443 var_entries = type.scope.var_entries 444 if var_entries: 445 for entry in var_entries: 446 i_code.putln("cdef %s" % ( 447 entry.type.declaration_code(entry.cname, pyrex=1))) 448 else: 449 i_code.putln("pass") 450 i_code.dedent() 451 452 def generate_c_code(self, env, options, result): 453 self.assure_safe_target(result.c_file, allow_failed=True) 454 modules = self.referenced_modules 455 456 if Options.annotate or options.annotate: 457 show_entire_c_code = Options.annotate == "fullc" or options.annotate == "fullc" 458 rootwriter = Annotate.AnnotationCCodeWriter( 459 show_entire_c_code=show_entire_c_code, 460 source_desc=self.compilation_source.source_desc, 461 ) 462 else: 463 rootwriter = Code.CCodeWriter() 464 465 c_code_config = generate_c_code_config(env, options) 466 467 globalstate = Code.GlobalState( 468 rootwriter, self, 469 code_config=c_code_config, 470 common_utility_include_dir=options.common_utility_include_dir, 471 ) 472 globalstate.initialize_main_c_code() 473 h_code = globalstate['h_code'] 474 475 self.generate_module_preamble(env, options, modules, result.embedded_metadata, h_code) 476 477 globalstate.module_pos = self.pos 478 globalstate.directives = self.directives 479 480 globalstate.use_utility_code(refnanny_utility_code) 481 482 code = globalstate['before_global_var'] 483 code.putln('#define __Pyx_MODULE_NAME %s' % 484 self.full_module_name.as_c_string_literal()) 485 module_is_main = self.is_main_module_flag_cname() 486 code.putln("extern int %s;" % module_is_main) 487 code.putln("int %s = 0;" % module_is_main) 488 code.putln("") 489 code.putln("/* Implementation of %s */" % env.qualified_name.as_c_string_literal()) 490 491 code = globalstate['late_includes'] 492 self.generate_includes(env, modules, code, early=False) 493 494 code = globalstate['module_code'] 495 496 self.generate_cached_builtins_decls(env, code) 497 498 # generate normal variable and function definitions 499 self.generate_lambda_definitions(env, code) 500 self.generate_variable_definitions(env, code) 501 self.body.generate_function_definitions(env, code) 502 503 code.mark_pos(None) 504 self.generate_typeobj_definitions(env, code) 505 self.generate_method_table(env, code) 506 if env.has_import_star: 507 self.generate_import_star(env, code) 508 509 # initialise the macro to reduce the code size of one-time functionality 510 code.putln(UtilityCode.load_as_string("SmallCodeConfig", "ModuleSetupCode.c")[0].strip()) 511 512 self.generate_module_state_start(env, globalstate['module_state']) 513 self.generate_module_state_defines(env, globalstate['module_state_defines']) 514 self.generate_module_state_clear(env, globalstate['module_state_clear']) 515 self.generate_module_state_traverse(env, globalstate['module_state_traverse']) 516 517 # init_globals is inserted before this 518 self.generate_module_init_func(modules[:-1], env, globalstate['init_module']) 519 self.generate_module_cleanup_func(env, globalstate['cleanup_module']) 520 if Options.embed: 521 self.generate_main_method(env, globalstate['main_method']) 522 self.generate_filename_table(globalstate['filename_table']) 523 524 self.generate_declarations_for_modules(env, modules, globalstate) 525 h_code.write('\n') 526 527 for utilcode in env.utility_code_list[:]: 528 globalstate.use_utility_code(utilcode) 529 globalstate.finalize_main_c_code() 530 531 self.generate_module_state_end(env, modules, globalstate) 532 533 f = open_new_file(result.c_file) 534 try: 535 rootwriter.copyto(f) 536 finally: 537 f.close() 538 result.c_file_generated = 1 539 if options.gdb_debug: 540 self._serialize_lineno_map(env, rootwriter) 541 if Options.annotate or options.annotate: 542 self._generate_annotations(rootwriter, result, options) 543 544 def _generate_annotations(self, rootwriter, result, options): 545 self.annotate(rootwriter) 546 547 coverage_xml_filename = Options.annotate_coverage_xml or options.annotate_coverage_xml 548 if coverage_xml_filename and os.path.exists(coverage_xml_filename): 549 try: 550 import xml.etree.cElementTree as ET 551 except ImportError: 552 import xml.etree.ElementTree as ET 553 coverage_xml = ET.parse(coverage_xml_filename).getroot() 554 for el in coverage_xml.iter(): 555 el.tail = None # save some memory 556 else: 557 coverage_xml = None 558 559 rootwriter.save_annotation(result.main_source_file, result.c_file, coverage_xml=coverage_xml) 560 561 # if we included files, additionally generate one annotation file for each 562 if not self.scope.included_files: 563 return 564 565 search_include_file = self.scope.context.search_include_directories 566 target_dir = os.path.abspath(os.path.dirname(result.c_file)) 567 for included_file in self.scope.included_files: 568 target_file = os.path.abspath(os.path.join(target_dir, included_file)) 569 target_file_dir = os.path.dirname(target_file) 570 if not target_file_dir.startswith(target_dir): 571 # any other directories may not be writable => avoid trying 572 continue 573 source_file = search_include_file(included_file, source_pos=self.pos, include=True) 574 if not source_file: 575 continue 576 if target_file_dir != target_dir and not os.path.exists(target_file_dir): 577 try: 578 os.makedirs(target_file_dir) 579 except OSError as e: 580 import errno 581 if e.errno != errno.EEXIST: 582 raise 583 rootwriter.save_annotation(source_file, target_file, coverage_xml=coverage_xml) 584 585 def _serialize_lineno_map(self, env, ccodewriter): 586 tb = env.context.gdb_debug_outputwriter 587 markers = ccodewriter.buffer.allmarkers() 588 589 d = defaultdict(list) 590 for c_lineno, (src_desc, src_lineno) in enumerate(markers): 591 if src_lineno > 0 and src_desc.filename is not None: 592 d[src_desc, src_lineno].append(c_lineno + 1) 593 594 tb.start('LineNumberMapping') 595 for (src_desc, src_lineno), c_linenos in sorted(d.items()): 596 assert src_desc.filename is not None 597 tb.add_entry( 598 'LineNumber', 599 c_linenos=' '.join(map(str, c_linenos)), 600 src_path=src_desc.filename, 601 src_lineno=str(src_lineno), 602 ) 603 tb.end('LineNumberMapping') 604 tb.serialize() 605 606 def find_referenced_modules(self, env, module_list, modules_seen): 607 if env not in modules_seen: 608 modules_seen[env] = 1 609 for imported_module in env.cimported_modules: 610 self.find_referenced_modules(imported_module, module_list, modules_seen) 611 module_list.append(env) 612 613 def sort_types_by_inheritance(self, type_dict, type_order, getkey): 614 # copy the types into a list moving each parent type before 615 # its first child 616 type_list = [] 617 for i, key in enumerate(type_order): 618 new_entry = type_dict[key] 619 620 # collect all base classes to check for children 621 hierarchy = set() 622 base = new_entry 623 while base: 624 base_type = base.type.base_type 625 if not base_type: 626 break 627 base_key = getkey(base_type) 628 hierarchy.add(base_key) 629 base = type_dict.get(base_key) 630 new_entry.base_keys = hierarchy 631 632 # find the first (sub-)subclass and insert before that 633 for j in range(i): 634 entry = type_list[j] 635 if key in entry.base_keys: 636 type_list.insert(j, new_entry) 637 break 638 else: 639 type_list.append(new_entry) 640 return type_list 641 642 def sort_type_hierarchy(self, module_list, env): 643 # poor developer's OrderedDict 644 vtab_dict, vtab_dict_order = {}, [] 645 vtabslot_dict, vtabslot_dict_order = {}, [] 646 647 for module in module_list: 648 for entry in module.c_class_entries: 649 if entry.used and not entry.in_cinclude: 650 type = entry.type 651 key = type.vtabstruct_cname 652 if not key: 653 continue 654 if key in vtab_dict: 655 # FIXME: this should *never* happen, but apparently it does 656 # for Cython generated utility code 657 from .UtilityCode import NonManglingModuleScope 658 assert isinstance(entry.scope, NonManglingModuleScope), str(entry.scope) 659 assert isinstance(vtab_dict[key].scope, NonManglingModuleScope), str(vtab_dict[key].scope) 660 else: 661 vtab_dict[key] = entry 662 vtab_dict_order.append(key) 663 all_defined_here = module is env 664 for entry in module.type_entries: 665 if entry.used and (all_defined_here or entry.defined_in_pxd): 666 type = entry.type 667 if type.is_extension_type and not entry.in_cinclude: 668 type = entry.type 669 key = type.objstruct_cname 670 assert key not in vtabslot_dict, key 671 vtabslot_dict[key] = entry 672 vtabslot_dict_order.append(key) 673 674 def vtabstruct_cname(entry_type): 675 return entry_type.vtabstruct_cname 676 vtab_list = self.sort_types_by_inheritance( 677 vtab_dict, vtab_dict_order, vtabstruct_cname) 678 679 def objstruct_cname(entry_type): 680 return entry_type.objstruct_cname 681 vtabslot_list = self.sort_types_by_inheritance( 682 vtabslot_dict, vtabslot_dict_order, objstruct_cname) 683 684 return (vtab_list, vtabslot_list) 685 686 def sort_cdef_classes(self, env): 687 key_func = operator.attrgetter('objstruct_cname') 688 entry_dict, entry_order = {}, [] 689 for entry in env.c_class_entries: 690 key = key_func(entry.type) 691 assert key not in entry_dict, key 692 entry_dict[key] = entry 693 entry_order.append(key) 694 env.c_class_entries[:] = self.sort_types_by_inheritance( 695 entry_dict, entry_order, key_func) 696 697 def generate_type_definitions(self, env, modules, vtab_list, vtabslot_list, code): 698 # TODO: Why are these separated out? 699 for entry in vtabslot_list: 700 self.generate_objstruct_predeclaration(entry.type, code) 701 vtabslot_entries = set(vtabslot_list) 702 ctuple_names = set() 703 for module in modules: 704 definition = module is env 705 type_entries = [] 706 for entry in module.type_entries: 707 if entry.type.is_ctuple and entry.used: 708 if entry.name not in ctuple_names: 709 ctuple_names.add(entry.name) 710 type_entries.append(entry) 711 elif definition or entry.defined_in_pxd: 712 type_entries.append(entry) 713 type_entries = [t for t in type_entries if t not in vtabslot_entries] 714 self.generate_type_header_code(type_entries, code) 715 for entry in vtabslot_list: 716 self.generate_objstruct_definition(entry.type, code) 717 self.generate_typeobj_predeclaration(entry, code) 718 for entry in vtab_list: 719 self.generate_typeobj_predeclaration(entry, code) 720 self.generate_exttype_vtable_struct(entry, code) 721 self.generate_exttype_vtabptr_declaration(entry, code) 722 self.generate_exttype_final_methods_declaration(entry, code) 723 724 def generate_declarations_for_modules(self, env, modules, globalstate): 725 typecode = globalstate['type_declarations'] 726 typecode.putln("") 727 typecode.putln("/*--- Type declarations ---*/") 728 # This is to work around the fact that array.h isn't part of the C-API, 729 # but we need to declare it earlier than utility code. 730 if 'cpython.array' in [m.qualified_name for m in modules]: 731 typecode.putln('#ifndef _ARRAYARRAY_H') 732 typecode.putln('struct arrayobject;') 733 typecode.putln('typedef struct arrayobject arrayobject;') 734 typecode.putln('#endif') 735 vtab_list, vtabslot_list = self.sort_type_hierarchy(modules, env) 736 self.generate_type_definitions( 737 env, modules, vtab_list, vtabslot_list, typecode) 738 modulecode = globalstate['module_declarations'] 739 for module in modules: 740 defined_here = module is env 741 modulecode.putln("") 742 modulecode.putln("/* Module declarations from %s */" % module.qualified_name.as_c_string_literal()) 743 self.generate_c_class_declarations(module, modulecode, defined_here, globalstate) 744 self.generate_cvariable_declarations(module, modulecode, defined_here) 745 self.generate_cfunction_declarations(module, modulecode, defined_here) 746 747 @staticmethod 748 def _put_setup_code(code, name): 749 code.put(UtilityCode.load_as_string(name, "ModuleSetupCode.c")[1]) 750 751 def generate_module_preamble(self, env, options, cimported_modules, metadata, code): 752 code.put_generated_by() 753 if metadata: 754 code.putln("/* BEGIN: Cython Metadata") 755 code.putln(json.dumps(metadata, indent=4, sort_keys=True)) 756 code.putln("END: Cython Metadata */") 757 code.putln("") 758 759 code.putln("#ifndef PY_SSIZE_T_CLEAN") 760 code.putln("#define PY_SSIZE_T_CLEAN") 761 code.putln("#endif /* PY_SSIZE_T_CLEAN */") 762 self._put_setup_code(code, "InitLimitedAPI") 763 764 for inc in sorted(env.c_includes.values(), key=IncludeCode.sortkey): 765 if inc.location == inc.INITIAL: 766 inc.write(code) 767 code.putln("#ifndef Py_PYTHON_H") 768 code.putln(" #error Python headers needed to compile C extensions, " 769 "please install development version of Python.") 770 code.putln("#elif PY_VERSION_HEX < 0x02070000 || " 771 "(0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000)") 772 code.putln(" #error Cython requires Python 2.7+ or Python 3.3+.") 773 code.putln("#else") 774 code.globalstate["end"].putln("#endif /* Py_PYTHON_H */") 775 776 from .. import __version__ 777 code.putln('#define CYTHON_ABI "%s"' % __version__.replace('.', '_')) 778 code.putln('#define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI') 779 code.putln('#define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "."') 780 code.putln('#define CYTHON_HEX_VERSION %s' % build_hex_version(__version__)) 781 code.putln("#define CYTHON_FUTURE_DIVISION %d" % ( 782 Future.division in env.context.future_directives)) 783 784 self._put_setup_code(code, "CModulePreamble") 785 if env.context.options.cplus: 786 self._put_setup_code(code, "CppInitCode") 787 else: 788 self._put_setup_code(code, "CInitCode") 789 self._put_setup_code(code, "PythonCompatibility") 790 self._put_setup_code(code, "MathInitCode") 791 792 # Using "(void)cname" to prevent "unused" warnings. 793 if options.c_line_in_traceback: 794 cinfo = "%s = %s; (void)%s; " % (Naming.clineno_cname, Naming.line_c_macro, Naming.clineno_cname) 795 else: 796 cinfo = "" 797 code.putln("#define __PYX_MARK_ERR_POS(f_index, lineno) \\") 798 code.putln(" { %s = %s[f_index]; (void)%s; %s = lineno; (void)%s; %s}" % ( 799 Naming.filename_cname, Naming.filetable_cname, Naming.filename_cname, 800 Naming.lineno_cname, Naming.lineno_cname, 801 cinfo 802 )) 803 code.putln("#define __PYX_ERR(f_index, lineno, Ln_error) \\") 804 code.putln(" { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; }") 805 806 code.putln("") 807 self.generate_extern_c_macro_definition(code) 808 code.putln("") 809 810 code.putln("#define %s" % self.api_name(Naming.h_guard_prefix, env)) 811 code.putln("#define %s" % self.api_name(Naming.api_guard_prefix, env)) 812 code.putln("/* Early includes */") 813 self.generate_includes(env, cimported_modules, code, late=False) 814 code.putln("") 815 code.putln("#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS)") 816 code.putln("#define CYTHON_WITHOUT_ASSERTIONS") 817 code.putln("#endif") 818 code.putln("") 819 820 if env.directives['ccomplex']: 821 code.putln("") 822 code.putln("#if !defined(CYTHON_CCOMPLEX)") 823 code.putln("#define CYTHON_CCOMPLEX 1") 824 code.putln("#endif") 825 code.putln("") 826 code.put(UtilityCode.load_as_string("UtilityFunctionPredeclarations", "ModuleSetupCode.c")[0]) 827 828 c_string_type = env.directives['c_string_type'] 829 c_string_encoding = env.directives['c_string_encoding'] 830 if c_string_type not in ('bytes', 'bytearray') and not c_string_encoding: 831 error(self.pos, "a default encoding must be provided if c_string_type is not a byte type") 832 code.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII %s' % int(c_string_encoding == 'ascii')) 833 code.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 %s' % 834 int(c_string_encoding.replace('-', '').lower() == 'utf8')) 835 if c_string_encoding == 'default': 836 code.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 1') 837 else: 838 code.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT ' 839 '(PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8)') 840 code.putln('#define __PYX_DEFAULT_STRING_ENCODING "%s"' % c_string_encoding) 841 if c_string_type == 'bytearray': 842 c_string_func_name = 'ByteArray' 843 else: 844 c_string_func_name = c_string_type.title() 845 code.putln('#define __Pyx_PyObject_FromString __Pyx_Py%s_FromString' % c_string_func_name) 846 code.putln('#define __Pyx_PyObject_FromStringAndSize __Pyx_Py%s_FromStringAndSize' % c_string_func_name) 847 code.put(UtilityCode.load_as_string("TypeConversions", "TypeConversion.c")[0]) 848 env.use_utility_code(UtilityCode.load_cached("FormatTypeName", "ObjectHandling.c")) 849 850 # These utility functions are assumed to exist and used elsewhere. 851 PyrexTypes.c_long_type.create_to_py_utility_code(env) 852 PyrexTypes.c_long_type.create_from_py_utility_code(env) 853 PyrexTypes.c_int_type.create_from_py_utility_code(env) 854 855 code.put(Nodes.branch_prediction_macros) 856 code.putln('static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; }') 857 code.putln('') 858 code.putln('#if !CYTHON_USE_MODULE_STATE') 859 code.putln('static PyObject *%s = NULL;' % env.module_cname) 860 code.putln('static PyObject *%s;' % env.module_dict_cname) 861 code.putln('static PyObject *%s;' % Naming.builtins_cname) 862 code.putln('static PyObject *%s = NULL;' % Naming.cython_runtime_cname) 863 code.putln('static PyObject *%s;' % Naming.empty_tuple) 864 code.putln('static PyObject *%s;' % Naming.empty_bytes) 865 code.putln('static PyObject *%s;' % Naming.empty_unicode) 866 if Options.pre_import is not None: 867 code.putln('static PyObject *%s;' % Naming.preimport_cname) 868 code.putln('#endif') 869 870 code.putln('static int %s;' % Naming.lineno_cname) 871 code.putln('static int %s = 0;' % Naming.clineno_cname) 872 code.putln('static const char * %s = %s;' % (Naming.cfilenm_cname, Naming.file_c_macro)) 873 code.putln('static const char *%s;' % Naming.filename_cname) 874 875 env.use_utility_code(UtilityCode.load_cached("FastTypeChecks", "ModuleSetupCode.c")) 876 if has_np_pythran(env): 877 env.use_utility_code(UtilityCode.load_cached("PythranConversion", "CppSupport.cpp")) 878 879 def generate_extern_c_macro_definition(self, code): 880 name = Naming.extern_c_macro 881 code.putln("#ifndef %s" % name) 882 code.putln(" #ifdef __cplusplus") 883 code.putln(' #define %s extern "C"' % name) 884 code.putln(" #else") 885 code.putln(" #define %s extern" % name) 886 code.putln(" #endif") 887 code.putln("#endif") 888 889 def generate_dl_import_macro(self, code): 890 code.putln("#ifndef DL_IMPORT") 891 code.putln(" #define DL_IMPORT(_T) _T") 892 code.putln("#endif") 893 894 def generate_includes(self, env, cimported_modules, code, early=True, late=True): 895 for inc in sorted(env.c_includes.values(), key=IncludeCode.sortkey): 896 if inc.location == inc.EARLY: 897 if early: 898 inc.write(code) 899 elif inc.location == inc.LATE: 900 if late: 901 inc.write(code) 902 if early: 903 code.putln_openmp("#include <omp.h>") 904 905 def generate_filename_table(self, code): 906 from os.path import isabs, basename 907 code.putln("") 908 code.putln("static const char *%s[] = {" % Naming.filetable_cname) 909 if code.globalstate.filename_list: 910 for source_desc in code.globalstate.filename_list: 911 file_path = source_desc.get_filenametable_entry() 912 if isabs(file_path): 913 file_path = basename(file_path) # never include absolute paths 914 escaped_filename = file_path.replace("\\", "\\\\").replace('"', r'\"') 915 escaped_filename = as_encoded_filename(escaped_filename) 916 code.putln('%s,' % escaped_filename.as_c_string_literal()) 917 else: 918 # Some C compilers don't like an empty array 919 code.putln("0") 920 code.putln("};") 921 922 def generate_type_predeclarations(self, env, code): 923 pass 924 925 def generate_type_header_code(self, type_entries, code): 926 # Generate definitions of structs/unions/enums/typedefs/objstructs. 927 #self.generate_gcc33_hack(env, code) # Is this still needed? 928 # Forward declarations 929 for entry in type_entries: 930 if not entry.in_cinclude: 931 #print "generate_type_header_code:", entry.name, repr(entry.type) ### 932 type = entry.type 933 if type.is_typedef: # Must test this first! 934 pass 935 elif type.is_struct_or_union or type.is_cpp_class: 936 self.generate_struct_union_predeclaration(entry, code) 937 elif type.is_ctuple and entry.used: 938 self.generate_struct_union_predeclaration(entry.type.struct_entry, code) 939 elif type.is_extension_type: 940 self.generate_objstruct_predeclaration(type, code) 941 # Actual declarations 942 for entry in type_entries: 943 if not entry.in_cinclude: 944 #print "generate_type_header_code:", entry.name, repr(entry.type) ### 945 type = entry.type 946 if type.is_typedef: # Must test this first! 947 self.generate_typedef(entry, code) 948 elif type.is_enum or type.is_cpp_enum: 949 self.generate_enum_definition(entry, code) 950 elif type.is_struct_or_union: 951 self.generate_struct_union_definition(entry, code) 952 elif type.is_ctuple and entry.used: 953 self.generate_struct_union_definition(entry.type.struct_entry, code) 954 elif type.is_cpp_class: 955 self.generate_cpp_class_definition(entry, code) 956 elif type.is_extension_type: 957 self.generate_objstruct_definition(type, code) 958 959 def generate_gcc33_hack(self, env, code): 960 # Workaround for spurious warning generation in gcc 3.3 961 code.putln("") 962 for entry in env.c_class_entries: 963 type = entry.type 964 if not type.typedef_flag: 965 name = type.objstruct_cname 966 if name.startswith("__pyx_"): 967 tail = name[6:] 968 else: 969 tail = name 970 code.putln("typedef struct %s __pyx_gcc33_%s;" % ( 971 name, tail)) 972 973 def generate_typedef(self, entry, code): 974 base_type = entry.type.typedef_base_type 975 if base_type.is_numeric: 976 try: 977 writer = code.globalstate['numeric_typedefs'] 978 except KeyError: 979 writer = code 980 else: 981 writer = code 982 writer.mark_pos(entry.pos) 983 writer.putln("typedef %s;" % base_type.declaration_code(entry.cname)) 984 985 def sue_predeclaration(self, type, kind, name): 986 if type.typedef_flag: 987 return "%s %s;\ntypedef %s %s %s;" % ( 988 kind, name, 989 kind, name, name) 990 else: 991 return "%s %s;" % (kind, name) 992 993 def generate_struct_union_predeclaration(self, entry, code): 994 type = entry.type 995 if type.is_cpp_class and type.templates: 996 code.putln("template <typename %s>" % ", typename ".join( 997 [T.empty_declaration_code() for T in type.templates])) 998 code.putln(self.sue_predeclaration(type, type.kind, type.cname)) 999 1000 def sue_header_footer(self, type, kind, name): 1001 header = "%s %s {" % (kind, name) 1002 footer = "};" 1003 return header, footer 1004 1005 def generate_struct_union_definition(self, entry, code): 1006 code.mark_pos(entry.pos) 1007 type = entry.type 1008 scope = type.scope 1009 if scope: 1010 kind = type.kind 1011 packed = type.is_struct and type.packed 1012 if packed: 1013 kind = "%s %s" % (type.kind, "__Pyx_PACKED") 1014 code.globalstate.use_utility_code(packed_struct_utility_code) 1015 header, footer = \ 1016 self.sue_header_footer(type, kind, type.cname) 1017 if packed: 1018 code.putln("#if defined(__SUNPRO_C)") 1019 code.putln(" #pragma pack(1)") 1020 code.putln("#elif !defined(__GNUC__)") 1021 code.putln(" #pragma pack(push, 1)") 1022 code.putln("#endif") 1023 code.putln(header) 1024 var_entries = scope.var_entries 1025 for attr in var_entries: 1026 code.putln( 1027 "%s;" % attr.type.declaration_code(attr.cname)) 1028 code.putln(footer) 1029 if packed: 1030 code.putln("#if defined(__SUNPRO_C)") 1031 code.putln(" #pragma pack()") 1032 code.putln("#elif !defined(__GNUC__)") 1033 code.putln(" #pragma pack(pop)") 1034 code.putln("#endif") 1035 1036 def generate_cpp_class_definition(self, entry, code): 1037 code.mark_pos(entry.pos) 1038 type = entry.type 1039 scope = type.scope 1040 if scope: 1041 if type.templates: 1042 code.putln("template <class %s>" % ", class ".join( 1043 [T.empty_declaration_code() for T in type.templates])) 1044 # Just let everything be public. 1045 code.put("struct %s" % type.cname) 1046 if type.base_classes: 1047 base_class_decl = ", public ".join( 1048 [base_class.empty_declaration_code() for base_class in type.base_classes]) 1049 code.put(" : public %s" % base_class_decl) 1050 code.putln(" {") 1051 py_attrs = [e for e in scope.entries.values() 1052 if e.type.is_pyobject and not e.is_inherited] 1053 has_virtual_methods = False 1054 constructor = None 1055 destructor = None 1056 for attr in scope.var_entries: 1057 if attr.type.is_cfunction and attr.type.is_static_method: 1058 code.put("static ") 1059 elif attr.name == "<init>": 1060 constructor = attr 1061 elif attr.name == "<del>": 1062 destructor = attr 1063 elif attr.type.is_cfunction: 1064 code.put("virtual ") 1065 has_virtual_methods = True 1066 code.putln("%s;" % attr.type.declaration_code(attr.cname)) 1067 is_implementing = 'init_module' in code.globalstate.parts 1068 if constructor or py_attrs: 1069 if constructor: 1070 arg_decls = [] 1071 arg_names = [] 1072 for arg in constructor.type.original_args[ 1073 :len(constructor.type.args)-constructor.type.optional_arg_count]: 1074 arg_decls.append(arg.declaration_code()) 1075 arg_names.append(arg.cname) 1076 if constructor.type.optional_arg_count: 1077 arg_decls.append(constructor.type.op_arg_struct.declaration_code(Naming.optional_args_cname)) 1078 arg_names.append(Naming.optional_args_cname) 1079 if not arg_decls: 1080 arg_decls = ["void"] 1081 else: 1082 arg_decls = ["void"] 1083 arg_names = [] 1084 if is_implementing: 1085 code.putln("%s(%s) {" % (type.cname, ", ".join(arg_decls))) 1086 if py_attrs: 1087 code.put_ensure_gil() 1088 for attr in py_attrs: 1089 code.put_init_var_to_py_none(attr, nanny=False) 1090 if constructor: 1091 code.putln("%s(%s);" % (constructor.cname, ", ".join(arg_names))) 1092 if py_attrs: 1093 code.put_release_ensured_gil() 1094 code.putln("}") 1095 else: 1096 code.putln("%s(%s);" % (type.cname, ", ".join(arg_decls))) 1097 if destructor or py_attrs or has_virtual_methods: 1098 if has_virtual_methods: 1099 code.put("virtual ") 1100 if is_implementing: 1101 code.putln("~%s() {" % type.cname) 1102 if py_attrs: 1103 code.put_ensure_gil() 1104 if destructor: 1105 code.putln("%s();" % destructor.cname) 1106 if py_attrs: 1107 for attr in py_attrs: 1108 code.put_var_xdecref(attr, nanny=False) 1109 code.put_release_ensured_gil() 1110 code.putln("}") 1111 else: 1112 code.putln("~%s();" % type.cname) 1113 if py_attrs: 1114 # Also need copy constructor and assignment operators. 1115 if is_implementing: 1116 code.putln("%s(const %s& __Pyx_other) {" % (type.cname, type.cname)) 1117 code.put_ensure_gil() 1118 for attr in scope.var_entries: 1119 if not attr.type.is_cfunction: 1120 code.putln("%s = __Pyx_other.%s;" % (attr.cname, attr.cname)) 1121 code.put_var_incref(attr, nanny=False) 1122 code.put_release_ensured_gil() 1123 code.putln("}") 1124 code.putln("%s& operator=(const %s& __Pyx_other) {" % (type.cname, type.cname)) 1125 code.putln("if (this != &__Pyx_other) {") 1126 code.put_ensure_gil() 1127 for attr in scope.var_entries: 1128 if not attr.type.is_cfunction: 1129 code.put_var_xdecref(attr, nanny=False) 1130 code.putln("%s = __Pyx_other.%s;" % (attr.cname, attr.cname)) 1131 code.put_var_incref(attr, nanny=False) 1132 code.put_release_ensured_gil() 1133 code.putln("}") 1134 code.putln("return *this;") 1135 code.putln("}") 1136 else: 1137 code.putln("%s(const %s& __Pyx_other);" % (type.cname, type.cname)) 1138 code.putln("%s& operator=(const %s& __Pyx_other);" % (type.cname, type.cname)) 1139 code.putln("};") 1140 1141 def generate_enum_definition(self, entry, code): 1142 code.mark_pos(entry.pos) 1143 type = entry.type 1144 name = entry.cname or entry.name or "" 1145 1146 kind = "enum class" if entry.type.is_cpp_enum else "enum" 1147 header, footer = self.sue_header_footer(type, kind, name) 1148 code.putln(header) 1149 enum_values = entry.enum_values 1150 if not enum_values: 1151 error(entry.pos, "Empty enum definition not allowed outside a 'cdef extern from' block") 1152 else: 1153 last_entry = enum_values[-1] 1154 # this does not really generate code, just builds the result value 1155 for value_entry in enum_values: 1156 if value_entry.value_node is not None: 1157 value_entry.value_node.generate_evaluation_code(code) 1158 1159 for value_entry in enum_values: 1160 if value_entry.value_node is None: 1161 value_code = value_entry.cname.split("::")[-1] 1162 else: 1163 value_code = ("%s = %s" % ( 1164 value_entry.cname.split("::")[-1], 1165 value_entry.value_node.result())) 1166 if value_entry is not last_entry: 1167 value_code += "," 1168 code.putln(value_code) 1169 code.putln(footer) 1170 1171 if entry.type.is_enum: 1172 if entry.type.typedef_flag: 1173 # Not pre-declared. 1174 code.putln("typedef enum %s %s;" % (name, name)) 1175 1176 def generate_typeobj_predeclaration(self, entry, code): 1177 code.putln("") 1178 name = entry.type.typeobj_cname 1179 if name: 1180 if entry.visibility == 'extern' and not entry.in_cinclude: 1181 code.putln("%s %s %s;" % ( 1182 Naming.extern_c_macro, 1183 PyrexTypes.public_decl("PyTypeObject", "DL_IMPORT"), 1184 name)) 1185 elif entry.visibility == 'public': 1186 code.putln("%s %s %s;" % ( 1187 Naming.extern_c_macro, 1188 PyrexTypes.public_decl("PyTypeObject", "DL_EXPORT"), 1189 name)) 1190 # ??? Do we really need the rest of this? ??? 1191 #else: 1192 # code.putln("static PyTypeObject %s;" % name) 1193 1194 def generate_exttype_vtable_struct(self, entry, code): 1195 if not entry.used: 1196 return 1197 1198 code.mark_pos(entry.pos) 1199 # Generate struct declaration for an extension type's vtable. 1200 type = entry.type 1201 scope = type.scope 1202 1203 self.specialize_fused_types(scope) 1204 1205 if type.vtabstruct_cname: 1206 code.putln("") 1207 code.putln("struct %s {" % type.vtabstruct_cname) 1208 if type.base_type and type.base_type.vtabstruct_cname: 1209 code.putln("struct %s %s;" % ( 1210 type.base_type.vtabstruct_cname, 1211 Naming.obj_base_cname)) 1212 for method_entry in scope.cfunc_entries: 1213 if not method_entry.is_inherited: 1214 code.putln("%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.cname)) 1215 code.putln("};") 1216 1217 def generate_exttype_vtabptr_declaration(self, entry, code): 1218 if not entry.used: 1219 return 1220 1221 code.mark_pos(entry.pos) 1222 # Generate declaration of pointer to an extension type's vtable. 1223 type = entry.type 1224 if type.vtabptr_cname: 1225 code.putln("static struct %s *%s;" % ( 1226 type.vtabstruct_cname, 1227 type.vtabptr_cname)) 1228 1229 def generate_exttype_final_methods_declaration(self, entry, code): 1230 if not entry.used: 1231 return 1232 1233 code.mark_pos(entry.pos) 1234 # Generate final methods prototypes 1235 type = entry.type 1236 for method_entry in entry.type.scope.cfunc_entries: 1237 if not method_entry.is_inherited and method_entry.final_func_cname: 1238 declaration = method_entry.type.declaration_code( 1239 method_entry.final_func_cname) 1240 modifiers = code.build_function_modifiers(method_entry.func_modifiers) 1241 code.putln("static %s%s;" % (modifiers, declaration)) 1242 1243 def generate_objstruct_predeclaration(self, type, code): 1244 if not type.scope: 1245 return 1246 code.putln(self.sue_predeclaration(type, "struct", type.objstruct_cname)) 1247 1248 def generate_objstruct_definition(self, type, code): 1249 code.mark_pos(type.pos) 1250 # Generate object struct definition for an 1251 # extension type. 1252 if not type.scope: 1253 return # Forward declared but never defined 1254 header, footer = \ 1255 self.sue_header_footer(type, "struct", type.objstruct_cname) 1256 code.putln(header) 1257 base_type = type.base_type 1258 if base_type: 1259 basestruct_cname = base_type.objstruct_cname 1260 if basestruct_cname == "PyTypeObject": 1261 # User-defined subclasses of type are heap allocated. 1262 basestruct_cname = "PyHeapTypeObject" 1263 code.putln( 1264 "%s%s %s;" % ( 1265 ("struct ", "")[base_type.typedef_flag], 1266 basestruct_cname, 1267 Naming.obj_base_cname)) 1268 else: 1269 code.putln( 1270 "PyObject_HEAD") 1271 if type.vtabslot_cname and not (type.base_type and type.base_type.vtabslot_cname): 1272 code.putln( 1273 "struct %s *%s;" % ( 1274 type.vtabstruct_cname, 1275 type.vtabslot_cname)) 1276 for attr in type.scope.var_entries: 1277 if attr.is_declared_generic: 1278 attr_type = py_object_type 1279 else: 1280 attr_type = attr.type 1281 if attr.is_cpp_optional: 1282 decl = attr_type.cpp_optional_declaration_code(attr.cname) 1283 else: 1284 decl = attr_type.declaration_code(attr.cname) 1285 type.scope.use_entry_utility_code(attr) 1286 code.putln("%s;" % decl) 1287 code.putln(footer) 1288 if type.objtypedef_cname is not None: 1289 # Only for exposing public typedef name. 1290 code.putln("typedef struct %s %s;" % (type.objstruct_cname, type.objtypedef_cname)) 1291 1292 def generate_c_class_declarations(self, env, code, definition, globalstate): 1293 module_state = globalstate['module_state'] 1294 module_state_defines = globalstate['module_state_defines'] 1295 module_state_clear = globalstate['module_state_clear'] 1296 module_state_traverse = globalstate['module_state_traverse'] 1297 code.putln("#if !CYTHON_USE_MODULE_STATE") 1298 for entry in env.c_class_entries: 1299 if definition or entry.defined_in_pxd: 1300 code.putln("static PyTypeObject *%s = 0;" % ( 1301 entry.type.typeptr_cname)) 1302 module_state.putln("PyTypeObject *%s;" % entry.type.typeptr_cname) 1303 module_state_defines.putln("#define %s %s->%s" % ( 1304 entry.type.typeptr_cname, 1305 Naming.modulestateglobal_cname, 1306 entry.type.typeptr_cname)) 1307 module_state_clear.putln( 1308 "Py_CLEAR(clear_module_state->%s);" % 1309 entry.type.typeptr_cname) 1310 module_state_traverse.putln( 1311 "Py_VISIT(traverse_module_state->%s);" % 1312 entry.type.typeptr_cname) 1313 if entry.type.typeobj_cname is not None: 1314 module_state.putln("PyObject *%s;" % entry.type.typeobj_cname) 1315 module_state_defines.putln("#define %s %s->%s" % ( 1316 entry.type.typeobj_cname, 1317 Naming.modulestateglobal_cname, 1318 entry.type.typeobj_cname)) 1319 module_state_clear.putln( 1320 "Py_CLEAR(clear_module_state->%s);" % ( 1321 entry.type.typeobj_cname)) 1322 module_state_traverse.putln( 1323 "Py_VISIT(traverse_module_state->%s);" % ( 1324 entry.type.typeobj_cname)) 1325 code.putln("#endif") 1326 1327 def generate_cvariable_declarations(self, env, code, definition): 1328 if env.is_cython_builtin: 1329 return 1330 for entry in env.var_entries: 1331 if (entry.in_cinclude or entry.in_closure or 1332 (entry.visibility == 'private' and not (entry.defined_in_pxd or entry.used))): 1333 continue 1334 1335 storage_class = None 1336 dll_linkage = None 1337 init = None 1338 1339 if entry.visibility == 'extern': 1340 storage_class = Naming.extern_c_macro 1341 dll_linkage = "DL_IMPORT" 1342 elif entry.visibility == 'public': 1343 storage_class = Naming.extern_c_macro 1344 if definition: 1345 dll_linkage = "DL_EXPORT" 1346 else: 1347 dll_linkage = "DL_IMPORT" 1348 elif entry.visibility == 'private': 1349 storage_class = "static" 1350 dll_linkage = None 1351 if entry.init is not None: 1352 init = entry.type.literal_code(entry.init) 1353 type = entry.type 1354 cname = entry.cname 1355 1356 if entry.defined_in_pxd and not definition: 1357 storage_class = "static" 1358 dll_linkage = None 1359 type = CPtrType(type) 1360 cname = env.mangle(Naming.varptr_prefix, entry.name) 1361 init = 0 1362 1363 if storage_class: 1364 code.put("%s " % storage_class) 1365 if entry.is_cpp_optional: 1366 code.put(type.cpp_optional_declaration_code( 1367 cname, dll_linkage=dll_linkage)) 1368 else: 1369 code.put(type.declaration_code( 1370 cname, dll_linkage=dll_linkage)) 1371 if init is not None: 1372 code.put_safe(" = %s" % init) 1373 code.putln(";") 1374 if entry.cname != cname: 1375 code.putln("#define %s (*%s)" % (entry.cname, cname)) 1376 env.use_entry_utility_code(entry) 1377 1378 def generate_cfunction_declarations(self, env, code, definition): 1379 for entry in env.cfunc_entries: 1380 if entry.used or (entry.visibility == 'public' or entry.api): 1381 generate_cfunction_declaration(entry, env, code, definition) 1382 1383 def generate_variable_definitions(self, env, code): 1384 for entry in env.var_entries: 1385 if not entry.in_cinclude and entry.visibility == "public": 1386 code.put(entry.type.declaration_code(entry.cname)) 1387 if entry.init is not None: 1388 init = entry.type.literal_code(entry.init) 1389 code.put_safe(" = %s" % init) 1390 code.putln(";") 1391 1392 def generate_typeobj_definitions(self, env, code): 1393 full_module_name = env.qualified_name 1394 for entry in env.c_class_entries: 1395 #print "generate_typeobj_definitions:", entry.name 1396 #print "...visibility =", entry.visibility 1397 if entry.visibility != 'extern': 1398 type = entry.type 1399 scope = type.scope 1400 if scope: # could be None if there was an error 1401 self.generate_exttype_vtable(scope, code) 1402 self.generate_new_function(scope, code, entry) 1403 self.generate_dealloc_function(scope, code) 1404 1405 if scope.needs_gc(): 1406 self.generate_traverse_function(scope, code, entry) 1407 if scope.needs_tp_clear(): 1408 self.generate_clear_function(scope, code, entry) 1409 if scope.defines_any_special(["__getitem__"]): 1410 self.generate_getitem_int_function(scope, code) 1411 if scope.defines_any_special(["__setitem__", "__delitem__"]): 1412 self.generate_ass_subscript_function(scope, code) 1413 if scope.defines_any_special(["__getslice__", "__setslice__", "__delslice__"]): 1414 warning(self.pos, 1415 "__getslice__, __setslice__, and __delslice__ are not supported by Python 3, " 1416 "use __getitem__, __setitem__, and __delitem__ instead", 1) 1417 code.putln("#if PY_MAJOR_VERSION >= 3") 1418 code.putln("#error __getslice__, __setslice__, and __delslice__ not supported in Python 3.") 1419 code.putln("#endif") 1420 if scope.defines_any_special(["__setslice__", "__delslice__"]): 1421 self.generate_ass_slice_function(scope, code) 1422 if scope.defines_any_special(["__getattr__", "__getattribute__"]): 1423 self.generate_getattro_function(scope, code) 1424 if scope.defines_any_special(["__setattr__", "__delattr__"]): 1425 self.generate_setattro_function(scope, code) 1426 if scope.defines_any_special(["__get__"]): 1427 self.generate_descr_get_function(scope, code) 1428 if scope.defines_any_special(["__set__", "__delete__"]): 1429 self.generate_descr_set_function(scope, code) 1430 if not scope.is_closure_class_scope and scope.defines_any(["__dict__"]): 1431 self.generate_dict_getter_function(scope, code) 1432 1433 if scope.defines_any_special(TypeSlots.richcmp_special_methods): 1434 self.generate_richcmp_function(scope, code) 1435 elif scope.directives.get('total_ordering'): 1436 # Warn if this is used when it can't have any effect. 1437 warning(scope.parent_type.pos, 1438 "total_ordering directive used, but no comparison and equality methods defined") 1439 1440 for slot in TypeSlots.PyNumberMethods: 1441 if slot.is_binop and scope.defines_any_special(slot.user_methods): 1442 self.generate_binop_function(scope, slot, code, entry.pos) 1443 1444 self.generate_property_accessors(scope, code) 1445 self.generate_method_table(scope, code) 1446 self.generate_getset_table(scope, code) 1447 code.putln("#if CYTHON_USE_TYPE_SPECS") 1448 self.generate_typeobj_spec(entry, code) 1449 code.putln("#else") 1450 self.generate_typeobj_definition(full_module_name, entry, code) 1451 code.putln("#endif") 1452 1453 def generate_exttype_vtable(self, scope, code): 1454 # Generate the definition of an extension type's vtable. 1455 type = scope.parent_type 1456 if type.vtable_cname: 1457 code.putln("static struct %s %s;" % ( 1458 type.vtabstruct_cname, 1459 type.vtable_cname)) 1460 1461 def generate_self_cast(self, scope, code): 1462 type = scope.parent_type 1463 code.putln( 1464 "%s = (%s)o;" % ( 1465 type.declaration_code("p"), 1466 type.empty_declaration_code())) 1467 1468 def generate_new_function(self, scope, code, cclass_entry): 1469 tp_slot = TypeSlots.ConstructorSlot("tp_new", "__cinit__") 1470 slot_func = scope.mangle_internal("tp_new") 1471 if tp_slot.slot_code(scope) != slot_func: 1472 return # never used 1473 1474 type = scope.parent_type 1475 base_type = type.base_type 1476 1477 have_entries, (py_attrs, py_buffers, memoryview_slices) = \ 1478 scope.get_refcounted_entries() 1479 is_final_type = scope.parent_type.is_final_type 1480 if scope.is_internal: 1481 # internal classes (should) never need None inits, normal zeroing will do 1482 py_attrs = [] 1483 cpp_constructable_attrs = [entry for entry in scope.var_entries if entry.type.needs_cpp_construction] 1484 1485 cinit_func_entry = scope.lookup_here("__cinit__") 1486 if cinit_func_entry and not cinit_func_entry.is_special: 1487 cinit_func_entry = None 1488 1489 if base_type or (cinit_func_entry and not cinit_func_entry.trivial_signature): 1490 unused_marker = '' 1491 else: 1492 unused_marker = 'CYTHON_UNUSED ' 1493 1494 if base_type: 1495 freelist_size = 0 # not currently supported 1496 else: 1497 freelist_size = scope.directives.get('freelist', 0) 1498 freelist_name = scope.mangle_internal(Naming.freelist_name) 1499 freecount_name = scope.mangle_internal(Naming.freecount_name) 1500 1501 decls = code.globalstate['decls'] 1502 decls.putln("static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/" % 1503 slot_func) 1504 code.putln("") 1505 if freelist_size: 1506 code.putln("static %s[%d];" % ( 1507 scope.parent_type.declaration_code(freelist_name), 1508 freelist_size)) 1509 code.putln("static int %s = 0;" % freecount_name) 1510 code.putln("") 1511 code.putln( 1512 "static PyObject *%s(PyTypeObject *t, %sPyObject *a, %sPyObject *k) {" % ( 1513 slot_func, unused_marker, unused_marker)) 1514 1515 need_self_cast = (type.vtabslot_cname or 1516 (py_buffers or memoryview_slices or py_attrs) or 1517 cpp_constructable_attrs) 1518 if need_self_cast: 1519 code.putln("%s;" % scope.parent_type.declaration_code("p")) 1520 if base_type: 1521 code.putln("#if CYTHON_COMPILING_IN_LIMITED_API") 1522 code.putln("newfunc new_func = (newfunc)PyType_GetSlot(%s, Py_tp_new);" % 1523 base_type.typeptr_cname) 1524 code.putln("PyObject *o = new_func(t, a, k);") 1525 code.putln("#else") 1526 tp_new = TypeSlots.get_base_slot_function(scope, tp_slot) 1527 if tp_new is None: 1528 tp_new = "%s->tp_new" % base_type.typeptr_cname 1529 code.putln("PyObject *o = %s(t, a, k);" % tp_new) 1530 code.putln("#endif") 1531 else: 1532 code.putln("PyObject *o;") 1533 code.putln("#if CYTHON_COMPILING_IN_LIMITED_API") 1534 code.putln("allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc);") 1535 code.putln("o = alloc_func(t, 0);") 1536 code.putln("#else") 1537 if freelist_size: 1538 code.globalstate.use_utility_code( 1539 UtilityCode.load_cached("IncludeStringH", "StringTools.c")) 1540 if is_final_type: 1541 type_safety_check = '' 1542 else: 1543 type_safety_check = ' & (!__Pyx_PyType_HasFeature(t, (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)))' 1544 obj_struct = type.declaration_code("", deref=True) 1545 code.putln( 1546 "if (CYTHON_COMPILING_IN_CPYTHON && likely((%s > 0) & (t->tp_basicsize == sizeof(%s))%s)) {" % ( 1547 freecount_name, obj_struct, type_safety_check)) 1548 code.putln("o = (PyObject*)%s[--%s];" % ( 1549 freelist_name, freecount_name)) 1550 code.putln("memset(o, 0, sizeof(%s));" % obj_struct) 1551 code.putln("(void) PyObject_INIT(o, t);") 1552 if scope.needs_gc(): 1553 code.putln("PyObject_GC_Track(o);") 1554 code.putln("} else {") 1555 if not is_final_type: 1556 code.putln("if (likely(!__Pyx_PyType_HasFeature(t, Py_TPFLAGS_IS_ABSTRACT))) {") 1557 code.putln("o = (*t->tp_alloc)(t, 0);") 1558 if not is_final_type: 1559 code.putln("} else {") 1560 code.putln("o = (PyObject *) PyBaseObject_Type.tp_new(t, %s, 0);" % Naming.empty_tuple) 1561 code.putln("}") 1562 code.putln("if (unlikely(!o)) return 0;") 1563 if freelist_size and not base_type: 1564 code.putln('}') 1565 if not base_type: 1566 code.putln("#endif") 1567 if need_self_cast: 1568 code.putln("p = %s;" % type.cast_code("o")) 1569 #if need_self_cast: 1570 # self.generate_self_cast(scope, code) 1571 1572 # from this point on, ensure DECREF(o) on failure 1573 needs_error_cleanup = False 1574 1575 if type.vtabslot_cname: 1576 vtab_base_type = type 1577 while vtab_base_type.base_type and vtab_base_type.base_type.vtabstruct_cname: 1578 vtab_base_type = vtab_base_type.base_type 1579 if vtab_base_type is not type: 1580 struct_type_cast = "(struct %s*)" % vtab_base_type.vtabstruct_cname 1581 else: 1582 struct_type_cast = "" 1583 code.putln("p->%s = %s%s;" % ( 1584 type.vtabslot_cname, 1585 struct_type_cast, type.vtabptr_cname)) 1586 1587 for entry in cpp_constructable_attrs: 1588 if entry.is_cpp_optional: 1589 decl_code = entry.type.cpp_optional_declaration_code("") 1590 else: 1591 decl_code = entry.type.empty_declaration_code() 1592 code.putln("new((void*)&(p->%s)) %s();" % ( 1593 entry.cname, decl_code)) 1594 1595 for entry in py_attrs: 1596 if entry.name == "__dict__": 1597 needs_error_cleanup = True 1598 code.put("p->%s = PyDict_New(); if (unlikely(!p->%s)) goto bad;" % ( 1599 entry.cname, entry.cname)) 1600 else: 1601 code.put_init_var_to_py_none(entry, "p->%s", nanny=False) 1602 1603 for entry in memoryview_slices: 1604 code.putln("p->%s.data = NULL;" % entry.cname) 1605 code.putln("p->%s.memview = NULL;" % entry.cname) 1606 1607 for entry in py_buffers: 1608 code.putln("p->%s.obj = NULL;" % entry.cname) 1609 1610 if cclass_entry.cname == '__pyx_memoryviewslice': 1611 code.putln("p->from_slice.memview = NULL;") 1612 1613 if cinit_func_entry: 1614 if cinit_func_entry.trivial_signature: 1615 cinit_args = "o, %s, NULL" % Naming.empty_tuple 1616 else: 1617 cinit_args = "o, a, k" 1618 needs_error_cleanup = True 1619 code.putln("if (unlikely(%s(%s) < 0)) goto bad;" % ( 1620 cinit_func_entry.func_cname, cinit_args)) 1621 1622 code.putln( 1623 "return o;") 1624 if needs_error_cleanup: 1625 code.putln("bad:") 1626 code.put_decref_clear("o", py_object_type, nanny=False) 1627 code.putln("return NULL;") 1628 code.putln( 1629 "}") 1630 1631 def generate_dealloc_function(self, scope, code): 1632 tp_slot = TypeSlots.ConstructorSlot("tp_dealloc", '__dealloc__') 1633 slot_func = scope.mangle_internal("tp_dealloc") 1634 base_type = scope.parent_type.base_type 1635 if tp_slot.slot_code(scope) != slot_func: 1636 return # never used 1637 1638 slot_func_cname = scope.mangle_internal("tp_dealloc") 1639 code.putln("") 1640 code.putln( 1641 "static void %s(PyObject *o) {" % slot_func_cname) 1642 1643 is_final_type = scope.parent_type.is_final_type 1644 needs_gc = scope.needs_gc() 1645 needs_trashcan = scope.needs_trashcan() 1646 1647 weakref_slot = scope.lookup_here("__weakref__") if not scope.is_closure_class_scope else None 1648 if weakref_slot not in scope.var_entries: 1649 weakref_slot = None 1650 1651 dict_slot = scope.lookup_here("__dict__") if not scope.is_closure_class_scope else None 1652 if dict_slot not in scope.var_entries: 1653 dict_slot = None 1654 1655 _, (py_attrs, _, memoryview_slices) = scope.get_refcounted_entries() 1656 cpp_destructable_attrs = [entry for entry in scope.var_entries 1657 if entry.type.needs_cpp_construction] 1658 1659 if py_attrs or cpp_destructable_attrs or memoryview_slices or weakref_slot or dict_slot: 1660 self.generate_self_cast(scope, code) 1661 1662 if not is_final_type: 1663 # in Py3.4+, call tp_finalize() as early as possible 1664 code.putln("#if CYTHON_USE_TP_FINALIZE") 1665 if needs_gc: 1666 finalised_check = '!_PyGC_FINALIZED(o)' 1667 else: 1668 finalised_check = ( 1669 '(!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))') 1670 code.putln( 1671 "if (unlikely(" 1672 "(PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE))" 1673 " && Py_TYPE(o)->tp_finalize) && %s) {" % finalised_check) 1674 # if instance was resurrected by finaliser, return 1675 code.putln("if (PyObject_CallFinalizerFromDealloc(o)) return;") 1676 code.putln("}") 1677 code.putln("#endif") 1678 1679 if needs_gc: 1680 # We must mark this object as (gc) untracked while tearing 1681 # it down, lest the garbage collection is invoked while 1682 # running this destructor. 1683 code.putln("PyObject_GC_UnTrack(o);") 1684 1685 if needs_trashcan: 1686 code.globalstate.use_utility_code( 1687 UtilityCode.load_cached("PyTrashcan", "ExtensionTypes.c")) 1688 code.putln("__Pyx_TRASHCAN_BEGIN(o, %s)" % slot_func_cname) 1689 1690 if weakref_slot: 1691 # We must clean the weakreferences before calling the user's __dealloc__ 1692 # because if the __dealloc__ releases the GIL, a weakref can be 1693 # dereferenced accessing the object in an inconsistent state or 1694 # resurrecting it. 1695 code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);") 1696 1697 # call the user's __dealloc__ 1698 self.generate_usr_dealloc_call(scope, code) 1699 1700 if dict_slot: 1701 code.putln("if (p->__dict__) PyDict_Clear(p->__dict__);") 1702 1703 for entry in cpp_destructable_attrs: 1704 code.putln("__Pyx_call_destructor(p->%s);" % entry.cname) 1705 1706 for entry in (py_attrs + memoryview_slices): 1707 code.put_xdecref_clear("p->%s" % entry.cname, entry.type, nanny=False, 1708 clear_before_decref=True, have_gil=True) 1709 1710 if base_type: 1711 if needs_gc: 1712 # The base class deallocator probably expects this to be tracked, 1713 # so undo the untracking above. 1714 if base_type.scope and base_type.scope.needs_gc(): 1715 code.putln("PyObject_GC_Track(o);") 1716 else: 1717 code.putln("#if CYTHON_USE_TYPE_SLOTS") 1718 code.putln("if (PyType_IS_GC(Py_TYPE(o)->tp_base))") 1719 code.putln("#endif") 1720 code.putln("PyObject_GC_Track(o);") 1721 1722 tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot) 1723 if tp_dealloc is not None: 1724 code.putln("%s(o);" % tp_dealloc) 1725 elif base_type.is_builtin_type: 1726 code.putln("%s->tp_dealloc(o);" % base_type.typeptr_cname) 1727 else: 1728 # This is an externally defined type. Calling through the 1729 # cimported base type pointer directly interacts badly with 1730 # the module cleanup, which may already have cleared it. 1731 # In that case, fall back to traversing the type hierarchy. 1732 base_cname = base_type.typeptr_cname 1733 code.putln("if (likely(%s)) %s->tp_dealloc(o); " 1734 "else __Pyx_call_next_tp_dealloc(o, %s);" % ( 1735 base_cname, base_cname, slot_func_cname)) 1736 code.globalstate.use_utility_code( 1737 UtilityCode.load_cached("CallNextTpDealloc", "ExtensionTypes.c")) 1738 else: 1739 freelist_size = scope.directives.get('freelist', 0) 1740 if freelist_size: 1741 freelist_name = scope.mangle_internal(Naming.freelist_name) 1742 freecount_name = scope.mangle_internal(Naming.freecount_name) 1743 1744 if is_final_type: 1745 type_safety_check = '' 1746 else: 1747 type_safety_check = ( 1748 ' & (!__Pyx_PyType_HasFeature(Py_TYPE(o), (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)))') 1749 1750 type = scope.parent_type 1751 code.putln( 1752 "if (CYTHON_COMPILING_IN_CPYTHON && ((%s < %d) & (Py_TYPE(o)->tp_basicsize == sizeof(%s))%s)) {" % ( 1753 freecount_name, 1754 freelist_size, 1755 type.declaration_code("", deref=True), 1756 type_safety_check)) 1757 code.putln("%s[%s++] = %s;" % ( 1758 freelist_name, freecount_name, type.cast_code("o"))) 1759 code.putln("} else {") 1760 code.putln("(*Py_TYPE(o)->tp_free)(o);") 1761 if freelist_size: 1762 code.putln("}") 1763 1764 if needs_trashcan: 1765 code.putln("__Pyx_TRASHCAN_END") 1766 1767 code.putln( 1768 "}") 1769 1770 def generate_usr_dealloc_call(self, scope, code): 1771 entry = scope.lookup_here("__dealloc__") 1772 if not entry or not entry.is_special: 1773 return 1774 1775 code.putln("{") 1776 code.putln("PyObject *etype, *eval, *etb;") 1777 code.putln("PyErr_Fetch(&etype, &eval, &etb);") 1778 # increase the refcount while we are calling into user code 1779 # to prevent recursive deallocation 1780 code.putln("__Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1);") 1781 code.putln("%s(o);" % entry.func_cname) 1782 code.putln("__Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1);") 1783 code.putln("PyErr_Restore(etype, eval, etb);") 1784 code.putln("}") 1785 1786 def generate_traverse_function(self, scope, code, cclass_entry): 1787 tp_slot = TypeSlots.GCDependentSlot("tp_traverse") 1788 slot_func = scope.mangle_internal("tp_traverse") 1789 base_type = scope.parent_type.base_type 1790 if tp_slot.slot_code(scope) != slot_func: 1791 return # never used 1792 code.putln("") 1793 code.putln( 1794 "static int %s(PyObject *o, visitproc v, void *a) {" % slot_func) 1795 1796 have_entries, (py_attrs, py_buffers, memoryview_slices) = ( 1797 scope.get_refcounted_entries(include_gc_simple=False)) 1798 1799 if base_type or py_attrs: 1800 code.putln("int e;") 1801 1802 if py_attrs or py_buffers: 1803 self.generate_self_cast(scope, code) 1804 1805 if base_type: 1806 # want to call it explicitly if possible so inlining can be performed 1807 static_call = TypeSlots.get_base_slot_function(scope, tp_slot) 1808 if static_call: 1809 code.putln("e = %s(o, v, a); if (e) return e;" % static_call) 1810 elif base_type.is_builtin_type: 1811 base_cname = base_type.typeptr_cname 1812 code.putln("if (!%s->tp_traverse); else { e = %s->tp_traverse(o,v,a); if (e) return e; }" % ( 1813 base_cname, base_cname)) 1814 else: 1815 # This is an externally defined type. Calling through the 1816 # cimported base type pointer directly interacts badly with 1817 # the module cleanup, which may already have cleared it. 1818 # In that case, fall back to traversing the type hierarchy. 1819 base_cname = base_type.typeptr_cname 1820 code.putln( 1821 "e = ((likely(%s)) ? ((%s->tp_traverse) ? %s->tp_traverse(o, v, a) : 0) : " 1822 "__Pyx_call_next_tp_traverse(o, v, a, %s)); if (e) return e;" % ( 1823 base_cname, base_cname, base_cname, slot_func)) 1824 code.globalstate.use_utility_code( 1825 UtilityCode.load_cached("CallNextTpTraverse", "ExtensionTypes.c")) 1826 1827 for entry in py_attrs: 1828 var_code = "p->%s" % entry.cname 1829 var_as_pyobject = PyrexTypes.typecast(py_object_type, entry.type, var_code) 1830 code.putln("if (%s) {" % var_code) 1831 code.putln("e = (*v)(%s, a); if (e) return e;" % var_as_pyobject) 1832 code.putln("}") 1833 1834 # Traverse buffer exporting objects. 1835 # Note: not traversing memoryview attributes of memoryview slices! 1836 # When triggered by the GC, it would cause multiple visits (gc_refs 1837 # subtractions which is not matched by its reference count!) 1838 for entry in py_buffers: 1839 cname = entry.cname + ".obj" 1840 code.putln("if (p->%s) {" % cname) 1841 code.putln("e = (*v)(p->%s, a); if (e) return e;" % cname) 1842 code.putln("}") 1843 1844 code.putln("return 0;") 1845 code.putln("}") 1846 1847 def generate_clear_function(self, scope, code, cclass_entry): 1848 tp_slot = TypeSlots.get_slot_by_name("tp_clear") 1849 slot_func = scope.mangle_internal("tp_clear") 1850 base_type = scope.parent_type.base_type 1851 if tp_slot.slot_code(scope) != slot_func: 1852 return # never used 1853 1854 have_entries, (py_attrs, py_buffers, memoryview_slices) = ( 1855 scope.get_refcounted_entries(include_gc_simple=False)) 1856 1857 if py_attrs or py_buffers or base_type: 1858 unused = '' 1859 else: 1860 unused = 'CYTHON_UNUSED ' 1861 1862 code.putln("") 1863 code.putln("static int %s(%sPyObject *o) {" % (slot_func, unused)) 1864 1865 if py_attrs and Options.clear_to_none: 1866 code.putln("PyObject* tmp;") 1867 1868 if py_attrs or py_buffers: 1869 self.generate_self_cast(scope, code) 1870 1871 if base_type: 1872 # want to call it explicitly if possible so inlining can be performed 1873 static_call = TypeSlots.get_base_slot_function(scope, tp_slot) 1874 if static_call: 1875 code.putln("%s(o);" % static_call) 1876 elif base_type.is_builtin_type: 1877 base_cname = base_type.typeptr_cname 1878 code.putln("if (!%s->tp_clear); else %s->tp_clear(o);" % ( 1879 base_cname, base_cname)) 1880 else: 1881 # This is an externally defined type. Calling through the 1882 # cimported base type pointer directly interacts badly with 1883 # the module cleanup, which may already have cleared it. 1884 # In that case, fall back to traversing the type hierarchy. 1885 base_cname = base_type.typeptr_cname 1886 code.putln( 1887 "if (likely(%s)) { if (%s->tp_clear) %s->tp_clear(o); } else __Pyx_call_next_tp_clear(o, %s);" % ( 1888 base_cname, base_cname, base_cname, slot_func)) 1889 code.globalstate.use_utility_code( 1890 UtilityCode.load_cached("CallNextTpClear", "ExtensionTypes.c")) 1891 1892 if Options.clear_to_none: 1893 for entry in py_attrs: 1894 name = "p->%s" % entry.cname 1895 code.putln("tmp = ((PyObject*)%s);" % name) 1896 if entry.is_declared_generic: 1897 code.put_init_to_py_none(name, py_object_type, nanny=False) 1898 else: 1899 code.put_init_to_py_none(name, entry.type, nanny=False) 1900 code.putln("Py_XDECREF(tmp);") 1901 else: 1902 for entry in py_attrs: 1903 code.putln("Py_CLEAR(p->%s);" % entry.cname) 1904 1905 for entry in py_buffers: 1906 # Note: shouldn't this call __Pyx_ReleaseBuffer ?? 1907 code.putln("Py_CLEAR(p->%s.obj);" % entry.cname) 1908 1909 if cclass_entry.cname == '__pyx_memoryviewslice': 1910 code.putln("__PYX_XCLEAR_MEMVIEW(&p->from_slice, 1);") 1911 1912 code.putln("return 0;") 1913 code.putln("}") 1914 1915 def generate_getitem_int_function(self, scope, code): 1916 # This function is put into the sq_item slot when 1917 # a __getitem__ method is present. It converts its 1918 # argument to a Python integer and calls mp_subscript. 1919 code.putln( 1920 "static PyObject *%s(PyObject *o, Py_ssize_t i) {" % ( 1921 scope.mangle_internal("sq_item"))) 1922 code.putln( 1923 "PyObject *r;") 1924 code.putln( 1925 "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;") 1926 code.putln( 1927 "r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);") 1928 code.putln( 1929 "Py_DECREF(x);") 1930 code.putln( 1931 "return r;") 1932 code.putln( 1933 "}") 1934 1935 def generate_ass_subscript_function(self, scope, code): 1936 # Setting and deleting an item are both done through 1937 # the ass_subscript method, so we dispatch to user's __setitem__ 1938 # or __delitem__, or raise an exception. 1939 base_type = scope.parent_type.base_type 1940 set_entry = scope.lookup_here("__setitem__") 1941 del_entry = scope.lookup_here("__delitem__") 1942 code.putln("") 1943 code.putln( 1944 "static int %s(PyObject *o, PyObject *i, PyObject *v) {" % ( 1945 scope.mangle_internal("mp_ass_subscript"))) 1946 code.putln( 1947 "if (v) {") 1948 if set_entry: 1949 code.putln("return %s(o, i, v);" % set_entry.func_cname) 1950 else: 1951 code.putln( 1952 "__Pyx_TypeName o_type_name;") 1953 self.generate_guarded_basetype_call( 1954 base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code) 1955 code.putln( 1956 "o_type_name = __Pyx_PyType_GetName(Py_TYPE(o));") 1957 code.putln( 1958 "PyErr_Format(PyExc_NotImplementedError,") 1959 code.putln( 1960 ' "Subscript assignment not supported by " __Pyx_FMT_TYPENAME, o_type_name);') 1961 code.putln( 1962 "__Pyx_DECREF_TypeName(o_type_name);") 1963 code.putln( 1964 "return -1;") 1965 code.putln( 1966 "}") 1967 code.putln( 1968 "else {") 1969 if del_entry: 1970 code.putln( 1971 "return %s(o, i);" % ( 1972 del_entry.func_cname)) 1973 else: 1974 code.putln( 1975 "__Pyx_TypeName o_type_name;") 1976 self.generate_guarded_basetype_call( 1977 base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code) 1978 code.putln( 1979 "o_type_name = __Pyx_PyType_GetName(Py_TYPE(o));") 1980 code.putln( 1981 "PyErr_Format(PyExc_NotImplementedError,") 1982 code.putln( 1983 ' "Subscript deletion not supported by " __Pyx_FMT_TYPENAME, o_type_name);') 1984 code.putln( 1985 "__Pyx_DECREF_TypeName(o_type_name);") 1986 code.putln( 1987 "return -1;") 1988 code.putln( 1989 "}") 1990 code.putln( 1991 "}") 1992 1993 def generate_guarded_basetype_call( 1994 self, base_type, substructure, slot, args, code): 1995 if base_type: 1996 base_tpname = base_type.typeptr_cname 1997 if substructure: 1998 code.putln( 1999 "if (%s->%s && %s->%s->%s)" % ( 2000 base_tpname, substructure, base_tpname, substructure, slot)) 2001 code.putln( 2002 " return %s->%s->%s(%s);" % ( 2003 base_tpname, substructure, slot, args)) 2004 else: 2005 code.putln( 2006 "if (%s->%s)" % ( 2007 base_tpname, slot)) 2008 code.putln( 2009 " return %s->%s(%s);" % ( 2010 base_tpname, slot, args)) 2011 2012 def generate_ass_slice_function(self, scope, code): 2013 # Setting and deleting a slice are both done through 2014 # the ass_slice method, so we dispatch to user's __setslice__ 2015 # or __delslice__, or raise an exception. 2016 base_type = scope.parent_type.base_type 2017 set_entry = scope.lookup_here("__setslice__") 2018 del_entry = scope.lookup_here("__delslice__") 2019 code.putln("") 2020 code.putln( 2021 "static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" % ( 2022 scope.mangle_internal("sq_ass_slice"))) 2023 code.putln( 2024 "if (v) {") 2025 if set_entry: 2026 code.putln( 2027 "return %s(o, i, j, v);" % ( 2028 set_entry.func_cname)) 2029 else: 2030 code.putln( 2031 "__Pyx_TypeName o_type_name;") 2032 self.generate_guarded_basetype_call( 2033 base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code) 2034 code.putln( 2035 "o_type_name = __Pyx_PyType_GetName(Py_TYPE(o));") 2036 code.putln( 2037 "PyErr_Format(PyExc_NotImplementedError,") 2038 code.putln( 2039 ' "2-element slice assignment not supported by " __Pyx_FMT_TYPENAME, o_type_name);') 2040 code.putln( 2041 "__Pyx_DECREF_TypeName(o_type_name);") 2042 code.putln( 2043 "return -1;") 2044 code.putln( 2045 "}") 2046 code.putln( 2047 "else {") 2048 if del_entry: 2049 code.putln( 2050 "return %s(o, i, j);" % ( 2051 del_entry.func_cname)) 2052 else: 2053 code.putln( 2054 "__Pyx_TypeName o_type_name;") 2055 self.generate_guarded_basetype_call( 2056 base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code) 2057 code.putln( 2058 "o_type_name = __Pyx_PyType_GetName(Py_TYPE(o));") 2059 code.putln( 2060 "PyErr_Format(PyExc_NotImplementedError,") 2061 code.putln( 2062 ' "2-element slice deletion not supported by " __Pyx_FMT_TYPENAME, o_type_name);') 2063 code.putln( 2064 "__Pyx_DECREF_TypeName(o_type_name);") 2065 code.putln( 2066 "return -1;") 2067 code.putln( 2068 "}") 2069 code.putln( 2070 "}") 2071 2072 def generate_richcmp_function(self, scope, code): 2073 if scope.lookup_here("__richcmp__"): 2074 # user implemented, nothing to do 2075 return 2076 # otherwise, we have to generate it from the Python special methods 2077 richcmp_cfunc = scope.mangle_internal("tp_richcompare") 2078 code.putln("") 2079 code.putln("static PyObject *%s(PyObject *o1, PyObject *o2, int op) {" % richcmp_cfunc) 2080 code.putln("switch (op) {") 2081 2082 class_scopes = [] 2083 cls = scope.parent_type 2084 while cls is not None and not cls.entry.visibility == 'extern': 2085 class_scopes.append(cls.scope) 2086 cls = cls.scope.parent_type.base_type 2087 assert scope in class_scopes 2088 2089 extern_parent = None 2090 if cls and cls.entry.visibility == 'extern': 2091 # need to call up into base classes as we may not know all implemented comparison methods 2092 extern_parent = cls if cls.typeptr_cname else scope.parent_type.base_type 2093 2094 total_ordering = scope.directives.get('total_ordering', False) 2095 2096 comp_entry = {} 2097 2098 for cmp_method in TypeSlots.richcmp_special_methods: 2099 for class_scope in class_scopes: 2100 entry = class_scope.lookup_here(cmp_method) 2101 if entry is not None: 2102 comp_entry[cmp_method] = entry 2103 break 2104 2105 if total_ordering: 2106 # Check this is valid - we must have at least 1 operation defined. 2107 comp_names = [from_name for from_name, to_name in TOTAL_ORDERING if from_name in comp_entry] 2108 if not comp_names: 2109 if '__eq__' not in comp_entry and '__ne__' not in comp_entry: 2110 warning(scope.parent_type.pos, 2111 "total_ordering directive used, but no comparison and equality methods defined") 2112 else: 2113 warning(scope.parent_type.pos, 2114 "total_ordering directive used, but no comparison methods defined") 2115 total_ordering = False 2116 else: 2117 if '__eq__' not in comp_entry and '__ne__' not in comp_entry: 2118 warning(scope.parent_type.pos, "total_ordering directive used, but no equality method defined") 2119 total_ordering = False 2120 2121 # Same priority as functools, prefers 2122 # __lt__ to __le__ to __gt__ to __ge__ 2123 ordering_source = max(comp_names) 2124 2125 for cmp_method in TypeSlots.richcmp_special_methods: 2126 cmp_type = cmp_method.strip('_').upper() # e.g. "__eq__" -> EQ 2127 entry = comp_entry.get(cmp_method) 2128 if entry is None and (not total_ordering or cmp_type in ('NE', 'EQ')): 2129 # No definition, fall back to superclasses. 2130 # eq/ne methods shouldn't use the total_ordering code. 2131 continue 2132 2133 code.putln("case Py_%s: {" % cmp_type) 2134 if entry is None: 2135 assert total_ordering 2136 # We need to generate this from the other methods. 2137 invert_comp, comp_op, invert_equals = TOTAL_ORDERING[ordering_source, cmp_method] 2138 2139 # First we always do the comparison. 2140 code.putln("PyObject *ret;") 2141 code.putln("ret = %s(o1, o2);" % comp_entry[ordering_source].func_cname) 2142 code.putln("if (likely(ret && ret != Py_NotImplemented)) {") 2143 code.putln("int order_res = __Pyx_PyObject_IsTrue(ret);") 2144 code.putln("Py_DECREF(ret);") 2145 code.putln("if (unlikely(order_res < 0)) return NULL;") 2146 # We may need to check equality too. For some combos it's never required. 2147 if invert_equals is not None: 2148 # Implement the and/or check with an if. 2149 if comp_op == '&&': 2150 code.putln("if (%s order_res) {" % ('!!' if invert_comp else '!')) 2151 code.putln("ret = __Pyx_NewRef(Py_False);") 2152 code.putln("} else {") 2153 elif comp_op == '||': 2154 code.putln("if (%s order_res) {" % ('!' if invert_comp else '')) 2155 code.putln("ret = __Pyx_NewRef(Py_True);") 2156 code.putln("} else {") 2157 else: 2158 raise AssertionError('Unknown op %s' % (comp_op, )) 2159 if '__eq__' in comp_entry: 2160 eq_func = '__eq__' 2161 else: 2162 # Fall back to NE, which is defined here. 2163 eq_func = '__ne__' 2164 invert_equals = not invert_equals 2165 2166 code.putln("ret = %s(o1, o2);" % comp_entry[eq_func].func_cname) 2167 code.putln("if (likely(ret && ret != Py_NotImplemented)) {") 2168 code.putln("int eq_res = __Pyx_PyObject_IsTrue(ret);") 2169 code.putln("Py_DECREF(ret);") 2170 code.putln("if (unlikely(eq_res < 0)) return NULL;") 2171 if invert_equals: 2172 code.putln("ret = eq_res ? Py_False : Py_True;") 2173 else: 2174 code.putln("ret = eq_res ? Py_True : Py_False;") 2175 code.putln("Py_INCREF(ret);") 2176 code.putln("}") # equals success 2177 code.putln("}") # Needs to try equals 2178 else: 2179 # Convert direct to a boolean. 2180 if invert_comp: 2181 code.putln("ret = order_res ? Py_False : Py_True;") 2182 else: 2183 code.putln("ret = order_res ? Py_True : Py_False;") 2184 code.putln("Py_INCREF(ret);") 2185 code.putln("}") # comp_op 2186 code.putln("return ret;") 2187 else: 2188 code.putln("return %s(o1, o2);" % entry.func_cname) 2189 code.putln("}") # Case 2190 2191 if '__eq__' in comp_entry and '__ne__' not in comp_entry and not extern_parent: 2192 code.putln("case Py_NE: {") 2193 code.putln("PyObject *ret;") 2194 # Python itself does not do this optimisation, it seems... 2195 #code.putln("if (o1 == o2) return __Pyx_NewRef(Py_False);") 2196 code.putln("ret = %s(o1, o2);" % comp_entry['__eq__'].func_cname) 2197 code.putln("if (likely(ret && ret != Py_NotImplemented)) {") 2198 code.putln("int b = __Pyx_PyObject_IsTrue(ret);") 2199 code.putln("Py_DECREF(ret);") 2200 code.putln("if (unlikely(b < 0)) return NULL;") 2201 code.putln("ret = (b) ? Py_False : Py_True;") 2202 code.putln("Py_INCREF(ret);") 2203 code.putln("}") 2204 code.putln("return ret;") 2205 code.putln("}") 2206 2207 code.putln("default: {") 2208 if extern_parent and extern_parent.typeptr_cname: 2209 code.putln("if (likely(%s->tp_richcompare)) return %s->tp_richcompare(o1, o2, op);" % ( 2210 extern_parent.typeptr_cname, extern_parent.typeptr_cname)) 2211 code.putln("return __Pyx_NewRef(Py_NotImplemented);") 2212 code.putln("}") 2213 2214 code.putln("}") # switch 2215 code.putln("}") 2216 2217 def generate_binop_function(self, scope, slot, code, pos): 2218 func_name = scope.mangle_internal(slot.slot_name) 2219 if scope.directives['c_api_binop_methods']: 2220 code.putln('#define %s %s' % (func_name, slot.left_slot.slot_code(scope))) 2221 return 2222 2223 code.putln() 2224 preprocessor_guard = slot.preprocessor_guard_code() 2225 if preprocessor_guard: 2226 code.putln(preprocessor_guard) 2227 2228 if slot.left_slot.signature == TypeSlots.binaryfunc: 2229 slot_type = 'binaryfunc' 2230 extra_arg = extra_arg_decl = '' 2231 elif slot.left_slot.signature == TypeSlots.ternaryfunc: 2232 slot_type = 'ternaryfunc' 2233 extra_arg = ', extra_arg' 2234 extra_arg_decl = ', PyObject* extra_arg' 2235 else: 2236 error(pos, "Unexpected type slot signature: %s" % slot) 2237 return 2238 2239 def get_slot_method_cname(method_name): 2240 entry = scope.lookup(method_name) 2241 return entry.func_cname if entry and entry.is_special else None 2242 2243 def call_slot_method(method_name, reverse): 2244 func_cname = get_slot_method_cname(method_name) 2245 if func_cname: 2246 return "%s(%s%s)" % ( 2247 func_cname, 2248 "right, left" if reverse else "left, right", 2249 extra_arg) 2250 else: 2251 return '%s_maybe_call_slot(%s->tp_base, left, right %s)' % ( 2252 func_name, 2253 scope.parent_type.typeptr_cname, 2254 extra_arg) 2255 2256 if get_slot_method_cname(slot.left_slot.method_name) and not get_slot_method_cname(slot.right_slot.method_name): 2257 warning(pos, "Extension type implements %s() but not %s(). " 2258 "The behaviour has changed from previous Cython versions to match Python semantics. " 2259 "You can implement both special methods in a backwards compatible way." % ( 2260 slot.left_slot.method_name, 2261 slot.right_slot.method_name, 2262 )) 2263 2264 overloads_left = int(bool(get_slot_method_cname(slot.left_slot.method_name))) 2265 overloads_right = int(bool(get_slot_method_cname(slot.right_slot.method_name))) 2266 code.putln( 2267 TempitaUtilityCode.load_as_string( 2268 "BinopSlot", "ExtensionTypes.c", 2269 context={ 2270 "func_name": func_name, 2271 "slot_name": slot.slot_name, 2272 "overloads_left": overloads_left, 2273 "overloads_right": overloads_right, 2274 "call_left": call_slot_method(slot.left_slot.method_name, reverse=False), 2275 "call_right": call_slot_method(slot.right_slot.method_name, reverse=True), 2276 "type_cname": scope.parent_type.typeptr_cname, 2277 "slot_type": slot_type, 2278 "extra_arg": extra_arg, 2279 "extra_arg_decl": extra_arg_decl, 2280 })[1]) 2281 if preprocessor_guard: 2282 code.putln("#endif") 2283 2284 def generate_getattro_function(self, scope, code): 2285 # First try to get the attribute using __getattribute__, if defined, or 2286 # PyObject_GenericGetAttr. 2287 # 2288 # If that raises an AttributeError, call the __getattr__ if defined. 2289 # 2290 # In both cases, defined can be in this class, or any base class. 2291 def lookup_here_or_base(n, tp=None, extern_return=None): 2292 # Recursive lookup 2293 if tp is None: 2294 tp = scope.parent_type 2295 r = tp.scope.lookup_here(n) 2296 if r is None: 2297 if tp.is_external and extern_return is not None: 2298 return extern_return 2299 if tp.base_type is not None: 2300 return lookup_here_or_base(n, tp.base_type) 2301 return r 2302 2303 has_instance_dict = lookup_here_or_base("__dict__", extern_return="extern") 2304 getattr_entry = lookup_here_or_base("__getattr__") 2305 getattribute_entry = lookup_here_or_base("__getattribute__") 2306 code.putln("") 2307 code.putln( 2308 "static PyObject *%s(PyObject *o, PyObject *n) {" % ( 2309 scope.mangle_internal("tp_getattro"))) 2310 if getattribute_entry is not None: 2311 code.putln( 2312 "PyObject *v = %s(o, n);" % ( 2313 getattribute_entry.func_cname)) 2314 else: 2315 if not has_instance_dict and scope.parent_type.is_final_type: 2316 # Final with no dict => use faster type attribute lookup. 2317 code.globalstate.use_utility_code( 2318 UtilityCode.load_cached("PyObject_GenericGetAttrNoDict", "ObjectHandling.c")) 2319 generic_getattr_cfunc = "__Pyx_PyObject_GenericGetAttrNoDict" 2320 elif not has_instance_dict or has_instance_dict == "extern": 2321 # No dict in the known ancestors, but don't know about extern ancestors or subtypes. 2322 code.globalstate.use_utility_code( 2323 UtilityCode.load_cached("PyObject_GenericGetAttr", "ObjectHandling.c")) 2324 generic_getattr_cfunc = "__Pyx_PyObject_GenericGetAttr" 2325 else: 2326 generic_getattr_cfunc = "PyObject_GenericGetAttr" 2327 code.putln( 2328 "PyObject *v = %s(o, n);" % generic_getattr_cfunc) 2329 if getattr_entry is not None: 2330 code.putln( 2331 "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {") 2332 code.putln( 2333 "PyErr_Clear();") 2334 code.putln( 2335 "v = %s(o, n);" % ( 2336 getattr_entry.func_cname)) 2337 code.putln( 2338 "}") 2339 code.putln( 2340 "return v;") 2341 code.putln( 2342 "}") 2343 2344 def generate_setattro_function(self, scope, code): 2345 # Setting and deleting an attribute are both done through 2346 # the setattro method, so we dispatch to user's __setattr__ 2347 # or __delattr__ or fall back on PyObject_GenericSetAttr. 2348 base_type = scope.parent_type.base_type 2349 set_entry = scope.lookup_here("__setattr__") 2350 del_entry = scope.lookup_here("__delattr__") 2351 code.putln("") 2352 code.putln( 2353 "static int %s(PyObject *o, PyObject *n, PyObject *v) {" % ( 2354 scope.mangle_internal("tp_setattro"))) 2355 code.putln( 2356 "if (v) {") 2357 if set_entry: 2358 code.putln( 2359 "return %s(o, n, v);" % ( 2360 set_entry.func_cname)) 2361 else: 2362 self.generate_guarded_basetype_call( 2363 base_type, None, "tp_setattro", "o, n, v", code) 2364 code.putln( 2365 "return PyObject_GenericSetAttr(o, n, v);") 2366 code.putln( 2367 "}") 2368 code.putln( 2369 "else {") 2370 if del_entry: 2371 code.putln( 2372 "return %s(o, n);" % ( 2373 del_entry.func_cname)) 2374 else: 2375 self.generate_guarded_basetype_call( 2376 base_type, None, "tp_setattro", "o, n, v", code) 2377 code.putln( 2378 "return PyObject_GenericSetAttr(o, n, 0);") 2379 code.putln( 2380 "}") 2381 code.putln( 2382 "}") 2383 2384 def generate_descr_get_function(self, scope, code): 2385 # The __get__ function of a descriptor object can be 2386 # called with NULL for the second or third arguments 2387 # under some circumstances, so we replace them with 2388 # None in that case. 2389 user_get_entry = scope.lookup_here("__get__") 2390 code.putln("") 2391 code.putln( 2392 "static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" % ( 2393 scope.mangle_internal("tp_descr_get"))) 2394 code.putln( 2395 "PyObject *r = 0;") 2396 code.putln( 2397 "if (!i) i = Py_None;") 2398 code.putln( 2399 "if (!c) c = Py_None;") 2400 #code.put_incref("i", py_object_type) 2401 #code.put_incref("c", py_object_type) 2402 code.putln( 2403 "r = %s(o, i, c);" % ( 2404 user_get_entry.func_cname)) 2405 #code.put_decref("i", py_object_type) 2406 #code.put_decref("c", py_object_type) 2407 code.putln( 2408 "return r;") 2409 code.putln( 2410 "}") 2411 2412 def generate_descr_set_function(self, scope, code): 2413 # Setting and deleting are both done through the __set__ 2414 # method of a descriptor, so we dispatch to user's __set__ 2415 # or __delete__ or raise an exception. 2416 base_type = scope.parent_type.base_type 2417 user_set_entry = scope.lookup_here("__set__") 2418 user_del_entry = scope.lookup_here("__delete__") 2419 code.putln("") 2420 code.putln( 2421 "static int %s(PyObject *o, PyObject *i, PyObject *v) {" % ( 2422 scope.mangle_internal("tp_descr_set"))) 2423 code.putln( 2424 "if (v) {") 2425 if user_set_entry: 2426 code.putln( 2427 "return %s(o, i, v);" % ( 2428 user_set_entry.func_cname)) 2429 else: 2430 self.generate_guarded_basetype_call( 2431 base_type, None, "tp_descr_set", "o, i, v", code) 2432 code.putln( 2433 'PyErr_SetString(PyExc_NotImplementedError, "__set__");') 2434 code.putln( 2435 "return -1;") 2436 code.putln( 2437 "}") 2438 code.putln( 2439 "else {") 2440 if user_del_entry: 2441 code.putln( 2442 "return %s(o, i);" % ( 2443 user_del_entry.func_cname)) 2444 else: 2445 self.generate_guarded_basetype_call( 2446 base_type, None, "tp_descr_set", "o, i, v", code) 2447 code.putln( 2448 'PyErr_SetString(PyExc_NotImplementedError, "__delete__");') 2449 code.putln( 2450 "return -1;") 2451 code.putln( 2452 "}") 2453 code.putln( 2454 "}") 2455 2456 def generate_property_accessors(self, cclass_scope, code): 2457 for entry in cclass_scope.property_entries: 2458 property_scope = entry.scope 2459 if property_scope.defines_any(["__get__"]): 2460 self.generate_property_get_function(entry, code) 2461 if property_scope.defines_any(["__set__", "__del__"]): 2462 self.generate_property_set_function(entry, code) 2463 2464 def generate_property_get_function(self, property_entry, code): 2465 property_scope = property_entry.scope 2466 property_entry.getter_cname = property_scope.parent_scope.mangle( 2467 Naming.prop_get_prefix, property_entry.name) 2468 get_entry = property_scope.lookup_here("__get__") 2469 code.putln("") 2470 code.putln( 2471 "static PyObject *%s(PyObject *o, CYTHON_UNUSED void *x) {" % ( 2472 property_entry.getter_cname)) 2473 code.putln( 2474 "return %s(o);" % ( 2475 get_entry.func_cname)) 2476 code.putln( 2477 "}") 2478 2479 def generate_property_set_function(self, property_entry, code): 2480 property_scope = property_entry.scope 2481 property_entry.setter_cname = property_scope.parent_scope.mangle( 2482 Naming.prop_set_prefix, property_entry.name) 2483 set_entry = property_scope.lookup_here("__set__") 2484 del_entry = property_scope.lookup_here("__del__") 2485 code.putln("") 2486 code.putln( 2487 "static int %s(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {" % ( 2488 property_entry.setter_cname)) 2489 code.putln( 2490 "if (v) {") 2491 if set_entry: 2492 code.putln( 2493 "return %s(o, v);" % ( 2494 set_entry.func_cname)) 2495 else: 2496 code.putln( 2497 'PyErr_SetString(PyExc_NotImplementedError, "__set__");') 2498 code.putln( 2499 "return -1;") 2500 code.putln( 2501 "}") 2502 code.putln( 2503 "else {") 2504 if del_entry: 2505 code.putln( 2506 "return %s(o);" % ( 2507 del_entry.func_cname)) 2508 else: 2509 code.putln( 2510 'PyErr_SetString(PyExc_NotImplementedError, "__del__");') 2511 code.putln( 2512 "return -1;") 2513 code.putln( 2514 "}") 2515 code.putln( 2516 "}") 2517 2518 def generate_typeobj_spec(self, entry, code): 2519 ext_type = entry.type 2520 scope = ext_type.scope 2521 2522 members_slot = TypeSlots.get_slot_by_name("tp_members") 2523 members_slot.generate_substructure_spec(scope, code) 2524 2525 buffer_slot = TypeSlots.get_slot_by_name("tp_as_buffer") 2526 if not buffer_slot.is_empty(scope): 2527 code.putln("#if !CYTHON_COMPILING_IN_LIMITED_API") 2528 buffer_slot.generate_substructure(scope, code) 2529 code.putln("#endif") 2530 2531 code.putln("static PyType_Slot %s_slots[] = {" % ext_type.typeobj_cname) 2532 for slot in TypeSlots.slot_table: 2533 slot.generate_spec(scope, code) 2534 code.putln("{0, 0},") 2535 code.putln("};") 2536 2537 if ext_type.typedef_flag: 2538 objstruct = ext_type.objstruct_cname 2539 else: 2540 objstruct = "struct %s" % ext_type.objstruct_cname 2541 classname = scope.class_name.as_c_string_literal() 2542 code.putln("static PyType_Spec %s_spec = {" % ext_type.typeobj_cname) 2543 code.putln('"%s.%s",' % (self.full_module_name, classname.replace('"', ''))) 2544 code.putln("sizeof(%s)," % objstruct) 2545 code.putln("0,") 2546 code.putln("%s," % TypeSlots.get_slot_by_name("tp_flags").slot_code(scope)) 2547 code.putln("%s_slots," % ext_type.typeobj_cname) 2548 code.putln("};") 2549 2550 def generate_typeobj_definition(self, modname, entry, code): 2551 type = entry.type 2552 scope = type.scope 2553 for suite in TypeSlots.substructures: 2554 suite.generate_substructure(scope, code) 2555 code.putln("") 2556 if entry.visibility == 'public': 2557 header = "DL_EXPORT(PyTypeObject) %s = {" 2558 else: 2559 header = "static PyTypeObject %s = {" 2560 #code.putln(header % scope.parent_type.typeobj_cname) 2561 code.putln(header % type.typeobj_cname) 2562 code.putln( 2563 "PyVarObject_HEAD_INIT(0, 0)") 2564 classname = scope.class_name.as_c_string_literal() 2565 code.putln( 2566 '"%s."%s, /*tp_name*/' % ( 2567 self.full_module_name, 2568 classname)) 2569 if type.typedef_flag: 2570 objstruct = type.objstruct_cname 2571 else: 2572 objstruct = "struct %s" % type.objstruct_cname 2573 code.putln( 2574 "sizeof(%s), /*tp_basicsize*/" % objstruct) 2575 code.putln( 2576 "0, /*tp_itemsize*/") 2577 for slot in TypeSlots.slot_table: 2578 slot.generate(scope, code) 2579 code.putln( 2580 "};") 2581 2582 def generate_method_table(self, env, code): 2583 if env.is_c_class_scope and not env.pyfunc_entries: 2584 return 2585 binding = env.directives['binding'] 2586 2587 code.putln("") 2588 wrapper_code_writer = code.insertion_point() 2589 2590 code.putln( 2591 "static PyMethodDef %s[] = {" % ( 2592 env.method_table_cname)) 2593 for entry in env.pyfunc_entries: 2594 if not entry.fused_cfunction and not (binding and entry.is_overridable): 2595 code.put_pymethoddef(entry, ",", wrapper_code_writer=wrapper_code_writer) 2596 code.putln( 2597 "{0, 0, 0, 0}") 2598 code.putln( 2599 "};") 2600 2601 if wrapper_code_writer.getvalue(): 2602 wrapper_code_writer.putln("") 2603 2604 def generate_dict_getter_function(self, scope, code): 2605 dict_attr = scope.lookup_here("__dict__") 2606 if not dict_attr or not dict_attr.is_variable: 2607 return 2608 func_name = scope.mangle_internal("__dict__getter") 2609 dict_name = dict_attr.cname 2610 code.putln("") 2611 code.putln("static PyObject *%s(PyObject *o, CYTHON_UNUSED void *x) {" % func_name) 2612 self.generate_self_cast(scope, code) 2613 code.putln("if (unlikely(!p->%s)){" % dict_name) 2614 code.putln("p->%s = PyDict_New();" % dict_name) 2615 code.putln("}") 2616 code.putln("Py_XINCREF(p->%s);" % dict_name) 2617 code.putln("return p->%s;" % dict_name) 2618 code.putln("}") 2619 2620 def generate_getset_table(self, env, code): 2621 if env.property_entries: 2622 code.putln("") 2623 code.putln( 2624 "static struct PyGetSetDef %s[] = {" % 2625 env.getset_table_cname) 2626 for entry in env.property_entries: 2627 doc = entry.doc 2628 if doc: 2629 if doc.is_unicode: 2630 doc = doc.as_utf8_string() 2631 doc_code = "PyDoc_STR(%s)" % doc.as_c_string_literal() 2632 else: 2633 doc_code = "0" 2634 code.putln( 2635 '{(char *)%s, %s, %s, (char *)%s, 0},' % ( 2636 entry.name.as_c_string_literal(), 2637 entry.getter_cname or "0", 2638 entry.setter_cname or "0", 2639 doc_code)) 2640 code.putln( 2641 "{0, 0, 0, 0, 0}") 2642 code.putln( 2643 "};") 2644 2645 def create_import_star_conversion_utility_code(self, env): 2646 # Create all conversion helpers that are needed for "import *" assignments. 2647 # Must be done before code generation to support CythonUtilityCode. 2648 for name, entry in sorted(env.entries.items()): 2649 if entry.is_cglobal and entry.used: 2650 if not entry.type.is_pyobject: 2651 entry.type.create_from_py_utility_code(env) 2652 2653 def generate_import_star(self, env, code): 2654 env.use_utility_code(UtilityCode.load_cached("CStringEquals", "StringTools.c")) 2655 code.putln() 2656 code.enter_cfunc_scope() # as we need labels 2657 code.putln("static int %s(PyObject *o, PyObject* py_name, char *name) {" % Naming.import_star_set) 2658 2659 code.putln("static const char* internal_type_names[] = {") 2660 for name, entry in sorted(env.entries.items()): 2661 if entry.is_type: 2662 code.putln('"%s",' % name) 2663 code.putln("0") 2664 code.putln("};") 2665 2666 code.putln("const char** type_name = internal_type_names;") 2667 code.putln("while (*type_name) {") 2668 code.putln("if (__Pyx_StrEq(name, *type_name)) {") 2669 code.putln('PyErr_Format(PyExc_TypeError, "Cannot overwrite C type %s", name);') 2670 code.putln('goto bad;') 2671 code.putln("}") 2672 code.putln("type_name++;") 2673 code.putln("}") 2674 2675 old_error_label = code.new_error_label() 2676 code.putln("if (0);") # so the first one can be "else if" 2677 msvc_count = 0 2678 for name, entry in sorted(env.entries.items()): 2679 if entry.is_cglobal and entry.used and not entry.type.is_const: 2680 msvc_count += 1 2681 if msvc_count % 100 == 0: 2682 code.putln("#ifdef _MSC_VER") 2683 code.putln("if (0); /* Workaround for MSVC C1061. */") 2684 code.putln("#endif") 2685 code.putln('else if (__Pyx_StrEq(name, "%s")) {' % name) 2686 if entry.type.is_pyobject: 2687 if entry.type.is_extension_type or entry.type.is_builtin_type: 2688 code.putln("if (!(%s)) %s;" % ( 2689 entry.type.type_test_code("o"), 2690 code.error_goto(entry.pos))) 2691 code.putln("Py_INCREF(o);") 2692 code.put_decref(entry.cname, entry.type, nanny=False) 2693 code.putln("%s = %s;" % ( 2694 entry.cname, 2695 PyrexTypes.typecast(entry.type, py_object_type, "o"))) 2696 elif entry.type.create_from_py_utility_code(env): 2697 # if available, utility code was already created in self.prepare_utility_code() 2698 code.putln(entry.type.from_py_call_code( 2699 'o', entry.cname, entry.pos, code)) 2700 else: 2701 code.putln('PyErr_Format(PyExc_TypeError, "Cannot convert Python object %s to %s");' % ( 2702 name, entry.type)) 2703 code.putln(code.error_goto(entry.pos)) 2704 code.putln("}") 2705 code.putln("else {") 2706 code.putln("if (PyObject_SetAttr(%s, py_name, o) < 0) goto bad;" % Naming.module_cname) 2707 code.putln("}") 2708 code.putln("return 0;") 2709 if code.label_used(code.error_label): 2710 code.put_label(code.error_label) 2711 # This helps locate the offending name. 2712 code.put_add_traceback(EncodedString(self.full_module_name)) 2713 code.error_label = old_error_label 2714 code.putln("bad:") 2715 code.putln("return -1;") 2716 code.putln("}") 2717 code.putln("") 2718 code.putln(UtilityCode.load_as_string("ImportStar", "ImportExport.c")[1]) 2719 code.exit_cfunc_scope() # done with labels 2720 2721 def generate_module_state_start(self, env, code): 2722 # TODO: Refactor to move module state struct decl closer to the static decl 2723 code.putln("#if CYTHON_USE_MODULE_STATE") 2724 code.putln('typedef struct {') 2725 code.putln('PyObject *%s;' % env.module_dict_cname) 2726 code.putln('PyObject *%s;' % Naming.builtins_cname) 2727 code.putln('PyObject *%s;' % Naming.cython_runtime_cname) 2728 code.putln('PyObject *%s;' % Naming.empty_tuple) 2729 code.putln('PyObject *%s;' % Naming.empty_bytes) 2730 code.putln('PyObject *%s;' % Naming.empty_unicode) 2731 if Options.pre_import is not None: 2732 code.putln('PyObject *%s;' % Naming.preimport_cname) 2733 code.putln('#ifdef __Pyx_CyFunction_USED') 2734 code.putln('PyTypeObject *%s;' % Naming.cyfunction_type_cname) 2735 code.putln('#endif') 2736 code.putln('#ifdef __Pyx_FusedFunction_USED') 2737 code.putln('PyTypeObject *%s;' % Naming.fusedfunction_type_cname) 2738 code.putln('#endif') 2739 2740 def generate_module_state_end(self, env, modules, globalstate): 2741 module_state = globalstate['module_state'] 2742 module_state_defines = globalstate['module_state_defines'] 2743 module_state_clear = globalstate['module_state_clear'] 2744 module_state_traverse = globalstate['module_state_traverse'] 2745 module_state.putln('} %s;' % Naming.modulestate_cname) 2746 module_state.putln('') 2747 module_state.putln('#ifdef __cplusplus') 2748 module_state.putln('namespace {') 2749 module_state.putln('extern struct PyModuleDef %s;' % Naming.pymoduledef_cname) 2750 module_state.putln('} /* anonymous namespace */') 2751 module_state.putln('#else') 2752 module_state.putln('static struct PyModuleDef %s;' % Naming.pymoduledef_cname) 2753 module_state.putln('#endif') 2754 module_state.putln('') 2755 module_state.putln('#define %s(o) ((%s *)__Pyx_PyModule_GetState(o))' % ( 2756 Naming.modulestate_cname, 2757 Naming.modulestate_cname)) 2758 module_state.putln('') 2759 module_state.putln('#define %s (%s(PyState_FindModule(&%s)))' % ( 2760 Naming.modulestateglobal_cname, 2761 Naming.modulestate_cname, 2762 Naming.pymoduledef_cname)) 2763 module_state.putln('') 2764 module_state.putln('#define %s (PyState_FindModule(&%s))' % ( 2765 env.module_cname, 2766 Naming.pymoduledef_cname)) 2767 module_state.putln("#endif") 2768 module_state_defines.putln("#endif") 2769 module_state_clear.putln("return 0;") 2770 module_state_clear.putln("}") 2771 module_state_clear.putln("#endif") 2772 module_state_traverse.putln("return 0;") 2773 module_state_traverse.putln("}") 2774 module_state_traverse.putln("#endif") 2775 2776 def generate_module_state_defines(self, env, code): 2777 code.putln("#if CYTHON_USE_MODULE_STATE") 2778 code.putln('#define %s %s->%s' % ( 2779 env.module_dict_cname, 2780 Naming.modulestateglobal_cname, 2781 env.module_dict_cname)) 2782 code.putln('#define %s %s->%s' % ( 2783 Naming.builtins_cname, 2784 Naming.modulestateglobal_cname, 2785 Naming.builtins_cname)) 2786 code.putln('#define %s %s->%s' % ( 2787 Naming.cython_runtime_cname, 2788 Naming.modulestateglobal_cname, 2789 Naming.cython_runtime_cname)) 2790 code.putln('#define %s %s->%s' % ( 2791 Naming.empty_tuple, 2792 Naming.modulestateglobal_cname, 2793 Naming.empty_tuple)) 2794 code.putln('#define %s %s->%s' % ( 2795 Naming.empty_bytes, 2796 Naming.modulestateglobal_cname, 2797 Naming.empty_bytes)) 2798 code.putln('#define %s %s->%s' % ( 2799 Naming.empty_unicode, 2800 Naming.modulestateglobal_cname, 2801 Naming.empty_unicode)) 2802 if Options.pre_import is not None: 2803 code.putln('#define %s %s->%s' % ( 2804 Naming.preimport_cname, 2805 Naming.modulestateglobal_cname, 2806 Naming.preimport_cname)) 2807 code.putln('#ifdef __Pyx_CyFunction_USED') 2808 code.putln('#define %s %s->%s' % ( 2809 Naming.cyfunction_type_cname, 2810 Naming.modulestateglobal_cname, 2811 Naming.cyfunction_type_cname)) 2812 code.putln('#endif') 2813 code.putln('#ifdef __Pyx_FusedFunction_USED') 2814 code.putln('#define %s %s->%s' % 2815 (Naming.fusedfunction_type_cname, 2816 Naming.modulestateglobal_cname, 2817 Naming.fusedfunction_type_cname)) 2818 code.putln('#endif') 2819 2820 def generate_module_state_clear(self, env, code): 2821 code.putln("#if CYTHON_USE_MODULE_STATE") 2822 code.putln("static int %s_clear(PyObject *m) {" % Naming.module_cname) 2823 code.putln("%s *clear_module_state = %s(m);" % ( 2824 Naming.modulestate_cname, 2825 Naming.modulestate_cname)) 2826 code.putln("if (!clear_module_state) return 0;") 2827 code.putln('Py_CLEAR(clear_module_state->%s);' % 2828 env.module_dict_cname) 2829 code.putln('Py_CLEAR(clear_module_state->%s);' % 2830 Naming.builtins_cname) 2831 code.putln('Py_CLEAR(clear_module_state->%s);' % 2832 Naming.cython_runtime_cname) 2833 code.putln('Py_CLEAR(clear_module_state->%s);' % 2834 Naming.empty_tuple) 2835 code.putln('Py_CLEAR(clear_module_state->%s);' % 2836 Naming.empty_bytes) 2837 code.putln('Py_CLEAR(clear_module_state->%s);' % 2838 Naming.empty_unicode) 2839 code.putln('#ifdef __Pyx_CyFunction_USED') 2840 code.putln('Py_CLEAR(clear_module_state->%s);' % 2841 Naming.cyfunction_type_cname) 2842 code.putln('#endif') 2843 code.putln('#ifdef __Pyx_FusedFunction_USED') 2844 code.putln('Py_CLEAR(clear_module_state->%s);' % 2845 Naming.fusedfunction_type_cname) 2846 code.putln('#endif') 2847 2848 def generate_module_state_traverse(self, env, code): 2849 code.putln("#if CYTHON_USE_MODULE_STATE") 2850 code.putln("static int %s_traverse(PyObject *m, visitproc visit, void *arg) {" % Naming.module_cname) 2851 code.putln("%s *traverse_module_state = %s(m);" % ( 2852 Naming.modulestate_cname, 2853 Naming.modulestate_cname)) 2854 code.putln("if (!traverse_module_state) return 0;") 2855 code.putln('Py_VISIT(traverse_module_state->%s);' % 2856 env.module_dict_cname) 2857 code.putln('Py_VISIT(traverse_module_state->%s);' % 2858 Naming.builtins_cname) 2859 code.putln('Py_VISIT(traverse_module_state->%s);' % 2860 Naming.cython_runtime_cname) 2861 code.putln('Py_VISIT(traverse_module_state->%s);' % 2862 Naming.empty_tuple) 2863 code.putln('Py_VISIT(traverse_module_state->%s);' % 2864 Naming.empty_bytes) 2865 code.putln('Py_VISIT(traverse_module_state->%s);' % 2866 Naming.empty_unicode) 2867 code.putln('#ifdef __Pyx_CyFunction_USED') 2868 code.putln('Py_VISIT(traverse_module_state->%s);' % 2869 Naming.cyfunction_type_cname) 2870 code.putln('#endif') 2871 code.putln('#ifdef __Pyx_FusedFunction_USED') 2872 code.putln('Py_VISIT(traverse_module_state->%s);' % 2873 Naming.fusedfunction_type_cname) 2874 code.putln('#endif') 2875 2876 def generate_module_init_func(self, imported_modules, env, code): 2877 subfunction = self.mod_init_subfunction(self.pos, self.scope, code) 2878 2879 self.generate_pymoduledef_struct(env, code) 2880 2881 code.enter_cfunc_scope(self.scope) 2882 code.putln("") 2883 code.putln(UtilityCode.load_as_string("PyModInitFuncType", "ModuleSetupCode.c")[0]) 2884 if env.module_name.isascii(): 2885 py2_mod_name = env.module_name 2886 fail_compilation_in_py2 = False 2887 else: 2888 fail_compilation_in_py2 = True 2889 # at this point py2_mod_name is largely a placeholder and the value doesn't matter 2890 py2_mod_name = env.module_name.encode("ascii", errors="ignore").decode("utf8") 2891 2892 header2 = "__Pyx_PyMODINIT_FUNC init%s(void)" % py2_mod_name 2893 header3 = "__Pyx_PyMODINIT_FUNC %s(void)" % self.mod_init_func_cname('PyInit', env) 2894 header3 = EncodedString(header3) 2895 code.putln("#if PY_MAJOR_VERSION < 3") 2896 # Optimise for small code size as the module init function is only executed once. 2897 code.putln("%s CYTHON_SMALL_CODE; /*proto*/" % header2) 2898 if fail_compilation_in_py2: 2899 code.putln('#error "Unicode module names are not supported in Python 2";') 2900 if self.scope.is_package: 2901 code.putln("#if !defined(CYTHON_NO_PYINIT_EXPORT) && (defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS))") 2902 code.putln("__Pyx_PyMODINIT_FUNC init__init__(void) { init%s(); }" % py2_mod_name) 2903 code.putln("#endif") 2904 code.putln(header2) 2905 code.putln("#else") 2906 code.putln("%s CYTHON_SMALL_CODE; /*proto*/" % header3) 2907 if self.scope.is_package: 2908 code.putln("#if !defined(CYTHON_NO_PYINIT_EXPORT) && (defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS))") 2909 code.putln("__Pyx_PyMODINIT_FUNC PyInit___init__(void) { return %s(); }" % ( 2910 self.mod_init_func_cname('PyInit', env))) 2911 code.putln("#endif") 2912 # Hack for a distutils bug - https://bugs.python.org/issue39432 2913 # distutils attempts to make visible a slightly wrong PyInitU module name. Just create a dummy 2914 # function to keep it quiet 2915 wrong_punycode_module_name = self.wrong_punycode_module_name(env.module_name) 2916 if wrong_punycode_module_name: 2917 code.putln("#if !defined(CYTHON_NO_PYINIT_EXPORT) && (defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS))") 2918 code.putln("void %s(void) {} /* workaround for https://bugs.python.org/issue39432 */" % wrong_punycode_module_name) 2919 code.putln("#endif") 2920 code.putln(header3) 2921 2922 # CPython 3.5+ supports multi-phase module initialisation (gives access to __spec__, __file__, etc.) 2923 code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT") 2924 code.putln("{") 2925 code.putln("return PyModuleDef_Init(&%s);" % Naming.pymoduledef_cname) 2926 code.putln("}") 2927 2928 mod_create_func = UtilityCode.load_as_string("ModuleCreationPEP489", "ModuleSetupCode.c")[1] 2929 code.put(mod_create_func) 2930 2931 code.putln("") 2932 # main module init code lives in Py_mod_exec function, not in PyInit function 2933 code.putln("static CYTHON_SMALL_CODE int %s(PyObject *%s)" % ( 2934 self.module_init_func_cname(), 2935 Naming.pymodinit_module_arg)) 2936 code.putln("#endif") # PEP489 2937 2938 code.putln("#endif") # Py3 2939 2940 # start of module init/exec function (pre/post PEP 489) 2941 code.putln("{") 2942 code.putln('int stringtab_initialized = 0;') 2943 tempdecl_code = code.insertion_point() 2944 2945 profile = code.globalstate.directives['profile'] 2946 linetrace = code.globalstate.directives['linetrace'] 2947 if profile or linetrace: 2948 if linetrace: 2949 code.use_fast_gil_utility_code() 2950 code.globalstate.use_utility_code(UtilityCode.load_cached("Profile", "Profile.c")) 2951 2952 code.put_declare_refcount_context() 2953 code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT") 2954 # Most extension modules simply can't deal with it, and Cython isn't ready either. 2955 # See issues listed here: https://docs.python.org/3/c-api/init.html#sub-interpreter-support 2956 code.putln("if (%s) {" % Naming.module_cname) 2957 # Hack: enforce single initialisation. 2958 code.putln("if (%s == %s) return 0;" % ( 2959 Naming.module_cname, 2960 Naming.pymodinit_module_arg, 2961 )) 2962 code.putln('PyErr_SetString(PyExc_RuntimeError,' 2963 ' "Module \'%s\' has already been imported. Re-initialisation is not supported.");' % 2964 env.module_name.as_c_string_literal()[1:-1]) 2965 code.putln("return -1;") 2966 code.putln("}") 2967 code.putln("#elif PY_MAJOR_VERSION >= 3") 2968 # Hack: enforce single initialisation also on reimports under different names on Python 3 (with PEP 3121/489). 2969 code.putln("if (%s) return __Pyx_NewRef(%s);" % ( 2970 Naming.module_cname, 2971 Naming.module_cname, 2972 )) 2973 code.putln("#endif") 2974 2975 code.putln("/*--- Module creation code ---*/") 2976 self.generate_module_creation_code(env, code) 2977 2978 if profile or linetrace: 2979 tempdecl_code.put_trace_declarations() 2980 code.put_trace_frame_init() 2981 2982 refnanny_import_code = UtilityCode.load_as_string("ImportRefnannyAPI", "ModuleSetupCode.c")[1] 2983 code.putln(refnanny_import_code.rstrip()) 2984 code.put_setup_refcount_context(header3) 2985 2986 env.use_utility_code(UtilityCode.load("CheckBinaryVersion", "ModuleSetupCode.c")) 2987 code.put_error_if_neg(self.pos, "__Pyx_check_binary_version()") 2988 2989 code.putln("#ifdef __Pxy_PyFrame_Initialize_Offsets") 2990 code.putln("__Pxy_PyFrame_Initialize_Offsets();") 2991 code.putln("#endif") 2992 code.putln("%s = PyTuple_New(0); %s" % ( 2993 Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos))) 2994 code.putln("%s = PyBytes_FromStringAndSize(\"\", 0); %s" % ( 2995 Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos))) 2996 code.putln("%s = PyUnicode_FromStringAndSize(\"\", 0); %s" % ( 2997 Naming.empty_unicode, code.error_goto_if_null(Naming.empty_unicode, self.pos))) 2998 2999 for ext_type in ('CyFunction', 'FusedFunction', 'Coroutine', 'Generator', 'AsyncGen', 'StopAsyncIteration'): 3000 code.putln("#ifdef __Pyx_%s_USED" % ext_type) 3001 code.put_error_if_neg(self.pos, "__pyx_%s_init(%s)" % (ext_type, env.module_cname)) 3002 code.putln("#endif") 3003 3004 code.putln("/*--- Library function declarations ---*/") 3005 if env.directives['np_pythran']: 3006 code.put_error_if_neg(self.pos, "_import_array()") 3007 3008 code.putln("/*--- Threads initialization code ---*/") 3009 code.putln("#if defined(WITH_THREAD) && PY_VERSION_HEX < 0x030700F0 " 3010 "&& defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS") 3011 code.putln("PyEval_InitThreads();") 3012 code.putln("#endif") 3013 3014 code.putln("/*--- Initialize various global constants etc. ---*/") 3015 code.put_error_if_neg(self.pos, "__Pyx_InitConstants()") 3016 code.putln("stringtab_initialized = 1;") 3017 code.put_error_if_neg(self.pos, "__Pyx_InitGlobals()") # calls any utility code 3018 3019 3020 code.putln("#if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || " 3021 "__PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)") 3022 code.put_error_if_neg(self.pos, "__Pyx_init_sys_getdefaultencoding_params()") 3023 code.putln("#endif") 3024 3025 code.putln("if (%s) {" % self.is_main_module_flag_cname()) 3026 code.put_error_if_neg(self.pos, 'PyObject_SetAttr(%s, %s, %s)' % ( 3027 env.module_cname, 3028 code.intern_identifier(EncodedString("__name__")), 3029 code.intern_identifier(EncodedString("__main__")))) 3030 code.putln("}") 3031 3032 # set up __file__ and __path__, then add the module to sys.modules 3033 self.generate_module_import_setup(env, code) 3034 3035 if Options.cache_builtins: 3036 code.putln("/*--- Builtin init code ---*/") 3037 code.put_error_if_neg(self.pos, "__Pyx_InitCachedBuiltins()") 3038 3039 code.putln("/*--- Constants init code ---*/") 3040 code.put_error_if_neg(self.pos, "__Pyx_InitCachedConstants()") 3041 3042 code.putln("/*--- Global type/function init code ---*/") 3043 3044 with subfunction("Global init code") as inner_code: 3045 self.generate_global_init_code(env, inner_code) 3046 3047 with subfunction("Variable export code") as inner_code: 3048 self.generate_c_variable_export_code(env, inner_code) 3049 3050 with subfunction("Function export code") as inner_code: 3051 self.generate_c_function_export_code(env, inner_code) 3052 3053 with subfunction("Type init code") as inner_code: 3054 self.generate_type_init_code(env, inner_code) 3055 3056 with subfunction("Type import code") as inner_code: 3057 for module in imported_modules: 3058 self.generate_type_import_code_for_module(module, env, inner_code) 3059 3060 with subfunction("Variable import code") as inner_code: 3061 for module in imported_modules: 3062 self.generate_c_variable_import_code_for_module(module, env, inner_code) 3063 3064 with subfunction("Function import code") as inner_code: 3065 for module in imported_modules: 3066 self.specialize_fused_types(module) 3067 self.generate_c_function_import_code_for_module(module, env, inner_code) 3068 3069 code.putln("/*--- Execution code ---*/") 3070 code.mark_pos(None) 3071 3072 code.putln("#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED)") 3073 code.put_error_if_neg(self.pos, "__Pyx_patch_abc()") 3074 code.putln("#endif") 3075 3076 if profile or linetrace: 3077 code.put_trace_call(header3, self.pos, nogil=not code.funcstate.gil_owned) 3078 code.funcstate.can_trace = True 3079 3080 self.body.generate_execution_code(code) 3081 3082 if profile or linetrace: 3083 code.funcstate.can_trace = False 3084 code.put_trace_return("Py_None", nogil=not code.funcstate.gil_owned) 3085 3086 code.putln() 3087 code.putln("/*--- Wrapped vars code ---*/") 3088 self.generate_wrapped_entries_code(env, code) 3089 code.putln() 3090 3091 if Options.generate_cleanup_code: 3092 code.globalstate.use_utility_code( 3093 UtilityCode.load_cached("RegisterModuleCleanup", "ModuleSetupCode.c")) 3094 code.putln("if (__Pyx_RegisterCleanup()) %s;" % code.error_goto(self.pos)) 3095 3096 code.put_goto(code.return_label) 3097 code.put_label(code.error_label) 3098 for cname, type in code.funcstate.all_managed_temps(): 3099 code.put_xdecref(cname, type) 3100 code.putln('if (%s) {' % env.module_cname) 3101 code.putln('if (%s && stringtab_initialized) {' % env.module_dict_cname) 3102 # We can run into errors before the module or stringtab are initialized. 3103 # In this case it is not safe to add a traceback (because it uses the stringtab) 3104 code.put_add_traceback(EncodedString("init %s" % env.qualified_name)) 3105 code.globalstate.use_utility_code(Nodes.traceback_utility_code) 3106 # Module reference and module dict are in global variables which might still be needed 3107 # for cleanup, atexit code, etc., so leaking is better than crashing. 3108 # At least clearing the module dict here might be a good idea, but could still break 3109 # user code in atexit or other global registries. 3110 ##code.put_decref_clear(env.module_dict_cname, py_object_type, nanny=False) 3111 code.putln('}') 3112 code.putln("#if !CYTHON_COMPILING_IN_LIMITED_API") 3113 code.put_decref_clear(env.module_cname, py_object_type, nanny=False, clear_before_decref=True) 3114 code.putln("#endif") 3115 code.putln('} else if (!PyErr_Occurred()) {') 3116 code.putln('PyErr_SetString(PyExc_ImportError, "init %s");' % 3117 env.qualified_name.as_c_string_literal()[1:-1]) 3118 code.putln('}') 3119 code.put_label(code.return_label) 3120 3121 code.put_finish_refcount_context() 3122 3123 code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT") 3124 code.putln("return (%s != NULL) ? 0 : -1;" % env.module_cname) 3125 code.putln("#elif PY_MAJOR_VERSION >= 3") 3126 code.putln("return %s;" % env.module_cname) 3127 code.putln("#else") 3128 code.putln("return;") 3129 code.putln("#endif") 3130 code.putln('}') 3131 3132 tempdecl_code.put_temp_declarations(code.funcstate) 3133 3134 code.exit_cfunc_scope() 3135 3136 def mod_init_subfunction(self, pos, scope, orig_code): 3137 """ 3138 Return a context manager that allows deviating the module init code generation 3139 into a separate function and instead inserts a call to it. 3140 3141 Can be reused sequentially to create multiple functions. 3142 The functions get inserted at the point where the context manager was created. 3143 The call gets inserted where the context manager is used (on entry). 3144 """ 3145 prototypes = orig_code.insertion_point() 3146 prototypes.putln("") 3147 function_code = orig_code.insertion_point() 3148 function_code.putln("") 3149 3150 class ModInitSubfunction(object): 3151 def __init__(self, code_type): 3152 cname = '_'.join(code_type.lower().split()) 3153 assert re.match("^[a-z0-9_]+$", cname) 3154 self.cfunc_name = "__Pyx_modinit_%s" % cname 3155 self.description = code_type 3156 self.tempdecl_code = None 3157 self.call_code = None 3158 3159 def __enter__(self): 3160 self.call_code = orig_code.insertion_point() 3161 code = function_code 3162 code.enter_cfunc_scope(scope) 3163 prototypes.putln("static CYTHON_SMALL_CODE int %s(void); /*proto*/" % self.cfunc_name) 3164 code.putln("static int %s(void) {" % self.cfunc_name) 3165 code.put_declare_refcount_context() 3166 self.tempdecl_code = code.insertion_point() 3167 code.put_setup_refcount_context(EncodedString(self.cfunc_name)) 3168 # Leave a grepable marker that makes it easy to find the generator source. 3169 code.putln("/*--- %s ---*/" % self.description) 3170 return code 3171 3172 def __exit__(self, *args): 3173 code = function_code 3174 code.put_finish_refcount_context() 3175 code.putln("return 0;") 3176 3177 self.tempdecl_code.put_temp_declarations(code.funcstate) 3178 self.tempdecl_code = None 3179 3180 needs_error_handling = code.label_used(code.error_label) 3181 if needs_error_handling: 3182 code.put_label(code.error_label) 3183 for cname, type in code.funcstate.all_managed_temps(): 3184 code.put_xdecref(cname, type) 3185 code.put_finish_refcount_context() 3186 code.putln("return -1;") 3187 code.putln("}") 3188 code.exit_cfunc_scope() 3189 code.putln("") 3190 3191 if needs_error_handling: 3192 self.call_code.putln( 3193 self.call_code.error_goto_if_neg("%s()" % self.cfunc_name, pos)) 3194 else: 3195 self.call_code.putln("(void)%s();" % self.cfunc_name) 3196 self.call_code = None 3197 3198 return ModInitSubfunction 3199 3200 def generate_module_import_setup(self, env, code): 3201 module_path = env.directives['set_initial_path'] 3202 if module_path == 'SOURCEFILE': 3203 module_path = self.pos[0].filename 3204 3205 if module_path: 3206 code.putln('if (!CYTHON_PEP489_MULTI_PHASE_INIT) {') 3207 code.putln('if (PyObject_SetAttrString(%s, "__file__", %s) < 0) %s;' % ( 3208 env.module_cname, 3209 code.globalstate.get_py_string_const( 3210 EncodedString(decode_filename(module_path))).cname, 3211 code.error_goto(self.pos))) 3212 code.putln("}") 3213 3214 if env.is_package: 3215 # set __path__ to mark the module as package 3216 code.putln('if (!CYTHON_PEP489_MULTI_PHASE_INIT) {') 3217 temp = code.funcstate.allocate_temp(py_object_type, True) 3218 code.putln('%s = Py_BuildValue("[O]", %s); %s' % ( 3219 temp, 3220 code.globalstate.get_py_string_const( 3221 EncodedString(decode_filename( 3222 os.path.dirname(module_path)))).cname, 3223 code.error_goto_if_null(temp, self.pos))) 3224 code.put_gotref(temp, py_object_type) 3225 code.putln( 3226 'if (PyObject_SetAttrString(%s, "__path__", %s) < 0) %s;' % ( 3227 env.module_cname, temp, code.error_goto(self.pos))) 3228 code.put_decref_clear(temp, py_object_type) 3229 code.funcstate.release_temp(temp) 3230 code.putln("}") 3231 3232 elif env.is_package: 3233 # packages require __path__, so all we can do is try to figure 3234 # out the module path at runtime by rerunning the import lookup 3235 code.putln("if (!CYTHON_PEP489_MULTI_PHASE_INIT) {") 3236 package_name, _ = self.full_module_name.rsplit('.', 1) 3237 if '.' in package_name: 3238 parent_name = '"%s"' % (package_name.rsplit('.', 1)[0],) 3239 else: 3240 parent_name = 'NULL' 3241 code.globalstate.use_utility_code(UtilityCode.load( 3242 "SetPackagePathFromImportLib", "ImportExport.c")) 3243 code.putln(code.error_goto_if_neg( 3244 '__Pyx_SetPackagePathFromImportLib(%s, %s)' % ( 3245 parent_name, 3246 code.globalstate.get_py_string_const( 3247 EncodedString(env.module_name)).cname), 3248 self.pos)) 3249 code.putln("}") 3250 3251 # CPython may not have put us into sys.modules yet, but relative imports and reimports require it 3252 fq_module_name = self.full_module_name 3253 if fq_module_name.endswith('.__init__'): 3254 fq_module_name = EncodedString(fq_module_name[:-len('.__init__')]) 3255 fq_module_name_cstring = fq_module_name.as_c_string_literal() 3256 code.putln("#if PY_MAJOR_VERSION >= 3") 3257 code.putln("{") 3258 code.putln("PyObject *modules = PyImport_GetModuleDict(); %s" % 3259 code.error_goto_if_null("modules", self.pos)) 3260 code.putln('if (!PyDict_GetItemString(modules, %s)) {' % fq_module_name_cstring) 3261 code.putln(code.error_goto_if_neg('PyDict_SetItemString(modules, %s, %s)' % ( 3262 fq_module_name_cstring, env.module_cname), self.pos)) 3263 code.putln("}") 3264 code.putln("}") 3265 code.putln("#endif") 3266 3267 def generate_module_cleanup_func(self, env, code): 3268 if not Options.generate_cleanup_code: 3269 return 3270 3271 code.putln('static void %s(CYTHON_UNUSED PyObject *self) {' % 3272 Naming.cleanup_cname) 3273 code.enter_cfunc_scope(env) 3274 3275 if Options.generate_cleanup_code >= 2: 3276 code.putln("/*--- Global cleanup code ---*/") 3277 rev_entries = list(env.var_entries) 3278 rev_entries.reverse() 3279 for entry in rev_entries: 3280 if entry.visibility != 'extern': 3281 if entry.type.is_pyobject and entry.used: 3282 code.put_xdecref_clear( 3283 entry.cname, entry.type, 3284 clear_before_decref=True, 3285 nanny=False) 3286 code.putln("__Pyx_CleanupGlobals();") 3287 if Options.generate_cleanup_code >= 3: 3288 code.putln("/*--- Type import cleanup code ---*/") 3289 for ext_type in sorted(env.types_imported, key=operator.attrgetter('typeptr_cname')): 3290 code.put_xdecref_clear( 3291 ext_type.typeptr_cname, ext_type, 3292 clear_before_decref=True, 3293 nanny=False) 3294 if Options.cache_builtins: 3295 code.putln("/*--- Builtin cleanup code ---*/") 3296 for entry in env.cached_builtins: 3297 code.put_xdecref_clear( 3298 entry.cname, PyrexTypes.py_object_type, 3299 clear_before_decref=True, 3300 nanny=False) 3301 code.putln("/*--- Intern cleanup code ---*/") 3302 code.put_decref_clear(Naming.empty_tuple, 3303 PyrexTypes.py_object_type, 3304 clear_before_decref=True, 3305 nanny=False) 3306 for entry in env.c_class_entries: 3307 cclass_type = entry.type 3308 if cclass_type.is_external or cclass_type.base_type: 3309 continue 3310 if cclass_type.scope.directives.get('freelist', 0): 3311 scope = cclass_type.scope 3312 freelist_name = scope.mangle_internal(Naming.freelist_name) 3313 freecount_name = scope.mangle_internal(Naming.freecount_name) 3314 code.putln("while (%s > 0) {" % freecount_name) 3315 code.putln("PyObject* o = (PyObject*)%s[--%s];" % ( 3316 freelist_name, freecount_name)) 3317 code.putln("(*Py_TYPE(o)->tp_free)(o);") 3318 code.putln("}") 3319# for entry in env.pynum_entries: 3320# code.put_decref_clear(entry.cname, 3321# PyrexTypes.py_object_type, 3322# nanny=False) 3323# for entry in env.all_pystring_entries: 3324# if entry.is_interned: 3325# code.put_decref_clear(entry.pystring_cname, 3326# PyrexTypes.py_object_type, 3327# nanny=False) 3328# for entry in env.default_entries: 3329# if entry.type.is_pyobject and entry.used: 3330# code.putln("Py_DECREF(%s); %s = 0;" % ( 3331# code.entry_as_pyobject(entry), entry.cname)) 3332 if Options.pre_import is not None: 3333 code.put_decref_clear(Naming.preimport_cname, py_object_type, 3334 nanny=False, clear_before_decref=True) 3335 for cname in [Naming.cython_runtime_cname, Naming.builtins_cname]: 3336 code.put_decref_clear(cname, py_object_type, nanny=False, clear_before_decref=True) 3337 code.put_decref_clear(env.module_dict_cname, py_object_type, nanny=False, clear_before_decref=True) 3338 3339 def generate_main_method(self, env, code): 3340 module_is_main = self.is_main_module_flag_cname() 3341 if Options.embed == "main": 3342 wmain = "wmain" 3343 else: 3344 wmain = Options.embed 3345 main_method = UtilityCode.load_cached("MainFunction", "Embed.c") 3346 code.globalstate.use_utility_code( 3347 main_method.specialize( 3348 module_name=env.module_name, 3349 module_is_main=module_is_main, 3350 main_method=Options.embed, 3351 wmain_method=wmain)) 3352 3353 def punycode_module_name(self, prefix, name): 3354 # adapted from PEP483 3355 try: 3356 name = '_' + name.encode('ascii').decode('ascii') 3357 except UnicodeEncodeError: 3358 name = 'U_' + name.encode('punycode').replace(b'-', b'_').decode('ascii') 3359 return "%s%s" % (prefix, name) 3360 3361 def wrong_punycode_module_name(self, name): 3362 # to work around a distutils bug by also generating an incorrect symbol... 3363 try: 3364 name.encode("ascii") 3365 return None # workaround is not needed 3366 except UnicodeEncodeError: 3367 return "PyInitU" + (u"_"+name).encode('punycode').replace(b'-', b'_').decode('ascii') 3368 3369 def mod_init_func_cname(self, prefix, env): 3370 # from PEP483 3371 return self.punycode_module_name(prefix, env.module_name) 3372 3373 # Returns the name of the C-function that corresponds to the module initialisation. 3374 # (module initialisation == the cython code outside of functions) 3375 # Note that this should never be the name of a wrapper and always the name of the 3376 # function containing the actual code. Otherwise, cygdb will experience problems. 3377 def module_init_func_cname(self): 3378 env = self.scope 3379 return self.mod_init_func_cname(Naming.pymodule_exec_func_cname, env) 3380 3381 def generate_pymoduledef_struct(self, env, code): 3382 if env.doc: 3383 doc = "%s" % code.get_string_const(env.doc) 3384 else: 3385 doc = "0" 3386 if Options.generate_cleanup_code: 3387 cleanup_func = "(freefunc)%s" % Naming.cleanup_cname 3388 else: 3389 cleanup_func = 'NULL' 3390 3391 code.putln("") 3392 code.putln("#if PY_MAJOR_VERSION >= 3") 3393 code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT") 3394 exec_func_cname = self.module_init_func_cname() 3395 code.putln("static PyObject* %s(PyObject *spec, PyModuleDef *def); /*proto*/" % 3396 Naming.pymodule_create_func_cname) 3397 code.putln("static int %s(PyObject* module); /*proto*/" % exec_func_cname) 3398 3399 code.putln("static PyModuleDef_Slot %s[] = {" % Naming.pymoduledef_slots_cname) 3400 code.putln("{Py_mod_create, (void*)%s}," % Naming.pymodule_create_func_cname) 3401 code.putln("{Py_mod_exec, (void*)%s}," % exec_func_cname) 3402 code.putln("{0, NULL}") 3403 code.putln("};") 3404 if not env.module_name.isascii(): 3405 code.putln("#else /* CYTHON_PEP489_MULTI_PHASE_INIT */") 3406 code.putln('#error "Unicode module names are only supported with multi-phase init' 3407 ' as per PEP489"') 3408 code.putln("#endif") 3409 3410 code.putln("") 3411 code.putln('#ifdef __cplusplus') 3412 code.putln('namespace {') 3413 code.putln("struct PyModuleDef %s =" % Naming.pymoduledef_cname) 3414 code.putln('#else') 3415 code.putln("static struct PyModuleDef %s =" % Naming.pymoduledef_cname) 3416 code.putln('#endif') 3417 code.putln('{') 3418 code.putln(" PyModuleDef_HEAD_INIT,") 3419 code.putln(' %s,' % env.module_name.as_c_string_literal()) 3420 code.putln(" %s, /* m_doc */" % doc) 3421 code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT") 3422 code.putln(" 0, /* m_size */") 3423 code.putln("#elif CYTHON_USE_MODULE_STATE") # FIXME: should allow combination with PEP-489 3424 code.putln(" sizeof(%s), /* m_size */" % Naming.modulestate_cname) 3425 code.putln("#else") 3426 code.putln(" -1, /* m_size */") 3427 code.putln("#endif") 3428 code.putln(" %s /* m_methods */," % env.method_table_cname) 3429 code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT") 3430 code.putln(" %s, /* m_slots */" % Naming.pymoduledef_slots_cname) 3431 code.putln("#else") 3432 code.putln(" NULL, /* m_reload */") 3433 code.putln("#endif") 3434 code.putln("#if CYTHON_USE_MODULE_STATE") 3435 code.putln(" %s_traverse, /* m_traverse */" % Naming.module_cname) 3436 code.putln(" %s_clear, /* m_clear */" % Naming.module_cname) 3437 code.putln(" %s /* m_free */" % cleanup_func) 3438 code.putln("#else") 3439 code.putln(" NULL, /* m_traverse */") 3440 code.putln(" NULL, /* m_clear */") 3441 code.putln(" %s /* m_free */" % cleanup_func) 3442 code.putln("#endif") 3443 code.putln("};") 3444 code.putln('#ifdef __cplusplus') 3445 code.putln('} /* anonymous namespace */') 3446 code.putln('#endif') 3447 code.putln("#endif") 3448 3449 def generate_module_creation_code(self, env, code): 3450 # Generate code to create the module object and 3451 # install the builtins. 3452 if env.doc: 3453 doc = "%s" % code.get_string_const(env.doc) 3454 else: 3455 doc = "0" 3456 3457 code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT") 3458 code.putln("%s = %s;" % ( 3459 env.module_cname, 3460 Naming.pymodinit_module_arg)) 3461 code.put_incref(env.module_cname, py_object_type, nanny=False) 3462 code.putln("#else") 3463 code.putln("#if PY_MAJOR_VERSION < 3") 3464 code.putln( 3465 '%s = Py_InitModule4(%s, %s, %s, 0, PYTHON_API_VERSION); Py_XINCREF(%s);' % ( 3466 env.module_cname, 3467 env.module_name.as_c_string_literal(), 3468 env.method_table_cname, 3469 doc, 3470 env.module_cname)) 3471 code.putln(code.error_goto_if_null(env.module_cname, self.pos)) 3472 code.putln("#elif CYTHON_COMPILING_IN_LIMITED_API") 3473 module_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True) 3474 code.putln( 3475 "%s = PyModule_Create(&%s); %s" % ( 3476 module_temp, 3477 Naming.pymoduledef_cname, 3478 code.error_goto_if_null(module_temp, self.pos))) 3479 code.put_gotref(module_temp, py_object_type) 3480 code.putln(code.error_goto_if_neg("PyState_AddModule(%s, &%s)" % ( 3481 module_temp, Naming.pymoduledef_cname), self.pos)) 3482 code.put_decref_clear(module_temp, type=py_object_type) 3483 code.funcstate.release_temp(module_temp) 3484 code.putln('#else') 3485 code.putln( 3486 "%s = PyModule_Create(&%s);" % ( 3487 env.module_cname, 3488 Naming.pymoduledef_cname)) 3489 code.putln(code.error_goto_if_null(env.module_cname, self.pos)) 3490 code.putln("#endif") 3491 code.putln("#endif") # CYTHON_PEP489_MULTI_PHASE_INIT 3492 3493 code.putln( 3494 "%s = PyModule_GetDict(%s); %s" % ( 3495 env.module_dict_cname, env.module_cname, 3496 code.error_goto_if_null(env.module_dict_cname, self.pos))) 3497 code.put_incref(env.module_dict_cname, py_object_type, nanny=False) 3498 3499 code.putln( 3500 '%s = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); %s' % ( 3501 Naming.builtins_cname, 3502 code.error_goto_if_null(Naming.builtins_cname, self.pos))) 3503 code.put_incref(Naming.builtins_cname, py_object_type, nanny=False) 3504 code.putln( 3505 '%s = PyImport_AddModule((char *) "cython_runtime"); %s' % ( 3506 Naming.cython_runtime_cname, 3507 code.error_goto_if_null(Naming.cython_runtime_cname, self.pos))) 3508 code.put_incref(Naming.cython_runtime_cname, py_object_type, nanny=False) 3509 code.putln( 3510 'if (PyObject_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % ( 3511 env.module_cname, 3512 Naming.builtins_cname, 3513 code.error_goto(self.pos))) 3514 if Options.pre_import is not None: 3515 code.putln( 3516 '%s = PyImport_AddModule("%s"); %s' % ( 3517 Naming.preimport_cname, 3518 Options.pre_import, 3519 code.error_goto_if_null(Naming.preimport_cname, self.pos))) 3520 code.put_incref(Naming.preimport_cname, py_object_type, nanny=False) 3521 3522 def generate_global_init_code(self, env, code): 3523 # Generate code to initialise global PyObject * 3524 # variables to None. 3525 for entry in env.var_entries: 3526 if entry.visibility != 'extern': 3527 if entry.used: 3528 entry.type.global_init_code(entry, code) 3529 3530 def generate_wrapped_entries_code(self, env, code): 3531 for name, entry in sorted(env.entries.items()): 3532 if (entry.create_wrapper 3533 and not entry.is_type 3534 and entry.scope is env): 3535 if not entry.type.create_to_py_utility_code(env): 3536 error(entry.pos, "Cannot convert '%s' to Python object" % entry.type) 3537 code.putln("{") 3538 code.putln("PyObject* wrapped = %s(%s);" % ( 3539 entry.type.to_py_function, 3540 entry.cname)) 3541 code.putln(code.error_goto_if_null("wrapped", entry.pos)) 3542 code.putln( 3543 'if (PyObject_SetAttrString(%s, "%s", wrapped) < 0) %s;' % ( 3544 env.module_cname, 3545 name, 3546 code.error_goto(entry.pos))) 3547 code.putln("}") 3548 3549 def generate_c_variable_export_code(self, env, code): 3550 # Generate code to create PyCFunction wrappers for exported C functions. 3551 entries = [] 3552 for entry in env.var_entries: 3553 if (entry.api 3554 or entry.defined_in_pxd 3555 or (Options.cimport_from_pyx and not entry.visibility == 'extern')): 3556 entries.append(entry) 3557 if entries: 3558 env.use_utility_code(UtilityCode.load_cached("VoidPtrExport", "ImportExport.c")) 3559 for entry in entries: 3560 signature = entry.type.empty_declaration_code() 3561 name = code.intern_identifier(entry.name) 3562 code.putln('if (__Pyx_ExportVoidPtr(%s, (void *)&%s, "%s") < 0) %s' % ( 3563 name, entry.cname, signature, 3564 code.error_goto(self.pos))) 3565 3566 def generate_c_function_export_code(self, env, code): 3567 # Generate code to create PyCFunction wrappers for exported C functions. 3568 entries = [] 3569 for entry in env.cfunc_entries: 3570 if (entry.api 3571 or entry.defined_in_pxd 3572 or (Options.cimport_from_pyx and not entry.visibility == 'extern')): 3573 entries.append(entry) 3574 if entries: 3575 env.use_utility_code( 3576 UtilityCode.load_cached("FunctionExport", "ImportExport.c")) 3577 # Note: while this looks like it could be more cheaply stored and read from a struct array, 3578 # investigation shows that the resulting binary is smaller with repeated functions calls. 3579 for entry in entries: 3580 signature = entry.type.signature_string() 3581 code.putln('if (__Pyx_ExportFunction(%s, (void (*)(void))%s, "%s") < 0) %s' % ( 3582 entry.name.as_c_string_literal(), 3583 entry.cname, 3584 signature, 3585 code.error_goto(self.pos))) 3586 3587 def generate_type_import_code_for_module(self, module, env, code): 3588 # Generate type import code for all exported extension types in 3589 # an imported module. 3590 #if module.c_class_entries: 3591 with ModuleImportGenerator(code) as import_generator: 3592 for entry in module.c_class_entries: 3593 if entry.defined_in_pxd: 3594 self.generate_type_import_code(env, entry.type, entry.pos, code, import_generator) 3595 3596 def specialize_fused_types(self, pxd_env): 3597 """ 3598 If fused c(p)def functions are defined in an imported pxd, but not 3599 used in this implementation file, we still have fused entries and 3600 not specialized ones. This method replaces any fused entries with their 3601 specialized ones. 3602 """ 3603 for entry in pxd_env.cfunc_entries[:]: 3604 if entry.type.is_fused: 3605 # This call modifies the cfunc_entries in-place 3606 entry.type.get_all_specialized_function_types() 3607 3608 def generate_c_variable_import_code_for_module(self, module, env, code): 3609 # Generate import code for all exported C functions in a cimported module. 3610 entries = [] 3611 for entry in module.var_entries: 3612 if entry.defined_in_pxd: 3613 entries.append(entry) 3614 if entries: 3615 env.use_utility_code( 3616 UtilityCode.load_cached("VoidPtrImport", "ImportExport.c")) 3617 temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True) 3618 code.putln( 3619 '%s = PyImport_ImportModule("%s"); if (!%s) %s' % ( 3620 temp, 3621 module.qualified_name, 3622 temp, 3623 code.error_goto(self.pos))) 3624 code.put_gotref(temp, py_object_type) 3625 for entry in entries: 3626 if env is module: 3627 cname = entry.cname 3628 else: 3629 cname = module.mangle(Naming.varptr_prefix, entry.name) 3630 signature = entry.type.empty_declaration_code() 3631 code.putln( 3632 'if (__Pyx_ImportVoidPtr(%s, "%s", (void **)&%s, "%s") < 0) %s' % ( 3633 temp, entry.name, cname, signature, 3634 code.error_goto(self.pos))) 3635 code.put_decref_clear(temp, py_object_type) 3636 code.funcstate.release_temp(temp) 3637 3638 def generate_c_function_import_code_for_module(self, module, env, code): 3639 # Generate import code for all exported C functions in a cimported module. 3640 entries = [] 3641 for entry in module.cfunc_entries: 3642 if entry.defined_in_pxd and entry.used: 3643 entries.append(entry) 3644 if entries: 3645 env.use_utility_code( 3646 UtilityCode.load_cached("FunctionImport", "ImportExport.c")) 3647 temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True) 3648 code.putln( 3649 '%s = PyImport_ImportModule("%s"); if (!%s) %s' % ( 3650 temp, 3651 module.qualified_name, 3652 temp, 3653 code.error_goto(self.pos))) 3654 code.put_gotref(temp, py_object_type) 3655 for entry in entries: 3656 code.putln( 3657 'if (__Pyx_ImportFunction(%s, %s, (void (**)(void))&%s, "%s") < 0) %s' % ( 3658 temp, 3659 entry.name.as_c_string_literal(), 3660 entry.cname, 3661 entry.type.signature_string(), 3662 code.error_goto(self.pos))) 3663 code.put_decref_clear(temp, py_object_type) 3664 code.funcstate.release_temp(temp) 3665 3666 def generate_type_init_code(self, env, code): 3667 # Generate type import code for extern extension types 3668 # and type ready code for non-extern ones. 3669 with ModuleImportGenerator(code) as import_generator: 3670 for entry in env.c_class_entries: 3671 if entry.visibility == 'extern' and not entry.utility_code_definition: 3672 self.generate_type_import_code(env, entry.type, entry.pos, code, import_generator) 3673 else: 3674 self.generate_base_type_import_code(env, entry, code, import_generator) 3675 self.generate_exttype_vtable_init_code(entry, code) 3676 if entry.type.early_init: 3677 self.generate_type_ready_code(entry, code) 3678 3679 def generate_base_type_import_code(self, env, entry, code, import_generator): 3680 base_type = entry.type.base_type 3681 if (base_type and base_type.module_name != env.qualified_name and not 3682 (base_type.is_builtin_type or base_type.is_cython_builtin_type) 3683 and not entry.utility_code_definition): 3684 self.generate_type_import_code(env, base_type, self.pos, code, import_generator) 3685 3686 def generate_type_import_code(self, env, type, pos, code, import_generator): 3687 # If not already done, generate code to import the typeobject of an 3688 # extension type defined in another module, and extract its C method 3689 # table pointer if any. 3690 if type in env.types_imported: 3691 return 3692 if type.name not in Code.ctypedef_builtins_map: 3693 # see corresponding condition in generate_type_import_call() below! 3694 code.globalstate.use_utility_code( 3695 UtilityCode.load_cached("TypeImport", "ImportExport.c")) 3696 self.generate_type_import_call(type, code, import_generator, error_pos=pos) 3697 if type.vtabptr_cname: 3698 code.globalstate.use_utility_code( 3699 UtilityCode.load_cached('GetVTable', 'ImportExport.c')) 3700 code.putln("%s = (struct %s*)__Pyx_GetVtable(%s); %s" % ( 3701 type.vtabptr_cname, 3702 type.vtabstruct_cname, 3703 type.typeptr_cname, 3704 code.error_goto_if_null(type.vtabptr_cname, pos))) 3705 env.types_imported.add(type) 3706 3707 def generate_type_import_call(self, type, code, import_generator, error_code=None, error_pos=None): 3708 if type.typedef_flag: 3709 objstruct = type.objstruct_cname 3710 else: 3711 objstruct = "struct %s" % type.objstruct_cname 3712 sizeof_objstruct = objstruct 3713 module_name = type.module_name 3714 condition = replacement = None 3715 if module_name not in ('__builtin__', 'builtins'): 3716 module_name = '"%s"' % module_name 3717 elif type.name in Code.ctypedef_builtins_map: 3718 # Fast path for special builtins, don't actually import 3719 ctypename = Code.ctypedef_builtins_map[type.name] 3720 code.putln('%s = %s;' % (type.typeptr_cname, ctypename)) 3721 return 3722 else: 3723 module_name = '__Pyx_BUILTIN_MODULE_NAME' 3724 if type.name in Code.non_portable_builtins_map: 3725 condition, replacement = Code.non_portable_builtins_map[type.name] 3726 if objstruct in Code.basicsize_builtins_map: 3727 # Some builtin types have a tp_basicsize which differs from sizeof(...): 3728 sizeof_objstruct = Code.basicsize_builtins_map[objstruct] 3729 3730 if not error_code: 3731 assert error_pos is not None 3732 error_code = code.error_goto(error_pos) 3733 3734 module = import_generator.imported_module(module_name, error_code) 3735 code.put('%s = __Pyx_ImportType(%s, %s,' % ( 3736 type.typeptr_cname, 3737 module, 3738 module_name)) 3739 3740 type_name = type.name.as_c_string_literal() 3741 3742 if condition and replacement: 3743 code.putln("") # start in new line 3744 code.putln("#if %s" % condition) 3745 code.putln('"%s",' % replacement) 3746 code.putln("#else") 3747 code.putln('%s,' % type_name) 3748 code.putln("#endif") 3749 else: 3750 code.put(' %s, ' % type_name) 3751 3752 if sizeof_objstruct != objstruct: 3753 if not condition: 3754 code.putln("") # start in new line 3755 code.putln("#if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000") 3756 code.putln('sizeof(%s),' % objstruct) 3757 code.putln("#elif CYTHON_COMPILING_IN_LIMITED_API") 3758 code.putln('sizeof(%s),' % objstruct) 3759 code.putln("#else") 3760 code.putln('sizeof(%s),' % sizeof_objstruct) 3761 code.putln("#endif") 3762 else: 3763 code.put('sizeof(%s), ' % objstruct) 3764 3765 # check_size 3766 if type.check_size and type.check_size in ('error', 'warn', 'ignore'): 3767 check_size = type.check_size 3768 elif not type.is_external or type.is_subclassed: 3769 check_size = 'error' 3770 else: 3771 raise RuntimeError("invalid value for check_size '%s' when compiling %s.%s" % ( 3772 type.check_size, module_name, type.name)) 3773 code.putln('__Pyx_ImportType_CheckSize_%s);' % check_size.title()) 3774 3775 code.putln(' if (!%s) %s' % (type.typeptr_cname, error_code)) 3776 3777 def generate_type_ready_code(self, entry, code): 3778 Nodes.CClassDefNode.generate_type_ready_code(entry, code) 3779 3780 def is_main_module_flag_cname(self): 3781 full_module_name = self.full_module_name.replace('.', '__') 3782 return self.punycode_module_name(Naming.module_is_main, full_module_name) 3783 3784 def generate_exttype_vtable_init_code(self, entry, code): 3785 # Generate code to initialise the C method table of an 3786 # extension type. 3787 type = entry.type 3788 if type.vtable_cname: 3789 code.putln( 3790 "%s = &%s;" % ( 3791 type.vtabptr_cname, 3792 type.vtable_cname)) 3793 if type.base_type and type.base_type.vtabptr_cname: 3794 code.putln( 3795 "%s.%s = *%s;" % ( 3796 type.vtable_cname, 3797 Naming.obj_base_cname, 3798 type.base_type.vtabptr_cname)) 3799 3800 c_method_entries = [ 3801 entry for entry in type.scope.cfunc_entries 3802 if entry.func_cname] 3803 if c_method_entries: 3804 for meth_entry in c_method_entries: 3805 cast = meth_entry.type.signature_cast_string() 3806 code.putln( 3807 "%s.%s = %s%s;" % ( 3808 type.vtable_cname, 3809 meth_entry.cname, 3810 cast, 3811 meth_entry.func_cname)) 3812 3813 3814class ModuleImportGenerator(object): 3815 """ 3816 Helper to generate module import while importing external types. 3817 This is used to avoid excessive re-imports of external modules when multiple types are looked up. 3818 """ 3819 def __init__(self, code, imported_modules=None): 3820 self.code = code 3821 self.imported = {} 3822 if imported_modules: 3823 for name, cname in imported_modules.items(): 3824 self.imported['"%s"' % name] = cname 3825 self.temps = [] # remember original import order for freeing 3826 3827 def imported_module(self, module_name_string, error_code): 3828 if module_name_string in self.imported: 3829 return self.imported[module_name_string] 3830 3831 code = self.code 3832 temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True) 3833 self.temps.append(temp) 3834 code.putln('%s = PyImport_ImportModule(%s); if (unlikely(!%s)) %s' % ( 3835 temp, module_name_string, temp, error_code)) 3836 code.put_gotref(temp, py_object_type) 3837 self.imported[module_name_string] = temp 3838 return temp 3839 3840 def __enter__(self): 3841 return self 3842 3843 def __exit__(self, *exc): 3844 code = self.code 3845 for temp in self.temps: 3846 code.put_decref_clear(temp, py_object_type) 3847 code.funcstate.release_temp(temp) 3848 3849 3850def generate_cfunction_declaration(entry, env, code, definition): 3851 from_cy_utility = entry.used and entry.utility_code_definition 3852 if entry.used and entry.inline_func_in_pxd or (not entry.in_cinclude and ( 3853 definition or entry.defined_in_pxd or entry.visibility == 'extern' or from_cy_utility)): 3854 if entry.visibility == 'extern': 3855 storage_class = Naming.extern_c_macro 3856 dll_linkage = "DL_IMPORT" 3857 elif entry.visibility == 'public': 3858 storage_class = Naming.extern_c_macro 3859 dll_linkage = None 3860 elif entry.visibility == 'private': 3861 storage_class = "static" 3862 dll_linkage = None 3863 else: 3864 storage_class = "static" 3865 dll_linkage = None 3866 type = entry.type 3867 3868 if entry.defined_in_pxd and not definition: 3869 storage_class = "static" 3870 dll_linkage = None 3871 type = CPtrType(type) 3872 3873 header = type.declaration_code( 3874 entry.cname, dll_linkage=dll_linkage) 3875 modifiers = code.build_function_modifiers(entry.func_modifiers) 3876 code.putln("%s %s%s; /*proto*/" % ( 3877 storage_class, 3878 modifiers, 3879 header)) 3880 3881#------------------------------------------------------------------------------------ 3882# 3883# Runtime support code 3884# 3885#------------------------------------------------------------------------------------ 3886 3887refnanny_utility_code = UtilityCode.load("Refnanny", "ModuleSetupCode.c") 3888 3889packed_struct_utility_code = UtilityCode(proto=""" 3890#if defined(__GNUC__) 3891#define __Pyx_PACKED __attribute__((__packed__)) 3892#else 3893#define __Pyx_PACKED 3894#endif 3895""", impl="", proto_block='utility_code_proto_before_types') 3896 3897capsule_utility_code = UtilityCode.load("Capsule", "Capsule.c") 3898