1# 2# Symbol Table 3# 4 5from __future__ import absolute_import 6 7import re 8import copy 9import operator 10 11try: 12 import __builtin__ as builtins 13except ImportError: # Py3 14 import builtins 15 16from .Errors import warning, error, InternalError 17from .StringEncoding import EncodedString 18from . import Options, Naming 19from . import PyrexTypes 20from .PyrexTypes import py_object_type, unspecified_type 21from .TypeSlots import ( 22 pyfunction_signature, pymethod_signature, richcmp_special_methods, 23 get_special_method_signature, get_property_accessor_signature) 24from . import Future 25 26from . import Code 27 28iso_c99_keywords = set( 29['auto', 'break', 'case', 'char', 'const', 'continue', 'default', 'do', 30 'double', 'else', 'enum', 'extern', 'float', 'for', 'goto', 'if', 31 'int', 'long', 'register', 'return', 'short', 'signed', 'sizeof', 32 'static', 'struct', 'switch', 'typedef', 'union', 'unsigned', 'void', 33 'volatile', 'while', 34 '_Bool', '_Complex'', _Imaginary', 'inline', 'restrict']) 35 36 37def c_safe_identifier(cname): 38 # There are some C limitations on struct entry names. 39 if ((cname[:2] == '__' and not (cname.startswith(Naming.pyrex_prefix) 40 or cname in ('__weakref__', '__dict__'))) 41 or cname in iso_c99_keywords): 42 cname = Naming.pyrex_prefix + cname 43 return cname 44 45 46class BufferAux(object): 47 writable_needed = False 48 49 def __init__(self, buflocal_nd_var, rcbuf_var): 50 self.buflocal_nd_var = buflocal_nd_var 51 self.rcbuf_var = rcbuf_var 52 53 def __repr__(self): 54 return "<BufferAux %r>" % self.__dict__ 55 56 57class Entry(object): 58 # A symbol table entry in a Scope or ModuleNamespace. 59 # 60 # name string Python name of entity 61 # cname string C name of entity 62 # type PyrexType Type of entity 63 # doc string Doc string 64 # annotation ExprNode PEP 484/526 annotation 65 # init string Initial value 66 # visibility 'private' or 'public' or 'extern' 67 # is_builtin boolean Is an entry in the Python builtins dict 68 # is_cglobal boolean Is a C global variable 69 # is_pyglobal boolean Is a Python module-level variable 70 # or class attribute during 71 # class construction 72 # is_member boolean Is an assigned class member 73 # is_pyclass_attr boolean Is a name in a Python class namespace 74 # is_variable boolean Is a variable 75 # is_cfunction boolean Is a C function 76 # is_cmethod boolean Is a C method of an extension type 77 # is_builtin_cmethod boolean Is a C method of a builtin type (implies is_cmethod) 78 # is_unbound_cmethod boolean Is an unbound C method of an extension type 79 # is_final_cmethod boolean Is non-overridable C method 80 # is_inline_cmethod boolean Is inlined C method 81 # is_anonymous boolean Is a anonymous pyfunction entry 82 # is_type boolean Is a type definition 83 # is_cclass boolean Is an extension class 84 # is_cpp_class boolean Is a C++ class 85 # is_const boolean Is a constant 86 # is_property boolean Is a property of an extension type: 87 # doc_cname string or None C const holding the docstring 88 # getter_cname string C func for getting property 89 # setter_cname string C func for setting or deleting property 90 # is_self_arg boolean Is the "self" arg of an exttype method 91 # is_arg boolean Is the arg of a method 92 # is_local boolean Is a local variable 93 # in_closure boolean Is referenced in an inner scope 94 # in_subscope boolean Belongs to a generator expression scope 95 # is_readonly boolean Can't be assigned to 96 # func_cname string C func implementing Python func 97 # func_modifiers [string] C function modifiers ('inline') 98 # pos position Source position where declared 99 # namespace_cname string If is_pyglobal, the C variable 100 # holding its home namespace 101 # pymethdef_cname string PyMethodDef structure 102 # signature Signature Arg & return types for Python func 103 # as_variable Entry Alternative interpretation of extension 104 # type name or builtin C function as a variable 105 # xdecref_cleanup boolean Use Py_XDECREF for error cleanup 106 # in_cinclude boolean Suppress C declaration code 107 # enum_values [Entry] For enum types, list of values 108 # qualified_name string "modname.funcname" or "modname.classname" 109 # or "modname.classname.funcname" 110 # is_declared_generic boolean Is declared as PyObject * even though its 111 # type is an extension type 112 # as_module None Module scope, if a cimported module 113 # is_inherited boolean Is an inherited attribute of an extension type 114 # pystring_cname string C name of Python version of string literal 115 # is_interned boolean For string const entries, value is interned 116 # is_identifier boolean For string const entries, value is an identifier 117 # used boolean 118 # is_special boolean Is a special method or property accessor 119 # of an extension type 120 # defined_in_pxd boolean Is defined in a .pxd file (not just declared) 121 # api boolean Generate C API for C class or function 122 # utility_code string Utility code needed when this entry is used 123 # 124 # buffer_aux BufferAux or None Extra information needed for buffer variables 125 # inline_func_in_pxd boolean Hacky special case for inline function in pxd file. 126 # Ideally this should not be necessary. 127 # might_overflow boolean In an arithmetic expression that could cause 128 # overflow (used for type inference). 129 # utility_code_definition For some Cython builtins, the utility code 130 # which contains the definition of the entry. 131 # Currently only supported for CythonScope entries. 132 # error_on_uninitialized Have Control Flow issue an error when this entry is 133 # used uninitialized 134 # cf_used boolean Entry is used 135 # is_fused_specialized boolean Whether this entry of a cdef or def function 136 # is a specialization 137 138 # TODO: utility_code and utility_code_definition serves the same purpose... 139 140 inline_func_in_pxd = False 141 borrowed = 0 142 init = "" 143 annotation = None 144 visibility = 'private' 145 is_builtin = 0 146 is_cglobal = 0 147 is_pyglobal = 0 148 is_member = 0 149 is_pyclass_attr = 0 150 is_variable = 0 151 is_cfunction = 0 152 is_cmethod = 0 153 is_builtin_cmethod = False 154 is_unbound_cmethod = 0 155 is_final_cmethod = 0 156 is_inline_cmethod = 0 157 is_anonymous = 0 158 is_type = 0 159 is_cclass = 0 160 is_cpp_class = 0 161 is_const = 0 162 is_property = 0 163 doc_cname = None 164 getter_cname = None 165 setter_cname = None 166 is_self_arg = 0 167 is_arg = 0 168 is_local = 0 169 in_closure = 0 170 from_closure = 0 171 in_subscope = 0 172 is_declared_generic = 0 173 is_readonly = 0 174 pyfunc_cname = None 175 func_cname = None 176 func_modifiers = [] 177 final_func_cname = None 178 doc = None 179 as_variable = None 180 xdecref_cleanup = 0 181 in_cinclude = 0 182 as_module = None 183 is_inherited = 0 184 pystring_cname = None 185 is_identifier = 0 186 is_interned = 0 187 used = 0 188 is_special = 0 189 defined_in_pxd = 0 190 is_implemented = 0 191 api = 0 192 utility_code = None 193 is_overridable = 0 194 buffer_aux = None 195 prev_entry = None 196 might_overflow = 0 197 fused_cfunction = None 198 is_fused_specialized = False 199 utility_code_definition = None 200 needs_property = False 201 in_with_gil_block = 0 202 from_cython_utility_code = None 203 error_on_uninitialized = False 204 cf_used = True 205 outer_entry = None 206 207 def __init__(self, name, cname, type, pos = None, init = None): 208 self.name = name 209 self.cname = cname 210 self.type = type 211 self.pos = pos 212 self.init = init 213 self.overloaded_alternatives = [] 214 self.cf_assignments = [] 215 self.cf_references = [] 216 self.inner_entries = [] 217 self.defining_entry = self 218 219 def __repr__(self): 220 return "%s(<%x>, name=%s, type=%s)" % (type(self).__name__, id(self), self.name, self.type) 221 222 def already_declared_here(self): 223 error(self.pos, "Previous declaration is here") 224 225 def redeclared(self, pos): 226 error(pos, "'%s' does not match previous declaration" % self.name) 227 self.already_declared_here() 228 229 def all_alternatives(self): 230 return [self] + self.overloaded_alternatives 231 232 def all_entries(self): 233 return [self] + self.inner_entries 234 235 def __lt__(left, right): 236 if isinstance(left, Entry) and isinstance(right, Entry): 237 return (left.name, left.cname) < (right.name, right.cname) 238 else: 239 return NotImplemented 240 241 242class InnerEntry(Entry): 243 """ 244 An entry in a closure scope that represents the real outer Entry. 245 """ 246 from_closure = True 247 248 def __init__(self, outer_entry, scope): 249 Entry.__init__(self, outer_entry.name, 250 outer_entry.cname, 251 outer_entry.type, 252 outer_entry.pos) 253 self.outer_entry = outer_entry 254 self.scope = scope 255 256 # share state with (outermost) defining entry 257 outermost_entry = outer_entry 258 while outermost_entry.outer_entry: 259 outermost_entry = outermost_entry.outer_entry 260 self.defining_entry = outermost_entry 261 self.inner_entries = outermost_entry.inner_entries 262 self.cf_assignments = outermost_entry.cf_assignments 263 self.cf_references = outermost_entry.cf_references 264 self.overloaded_alternatives = outermost_entry.overloaded_alternatives 265 self.inner_entries.append(self) 266 267 def __getattr__(self, name): 268 if name.startswith('__'): 269 # we wouldn't have been called if it was there 270 raise AttributeError(name) 271 return getattr(self.defining_entry, name) 272 273 def all_entries(self): 274 return self.defining_entry.all_entries() 275 276 277class Scope(object): 278 # name string Unqualified name 279 # outer_scope Scope or None Enclosing scope 280 # entries {string : Entry} Python name to entry, non-types 281 # const_entries [Entry] Constant entries 282 # type_entries [Entry] Struct/union/enum/typedef/exttype entries 283 # sue_entries [Entry] Struct/union/enum entries 284 # arg_entries [Entry] Function argument entries 285 # var_entries [Entry] User-defined variable entries 286 # pyfunc_entries [Entry] Python function entries 287 # cfunc_entries [Entry] C function entries 288 # c_class_entries [Entry] All extension type entries 289 # cname_to_entry {string : Entry} Temp cname to entry mapping 290 # return_type PyrexType or None Return type of function owning scope 291 # is_builtin_scope boolean Is the builtin scope of Python/Cython 292 # is_py_class_scope boolean Is a Python class scope 293 # is_c_class_scope boolean Is an extension type scope 294 # is_closure_scope boolean Is a closure scope 295 # is_passthrough boolean Outer scope is passed directly 296 # is_cpp_class_scope boolean Is a C++ class scope 297 # is_property_scope boolean Is a extension type property scope 298 # scope_prefix string Disambiguator for C names 299 # in_cinclude boolean Suppress C declaration code 300 # qualified_name string "modname" or "modname.classname" 301 # Python strings in this scope 302 # nogil boolean In a nogil section 303 # directives dict Helper variable for the recursive 304 # analysis, contains directive values. 305 # is_internal boolean Is only used internally (simpler setup) 306 307 is_builtin_scope = 0 308 is_py_class_scope = 0 309 is_c_class_scope = 0 310 is_closure_scope = 0 311 is_genexpr_scope = 0 312 is_passthrough = 0 313 is_cpp_class_scope = 0 314 is_property_scope = 0 315 is_module_scope = 0 316 is_internal = 0 317 scope_prefix = "" 318 in_cinclude = 0 319 nogil = 0 320 fused_to_specific = None 321 return_type = None 322 323 def __init__(self, name, outer_scope, parent_scope): 324 # The outer_scope is the next scope in the lookup chain. 325 # The parent_scope is used to derive the qualified name of this scope. 326 self.name = name 327 self.outer_scope = outer_scope 328 self.parent_scope = parent_scope 329 mangled_name = "%d%s_" % (len(name), name.replace('.', '_dot_')) 330 qual_scope = self.qualifying_scope() 331 if qual_scope: 332 self.qualified_name = qual_scope.qualify_name(name) 333 self.scope_prefix = qual_scope.scope_prefix + mangled_name 334 else: 335 self.qualified_name = EncodedString(name) 336 self.scope_prefix = mangled_name 337 self.entries = {} 338 self.subscopes = set() 339 self.const_entries = [] 340 self.type_entries = [] 341 self.sue_entries = [] 342 self.arg_entries = [] 343 self.var_entries = [] 344 self.pyfunc_entries = [] 345 self.cfunc_entries = [] 346 self.c_class_entries = [] 347 self.defined_c_classes = [] 348 self.imported_c_classes = {} 349 self.cname_to_entry = {} 350 self.string_to_entry = {} 351 self.identifier_to_entry = {} 352 self.num_to_entry = {} 353 self.obj_to_entry = {} 354 self.buffer_entries = [] 355 self.lambda_defs = [] 356 self.id_counters = {} 357 358 def __deepcopy__(self, memo): 359 return self 360 361 def merge_in(self, other, merge_unused=True, whitelist=None): 362 # Use with care... 363 entries = [] 364 for name, entry in other.entries.items(): 365 if not whitelist or name in whitelist: 366 if entry.used or merge_unused: 367 entries.append((name, entry)) 368 369 self.entries.update(entries) 370 371 for attr in ('const_entries', 372 'type_entries', 373 'sue_entries', 374 'arg_entries', 375 'var_entries', 376 'pyfunc_entries', 377 'cfunc_entries', 378 'c_class_entries'): 379 self_entries = getattr(self, attr) 380 names = set(e.name for e in self_entries) 381 for entry in getattr(other, attr): 382 if (entry.used or merge_unused) and entry.name not in names: 383 self_entries.append(entry) 384 385 def __str__(self): 386 return "<%s %s>" % (self.__class__.__name__, self.qualified_name) 387 388 def qualifying_scope(self): 389 return self.parent_scope 390 391 def mangle(self, prefix, name = None): 392 if name: 393 return "%s%s%s" % (prefix, self.scope_prefix, name) 394 else: 395 return self.parent_scope.mangle(prefix, self.name) 396 397 def mangle_internal(self, name): 398 # Mangle an internal name so as not to clash with any 399 # user-defined name in this scope. 400 prefix = "%s%s_" % (Naming.pyrex_prefix, name) 401 return self.mangle(prefix) 402 #return self.parent_scope.mangle(prefix, self.name) 403 404 def mangle_class_private_name(self, name): 405 if self.parent_scope: 406 return self.parent_scope.mangle_class_private_name(name) 407 return name 408 409 def next_id(self, name=None): 410 # Return a cname fragment that is unique for this module 411 counters = self.global_scope().id_counters 412 try: 413 count = counters[name] + 1 414 except KeyError: 415 count = 0 416 counters[name] = count 417 if name: 418 if not count: 419 # unique names don't need a suffix, reoccurrences will get one 420 return name 421 return '%s%d' % (name, count) 422 else: 423 return '%d' % count 424 425 def global_scope(self): 426 """ Return the module-level scope containing this scope. """ 427 return self.outer_scope.global_scope() 428 429 def builtin_scope(self): 430 """ Return the module-level scope containing this scope. """ 431 return self.outer_scope.builtin_scope() 432 433 def iter_local_scopes(self): 434 yield self 435 if self.subscopes: 436 for scope in sorted(self.subscopes, key=operator.attrgetter('scope_prefix')): 437 yield scope 438 439 def declare(self, name, cname, type, pos, visibility, shadow = 0, is_type = 0, create_wrapper = 0): 440 # Create new entry, and add to dictionary if 441 # name is not None. Reports a warning if already 442 # declared. 443 if type.is_buffer and not isinstance(self, LocalScope): # and not is_type: 444 error(pos, 'Buffer types only allowed as function local variables') 445 if not self.in_cinclude and cname and re.match("^_[_A-Z]+$", cname): 446 # See http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html#Reserved-Names 447 warning(pos, "'%s' is a reserved name in C." % cname, -1) 448 entries = self.entries 449 if name and name in entries and not shadow: 450 old_entry = entries[name] 451 452 # Reject redeclared C++ functions only if they have the same type signature. 453 cpp_override_allowed = False 454 if type.is_cfunction and old_entry.type.is_cfunction and self.is_cpp(): 455 for alt_entry in old_entry.all_alternatives(): 456 if type == alt_entry.type: 457 if name == '<init>' and not type.args: 458 # Cython pre-declares the no-args constructor - allow later user definitions. 459 cpp_override_allowed = True 460 break 461 else: 462 cpp_override_allowed = True 463 464 if cpp_override_allowed: 465 # C++ function/method overrides with different signatures are ok. 466 pass 467 elif self.is_cpp_class_scope and entries[name].is_inherited: 468 # Likewise ignore inherited classes. 469 pass 470 elif visibility == 'extern': 471 # Silenced outside of "cdef extern" blocks, until we have a safe way to 472 # prevent pxd-defined cpdef functions from ending up here. 473 warning(pos, "'%s' redeclared " % name, 1 if self.in_cinclude else 0) 474 elif visibility != 'ignore': 475 error(pos, "'%s' redeclared " % name) 476 entries[name].already_declared_here() 477 entry = Entry(name, cname, type, pos = pos) 478 entry.in_cinclude = self.in_cinclude 479 entry.create_wrapper = create_wrapper 480 if name: 481 entry.qualified_name = self.qualify_name(name) 482# if name in entries and self.is_cpp(): 483# entries[name].overloaded_alternatives.append(entry) 484# else: 485# entries[name] = entry 486 if not shadow: 487 entries[name] = entry 488 489 if type.is_memoryviewslice: 490 from . import MemoryView 491 entry.init = MemoryView.memslice_entry_init 492 493 entry.scope = self 494 entry.visibility = visibility 495 return entry 496 497 def qualify_name(self, name): 498 return EncodedString("%s.%s" % (self.qualified_name, name)) 499 500 def declare_const(self, name, type, value, pos, cname = None, visibility = 'private', api = 0, create_wrapper = 0): 501 # Add an entry for a named constant. 502 if not cname: 503 if self.in_cinclude or (visibility == 'public' or api): 504 cname = name 505 else: 506 cname = self.mangle(Naming.enum_prefix, name) 507 entry = self.declare(name, cname, type, pos, visibility, create_wrapper = create_wrapper) 508 entry.is_const = 1 509 entry.value_node = value 510 return entry 511 512 def declare_type(self, name, type, pos, 513 cname = None, visibility = 'private', api = 0, defining = 1, 514 shadow = 0, template = 0): 515 # Add an entry for a type definition. 516 if not cname: 517 cname = name 518 entry = self.declare(name, cname, type, pos, visibility, shadow, 519 is_type=True) 520 entry.is_type = 1 521 entry.api = api 522 if defining: 523 self.type_entries.append(entry) 524 525 if not template: 526 type.entry = entry 527 528 # here we would set as_variable to an object representing this type 529 return entry 530 531 def declare_typedef(self, name, base_type, pos, cname = None, 532 visibility = 'private', api = 0): 533 if not cname: 534 if self.in_cinclude or (visibility != 'private' or api): 535 cname = name 536 else: 537 cname = self.mangle(Naming.type_prefix, name) 538 try: 539 if self.is_cpp_class_scope: 540 namespace = self.outer_scope.lookup(self.name).type 541 else: 542 namespace = None 543 type = PyrexTypes.create_typedef_type(name, base_type, cname, 544 (visibility == 'extern'), 545 namespace) 546 except ValueError as e: 547 error(pos, e.args[0]) 548 type = PyrexTypes.error_type 549 entry = self.declare_type(name, type, pos, cname, 550 visibility = visibility, api = api) 551 type.qualified_name = entry.qualified_name 552 return entry 553 554 def declare_struct_or_union(self, name, kind, scope, 555 typedef_flag, pos, cname = None, 556 visibility = 'private', api = 0, 557 packed = False): 558 # Add an entry for a struct or union definition. 559 if not cname: 560 if self.in_cinclude or (visibility == 'public' or api): 561 cname = name 562 else: 563 cname = self.mangle(Naming.type_prefix, name) 564 entry = self.lookup_here(name) 565 if not entry: 566 type = PyrexTypes.CStructOrUnionType( 567 name, kind, scope, typedef_flag, cname, packed) 568 entry = self.declare_type(name, type, pos, cname, 569 visibility = visibility, api = api, 570 defining = scope is not None) 571 self.sue_entries.append(entry) 572 type.entry = entry 573 else: 574 if not (entry.is_type and entry.type.is_struct_or_union 575 and entry.type.kind == kind): 576 warning(pos, "'%s' redeclared " % name, 0) 577 elif scope and entry.type.scope: 578 warning(pos, "'%s' already defined (ignoring second definition)" % name, 0) 579 else: 580 self.check_previous_typedef_flag(entry, typedef_flag, pos) 581 self.check_previous_visibility(entry, visibility, pos) 582 if scope: 583 entry.type.scope = scope 584 self.type_entries.append(entry) 585 if self.is_cpp_class_scope: 586 entry.type.namespace = self.outer_scope.lookup(self.name).type 587 return entry 588 589 def declare_cpp_class(self, name, scope, 590 pos, cname = None, base_classes = (), 591 visibility = 'extern', templates = None): 592 if cname is None: 593 if self.in_cinclude or (visibility != 'private'): 594 cname = name 595 else: 596 cname = self.mangle(Naming.type_prefix, name) 597 base_classes = list(base_classes) 598 entry = self.lookup_here(name) 599 if not entry: 600 type = PyrexTypes.CppClassType( 601 name, scope, cname, base_classes, templates = templates) 602 entry = self.declare_type(name, type, pos, cname, 603 visibility = visibility, defining = scope is not None) 604 self.sue_entries.append(entry) 605 else: 606 if not (entry.is_type and entry.type.is_cpp_class): 607 error(pos, "'%s' redeclared " % name) 608 entry.already_declared_here() 609 return None 610 elif scope and entry.type.scope: 611 warning(pos, "'%s' already defined (ignoring second definition)" % name, 0) 612 else: 613 if scope: 614 entry.type.scope = scope 615 self.type_entries.append(entry) 616 if base_classes: 617 if entry.type.base_classes and entry.type.base_classes != base_classes: 618 error(pos, "Base type does not match previous declaration") 619 entry.already_declared_here() 620 else: 621 entry.type.base_classes = base_classes 622 if templates or entry.type.templates: 623 if templates != entry.type.templates: 624 error(pos, "Template parameters do not match previous declaration") 625 entry.already_declared_here() 626 627 def declare_inherited_attributes(entry, base_classes): 628 for base_class in base_classes: 629 if base_class is PyrexTypes.error_type: 630 continue 631 if base_class.scope is None: 632 error(pos, "Cannot inherit from incomplete type") 633 else: 634 declare_inherited_attributes(entry, base_class.base_classes) 635 entry.type.scope.declare_inherited_cpp_attributes(base_class) 636 if scope: 637 declare_inherited_attributes(entry, base_classes) 638 scope.declare_var(name="this", cname="this", type=PyrexTypes.CPtrType(entry.type), pos=entry.pos) 639 if self.is_cpp_class_scope: 640 entry.type.namespace = self.outer_scope.lookup(self.name).type 641 return entry 642 643 def check_previous_typedef_flag(self, entry, typedef_flag, pos): 644 if typedef_flag != entry.type.typedef_flag: 645 error(pos, "'%s' previously declared using '%s'" % ( 646 entry.name, ("cdef", "ctypedef")[entry.type.typedef_flag])) 647 648 def check_previous_visibility(self, entry, visibility, pos): 649 if entry.visibility != visibility: 650 error(pos, "'%s' previously declared as '%s'" % ( 651 entry.name, entry.visibility)) 652 653 def declare_enum(self, name, pos, cname, typedef_flag, 654 visibility = 'private', api = 0, create_wrapper = 0): 655 if name: 656 if not cname: 657 if (self.in_cinclude or visibility == 'public' 658 or visibility == 'extern' or api): 659 cname = name 660 else: 661 cname = self.mangle(Naming.type_prefix, name) 662 if self.is_cpp_class_scope: 663 namespace = self.outer_scope.lookup(self.name).type 664 else: 665 namespace = None 666 type = PyrexTypes.CEnumType(name, cname, typedef_flag, namespace) 667 else: 668 type = PyrexTypes.c_anon_enum_type 669 entry = self.declare_type(name, type, pos, cname = cname, 670 visibility = visibility, api = api) 671 entry.create_wrapper = create_wrapper 672 entry.enum_values = [] 673 self.sue_entries.append(entry) 674 return entry 675 676 def declare_tuple_type(self, pos, components): 677 return self.outer_scope.declare_tuple_type(pos, components) 678 679 def declare_var(self, name, type, pos, 680 cname = None, visibility = 'private', 681 api = 0, in_pxd = 0, is_cdef = 0): 682 # Add an entry for a variable. 683 if not cname: 684 if visibility != 'private' or api: 685 cname = name 686 else: 687 cname = self.mangle(Naming.var_prefix, name) 688 if type.is_cpp_class and visibility != 'extern': 689 type.check_nullary_constructor(pos) 690 entry = self.declare(name, cname, type, pos, visibility) 691 entry.is_variable = 1 692 if in_pxd and visibility != 'extern': 693 entry.defined_in_pxd = 1 694 entry.used = 1 695 if api: 696 entry.api = 1 697 entry.used = 1 698 return entry 699 700 def declare_builtin(self, name, pos): 701 return self.outer_scope.declare_builtin(name, pos) 702 703 def _declare_pyfunction(self, name, pos, visibility='extern', entry=None): 704 if entry and not entry.type.is_cfunction: 705 error(pos, "'%s' already declared" % name) 706 error(entry.pos, "Previous declaration is here") 707 entry = self.declare_var(name, py_object_type, pos, visibility=visibility) 708 entry.signature = pyfunction_signature 709 self.pyfunc_entries.append(entry) 710 return entry 711 712 def declare_pyfunction(self, name, pos, allow_redefine=False, visibility='extern'): 713 # Add an entry for a Python function. 714 entry = self.lookup_here(name) 715 if not allow_redefine: 716 return self._declare_pyfunction(name, pos, visibility=visibility, entry=entry) 717 if entry: 718 if entry.type.is_unspecified: 719 entry.type = py_object_type 720 elif entry.type is not py_object_type: 721 return self._declare_pyfunction(name, pos, visibility=visibility, entry=entry) 722 else: # declare entry stub 723 self.declare_var(name, py_object_type, pos, visibility=visibility) 724 entry = self.declare_var(None, py_object_type, pos, 725 cname=name, visibility='private') 726 entry.name = EncodedString(name) 727 entry.qualified_name = self.qualify_name(name) 728 entry.signature = pyfunction_signature 729 entry.is_anonymous = True 730 return entry 731 732 def declare_lambda_function(self, lambda_name, pos): 733 # Add an entry for an anonymous Python function. 734 func_cname = self.mangle(Naming.lambda_func_prefix + u'funcdef_', lambda_name) 735 pymethdef_cname = self.mangle(Naming.lambda_func_prefix + u'methdef_', lambda_name) 736 qualified_name = self.qualify_name(lambda_name) 737 738 entry = self.declare(None, func_cname, py_object_type, pos, 'private') 739 entry.name = lambda_name 740 entry.qualified_name = qualified_name 741 entry.pymethdef_cname = pymethdef_cname 742 entry.func_cname = func_cname 743 entry.signature = pyfunction_signature 744 entry.is_anonymous = True 745 return entry 746 747 def add_lambda_def(self, def_node): 748 self.lambda_defs.append(def_node) 749 750 def register_pyfunction(self, entry): 751 self.pyfunc_entries.append(entry) 752 753 def declare_cfunction(self, name, type, pos, 754 cname=None, visibility='private', api=0, in_pxd=0, 755 defining=0, modifiers=(), utility_code=None, overridable=False): 756 # Add an entry for a C function. 757 if not cname: 758 if visibility != 'private' or api: 759 cname = name 760 else: 761 cname = self.mangle(Naming.func_prefix, name) 762 entry = self.lookup_here(name) 763 if entry: 764 if not in_pxd and visibility != entry.visibility and visibility == 'extern': 765 # Previously declared, but now extern => treat this 766 # as implementing the function, using the new cname 767 defining = True 768 visibility = entry.visibility 769 entry.cname = cname 770 entry.func_cname = cname 771 if visibility != 'private' and visibility != entry.visibility: 772 warning(pos, "Function '%s' previously declared as '%s', now as '%s'" % (name, entry.visibility, visibility), 1) 773 if overridable != entry.is_overridable: 774 warning(pos, "Function '%s' previously declared as '%s'" % ( 775 name, 'cpdef' if overridable else 'cdef'), 1) 776 if entry.type.same_as(type): 777 # Fix with_gil vs nogil. 778 entry.type = entry.type.with_with_gil(type.with_gil) 779 else: 780 if visibility == 'extern' and entry.visibility == 'extern': 781 can_override = False 782 if self.is_cpp(): 783 can_override = True 784 elif cname: 785 # if all alternatives have different cnames, 786 # it's safe to allow signature overrides 787 for alt_entry in entry.all_alternatives(): 788 if not alt_entry.cname or cname == alt_entry.cname: 789 break # cname not unique! 790 else: 791 can_override = True 792 if can_override: 793 temp = self.add_cfunction(name, type, pos, cname, visibility, modifiers) 794 temp.overloaded_alternatives = entry.all_alternatives() 795 entry = temp 796 else: 797 warning(pos, "Function signature does not match previous declaration", 1) 798 entry.type = type 799 elif not in_pxd and entry.defined_in_pxd and type.compatible_signature_with(entry.type): 800 # TODO: check that this was done by a signature optimisation and not a user error. 801 #warning(pos, "Function signature does not match previous declaration", 1) 802 entry.type = type 803 else: 804 error(pos, "Function signature does not match previous declaration") 805 else: 806 entry = self.add_cfunction(name, type, pos, cname, visibility, modifiers) 807 entry.func_cname = cname 808 entry.is_overridable = overridable 809 if in_pxd and visibility != 'extern': 810 entry.defined_in_pxd = 1 811 if api: 812 entry.api = 1 813 if not defining and not in_pxd and visibility != 'extern': 814 error(pos, "Non-extern C function '%s' declared but not defined" % name) 815 if defining: 816 entry.is_implemented = True 817 if modifiers: 818 entry.func_modifiers = modifiers 819 if utility_code: 820 assert not entry.utility_code, "duplicate utility code definition in entry %s (%s)" % (name, cname) 821 entry.utility_code = utility_code 822 if overridable: 823 # names of cpdef functions can be used as variables and can be assigned to 824 var_entry = Entry(name, cname, py_object_type) # FIXME: cname? 825 var_entry.qualified_name = self.qualify_name(name) 826 var_entry.is_variable = 1 827 var_entry.is_pyglobal = 1 828 var_entry.scope = entry.scope 829 entry.as_variable = var_entry 830 type.entry = entry 831 return entry 832 833 def add_cfunction(self, name, type, pos, cname, visibility, modifiers, inherited=False): 834 # Add a C function entry without giving it a func_cname. 835 entry = self.declare(name, cname, type, pos, visibility) 836 entry.is_cfunction = 1 837 if modifiers: 838 entry.func_modifiers = modifiers 839 if inherited or type.is_fused: 840 self.cfunc_entries.append(entry) 841 else: 842 # For backwards compatibility reasons, we must keep all non-fused methods 843 # before all fused methods, but separately for each type. 844 i = len(self.cfunc_entries) 845 for cfunc_entry in reversed(self.cfunc_entries): 846 if cfunc_entry.is_inherited or not cfunc_entry.type.is_fused: 847 break 848 i -= 1 849 self.cfunc_entries.insert(i, entry) 850 return entry 851 852 def find(self, name, pos): 853 # Look up name, report error if not found. 854 entry = self.lookup(name) 855 if entry: 856 return entry 857 else: 858 error(pos, "'%s' is not declared" % name) 859 860 def find_imported_module(self, path, pos): 861 # Look up qualified name, must be a module, report error if not found. 862 # Path is a list of names. 863 scope = self 864 for name in path: 865 entry = scope.find(name, pos) 866 if not entry: 867 return None 868 if entry.as_module: 869 scope = entry.as_module 870 else: 871 error(pos, "'%s' is not a cimported module" % '.'.join(path)) 872 return None 873 return scope 874 875 def lookup(self, name): 876 # Look up name in this scope or an enclosing one. 877 # Return None if not found. 878 return (self.lookup_here(name) 879 or (self.outer_scope and self.outer_scope.lookup(name)) 880 or None) 881 882 def lookup_here(self, name): 883 # Look up in this scope only, return None if not found. 884 return self.entries.get(name, None) 885 886 def lookup_target(self, name): 887 # Look up name in this scope only. Declare as Python 888 # variable if not found. 889 entry = self.lookup_here(name) 890 if not entry: 891 entry = self.declare_var(name, py_object_type, None) 892 return entry 893 894 def lookup_type(self, name): 895 entry = self.lookup(name) 896 if entry and entry.is_type: 897 if entry.type.is_fused and self.fused_to_specific: 898 return entry.type.specialize(self.fused_to_specific) 899 return entry.type 900 901 def lookup_operator(self, operator, operands): 902 if operands[0].type.is_cpp_class: 903 obj_type = operands[0].type 904 method = obj_type.scope.lookup("operator%s" % operator) 905 if method is not None: 906 arg_types = [arg.type for arg in operands[1:]] 907 res = PyrexTypes.best_match([arg.type for arg in operands[1:]], 908 method.all_alternatives()) 909 if res is not None: 910 return res 911 function = self.lookup("operator%s" % operator) 912 function_alternatives = [] 913 if function is not None: 914 function_alternatives = function.all_alternatives() 915 916 # look-up nonmember methods listed within a class 917 method_alternatives = [] 918 if len(operands)==2: # binary operators only 919 for n in range(2): 920 if operands[n].type.is_cpp_class: 921 obj_type = operands[n].type 922 method = obj_type.scope.lookup("operator%s" % operator) 923 if method is not None: 924 method_alternatives += method.all_alternatives() 925 926 if (not method_alternatives) and (not function_alternatives): 927 return None 928 929 # select the unique alternatives 930 all_alternatives = list(set(method_alternatives + function_alternatives)) 931 932 return PyrexTypes.best_match([arg.type for arg in operands], 933 all_alternatives) 934 935 def lookup_operator_for_types(self, pos, operator, types): 936 from .Nodes import Node 937 class FakeOperand(Node): 938 pass 939 operands = [FakeOperand(pos, type=type) for type in types] 940 return self.lookup_operator(operator, operands) 941 942 def use_utility_code(self, new_code): 943 self.global_scope().use_utility_code(new_code) 944 945 def use_entry_utility_code(self, entry): 946 self.global_scope().use_entry_utility_code(entry) 947 948 def defines_any(self, names): 949 # Test whether any of the given names are defined in this scope. 950 for name in names: 951 if name in self.entries: 952 return 1 953 return 0 954 955 def defines_any_special(self, names): 956 # Test whether any of the given names are defined as special methods in this scope. 957 for name in names: 958 if name in self.entries and self.entries[name].is_special: 959 return 1 960 return 0 961 962 def infer_types(self): 963 from .TypeInference import get_type_inferer 964 get_type_inferer().infer_types(self) 965 966 def is_cpp(self): 967 outer = self.outer_scope 968 if outer is None: 969 return False 970 else: 971 return outer.is_cpp() 972 973 def add_include_file(self, filename, verbatim_include=None, late=False): 974 self.outer_scope.add_include_file(filename, verbatim_include, late) 975 976 977class PreImportScope(Scope): 978 979 namespace_cname = Naming.preimport_cname 980 981 def __init__(self): 982 Scope.__init__(self, Options.pre_import, None, None) 983 984 def declare_builtin(self, name, pos): 985 entry = self.declare(name, name, py_object_type, pos, 'private') 986 entry.is_variable = True 987 entry.is_pyglobal = True 988 return entry 989 990 991class BuiltinScope(Scope): 992 # The builtin namespace. 993 994 is_builtin_scope = True 995 996 def __init__(self): 997 if Options.pre_import is None: 998 Scope.__init__(self, "__builtin__", None, None) 999 else: 1000 Scope.__init__(self, "__builtin__", PreImportScope(), None) 1001 self.type_names = {} 1002 1003 for name, definition in sorted(self.builtin_entries.items()): 1004 cname, type = definition 1005 self.declare_var(name, type, None, cname) 1006 1007 def lookup(self, name, language_level=None, str_is_str=None): 1008 # 'language_level' and 'str_is_str' are passed by ModuleScope 1009 if name == 'str': 1010 if str_is_str is None: 1011 str_is_str = language_level in (None, 2) 1012 if not str_is_str: 1013 name = 'unicode' 1014 return Scope.lookup(self, name) 1015 1016 def declare_builtin(self, name, pos): 1017 if not hasattr(builtins, name): 1018 if self.outer_scope is not None: 1019 return self.outer_scope.declare_builtin(name, pos) 1020 else: 1021 if Options.error_on_unknown_names: 1022 error(pos, "undeclared name not builtin: %s" % name) 1023 else: 1024 warning(pos, "undeclared name not builtin: %s" % name, 2) 1025 1026 def declare_builtin_cfunction(self, name, type, cname, python_equiv=None, utility_code=None): 1027 # If python_equiv == "*", the Python equivalent has the same name 1028 # as the entry, otherwise it has the name specified by python_equiv. 1029 name = EncodedString(name) 1030 entry = self.declare_cfunction(name, type, None, cname, visibility='extern', 1031 utility_code=utility_code) 1032 if python_equiv: 1033 if python_equiv == "*": 1034 python_equiv = name 1035 else: 1036 python_equiv = EncodedString(python_equiv) 1037 var_entry = Entry(python_equiv, python_equiv, py_object_type) 1038 var_entry.qualified_name = self.qualify_name(name) 1039 var_entry.is_variable = 1 1040 var_entry.is_builtin = 1 1041 var_entry.utility_code = utility_code 1042 var_entry.scope = entry.scope 1043 entry.as_variable = var_entry 1044 return entry 1045 1046 def declare_builtin_type(self, name, cname, utility_code = None, objstruct_cname = None): 1047 name = EncodedString(name) 1048 type = PyrexTypes.BuiltinObjectType(name, cname, objstruct_cname) 1049 scope = CClassScope(name, outer_scope=None, visibility='extern') 1050 scope.directives = {} 1051 if name == 'bool': 1052 type.is_final_type = True 1053 type.set_scope(scope) 1054 self.type_names[name] = 1 1055 entry = self.declare_type(name, type, None, visibility='extern') 1056 entry.utility_code = utility_code 1057 1058 var_entry = Entry(name = entry.name, 1059 type = self.lookup('type').type, # make sure "type" is the first type declared... 1060 pos = entry.pos, 1061 cname = entry.type.typeptr_cname) 1062 var_entry.qualified_name = self.qualify_name(name) 1063 var_entry.is_variable = 1 1064 var_entry.is_cglobal = 1 1065 var_entry.is_readonly = 1 1066 var_entry.is_builtin = 1 1067 var_entry.utility_code = utility_code 1068 var_entry.scope = self 1069 if Options.cache_builtins: 1070 var_entry.is_const = True 1071 entry.as_variable = var_entry 1072 1073 return type 1074 1075 def builtin_scope(self): 1076 return self 1077 1078 builtin_entries = { 1079 1080 "type": ["((PyObject*)&PyType_Type)", py_object_type], 1081 1082 "bool": ["((PyObject*)&PyBool_Type)", py_object_type], 1083 "int": ["((PyObject*)&PyInt_Type)", py_object_type], 1084 "long": ["((PyObject*)&PyLong_Type)", py_object_type], 1085 "float": ["((PyObject*)&PyFloat_Type)", py_object_type], 1086 "complex":["((PyObject*)&PyComplex_Type)", py_object_type], 1087 1088 "bytes": ["((PyObject*)&PyBytes_Type)", py_object_type], 1089 "bytearray": ["((PyObject*)&PyByteArray_Type)", py_object_type], 1090 "str": ["((PyObject*)&PyString_Type)", py_object_type], 1091 "unicode":["((PyObject*)&PyUnicode_Type)", py_object_type], 1092 1093 "tuple": ["((PyObject*)&PyTuple_Type)", py_object_type], 1094 "list": ["((PyObject*)&PyList_Type)", py_object_type], 1095 "dict": ["((PyObject*)&PyDict_Type)", py_object_type], 1096 "set": ["((PyObject*)&PySet_Type)", py_object_type], 1097 "frozenset": ["((PyObject*)&PyFrozenSet_Type)", py_object_type], 1098 1099 "slice": ["((PyObject*)&PySlice_Type)", py_object_type], 1100# "file": ["((PyObject*)&PyFile_Type)", py_object_type], # not in Py3 1101 1102 "None": ["Py_None", py_object_type], 1103 "False": ["Py_False", py_object_type], 1104 "True": ["Py_True", py_object_type], 1105 } 1106 1107const_counter = 1 # As a temporary solution for compiling code in pxds 1108 1109class ModuleScope(Scope): 1110 # module_name string Python name of the module 1111 # module_cname string C name of Python module object 1112 # #module_dict_cname string C name of module dict object 1113 # method_table_cname string C name of method table 1114 # doc string Module doc string 1115 # doc_cname string C name of module doc string 1116 # utility_code_list [UtilityCode] Queuing utility codes for forwarding to Code.py 1117 # c_includes {key: IncludeCode} C headers or verbatim code to be generated 1118 # See process_include() for more documentation 1119 # string_to_entry {string : Entry} Map string const to entry 1120 # identifier_to_entry {string : Entry} Map identifier string const to entry 1121 # context Context 1122 # parent_module Scope Parent in the import namespace 1123 # module_entries {string : Entry} For cimport statements 1124 # type_names {string : 1} Set of type names (used during parsing) 1125 # included_files [string] Cython sources included with 'include' 1126 # pxd_file_loaded boolean Corresponding .pxd file has been processed 1127 # cimported_modules [ModuleScope] Modules imported with cimport 1128 # types_imported {PyrexType} Set of types for which import code generated 1129 # has_import_star boolean Module contains import * 1130 # cpp boolean Compiling a C++ file 1131 # is_cython_builtin boolean Is this the Cython builtin scope (or a child scope) 1132 # is_package boolean Is this a package module? (__init__) 1133 1134 is_module_scope = 1 1135 has_import_star = 0 1136 is_cython_builtin = 0 1137 old_style_globals = 0 1138 1139 def __init__(self, name, parent_module, context): 1140 from . import Builtin 1141 self.parent_module = parent_module 1142 outer_scope = Builtin.builtin_scope 1143 Scope.__init__(self, name, outer_scope, parent_module) 1144 if name == "__init__": 1145 # Treat Spam/__init__.pyx specially, so that when Python loads 1146 # Spam/__init__.so, initSpam() is defined. 1147 self.module_name = parent_module.module_name 1148 self.is_package = True 1149 else: 1150 self.module_name = name 1151 self.is_package = False 1152 self.module_name = EncodedString(self.module_name) 1153 self.context = context 1154 self.module_cname = Naming.module_cname 1155 self.module_dict_cname = Naming.moddict_cname 1156 self.method_table_cname = Naming.methtable_cname 1157 self.doc = "" 1158 self.doc_cname = Naming.moddoc_cname 1159 self.utility_code_list = [] 1160 self.module_entries = {} 1161 self.c_includes = {} 1162 self.type_names = dict(outer_scope.type_names) 1163 self.pxd_file_loaded = 0 1164 self.cimported_modules = [] 1165 self.types_imported = set() 1166 self.included_files = [] 1167 self.has_extern_class = 0 1168 self.cached_builtins = [] 1169 self.undeclared_cached_builtins = [] 1170 self.namespace_cname = self.module_cname 1171 self._cached_tuple_types = {} 1172 for var_name in ['__builtins__', '__name__', '__file__', '__doc__', '__path__', 1173 '__spec__', '__loader__', '__package__', '__cached__']: 1174 self.declare_var(EncodedString(var_name), py_object_type, None) 1175 self.process_include(Code.IncludeCode("Python.h", initial=True)) 1176 1177 def qualifying_scope(self): 1178 return self.parent_module 1179 1180 def global_scope(self): 1181 return self 1182 1183 def lookup(self, name, language_level=None, str_is_str=None): 1184 entry = self.lookup_here(name) 1185 if entry is not None: 1186 return entry 1187 1188 if language_level is None: 1189 language_level = self.context.language_level if self.context is not None else 3 1190 if str_is_str is None: 1191 str_is_str = language_level == 2 or ( 1192 self.context is not None and Future.unicode_literals not in self.context.future_directives) 1193 1194 return self.outer_scope.lookup(name, language_level=language_level, str_is_str=str_is_str) 1195 1196 def declare_tuple_type(self, pos, components): 1197 components = tuple(components) 1198 try: 1199 ttype = self._cached_tuple_types[components] 1200 except KeyError: 1201 ttype = self._cached_tuple_types[components] = PyrexTypes.c_tuple_type(components) 1202 cname = ttype.cname 1203 entry = self.lookup_here(cname) 1204 if not entry: 1205 scope = StructOrUnionScope(cname) 1206 for ix, component in enumerate(components): 1207 scope.declare_var(name="f%s" % ix, type=component, pos=pos) 1208 struct_entry = self.declare_struct_or_union( 1209 cname + '_struct', 'struct', scope, typedef_flag=True, pos=pos, cname=cname) 1210 self.type_entries.remove(struct_entry) 1211 ttype.struct_entry = struct_entry 1212 entry = self.declare_type(cname, ttype, pos, cname) 1213 ttype.entry = entry 1214 return entry 1215 1216 def declare_builtin(self, name, pos): 1217 if not hasattr(builtins, name) \ 1218 and name not in Code.non_portable_builtins_map \ 1219 and name not in Code.uncachable_builtins: 1220 if self.has_import_star: 1221 entry = self.declare_var(name, py_object_type, pos) 1222 return entry 1223 else: 1224 if Options.error_on_unknown_names: 1225 error(pos, "undeclared name not builtin: %s" % name) 1226 else: 1227 warning(pos, "undeclared name not builtin: %s" % name, 2) 1228 # unknown - assume it's builtin and look it up at runtime 1229 entry = self.declare(name, None, py_object_type, pos, 'private') 1230 entry.is_builtin = 1 1231 return entry 1232 if Options.cache_builtins: 1233 for entry in self.cached_builtins: 1234 if entry.name == name: 1235 return entry 1236 if name == 'globals' and not self.old_style_globals: 1237 return self.outer_scope.lookup('__Pyx_Globals') 1238 else: 1239 entry = self.declare(None, None, py_object_type, pos, 'private') 1240 if Options.cache_builtins and name not in Code.uncachable_builtins: 1241 entry.is_builtin = 1 1242 entry.is_const = 1 # cached 1243 entry.name = name 1244 entry.cname = Naming.builtin_prefix + name 1245 self.cached_builtins.append(entry) 1246 self.undeclared_cached_builtins.append(entry) 1247 else: 1248 entry.is_builtin = 1 1249 entry.name = name 1250 entry.qualified_name = self.builtin_scope().qualify_name(name) 1251 return entry 1252 1253 def find_module(self, module_name, pos, relative_level=-1): 1254 # Find a module in the import namespace, interpreting 1255 # relative imports relative to this module's parent. 1256 # Finds and parses the module's .pxd file if the module 1257 # has not been referenced before. 1258 relative_to = None 1259 absolute_fallback = False 1260 if relative_level is not None and relative_level > 0: 1261 # explicit relative cimport 1262 # error of going beyond top-level is handled in cimport node 1263 relative_to = self 1264 while relative_level > 0 and relative_to: 1265 relative_to = relative_to.parent_module 1266 relative_level -= 1 1267 elif relative_level != 0: 1268 # -1 or None: try relative cimport first, then absolute 1269 relative_to = self.parent_module 1270 absolute_fallback = True 1271 1272 module_scope = self.global_scope() 1273 return module_scope.context.find_module( 1274 module_name, relative_to=relative_to, pos=pos, absolute_fallback=absolute_fallback) 1275 1276 def find_submodule(self, name): 1277 # Find and return scope for a submodule of this module, 1278 # creating a new empty one if necessary. Doesn't parse .pxd. 1279 if '.' in name: 1280 name, submodule = name.split('.', 1) 1281 else: 1282 submodule = None 1283 scope = self.lookup_submodule(name) 1284 if not scope: 1285 scope = ModuleScope(name, parent_module=self, context=self.context) 1286 self.module_entries[name] = scope 1287 if submodule: 1288 scope = scope.find_submodule(submodule) 1289 return scope 1290 1291 def lookup_submodule(self, name): 1292 # Return scope for submodule of this module, or None. 1293 if '.' in name: 1294 name, submodule = name.split('.', 1) 1295 else: 1296 submodule = None 1297 module = self.module_entries.get(name, None) 1298 if submodule and module is not None: 1299 module = module.lookup_submodule(submodule) 1300 return module 1301 1302 def add_include_file(self, filename, verbatim_include=None, late=False): 1303 """ 1304 Add `filename` as include file. Add `verbatim_include` as 1305 verbatim text in the C file. 1306 Both `filename` and `verbatim_include` can be `None` or empty. 1307 """ 1308 inc = Code.IncludeCode(filename, verbatim_include, late=late) 1309 self.process_include(inc) 1310 1311 def process_include(self, inc): 1312 """ 1313 Add `inc`, which is an instance of `IncludeCode`, to this 1314 `ModuleScope`. This either adds a new element to the 1315 `c_includes` dict or it updates an existing entry. 1316 1317 In detail: the values of the dict `self.c_includes` are 1318 instances of `IncludeCode` containing the code to be put in the 1319 generated C file. The keys of the dict are needed to ensure 1320 uniqueness in two ways: if an include file is specified in 1321 multiple "cdef extern" blocks, only one `#include` statement is 1322 generated. Second, the same include might occur multiple times 1323 if we find it through multiple "cimport" paths. So we use the 1324 generated code (of the form `#include "header.h"`) as dict key. 1325 1326 If verbatim code does not belong to any include file (i.e. it 1327 was put in a `cdef extern from *` block), then we use a unique 1328 dict key: namely, the `sortkey()`. 1329 1330 One `IncludeCode` object can contain multiple pieces of C code: 1331 one optional "main piece" for the include file and several other 1332 pieces for the verbatim code. The `IncludeCode.dict_update` 1333 method merges the pieces of two different `IncludeCode` objects 1334 if needed. 1335 """ 1336 key = inc.mainpiece() 1337 if key is None: 1338 key = inc.sortkey() 1339 inc.dict_update(self.c_includes, key) 1340 inc = self.c_includes[key] 1341 1342 def add_imported_module(self, scope): 1343 if scope not in self.cimported_modules: 1344 for inc in scope.c_includes.values(): 1345 self.process_include(inc) 1346 self.cimported_modules.append(scope) 1347 for m in scope.cimported_modules: 1348 self.add_imported_module(m) 1349 1350 def add_imported_entry(self, name, entry, pos): 1351 if entry.is_pyglobal: 1352 # Allow cimports to follow imports. 1353 entry.is_variable = True 1354 if entry not in self.entries: 1355 self.entries[name] = entry 1356 else: 1357 warning(pos, "'%s' redeclared " % name, 0) 1358 1359 def declare_module(self, name, scope, pos): 1360 # Declare a cimported module. This is represented as a 1361 # Python module-level variable entry with a module 1362 # scope attached to it. Reports an error and returns 1363 # None if previously declared as something else. 1364 entry = self.lookup_here(name) 1365 if entry: 1366 if entry.is_pyglobal and entry.as_module is scope: 1367 return entry # Already declared as the same module 1368 if not (entry.is_pyglobal and not entry.as_module): 1369 # SAGE -- I put this here so Pyrex 1370 # cimport's work across directories. 1371 # Currently it tries to multiply define 1372 # every module appearing in an import list. 1373 # It shouldn't be an error for a module 1374 # name to appear again, and indeed the generated 1375 # code compiles fine. 1376 return entry 1377 else: 1378 entry = self.declare_var(name, py_object_type, pos) 1379 entry.is_variable = 0 1380 entry.as_module = scope 1381 self.add_imported_module(scope) 1382 return entry 1383 1384 def declare_var(self, name, type, pos, 1385 cname = None, visibility = 'private', 1386 api = 0, in_pxd = 0, is_cdef = 0): 1387 # Add an entry for a global variable. If it is a Python 1388 # object type, and not declared with cdef, it will live 1389 # in the module dictionary, otherwise it will be a C 1390 # global variable. 1391 if not visibility in ('private', 'public', 'extern'): 1392 error(pos, "Module-level variable cannot be declared %s" % visibility) 1393 if not is_cdef: 1394 if type is unspecified_type: 1395 type = py_object_type 1396 if not (type.is_pyobject and not type.is_extension_type): 1397 raise InternalError( 1398 "Non-cdef global variable is not a generic Python object") 1399 1400 if not cname: 1401 defining = not in_pxd 1402 if visibility == 'extern' or (visibility == 'public' and defining): 1403 cname = name 1404 else: 1405 cname = self.mangle(Naming.var_prefix, name) 1406 1407 entry = self.lookup_here(name) 1408 if entry and entry.defined_in_pxd: 1409 #if visibility != 'private' and visibility != entry.visibility: 1410 # warning(pos, "Variable '%s' previously declared as '%s'" % (name, entry.visibility), 1) 1411 if not entry.type.same_as(type): 1412 if visibility == 'extern' and entry.visibility == 'extern': 1413 warning(pos, "Variable '%s' type does not match previous declaration" % name, 1) 1414 entry.type = type 1415 #else: 1416 # error(pos, "Variable '%s' type does not match previous declaration" % name) 1417 if entry.visibility != "private": 1418 mangled_cname = self.mangle(Naming.var_prefix, name) 1419 if entry.cname == mangled_cname: 1420 cname = name 1421 entry.cname = name 1422 if not entry.is_implemented: 1423 entry.is_implemented = True 1424 return entry 1425 1426 entry = Scope.declare_var(self, name, type, pos, 1427 cname=cname, visibility=visibility, 1428 api=api, in_pxd=in_pxd, is_cdef=is_cdef) 1429 if is_cdef: 1430 entry.is_cglobal = 1 1431 if entry.type.declaration_value: 1432 entry.init = entry.type.declaration_value 1433 self.var_entries.append(entry) 1434 else: 1435 entry.is_pyglobal = 1 1436 if Options.cimport_from_pyx: 1437 entry.used = 1 1438 return entry 1439 1440 def declare_cfunction(self, name, type, pos, 1441 cname=None, visibility='private', api=0, in_pxd=0, 1442 defining=0, modifiers=(), utility_code=None, overridable=False): 1443 if not defining and 'inline' in modifiers: 1444 # TODO(github/1736): Make this an error. 1445 warning(pos, "Declarations should not be declared inline.", 1) 1446 # Add an entry for a C function. 1447 if not cname: 1448 if visibility == 'extern' or (visibility == 'public' and defining): 1449 cname = name 1450 else: 1451 cname = self.mangle(Naming.func_prefix, name) 1452 if visibility == 'extern' and type.optional_arg_count: 1453 error(pos, "Extern functions cannot have default arguments values.") 1454 entry = self.lookup_here(name) 1455 if entry and entry.defined_in_pxd: 1456 if entry.visibility != "private": 1457 mangled_cname = self.mangle(Naming.var_prefix, name) 1458 if entry.cname == mangled_cname: 1459 cname = name 1460 entry.cname = cname 1461 entry.func_cname = cname 1462 entry = Scope.declare_cfunction( 1463 self, name, type, pos, 1464 cname=cname, visibility=visibility, api=api, in_pxd=in_pxd, 1465 defining=defining, modifiers=modifiers, utility_code=utility_code, 1466 overridable=overridable) 1467 return entry 1468 1469 def declare_global(self, name, pos): 1470 entry = self.lookup_here(name) 1471 if not entry: 1472 self.declare_var(name, py_object_type, pos) 1473 1474 def use_utility_code(self, new_code): 1475 if new_code is not None: 1476 self.utility_code_list.append(new_code) 1477 1478 def use_entry_utility_code(self, entry): 1479 if entry is None: 1480 return 1481 if entry.utility_code: 1482 self.utility_code_list.append(entry.utility_code) 1483 if entry.utility_code_definition: 1484 self.utility_code_list.append(entry.utility_code_definition) 1485 1486 def declare_c_class(self, name, pos, defining=0, implementing=0, 1487 module_name=None, base_type=None, objstruct_cname=None, 1488 typeobj_cname=None, typeptr_cname=None, visibility='private', 1489 typedef_flag=0, api=0, check_size=None, 1490 buffer_defaults=None, shadow=0): 1491 # If this is a non-extern typedef class, expose the typedef, but use 1492 # the non-typedef struct internally to avoid needing forward 1493 # declarations for anonymous structs. 1494 if typedef_flag and visibility != 'extern': 1495 if not (visibility == 'public' or api): 1496 warning(pos, "ctypedef only valid for 'extern' , 'public', and 'api'", 2) 1497 objtypedef_cname = objstruct_cname 1498 typedef_flag = 0 1499 else: 1500 objtypedef_cname = None 1501 # 1502 # Look for previous declaration as a type 1503 # 1504 entry = self.lookup_here(name) 1505 if entry and not shadow: 1506 type = entry.type 1507 if not (entry.is_type and type.is_extension_type): 1508 entry = None # Will cause redeclaration and produce an error 1509 else: 1510 scope = type.scope 1511 if typedef_flag and (not scope or scope.defined): 1512 self.check_previous_typedef_flag(entry, typedef_flag, pos) 1513 if (scope and scope.defined) or (base_type and type.base_type): 1514 if base_type and base_type is not type.base_type: 1515 error(pos, "Base type does not match previous declaration") 1516 if base_type and not type.base_type: 1517 type.base_type = base_type 1518 # 1519 # Make a new entry if needed 1520 # 1521 if not entry or shadow: 1522 type = PyrexTypes.PyExtensionType( 1523 name, typedef_flag, base_type, visibility == 'extern', check_size=check_size) 1524 type.pos = pos 1525 type.buffer_defaults = buffer_defaults 1526 if objtypedef_cname is not None: 1527 type.objtypedef_cname = objtypedef_cname 1528 if visibility == 'extern': 1529 type.module_name = module_name 1530 else: 1531 type.module_name = self.qualified_name 1532 if typeptr_cname: 1533 type.typeptr_cname = typeptr_cname 1534 else: 1535 type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name) 1536 entry = self.declare_type(name, type, pos, visibility = visibility, 1537 defining = 0, shadow = shadow) 1538 entry.is_cclass = True 1539 if objstruct_cname: 1540 type.objstruct_cname = objstruct_cname 1541 elif not entry.in_cinclude: 1542 type.objstruct_cname = self.mangle(Naming.objstruct_prefix, name) 1543 else: 1544 error(entry.pos, 1545 "Object name required for 'public' or 'extern' C class") 1546 self.attach_var_entry_to_c_class(entry) 1547 self.c_class_entries.append(entry) 1548 # 1549 # Check for re-definition and create scope if needed 1550 # 1551 if not type.scope: 1552 if defining or implementing: 1553 scope = CClassScope(name = name, outer_scope = self, 1554 visibility = visibility) 1555 scope.directives = self.directives.copy() 1556 if base_type and base_type.scope: 1557 scope.declare_inherited_c_attributes(base_type.scope) 1558 type.set_scope(scope) 1559 self.type_entries.append(entry) 1560 else: 1561 if defining and type.scope.defined: 1562 error(pos, "C class '%s' already defined" % name) 1563 elif implementing and type.scope.implemented: 1564 error(pos, "C class '%s' already implemented" % name) 1565 # 1566 # Fill in options, checking for compatibility with any previous declaration 1567 # 1568 if defining: 1569 entry.defined_in_pxd = 1 1570 if implementing: # So that filenames in runtime exceptions refer to 1571 entry.pos = pos # the .pyx file and not the .pxd file 1572 if visibility != 'private' and entry.visibility != visibility: 1573 error(pos, "Class '%s' previously declared as '%s'" 1574 % (name, entry.visibility)) 1575 if api: 1576 entry.api = 1 1577 if objstruct_cname: 1578 if type.objstruct_cname and type.objstruct_cname != objstruct_cname: 1579 error(pos, "Object struct name differs from previous declaration") 1580 type.objstruct_cname = objstruct_cname 1581 if typeobj_cname: 1582 if type.typeobj_cname and type.typeobj_cname != typeobj_cname: 1583 error(pos, "Type object name differs from previous declaration") 1584 type.typeobj_cname = typeobj_cname 1585 1586 if self.directives.get('final'): 1587 entry.type.is_final_type = True 1588 1589 # cdef classes are always exported, but we need to set it to 1590 # distinguish between unused Cython utility code extension classes 1591 entry.used = True 1592 1593 # 1594 # Return new or existing entry 1595 # 1596 return entry 1597 1598 def allocate_vtable_names(self, entry): 1599 # If extension type has a vtable, allocate vtable struct and 1600 # slot names for it. 1601 type = entry.type 1602 if type.base_type and type.base_type.vtabslot_cname: 1603 #print "...allocating vtabslot_cname because base type has one" ### 1604 type.vtabslot_cname = "%s.%s" % ( 1605 Naming.obj_base_cname, type.base_type.vtabslot_cname) 1606 elif type.scope and type.scope.cfunc_entries: 1607 # one special case here: when inheriting from builtin 1608 # types, the methods may also be built-in, in which 1609 # case they won't need a vtable 1610 entry_count = len(type.scope.cfunc_entries) 1611 base_type = type.base_type 1612 while base_type: 1613 # FIXME: this will break if we ever get non-inherited C methods 1614 if not base_type.scope or entry_count > len(base_type.scope.cfunc_entries): 1615 break 1616 if base_type.is_builtin_type: 1617 # builtin base type defines all methods => no vtable needed 1618 return 1619 base_type = base_type.base_type 1620 #print "...allocating vtabslot_cname because there are C methods" ### 1621 type.vtabslot_cname = Naming.vtabslot_cname 1622 if type.vtabslot_cname: 1623 #print "...allocating other vtable related cnames" ### 1624 type.vtabstruct_cname = self.mangle(Naming.vtabstruct_prefix, entry.name) 1625 type.vtabptr_cname = self.mangle(Naming.vtabptr_prefix, entry.name) 1626 1627 def check_c_classes_pxd(self): 1628 # Performs post-analysis checking and finishing up of extension types 1629 # being implemented in this module. This is called only for the .pxd. 1630 # 1631 # Checks all extension types declared in this scope to 1632 # make sure that: 1633 # 1634 # * The extension type is fully declared 1635 # 1636 # Also allocates a name for the vtable if needed. 1637 # 1638 for entry in self.c_class_entries: 1639 # Check defined 1640 if not entry.type.scope: 1641 error(entry.pos, "C class '%s' is declared but not defined" % entry.name) 1642 1643 def check_c_class(self, entry): 1644 type = entry.type 1645 name = entry.name 1646 visibility = entry.visibility 1647 # Check defined 1648 if not type.scope: 1649 error(entry.pos, "C class '%s' is declared but not defined" % name) 1650 # Generate typeobj_cname 1651 if visibility != 'extern' and not type.typeobj_cname: 1652 type.typeobj_cname = self.mangle(Naming.typeobj_prefix, name) 1653 ## Generate typeptr_cname 1654 #type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name) 1655 # Check C methods defined 1656 if type.scope: 1657 for method_entry in type.scope.cfunc_entries: 1658 if not method_entry.is_inherited and not method_entry.func_cname: 1659 error(method_entry.pos, "C method '%s' is declared but not defined" % 1660 method_entry.name) 1661 # Allocate vtable name if necessary 1662 if type.vtabslot_cname: 1663 #print "ModuleScope.check_c_classes: allocating vtable cname for", self ### 1664 type.vtable_cname = self.mangle(Naming.vtable_prefix, entry.name) 1665 1666 def check_c_classes(self): 1667 # Performs post-analysis checking and finishing up of extension types 1668 # being implemented in this module. This is called only for the main 1669 # .pyx file scope, not for cimported .pxd scopes. 1670 # 1671 # Checks all extension types declared in this scope to 1672 # make sure that: 1673 # 1674 # * The extension type is implemented 1675 # * All required object and type names have been specified or generated 1676 # * All non-inherited C methods are implemented 1677 # 1678 # Also allocates a name for the vtable if needed. 1679 # 1680 debug_check_c_classes = 0 1681 if debug_check_c_classes: 1682 print("Scope.check_c_classes: checking scope " + self.qualified_name) 1683 for entry in self.c_class_entries: 1684 if debug_check_c_classes: 1685 print("...entry %s %s" % (entry.name, entry)) 1686 print("......type = ", entry.type) 1687 print("......visibility = ", entry.visibility) 1688 self.check_c_class(entry) 1689 1690 def check_c_functions(self): 1691 # Performs post-analysis checking making sure all 1692 # defined c functions are actually implemented. 1693 for name, entry in self.entries.items(): 1694 if entry.is_cfunction: 1695 if (entry.defined_in_pxd 1696 and entry.scope is self 1697 and entry.visibility != 'extern' 1698 and not entry.in_cinclude 1699 and not entry.is_implemented): 1700 error(entry.pos, "Non-extern C function '%s' declared but not defined" % name) 1701 1702 def attach_var_entry_to_c_class(self, entry): 1703 # The name of an extension class has to serve as both a type 1704 # name and a variable name holding the type object. It is 1705 # represented in the symbol table by a type entry with a 1706 # variable entry attached to it. For the variable entry, 1707 # we use a read-only C global variable whose name is an 1708 # expression that refers to the type object. 1709 from . import Builtin 1710 var_entry = Entry(name = entry.name, 1711 type = Builtin.type_type, 1712 pos = entry.pos, 1713 cname = entry.type.typeptr_cname) 1714 var_entry.qualified_name = entry.qualified_name 1715 var_entry.is_variable = 1 1716 var_entry.is_cglobal = 1 1717 var_entry.is_readonly = 1 1718 var_entry.scope = entry.scope 1719 entry.as_variable = var_entry 1720 1721 def is_cpp(self): 1722 return self.cpp 1723 1724 def infer_types(self): 1725 from .TypeInference import PyObjectTypeInferer 1726 PyObjectTypeInferer().infer_types(self) 1727 1728 1729class LocalScope(Scope): 1730 1731 # Does the function have a 'with gil:' block? 1732 has_with_gil_block = False 1733 1734 # Transient attribute, used for symbol table variable declarations 1735 _in_with_gil_block = False 1736 1737 def __init__(self, name, outer_scope, parent_scope = None): 1738 if parent_scope is None: 1739 parent_scope = outer_scope 1740 Scope.__init__(self, name, outer_scope, parent_scope) 1741 1742 def mangle(self, prefix, name): 1743 return prefix + name 1744 1745 def declare_arg(self, name, type, pos): 1746 # Add an entry for an argument of a function. 1747 cname = self.mangle(Naming.var_prefix, name) 1748 entry = self.declare(name, cname, type, pos, 'private') 1749 entry.is_variable = 1 1750 if type.is_pyobject: 1751 entry.init = "0" 1752 entry.is_arg = 1 1753 #entry.borrowed = 1 # Not using borrowed arg refs for now 1754 self.arg_entries.append(entry) 1755 return entry 1756 1757 def declare_var(self, name, type, pos, 1758 cname = None, visibility = 'private', 1759 api = 0, in_pxd = 0, is_cdef = 0): 1760 # Add an entry for a local variable. 1761 if visibility in ('public', 'readonly'): 1762 error(pos, "Local variable cannot be declared %s" % visibility) 1763 entry = Scope.declare_var(self, name, type, pos, 1764 cname=cname, visibility=visibility, 1765 api=api, in_pxd=in_pxd, is_cdef=is_cdef) 1766 if entry.type.declaration_value: 1767 entry.init = entry.type.declaration_value 1768 entry.is_local = 1 1769 1770 entry.in_with_gil_block = self._in_with_gil_block 1771 self.var_entries.append(entry) 1772 return entry 1773 1774 def declare_global(self, name, pos): 1775 # Pull entry from global scope into local scope. 1776 if self.lookup_here(name): 1777 warning(pos, "'%s' redeclared ", 0) 1778 else: 1779 entry = self.global_scope().lookup_target(name) 1780 self.entries[name] = entry 1781 1782 def declare_nonlocal(self, name, pos): 1783 # Pull entry from outer scope into local scope 1784 orig_entry = self.lookup_here(name) 1785 if orig_entry and orig_entry.scope is self and not orig_entry.from_closure: 1786 error(pos, "'%s' redeclared as nonlocal" % name) 1787 orig_entry.already_declared_here() 1788 else: 1789 entry = self.lookup(name) 1790 if entry is None or not entry.from_closure: 1791 error(pos, "no binding for nonlocal '%s' found" % name) 1792 1793 def lookup(self, name): 1794 # Look up name in this scope or an enclosing one. 1795 # Return None if not found. 1796 entry = Scope.lookup(self, name) 1797 if entry is not None: 1798 entry_scope = entry.scope 1799 while entry_scope.is_genexpr_scope: 1800 entry_scope = entry_scope.outer_scope 1801 if entry_scope is not self and entry_scope.is_closure_scope: 1802 if hasattr(entry.scope, "scope_class"): 1803 raise InternalError("lookup() after scope class created.") 1804 # The actual c fragment for the different scopes differs 1805 # on the outside and inside, so we make a new entry 1806 entry.in_closure = True 1807 inner_entry = InnerEntry(entry, self) 1808 inner_entry.is_variable = True 1809 self.entries[name] = inner_entry 1810 return inner_entry 1811 return entry 1812 1813 def mangle_closure_cnames(self, outer_scope_cname): 1814 for scope in self.iter_local_scopes(): 1815 for entry in scope.entries.values(): 1816 if entry.from_closure: 1817 cname = entry.outer_entry.cname 1818 if self.is_passthrough: 1819 entry.cname = cname 1820 else: 1821 if cname.startswith(Naming.cur_scope_cname): 1822 cname = cname[len(Naming.cur_scope_cname)+2:] 1823 entry.cname = "%s->%s" % (outer_scope_cname, cname) 1824 elif entry.in_closure: 1825 entry.original_cname = entry.cname 1826 entry.cname = "%s->%s" % (Naming.cur_scope_cname, entry.cname) 1827 1828 1829class GeneratorExpressionScope(Scope): 1830 """Scope for generator expressions and comprehensions. As opposed 1831 to generators, these can be easily inlined in some cases, so all 1832 we really need is a scope that holds the loop variable(s). 1833 """ 1834 is_genexpr_scope = True 1835 1836 def __init__(self, outer_scope): 1837 parent_scope = outer_scope 1838 # TODO: also ignore class scopes? 1839 while parent_scope.is_genexpr_scope: 1840 parent_scope = parent_scope.parent_scope 1841 name = parent_scope.global_scope().next_id(Naming.genexpr_id_ref) 1842 Scope.__init__(self, name, outer_scope, parent_scope) 1843 self.directives = outer_scope.directives 1844 self.genexp_prefix = "%s%d%s" % (Naming.pyrex_prefix, len(name), name) 1845 1846 # Class/ExtType scopes are filled at class creation time, i.e. from the 1847 # module init function or surrounding function. 1848 while outer_scope.is_genexpr_scope or outer_scope.is_c_class_scope or outer_scope.is_py_class_scope: 1849 outer_scope = outer_scope.outer_scope 1850 self.var_entries = outer_scope.var_entries # keep declarations outside 1851 outer_scope.subscopes.add(self) 1852 1853 def mangle(self, prefix, name): 1854 return '%s%s' % (self.genexp_prefix, self.parent_scope.mangle(prefix, name)) 1855 1856 def declare_var(self, name, type, pos, 1857 cname = None, visibility = 'private', 1858 api = 0, in_pxd = 0, is_cdef = True): 1859 if type is unspecified_type: 1860 # if the outer scope defines a type for this variable, inherit it 1861 outer_entry = self.outer_scope.lookup(name) 1862 if outer_entry and outer_entry.is_variable: 1863 type = outer_entry.type # may still be 'unspecified_type' ! 1864 # the parent scope needs to generate code for the variable, but 1865 # this scope must hold its name exclusively 1866 cname = '%s%s' % (self.genexp_prefix, self.parent_scope.mangle(Naming.var_prefix, name or self.next_id())) 1867 entry = self.declare(name, cname, type, pos, visibility) 1868 entry.is_variable = True 1869 if self.parent_scope.is_module_scope: 1870 entry.is_cglobal = True 1871 else: 1872 entry.is_local = True 1873 entry.in_subscope = True 1874 self.var_entries.append(entry) 1875 self.entries[name] = entry 1876 return entry 1877 1878 def declare_pyfunction(self, name, pos, allow_redefine=False): 1879 return self.outer_scope.declare_pyfunction( 1880 name, pos, allow_redefine) 1881 1882 def declare_lambda_function(self, func_cname, pos): 1883 return self.outer_scope.declare_lambda_function(func_cname, pos) 1884 1885 def add_lambda_def(self, def_node): 1886 return self.outer_scope.add_lambda_def(def_node) 1887 1888 1889class ClosureScope(LocalScope): 1890 1891 is_closure_scope = True 1892 1893 def __init__(self, name, scope_name, outer_scope, parent_scope=None): 1894 LocalScope.__init__(self, name, outer_scope, parent_scope) 1895 self.closure_cname = "%s%s" % (Naming.closure_scope_prefix, scope_name) 1896 1897# def mangle_closure_cnames(self, scope_var): 1898# for entry in self.entries.values() + self.temp_entries: 1899# entry.in_closure = 1 1900# LocalScope.mangle_closure_cnames(self, scope_var) 1901 1902# def mangle(self, prefix, name): 1903# return "%s->%s" % (self.cur_scope_cname, name) 1904# return "%s->%s" % (self.closure_cname, name) 1905 1906 def declare_pyfunction(self, name, pos, allow_redefine=False): 1907 return LocalScope.declare_pyfunction(self, name, pos, allow_redefine, visibility='private') 1908 1909 1910class StructOrUnionScope(Scope): 1911 # Namespace of a C struct or union. 1912 1913 def __init__(self, name="?"): 1914 Scope.__init__(self, name, None, None) 1915 1916 def declare_var(self, name, type, pos, 1917 cname = None, visibility = 'private', 1918 api = 0, in_pxd = 0, is_cdef = 0, 1919 allow_pyobject=False, allow_memoryview=False): 1920 # Add an entry for an attribute. 1921 if not cname: 1922 cname = name 1923 if visibility == 'private': 1924 cname = c_safe_identifier(cname) 1925 if type.is_cfunction: 1926 type = PyrexTypes.CPtrType(type) 1927 entry = self.declare(name, cname, type, pos, visibility) 1928 entry.is_variable = 1 1929 self.var_entries.append(entry) 1930 if type.is_pyobject and not allow_pyobject: 1931 error(pos, "C struct/union member cannot be a Python object") 1932 elif type.is_memoryviewslice and not allow_memoryview: 1933 # Memory views wrap their buffer owner as a Python object. 1934 error(pos, "C struct/union member cannot be a memory view") 1935 if visibility != 'private': 1936 error(pos, "C struct/union member cannot be declared %s" % visibility) 1937 return entry 1938 1939 def declare_cfunction(self, name, type, pos, 1940 cname=None, visibility='private', api=0, in_pxd=0, 1941 defining=0, modifiers=(), overridable=False): # currently no utility code ... 1942 if overridable: 1943 error(pos, "C struct/union member cannot be declared 'cpdef'") 1944 return self.declare_var(name, type, pos, 1945 cname=cname, visibility=visibility) 1946 1947 1948class ClassScope(Scope): 1949 # Abstract base class for namespace of 1950 # Python class or extension type. 1951 # 1952 # class_name string Python name of the class 1953 # scope_prefix string Additional prefix for names 1954 # declared in the class 1955 # doc string or None Doc string 1956 1957 def __init__(self, name, outer_scope): 1958 Scope.__init__(self, name, outer_scope, outer_scope) 1959 self.class_name = name 1960 self.doc = None 1961 1962 def lookup(self, name): 1963 entry = Scope.lookup(self, name) 1964 if entry: 1965 return entry 1966 if name == "classmethod": 1967 # We don't want to use the builtin classmethod here 'cause it won't do the 1968 # right thing in this scope (as the class members aren't still functions). 1969 # Don't want to add a cfunction to this scope 'cause that would mess with 1970 # the type definition, so we just return the right entry. 1971 entry = Entry( 1972 "classmethod", 1973 "__Pyx_Method_ClassMethod", 1974 PyrexTypes.CFuncType( 1975 py_object_type, 1976 [PyrexTypes.CFuncTypeArg("", py_object_type, None)], 0, 0)) 1977 entry.utility_code_definition = Code.UtilityCode.load_cached("ClassMethod", "CythonFunction.c") 1978 self.use_entry_utility_code(entry) 1979 entry.is_cfunction = 1 1980 return entry 1981 1982 1983class PyClassScope(ClassScope): 1984 # Namespace of a Python class. 1985 # 1986 # class_obj_cname string C variable holding class object 1987 1988 is_py_class_scope = 1 1989 1990 def mangle_class_private_name(self, name): 1991 return self.mangle_special_name(name) 1992 1993 def mangle_special_name(self, name): 1994 if name and name.startswith('__') and not name.endswith('__'): 1995 name = EncodedString('_%s%s' % (self.class_name.lstrip('_'), name)) 1996 return name 1997 1998 def lookup_here(self, name): 1999 name = self.mangle_special_name(name) 2000 return ClassScope.lookup_here(self, name) 2001 2002 def declare_var(self, name, type, pos, 2003 cname = None, visibility = 'private', 2004 api = 0, in_pxd = 0, is_cdef = 0): 2005 name = self.mangle_special_name(name) 2006 if type is unspecified_type: 2007 type = py_object_type 2008 # Add an entry for a class attribute. 2009 entry = Scope.declare_var(self, name, type, pos, 2010 cname=cname, visibility=visibility, 2011 api=api, in_pxd=in_pxd, is_cdef=is_cdef) 2012 entry.is_pyglobal = 1 2013 entry.is_pyclass_attr = 1 2014 return entry 2015 2016 def declare_nonlocal(self, name, pos): 2017 # Pull entry from outer scope into local scope 2018 orig_entry = self.lookup_here(name) 2019 if orig_entry and orig_entry.scope is self and not orig_entry.from_closure: 2020 error(pos, "'%s' redeclared as nonlocal" % name) 2021 orig_entry.already_declared_here() 2022 else: 2023 entry = self.lookup(name) 2024 if entry is None: 2025 error(pos, "no binding for nonlocal '%s' found" % name) 2026 else: 2027 # FIXME: this works, but it's unclear if it's the 2028 # right thing to do 2029 self.entries[name] = entry 2030 2031 def declare_global(self, name, pos): 2032 # Pull entry from global scope into local scope. 2033 if self.lookup_here(name): 2034 warning(pos, "'%s' redeclared ", 0) 2035 else: 2036 entry = self.global_scope().lookup_target(name) 2037 self.entries[name] = entry 2038 2039 def add_default_value(self, type): 2040 return self.outer_scope.add_default_value(type) 2041 2042 2043class CClassScope(ClassScope): 2044 # Namespace of an extension type. 2045 # 2046 # parent_type CClassType 2047 # #typeobj_cname string or None 2048 # #objstruct_cname string 2049 # method_table_cname string 2050 # getset_table_cname string 2051 # has_pyobject_attrs boolean Any PyObject attributes? 2052 # has_memoryview_attrs boolean Any memory view attributes? 2053 # has_cpp_class_attrs boolean Any (non-pointer) C++ attributes? 2054 # has_cyclic_pyobject_attrs boolean Any PyObject attributes that may need GC? 2055 # property_entries [Entry] 2056 # defined boolean Defined in .pxd file 2057 # implemented boolean Defined in .pyx file 2058 # inherited_var_entries [Entry] Adapted var entries from base class 2059 2060 is_c_class_scope = 1 2061 is_closure_class_scope = False 2062 2063 has_pyobject_attrs = False 2064 has_memoryview_attrs = False 2065 has_cpp_class_attrs = False 2066 has_cyclic_pyobject_attrs = False 2067 defined = False 2068 implemented = False 2069 2070 def __init__(self, name, outer_scope, visibility): 2071 ClassScope.__init__(self, name, outer_scope) 2072 if visibility != 'extern': 2073 self.method_table_cname = outer_scope.mangle(Naming.methtab_prefix, name) 2074 self.getset_table_cname = outer_scope.mangle(Naming.gstab_prefix, name) 2075 self.property_entries = [] 2076 self.inherited_var_entries = [] 2077 2078 def needs_gc(self): 2079 # If the type or any of its base types have Python-valued 2080 # C attributes, then it needs to participate in GC. 2081 if self.has_cyclic_pyobject_attrs and not self.directives.get('no_gc', False): 2082 return True 2083 base_type = self.parent_type.base_type 2084 if base_type and base_type.scope is not None: 2085 return base_type.scope.needs_gc() 2086 elif self.parent_type.is_builtin_type: 2087 return not self.parent_type.is_gc_simple 2088 return False 2089 2090 def needs_tp_clear(self): 2091 """ 2092 Do we need to generate an implementation for the tp_clear slot? Can 2093 be disabled to keep references for the __dealloc__ cleanup function. 2094 """ 2095 return self.needs_gc() and not self.directives.get('no_gc_clear', False) 2096 2097 def get_refcounted_entries(self, include_weakref=False, 2098 include_gc_simple=True): 2099 py_attrs = [] 2100 py_buffers = [] 2101 memoryview_slices = [] 2102 2103 for entry in self.var_entries: 2104 if entry.type.is_pyobject: 2105 if include_weakref or (self.is_closure_class_scope or entry.name != "__weakref__"): 2106 if include_gc_simple or not entry.type.is_gc_simple: 2107 py_attrs.append(entry) 2108 elif entry.type == PyrexTypes.c_py_buffer_type: 2109 py_buffers.append(entry) 2110 elif entry.type.is_memoryviewslice: 2111 memoryview_slices.append(entry) 2112 2113 have_entries = py_attrs or py_buffers or memoryview_slices 2114 return have_entries, (py_attrs, py_buffers, memoryview_slices) 2115 2116 def declare_var(self, name, type, pos, 2117 cname = None, visibility = 'private', 2118 api = 0, in_pxd = 0, is_cdef = 0): 2119 if is_cdef: 2120 # Add an entry for an attribute. 2121 if self.defined: 2122 error(pos, 2123 "C attributes cannot be added in implementation part of" 2124 " extension type defined in a pxd") 2125 if not self.is_closure_class_scope and get_special_method_signature(name): 2126 error(pos, 2127 "The name '%s' is reserved for a special method." 2128 % name) 2129 if not cname: 2130 cname = name 2131 if visibility == 'private': 2132 cname = c_safe_identifier(cname) 2133 if type.is_cpp_class and visibility != 'extern': 2134 type.check_nullary_constructor(pos) 2135 self.use_utility_code(Code.UtilityCode("#include <new>")) 2136 entry = self.declare(name, cname, type, pos, visibility) 2137 entry.is_variable = 1 2138 self.var_entries.append(entry) 2139 if type.is_memoryviewslice: 2140 self.has_memoryview_attrs = True 2141 elif type.is_cpp_class: 2142 self.has_cpp_class_attrs = True 2143 elif type.is_pyobject and (self.is_closure_class_scope or name != '__weakref__'): 2144 self.has_pyobject_attrs = True 2145 if (not type.is_builtin_type 2146 or not type.scope or type.scope.needs_gc()): 2147 self.has_cyclic_pyobject_attrs = True 2148 if visibility not in ('private', 'public', 'readonly'): 2149 error(pos, 2150 "Attribute of extension type cannot be declared %s" % visibility) 2151 if visibility in ('public', 'readonly'): 2152 # If the field is an external typedef, we cannot be sure about the type, 2153 # so do conversion ourself rather than rely on the CPython mechanism (through 2154 # a property; made in AnalyseDeclarationsTransform). 2155 entry.needs_property = True 2156 if not self.is_closure_class_scope and name == "__weakref__": 2157 error(pos, "Special attribute __weakref__ cannot be exposed to Python") 2158 if not (type.is_pyobject or type.can_coerce_to_pyobject(self)): 2159 # we're not testing for coercion *from* Python here - that would fail later 2160 error(pos, "C attribute of type '%s' cannot be accessed from Python" % type) 2161 else: 2162 entry.needs_property = False 2163 return entry 2164 else: 2165 if type is unspecified_type: 2166 type = py_object_type 2167 # Add an entry for a class attribute. 2168 entry = Scope.declare_var(self, name, type, pos, 2169 cname=cname, visibility=visibility, 2170 api=api, in_pxd=in_pxd, is_cdef=is_cdef) 2171 entry.is_member = 1 2172 entry.is_pyglobal = 1 # xxx: is_pyglobal changes behaviour in so many places that 2173 # I keep it in for now. is_member should be enough 2174 # later on 2175 self.namespace_cname = "(PyObject *)%s" % self.parent_type.typeptr_cname 2176 return entry 2177 2178 def declare_pyfunction(self, name, pos, allow_redefine=False): 2179 # Add an entry for a method. 2180 if name in richcmp_special_methods: 2181 if self.lookup_here('__richcmp__'): 2182 error(pos, "Cannot define both % and __richcmp__" % name) 2183 elif name == '__richcmp__': 2184 for n in richcmp_special_methods: 2185 if self.lookup_here(n): 2186 error(pos, "Cannot define both % and __richcmp__" % n) 2187 if name == "__new__": 2188 error(pos, "__new__ method of extension type will change semantics " 2189 "in a future version of Pyrex and Cython. Use __cinit__ instead.") 2190 entry = self.declare_var(name, py_object_type, pos, 2191 visibility='extern') 2192 special_sig = get_special_method_signature(name) 2193 if special_sig: 2194 # Special methods get put in the method table with a particular 2195 # signature declared in advance. 2196 entry.signature = special_sig 2197 entry.is_special = 1 2198 else: 2199 entry.signature = pymethod_signature 2200 entry.is_special = 0 2201 2202 self.pyfunc_entries.append(entry) 2203 return entry 2204 2205 def lookup_here(self, name): 2206 if not self.is_closure_class_scope and name == "__new__": 2207 name = EncodedString("__cinit__") 2208 entry = ClassScope.lookup_here(self, name) 2209 if entry and entry.is_builtin_cmethod: 2210 if not self.parent_type.is_builtin_type: 2211 # For subtypes of builtin types, we can only return 2212 # optimised C methods if the type if final. 2213 # Otherwise, subtypes may choose to override the 2214 # method, but the optimisation would prevent the 2215 # subtype method from being called. 2216 if not self.parent_type.is_final_type: 2217 return None 2218 return entry 2219 2220 def declare_cfunction(self, name, type, pos, 2221 cname=None, visibility='private', api=0, in_pxd=0, 2222 defining=0, modifiers=(), utility_code=None, overridable=False): 2223 if get_special_method_signature(name) and not self.parent_type.is_builtin_type: 2224 error(pos, "Special methods must be declared with 'def', not 'cdef'") 2225 args = type.args 2226 if not type.is_static_method: 2227 if not args: 2228 error(pos, "C method has no self argument") 2229 elif not self.parent_type.assignable_from(args[0].type): 2230 error(pos, "Self argument (%s) of C method '%s' does not match parent type (%s)" % 2231 (args[0].type, name, self.parent_type)) 2232 entry = self.lookup_here(name) 2233 if cname is None: 2234 cname = c_safe_identifier(name) 2235 if entry: 2236 if not entry.is_cfunction: 2237 warning(pos, "'%s' redeclared " % name, 0) 2238 else: 2239 if defining and entry.func_cname: 2240 error(pos, "'%s' already defined" % name) 2241 #print "CClassScope.declare_cfunction: checking signature" ### 2242 if entry.is_final_cmethod and entry.is_inherited: 2243 error(pos, "Overriding final methods is not allowed") 2244 elif type.same_c_signature_as(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil: 2245 # Fix with_gil vs nogil. 2246 entry.type = entry.type.with_with_gil(type.with_gil) 2247 elif type.compatible_signature_with(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil: 2248 if (self.defined and not in_pxd 2249 and not type.same_c_signature_as_resolved_type(entry.type, as_cmethod = 1, as_pxd_definition = 1)): 2250 # TODO(robertwb): Make this an error. 2251 warning(pos, 2252 "Compatible but non-identical C method '%s' not redeclared " 2253 "in definition part of extension type '%s'. " 2254 "This may cause incorrect vtables to be generated." % ( 2255 name, self.class_name), 2) 2256 warning(entry.pos, "Previous declaration is here", 2) 2257 entry = self.add_cfunction(name, type, pos, cname, visibility='ignore', modifiers=modifiers) 2258 else: 2259 error(pos, "Signature not compatible with previous declaration") 2260 error(entry.pos, "Previous declaration is here") 2261 else: 2262 if self.defined: 2263 error(pos, 2264 "C method '%s' not previously declared in definition part of" 2265 " extension type '%s'" % (name, self.class_name)) 2266 entry = self.add_cfunction(name, type, pos, cname, visibility, modifiers) 2267 if defining: 2268 entry.func_cname = self.mangle(Naming.func_prefix, name) 2269 entry.utility_code = utility_code 2270 type.entry = entry 2271 2272 if u'inline' in modifiers: 2273 entry.is_inline_cmethod = True 2274 2275 if (self.parent_type.is_final_type or entry.is_inline_cmethod or 2276 self.directives.get('final')): 2277 entry.is_final_cmethod = True 2278 entry.final_func_cname = entry.func_cname 2279 2280 return entry 2281 2282 def add_cfunction(self, name, type, pos, cname, visibility, modifiers, inherited=False): 2283 # Add a cfunction entry without giving it a func_cname. 2284 prev_entry = self.lookup_here(name) 2285 entry = ClassScope.add_cfunction(self, name, type, pos, cname, 2286 visibility, modifiers, inherited=inherited) 2287 entry.is_cmethod = 1 2288 entry.prev_entry = prev_entry 2289 return entry 2290 2291 def declare_builtin_cfunction(self, name, type, cname, utility_code = None): 2292 # overridden methods of builtin types still have their Python 2293 # equivalent that must be accessible to support bound methods 2294 name = EncodedString(name) 2295 entry = self.declare_cfunction(name, type, None, cname, visibility='extern', 2296 utility_code=utility_code) 2297 var_entry = Entry(name, name, py_object_type) 2298 var_entry.qualified_name = name 2299 var_entry.is_variable = 1 2300 var_entry.is_builtin = 1 2301 var_entry.utility_code = utility_code 2302 var_entry.scope = entry.scope 2303 entry.as_variable = var_entry 2304 return entry 2305 2306 def declare_property(self, name, doc, pos): 2307 entry = self.lookup_here(name) 2308 if entry is None: 2309 entry = self.declare(name, name, py_object_type, pos, 'private') 2310 entry.is_property = 1 2311 entry.doc = doc 2312 entry.scope = PropertyScope(name, 2313 outer_scope = self.global_scope(), parent_scope = self) 2314 entry.scope.parent_type = self.parent_type 2315 self.property_entries.append(entry) 2316 return entry 2317 2318 def declare_inherited_c_attributes(self, base_scope): 2319 # Declare entries for all the C attributes of an 2320 # inherited type, with cnames modified appropriately 2321 # to work with this type. 2322 def adapt(cname): 2323 return "%s.%s" % (Naming.obj_base_cname, base_entry.cname) 2324 2325 entries = base_scope.inherited_var_entries + base_scope.var_entries 2326 for base_entry in entries: 2327 entry = self.declare( 2328 base_entry.name, adapt(base_entry.cname), 2329 base_entry.type, None, 'private') 2330 entry.is_variable = 1 2331 self.inherited_var_entries.append(entry) 2332 2333 # If the class defined in a pxd, specific entries have not been added. 2334 # Ensure now that the parent (base) scope has specific entries 2335 # Iterate over a copy as get_all_specialized_function_types() will mutate 2336 for base_entry in base_scope.cfunc_entries[:]: 2337 if base_entry.type.is_fused: 2338 base_entry.type.get_all_specialized_function_types() 2339 2340 for base_entry in base_scope.cfunc_entries: 2341 cname = base_entry.cname 2342 var_entry = base_entry.as_variable 2343 is_builtin = var_entry and var_entry.is_builtin 2344 if not is_builtin: 2345 cname = adapt(cname) 2346 entry = self.add_cfunction(base_entry.name, base_entry.type, 2347 base_entry.pos, cname, 2348 base_entry.visibility, base_entry.func_modifiers, inherited=True) 2349 entry.is_inherited = 1 2350 if base_entry.is_final_cmethod: 2351 entry.is_final_cmethod = True 2352 entry.is_inline_cmethod = base_entry.is_inline_cmethod 2353 if (self.parent_scope == base_scope.parent_scope or 2354 entry.is_inline_cmethod): 2355 entry.final_func_cname = base_entry.final_func_cname 2356 if is_builtin: 2357 entry.is_builtin_cmethod = True 2358 entry.as_variable = var_entry 2359 if base_entry.utility_code: 2360 entry.utility_code = base_entry.utility_code 2361 2362 2363class CppClassScope(Scope): 2364 # Namespace of a C++ class. 2365 2366 is_cpp_class_scope = 1 2367 2368 default_constructor = None 2369 type = None 2370 2371 def __init__(self, name, outer_scope, templates=None): 2372 Scope.__init__(self, name, outer_scope, None) 2373 self.directives = outer_scope.directives 2374 self.inherited_var_entries = [] 2375 if templates is not None: 2376 for T in templates: 2377 template_entry = self.declare( 2378 T, T, PyrexTypes.TemplatePlaceholderType(T), None, 'extern') 2379 template_entry.is_type = 1 2380 2381 def declare_var(self, name, type, pos, 2382 cname = None, visibility = 'extern', 2383 api = 0, in_pxd = 0, is_cdef = 0, defining = 0): 2384 # Add an entry for an attribute. 2385 if not cname: 2386 cname = name 2387 entry = self.lookup_here(name) 2388 if defining and entry is not None: 2389 if entry.type.same_as(type): 2390 # Fix with_gil vs nogil. 2391 entry.type = entry.type.with_with_gil(type.with_gil) 2392 elif type.is_cfunction and type.compatible_signature_with(entry.type): 2393 entry.type = type 2394 else: 2395 error(pos, "Function signature does not match previous declaration") 2396 else: 2397 entry = self.declare(name, cname, type, pos, visibility) 2398 entry.is_variable = 1 2399 if type.is_cfunction and self.type: 2400 if not self.type.get_fused_types(): 2401 entry.func_cname = "%s::%s" % (self.type.empty_declaration_code(), cname) 2402 if name != "this" and (defining or name != "<init>"): 2403 self.var_entries.append(entry) 2404 return entry 2405 2406 def declare_cfunction(self, name, type, pos, 2407 cname=None, visibility='extern', api=0, in_pxd=0, 2408 defining=0, modifiers=(), utility_code=None, overridable=False): 2409 class_name = self.name.split('::')[-1] 2410 if name in (class_name, '__init__') and cname is None: 2411 cname = "%s__init__%s" % (Naming.func_prefix, class_name) 2412 name = '<init>' 2413 type.return_type = PyrexTypes.CVoidType() 2414 # This is called by the actual constructor, but need to support 2415 # arguments that cannot by called by value. 2416 type.original_args = type.args 2417 def maybe_ref(arg): 2418 if arg.type.is_cpp_class and not arg.type.is_reference: 2419 return PyrexTypes.CFuncTypeArg( 2420 arg.name, PyrexTypes.c_ref_type(arg.type), arg.pos) 2421 else: 2422 return arg 2423 type.args = [maybe_ref(arg) for arg in type.args] 2424 elif name == '__dealloc__' and cname is None: 2425 cname = "%s__dealloc__%s" % (Naming.func_prefix, class_name) 2426 name = '<del>' 2427 type.return_type = PyrexTypes.CVoidType() 2428 if name in ('<init>', '<del>') and type.nogil: 2429 for base in self.type.base_classes: 2430 base_entry = base.scope.lookup(name) 2431 if base_entry and not base_entry.type.nogil: 2432 error(pos, "Constructor cannot be called without GIL unless all base constructors can also be called without GIL") 2433 error(base_entry.pos, "Base constructor defined here.") 2434 prev_entry = self.lookup_here(name) 2435 entry = self.declare_var(name, type, pos, 2436 defining=defining, 2437 cname=cname, visibility=visibility) 2438 if prev_entry and not defining: 2439 entry.overloaded_alternatives = prev_entry.all_alternatives() 2440 entry.utility_code = utility_code 2441 type.entry = entry 2442 return entry 2443 2444 def declare_inherited_cpp_attributes(self, base_class): 2445 base_scope = base_class.scope 2446 template_type = base_class 2447 while getattr(template_type, 'template_type', None): 2448 template_type = template_type.template_type 2449 if getattr(template_type, 'templates', None): 2450 base_templates = [T.name for T in template_type.templates] 2451 else: 2452 base_templates = () 2453 # Declare entries for all the C++ attributes of an 2454 # inherited type, with cnames modified appropriately 2455 # to work with this type. 2456 for base_entry in \ 2457 base_scope.inherited_var_entries + base_scope.var_entries: 2458 #constructor/destructor is not inherited 2459 if base_entry.name in ("<init>", "<del>"): 2460 continue 2461 #print base_entry.name, self.entries 2462 if base_entry.name in self.entries: 2463 base_entry.name # FIXME: is there anything to do in this case? 2464 entry = self.declare(base_entry.name, base_entry.cname, 2465 base_entry.type, None, 'extern') 2466 entry.is_variable = 1 2467 entry.is_inherited = 1 2468 self.inherited_var_entries.append(entry) 2469 for base_entry in base_scope.cfunc_entries: 2470 entry = self.declare_cfunction(base_entry.name, base_entry.type, 2471 base_entry.pos, base_entry.cname, 2472 base_entry.visibility, api=0, 2473 modifiers=base_entry.func_modifiers, 2474 utility_code=base_entry.utility_code) 2475 entry.is_inherited = 1 2476 for base_entry in base_scope.type_entries: 2477 if base_entry.name not in base_templates: 2478 entry = self.declare_type(base_entry.name, base_entry.type, 2479 base_entry.pos, base_entry.cname, 2480 base_entry.visibility) 2481 entry.is_inherited = 1 2482 2483 def specialize(self, values, type_entry): 2484 scope = CppClassScope(self.name, self.outer_scope) 2485 scope.type = type_entry 2486 for entry in self.entries.values(): 2487 if entry.is_type: 2488 scope.declare_type(entry.name, 2489 entry.type.specialize(values), 2490 entry.pos, 2491 entry.cname, 2492 template=1) 2493 elif entry.type.is_cfunction: 2494 for e in entry.all_alternatives(): 2495 scope.declare_cfunction(e.name, 2496 e.type.specialize(values), 2497 e.pos, 2498 e.cname, 2499 utility_code=e.utility_code) 2500 else: 2501 scope.declare_var(entry.name, 2502 entry.type.specialize(values), 2503 entry.pos, 2504 entry.cname, 2505 entry.visibility) 2506 2507 return scope 2508 2509 2510class PropertyScope(Scope): 2511 # Scope holding the __get__, __set__ and __del__ methods for 2512 # a property of an extension type. 2513 # 2514 # parent_type PyExtensionType The type to which the property belongs 2515 2516 is_property_scope = 1 2517 2518 def declare_pyfunction(self, name, pos, allow_redefine=False): 2519 # Add an entry for a method. 2520 signature = get_property_accessor_signature(name) 2521 if signature: 2522 entry = self.declare(name, name, py_object_type, pos, 'private') 2523 entry.is_special = 1 2524 entry.signature = signature 2525 return entry 2526 else: 2527 error(pos, "Only __get__, __set__ and __del__ methods allowed " 2528 "in a property declaration") 2529 return None 2530 2531 2532class CConstScope(Scope): 2533 2534 def __init__(self, const_base_type_scope): 2535 Scope.__init__( 2536 self, 2537 'const_' + const_base_type_scope.name, 2538 const_base_type_scope.outer_scope, 2539 const_base_type_scope.parent_scope) 2540 self.const_base_type_scope = const_base_type_scope 2541 2542 def lookup_here(self, name): 2543 entry = self.const_base_type_scope.lookup_here(name) 2544 if entry is not None: 2545 entry = copy.copy(entry) 2546 entry.type = PyrexTypes.c_const_type(entry.type) 2547 return entry 2548 2549class TemplateScope(Scope): 2550 def __init__(self, name, outer_scope): 2551 Scope.__init__(self, name, outer_scope, None) 2552 self.directives = outer_scope.directives 2553