6 from Cython import Utils
7 from Errors import warning, error, InternalError
8 from StringEncoding import EncodedString
11 from PyrexTypes import py_object_type, unspecified_type
13 from TypeSlots import \
14 pyfunction_signature, pymethod_signature, \
15 get_special_method_signature, get_property_accessor_signature
18 import __builtin__ as builtins
22 from sets import Set as set
25 possible_identifier = re.compile(ur"(?![0-9])\w+$", re.U).match
26 nice_identifier = re.compile('^[a-zA-Z0-0_]+$').match
28 iso_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',
34 '_Bool', '_Complex'', _Imaginary', 'inline', 'restrict'])
36 def c_safe_identifier(cname):
37 # There are some C limitations on struct entry names.
38 if ((cname[:2] == '__'
39 and not (cname.startswith(Naming.pyrex_prefix)
40 or cname == '__weakref__'))
41 or cname in iso_c99_keywords):
42 cname = Naming.pyrex_prefix + cname
45 class BufferAux(object):
46 writable_needed = False
48 def __init__(self, buffer_info_var, stridevars, shapevars,
50 self.buffer_info_var = buffer_info_var
51 self.stridevars = stridevars
52 self.shapevars = shapevars
53 self.suboffsetvars = suboffsetvars
56 return "<BufferAux %r>" % self.__dict__
59 # A symbol table entry in a Scope or ModuleNamespace.
61 # name string Python name of entity
62 # cname string C name of entity
63 # type PyrexType Type of entity
64 # doc string Doc string
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
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_unbound_cmethod boolean Is an unbound C method of an extension type
78 # is_anonymous boolean Is a anonymous pyfunction entry
79 # is_type boolean Is a type definition
80 # is_cclass boolean Is an extension class
81 # is_cpp_class boolean Is a C++ class
82 # is_const boolean Is a constant
83 # is_property boolean Is a property of an extension type:
84 # doc_cname string or None C const holding the docstring
85 # getter_cname string C func for getting property
86 # setter_cname string C func for setting or deleting property
87 # is_self_arg boolean Is the "self" arg of an exttype method
88 # is_arg boolean Is the arg of a method
89 # is_local boolean Is a local variable
90 # in_closure boolean Is referenced in an inner scope
91 # is_readonly boolean Can't be assigned to
92 # func_cname string C func implementing Python func
93 # func_modifiers [string] C function modifiers ('inline')
94 # pos position Source position where declared
95 # namespace_cname string If is_pyglobal, the C variable
96 # holding its home namespace
97 # pymethdef_cname string PyMethodDef structure
98 # signature Signature Arg & return types for Python func
99 # init_to_none boolean True if initial value should be None
100 # as_variable Entry Alternative interpretation of extension
101 # type name or builtin C function as a variable
102 # xdecref_cleanup boolean Use Py_XDECREF for error cleanup
103 # in_cinclude boolean Suppress C declaration code
104 # enum_values [Entry] For enum types, list of values
105 # qualified_name string "modname.funcname" or "modname.classname"
106 # or "modname.classname.funcname"
107 # is_declared_generic boolean Is declared as PyObject * even though its
108 # type is an extension type
109 # as_module None Module scope, if a cimported module
110 # is_inherited boolean Is an inherited attribute of an extension type
111 # pystring_cname string C name of Python version of string literal
112 # is_interned boolean For string const entries, value is interned
113 # is_identifier boolean For string const entries, value is an identifier
115 # is_special boolean Is a special method or property accessor
116 # of an extension type
117 # defined_in_pxd boolean Is defined in a .pxd file (not just declared)
118 # api boolean Generate C API for C class or function
119 # utility_code string Utility code needed when this entry is used
121 # buffer_aux BufferAux or None Extra information needed for buffer variables
122 # inline_func_in_pxd boolean Hacky special case for inline function in pxd file.
123 # Ideally this should not be necesarry.
124 # assignments [ExprNode] List of expressions that get assigned to this entry.
125 # might_overflow boolean In an arithmetic expression that could cause
126 # overflow (used for type inference).
128 inline_func_in_pxd = False
131 visibility = 'private'
140 is_unbound_cmethod = 0
155 is_declared_generic = 0
166 pystring_cname = None
180 def __init__(self, name, cname, type, pos = None, init = None):
186 self.overloaded_alternatives = []
187 self.assignments = []
190 return "Entry(name=%s, type=%s)" % (self.name, self.type)
192 def redeclared(self, pos):
193 error(pos, "'%s' does not match previous declaration" % self.name)
194 error(self.pos, "Previous declaration is here")
196 def all_alternatives(self):
197 return [self] + self.overloaded_alternatives
200 # name string Unqualified name
201 # outer_scope Scope or None Enclosing scope
202 # entries {string : Entry} Python name to entry, non-types
203 # const_entries [Entry] Constant entries
204 # type_entries [Entry] Struct/union/enum/typedef/exttype entries
205 # sue_entries [Entry] Struct/union/enum entries
206 # arg_entries [Entry] Function argument entries
207 # var_entries [Entry] User-defined variable entries
208 # pyfunc_entries [Entry] Python function entries
209 # cfunc_entries [Entry] C function entries
210 # c_class_entries [Entry] All extension type entries
211 # cname_to_entry {string : Entry} Temp cname to entry mapping
212 # int_to_entry {int : Entry} Temp cname to entry mapping
213 # return_type PyrexType or None Return type of function owning scope
214 # is_builtin_scope boolean Is the builtin scope of Python/Cython
215 # is_py_class_scope boolean Is a Python class scope
216 # is_c_class_scope boolean Is an extension type scope
217 # is_closure_scope boolean Is a closure scope
218 # is_passthrough boolean Outer scope is passed directly
219 # is_cpp_class_scope boolean Is a C++ class scope
220 # is_property_scope boolean Is a extension type property scope
221 # scope_prefix string Disambiguator for C names
222 # in_cinclude boolean Suppress C declaration code
223 # qualified_name string "modname" or "modname.classname"
224 # pystring_entries [Entry] String const entries newly used as
225 # Python strings in this scope
226 # control_flow ControlFlow Used for keeping track of environment state
227 # nogil boolean In a nogil section
228 # directives dict Helper variable for the recursive
229 # analysis, contains directive values.
230 # is_internal boolean Is only used internally (simpler setup)
233 is_py_class_scope = 0
237 is_cpp_class_scope = 0
238 is_property_scope = 0
245 def __init__(self, name, outer_scope, parent_scope):
246 # The outer_scope is the next scope in the lookup chain.
247 # The parent_scope is used to derive the qualified name of this scope.
249 self.outer_scope = outer_scope
250 self.parent_scope = parent_scope
251 mangled_name = "%d%s_" % (len(name), name)
252 qual_scope = self.qualifying_scope()
254 self.qualified_name = qual_scope.qualify_name(name)
255 self.scope_prefix = qual_scope.scope_prefix + mangled_name
257 self.qualified_name = EncodedString(name)
258 self.scope_prefix = mangled_name
260 self.const_entries = []
261 self.type_entries = []
262 self.sue_entries = []
263 self.arg_entries = []
264 self.var_entries = []
265 self.pyfunc_entries = []
266 self.cfunc_entries = []
267 self.c_class_entries = []
268 self.defined_c_classes = []
269 self.imported_c_classes = {}
270 self.cname_to_entry = {}
271 self.string_to_entry = {}
272 self.identifier_to_entry = {}
273 self.num_to_entry = {}
274 self.obj_to_entry = {}
275 self.pystring_entries = []
276 self.buffer_entries = []
277 self.lambda_defs = []
278 self.control_flow = ControlFlow.LinearControlFlow()
279 self.return_type = None
280 self.id_counters = {}
282 def start_branching(self, pos):
283 self.control_flow = self.control_flow.start_branch(pos)
285 def next_branch(self, pos):
286 self.control_flow = self.control_flow.next_branch(pos)
288 def finish_branching(self, pos):
289 self.control_flow = self.control_flow.finish_branch(pos)
292 return "<%s %s>" % (self.__class__.__name__, self.qualified_name)
294 def qualifying_scope(self):
295 return self.parent_scope
297 def mangle(self, prefix, name = None):
299 return "%s%s%s" % (prefix, self.scope_prefix, name)
301 return self.parent_scope.mangle(prefix, self.name)
303 def mangle_internal(self, name):
304 # Mangle an internal name so as not to clash with any
305 # user-defined name in this scope.
306 prefix = "%s%s_" % (Naming.pyrex_prefix, name)
307 return self.mangle(prefix)
308 #return self.parent_scope.mangle(prefix, self.name)
310 def next_id(self, name=None):
311 # Return a cname fragment that is unique for this module
312 counters = self.global_scope().id_counters
314 count = counters[name] + 1
317 counters[name] = count
320 # unique names don't need a suffix, reoccurrences will get one
322 return '%s%d' % (name, count)
326 def global_scope(self):
327 # Return the module-level scope containing this scope.
328 return self.outer_scope.global_scope()
330 def builtin_scope(self):
331 # Return the module-level scope containing this scope.
332 return self.outer_scope.builtin_scope()
334 def declare(self, name, cname, type, pos, visibility, shadow = 0):
335 # Create new entry, and add to dictionary if
336 # name is not None. Reports a warning if already
338 if type.is_buffer and not isinstance(self, LocalScope):
339 error(pos, ERR_BUF_LOCALONLY)
340 if not self.in_cinclude and cname and re.match("^_[_A-Z]+$", cname):
341 # See http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html#Reserved-Names
342 warning(pos, "'%s' is a reserved name in C." % cname, -1)
343 entries = self.entries
344 if name and name in entries and not shadow:
345 if visibility == 'extern':
346 warning(pos, "'%s' redeclared " % name, 0)
347 elif visibility != 'ignore':
348 error(pos, "'%s' redeclared " % name)
349 entry = Entry(name, cname, type, pos = pos)
350 entry.in_cinclude = self.in_cinclude
352 entry.qualified_name = self.qualify_name(name)
353 # if name in entries and self.is_cpp():
354 # entries[name].overloaded_alternatives.append(entry)
356 # entries[name] = entry
358 entries[name] = entry
360 entry.visibility = visibility
363 def qualify_name(self, name):
364 return EncodedString("%s.%s" % (self.qualified_name, name))
366 def declare_const(self, name, type, value, pos, cname = None, visibility = 'private', api = 0):
367 # Add an entry for a named constant.
369 if self.in_cinclude or (visibility == 'public' or api):
372 cname = self.mangle(Naming.enum_prefix, name)
373 entry = self.declare(name, cname, type, pos, visibility)
375 entry.value_node = value
378 def declare_type(self, name, type, pos,
379 cname = None, visibility = 'private', api = 0, defining = 1, shadow = 0):
380 # Add an entry for a type definition.
383 entry = self.declare(name, cname, type, pos, visibility, shadow)
387 self.type_entries.append(entry)
388 # here we would set as_variable to an object representing this type
391 def declare_typedef(self, name, base_type, pos, cname = None,
392 visibility = 'private', api = 0):
394 if self.in_cinclude or (visibility == 'public' or api):
397 cname = self.mangle(Naming.type_prefix, name)
399 type = PyrexTypes.create_typedef_type(name, base_type, cname,
400 (visibility == 'extern'))
401 except ValueError, e:
402 error(pos, e.args[0])
403 type = PyrexTypes.error_type
404 entry = self.declare_type(name, type, pos, cname,
405 visibility = visibility, api = api)
406 type.qualified_name = entry.qualified_name
409 def declare_struct_or_union(self, name, kind, scope,
410 typedef_flag, pos, cname = None,
411 visibility = 'private', api = 0,
413 # Add an entry for a struct or union definition.
415 if self.in_cinclude or (visibility == 'public' or api):
418 cname = self.mangle(Naming.type_prefix, name)
419 entry = self.lookup_here(name)
421 type = PyrexTypes.CStructOrUnionType(
422 name, kind, scope, typedef_flag, cname, packed)
423 entry = self.declare_type(name, type, pos, cname,
424 visibility = visibility, api = api,
425 defining = scope is not None)
426 self.sue_entries.append(entry)
429 if not (entry.is_type and entry.type.is_struct_or_union
430 and entry.type.kind == kind):
431 warning(pos, "'%s' redeclared " % name, 0)
432 elif scope and entry.type.scope:
433 warning(pos, "'%s' already defined (ignoring second definition)" % name, 0)
435 self.check_previous_typedef_flag(entry, typedef_flag, pos)
436 self.check_previous_visibility(entry, visibility, pos)
438 entry.type.scope = scope
439 self.type_entries.append(entry)
440 if not scope and not entry.type.scope:
441 self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos)
444 def declare_cpp_class(self, name, scope,
445 pos, cname = None, base_classes = [],
446 visibility = 'extern', templates = None):
447 if visibility != 'extern':
448 error(pos, "C++ classes may only be extern")
451 entry = self.lookup_here(name)
453 type = PyrexTypes.CppClassType(
454 name, scope, cname, base_classes, templates = templates)
455 entry = self.declare_type(name, type, pos, cname,
456 visibility = visibility, defining = scope is not None)
458 if not (entry.is_type and entry.type.is_cpp_class):
459 error(pos, "'%s' redeclared " % name)
461 elif scope and entry.type.scope:
462 warning(pos, "'%s' already defined (ignoring second definition)" % name, 0)
465 entry.type.scope = scope
466 self.type_entries.append(entry)
467 if templates is not None:
469 template_entry = entry.type.scope.declare(T.name, T.name, T, None, 'extern')
470 template_entry.is_type = 1
472 def declare_inherited_attributes(entry, base_classes):
473 for base_class in base_classes:
474 declare_inherited_attributes(entry, base_class.base_classes)
475 entry.type.scope.declare_inherited_cpp_attributes(base_class.scope)
477 declare_inherited_attributes(entry, base_classes)
478 if self.is_cpp_class_scope:
479 entry.type.namespace = self.outer_scope.lookup(self.name).type
482 def check_previous_typedef_flag(self, entry, typedef_flag, pos):
483 if typedef_flag != entry.type.typedef_flag:
484 error(pos, "'%s' previously declared using '%s'" % (
485 entry.name, ("cdef", "ctypedef")[entry.type.typedef_flag]))
487 def check_previous_visibility(self, entry, visibility, pos):
488 if entry.visibility != visibility:
489 error(pos, "'%s' previously declared as '%s'" % (
490 entry.name, entry.visibility))
492 def declare_enum(self, name, pos, cname, typedef_flag,
493 visibility = 'private', api = 0):
496 if self.in_cinclude or (visibility == 'public' or api):
499 cname = self.mangle(Naming.type_prefix, name)
500 type = PyrexTypes.CEnumType(name, cname, typedef_flag)
502 type = PyrexTypes.c_anon_enum_type
503 entry = self.declare_type(name, type, pos, cname = cname,
504 visibility = visibility, api = api)
505 entry.enum_values = []
506 self.sue_entries.append(entry)
509 def declare_var(self, name, type, pos,
510 cname = None, visibility = 'private', api = 0, is_cdef = 0):
511 # Add an entry for a variable.
513 if visibility != 'private':
516 cname = self.mangle(Naming.var_prefix, name)
517 if type.is_cpp_class and visibility != 'extern':
518 constructor = type.scope.lookup(u'<init>')
519 if constructor is not None and PyrexTypes.best_match([], constructor.all_alternatives()) is None:
520 error(pos, "C++ class must have a default constructor to be stack allocated")
521 entry = self.declare(name, cname, type, pos, visibility)
522 entry.is_variable = 1
524 self.control_flow.set_state((), (name, 'initialized'), False)
527 def declare_builtin(self, name, pos):
528 return self.outer_scope.declare_builtin(name, pos)
530 def _declare_pyfunction(self, name, pos, visibility='extern', entry=None):
531 if entry and not entry.type.is_cfunction:
532 error(pos, "'%s' already declared" % name)
533 error(entry.pos, "Previous declaration is here")
534 entry = self.declare_var(name, py_object_type, pos, visibility=visibility)
535 entry.signature = pyfunction_signature
536 self.pyfunc_entries.append(entry)
539 def declare_pyfunction(self, name, pos, allow_redefine=False, visibility='extern'):
540 # Add an entry for a Python function.
541 entry = self.lookup_here(name)
542 if not allow_redefine or Options.disable_function_redefinition:
543 return self._declare_pyfunction(name, pos, visibility=visibility, entry=entry)
545 if entry.type.is_unspecified:
546 entry.type = py_object_type
547 elif entry.type is not py_object_type:
548 return self._declare_pyfunction(name, pos, visibility=visibility, entry=entry)
549 else: # declare entry stub
550 self.declare_var(name, py_object_type, pos, visibility=visibility)
551 entry = self.declare_var(None, py_object_type, pos,
552 cname=name, visibility='private')
553 entry.name = EncodedString(name)
554 entry.qualified_name = self.qualify_name(name)
555 entry.signature = pyfunction_signature
556 entry.is_anonymous = True
559 def declare_lambda_function(self, lambda_name, pos):
560 # Add an entry for an anonymous Python function.
561 func_cname = self.mangle(Naming.lambda_func_prefix + u'funcdef_', lambda_name)
562 pymethdef_cname = self.mangle(Naming.lambda_func_prefix + u'methdef_', lambda_name)
563 qualified_name = self.qualify_name(lambda_name)
565 entry = self.declare(None, func_cname, py_object_type, pos, 'private')
566 entry.name = lambda_name
567 entry.qualified_name = qualified_name
568 entry.pymethdef_cname = pymethdef_cname
569 entry.func_cname = func_cname
570 entry.signature = pyfunction_signature
571 entry.is_anonymous = True
574 def add_lambda_def(self, def_node):
575 self.lambda_defs.append(def_node)
577 def register_pyfunction(self, entry):
578 self.pyfunc_entries.append(entry)
580 def declare_cfunction(self, name, type, pos,
581 cname = None, visibility = 'private', defining = 0,
582 api = 0, in_pxd = 0, modifiers = (), utility_code = None):
583 # Add an entry for a C function.
585 if api or visibility != 'private':
588 cname = self.mangle(Naming.func_prefix, name)
589 entry = self.lookup_here(name)
591 if visibility != 'private' and visibility != entry.visibility:
592 warning(pos, "Function '%s' previously declared as '%s'" % (name, entry.visibility), 1)
593 if not entry.type.same_as(type):
594 if visibility == 'extern' and entry.visibility == 'extern':
599 # if all alternatives have different cnames,
600 # it's safe to allow signature overrides
601 for alt_entry in entry.all_alternatives():
602 if not alt_entry.cname or cname == alt_entry.cname:
603 break # cname not unique!
607 temp = self.add_cfunction(name, type, pos, cname, visibility, modifiers)
608 temp.overloaded_alternatives = entry.all_alternatives()
611 warning(pos, "Function signature does not match previous declaration", 1)
614 error(pos, "Function signature does not match previous declaration")
616 entry = self.add_cfunction(name, type, pos, cname, visibility, modifiers)
617 entry.func_cname = cname
618 if in_pxd and visibility != 'extern':
619 entry.defined_in_pxd = 1
622 if not defining and not in_pxd and visibility != 'extern':
623 error(pos, "Non-extern C function '%s' declared but not defined" % name)
625 entry.is_implemented = True
627 entry.func_modifiers = modifiers
628 entry.utility_code = utility_code
631 def add_cfunction(self, name, type, pos, cname, visibility, modifiers):
632 # Add a C function entry without giving it a func_cname.
633 entry = self.declare(name, cname, type, pos, visibility)
634 entry.is_cfunction = 1
636 entry.func_modifiers = modifiers
637 self.cfunc_entries.append(entry)
640 def find(self, name, pos):
641 # Look up name, report error if not found.
642 entry = self.lookup(name)
646 error(pos, "'%s' is not declared" % name)
648 def find_imported_module(self, path, pos):
649 # Look up qualified name, must be a module, report error if not found.
650 # Path is a list of names.
653 entry = scope.find(name, pos)
657 scope = entry.as_module
659 error(pos, "'%s' is not a cimported module" % '.'.join(path))
663 def lookup(self, name):
664 # Look up name in this scope or an enclosing one.
665 # Return None if not found.
666 return (self.lookup_here(name)
667 or (self.outer_scope and self.outer_scope.lookup(name))
670 def lookup_here(self, name):
671 # Look up in this scope only, return None if not found.
672 return self.entries.get(name, None)
674 def lookup_target(self, name):
675 # Look up name in this scope only. Declare as Python
676 # variable if not found.
677 entry = self.lookup_here(name)
679 entry = self.declare_var(name, py_object_type, None)
682 def lookup_type(self, name):
683 entry = self.lookup(name)
684 if entry and entry.is_type:
687 def lookup_operator(self, operator, operands):
688 if operands[0].type.is_cpp_class:
689 obj_type = operands[0].type
690 method = obj_type.scope.lookup("operator%s" % operator)
691 if method is not None:
692 res = PyrexTypes.best_match(operands[1:], method.all_alternatives())
695 function = self.lookup("operator%s" % operator)
698 return PyrexTypes.best_match(operands, function.all_alternatives())
700 def use_utility_code(self, new_code):
701 self.global_scope().use_utility_code(new_code)
703 def generate_library_function_declarations(self, code):
704 # Generate extern decls for C library funcs used.
707 def defines_any(self, names):
708 # Test whether any of the given names are
709 # defined in this scope.
711 if name in self.entries:
715 def infer_types(self):
716 from TypeInference import get_type_inferer
717 get_type_inferer().infer_types(self)
720 outer = self.outer_scope
724 return outer.is_cpp()
726 class PreImportScope(Scope):
728 namespace_cname = Naming.preimport_cname
731 Scope.__init__(self, Options.pre_import, None, None)
733 def declare_builtin(self, name, pos):
734 entry = self.declare(name, name, py_object_type, pos, 'private')
735 entry.is_variable = True
736 entry.is_pyglobal = True
740 class BuiltinScope(Scope):
741 # The builtin namespace.
743 is_builtin_scope = True
746 if Options.pre_import is None:
747 Scope.__init__(self, "__builtin__", None, None)
749 Scope.__init__(self, "__builtin__", PreImportScope(), None)
752 for name, definition in self.builtin_entries.iteritems():
753 cname, type = definition
754 self.declare_var(name, type, None, cname)
756 def lookup(self, name, language_level=None):
757 # 'language_level' is passed by ModuleScope
758 if language_level == 3:
761 return Scope.lookup(self, name)
763 def declare_builtin(self, name, pos):
764 if not hasattr(builtins, name):
765 if self.outer_scope is not None:
766 return self.outer_scope.declare_builtin(name, pos)
768 if Options.error_on_unknown_names:
769 error(pos, "undeclared name not builtin: %s" % name)
771 warning(pos, "undeclared name not builtin: %s" % name, 2)
773 def declare_builtin_cfunction(self, name, type, cname, python_equiv = None,
774 utility_code = None):
775 # If python_equiv == "*", the Python equivalent has the same name
776 # as the entry, otherwise it has the name specified by python_equiv.
777 name = EncodedString(name)
778 entry = self.declare_cfunction(name, type, None, cname, visibility='extern',
779 utility_code = utility_code)
781 if python_equiv == "*":
784 python_equiv = EncodedString(python_equiv)
785 var_entry = Entry(python_equiv, python_equiv, py_object_type)
786 var_entry.is_variable = 1
787 var_entry.is_builtin = 1
788 var_entry.utility_code = utility_code
789 entry.as_variable = var_entry
792 def declare_builtin_type(self, name, cname, utility_code = None, objstruct_cname = None):
793 name = EncodedString(name)
794 type = PyrexTypes.BuiltinObjectType(name, cname, objstruct_cname)
795 scope = CClassScope(name, outer_scope=None, visibility='extern')
796 scope.directives = {}
798 scope.directives['final'] = True
799 type.set_scope(scope)
800 self.type_names[name] = 1
801 entry = self.declare_type(name, type, None, visibility='extern')
802 entry.utility_code = utility_code
804 var_entry = Entry(name = entry.name,
805 type = self.lookup('type').type, # make sure "type" is the first type declared...
807 cname = "((PyObject*)%s)" % entry.type.typeptr_cname)
808 var_entry.is_variable = 1
809 var_entry.is_cglobal = 1
810 var_entry.is_readonly = 1
811 var_entry.is_builtin = 1
812 var_entry.utility_code = utility_code
813 if Options.cache_builtins:
814 var_entry.is_const = True
815 entry.as_variable = var_entry
819 def builtin_scope(self):
824 "type": ["((PyObject*)&PyType_Type)", py_object_type],
826 "bool": ["((PyObject*)&PyBool_Type)", py_object_type],
827 "int": ["((PyObject*)&PyInt_Type)", py_object_type],
828 "long": ["((PyObject*)&PyLong_Type)", py_object_type],
829 "float": ["((PyObject*)&PyFloat_Type)", py_object_type],
830 "complex":["((PyObject*)&PyComplex_Type)", py_object_type],
832 "bytes": ["((PyObject*)&PyBytes_Type)", py_object_type],
833 "str": ["((PyObject*)&PyString_Type)", py_object_type],
834 "unicode":["((PyObject*)&PyUnicode_Type)", py_object_type],
836 "tuple": ["((PyObject*)&PyTuple_Type)", py_object_type],
837 "list": ["((PyObject*)&PyList_Type)", py_object_type],
838 "dict": ["((PyObject*)&PyDict_Type)", py_object_type],
839 "set": ["((PyObject*)&PySet_Type)", py_object_type],
840 "frozenset": ["((PyObject*)&PyFrozenSet_Type)", py_object_type],
842 "slice": ["((PyObject*)&PySlice_Type)", py_object_type],
843 # "file": ["((PyObject*)&PyFile_Type)", py_object_type], # not in Py3
845 "None": ["Py_None", py_object_type],
846 "False": ["Py_False", py_object_type],
847 "True": ["Py_True", py_object_type],
850 const_counter = 1 # As a temporary solution for compiling code in pxds
852 class ModuleScope(Scope):
853 # module_name string Python name of the module
854 # module_cname string C name of Python module object
855 # #module_dict_cname string C name of module dict object
856 # method_table_cname string C name of method table
857 # doc string Module doc string
858 # doc_cname string C name of module doc string
859 # utility_code_list [UtilityCode] Queuing utility codes for forwarding to Code.py
860 # python_include_files [string] Standard Python headers to be included
861 # include_files [string] Other C headers to be included
862 # string_to_entry {string : Entry} Map string const to entry
863 # identifier_to_entry {string : Entry} Map identifier string const to entry
865 # parent_module Scope Parent in the import namespace
866 # module_entries {string : Entry} For cimport statements
867 # type_names {string : 1} Set of type names (used during parsing)
868 # included_files [string] Cython sources included with 'include'
869 # pxd_file_loaded boolean Corresponding .pxd file has been processed
870 # cimported_modules [ModuleScope] Modules imported with cimport
871 # types_imported {PyrexType : 1} Set of types for which import code generated
872 # has_import_star boolean Module contains import *
873 # cpp boolean Compiling a C++ file
878 def __init__(self, name, parent_module, context):
879 self.parent_module = parent_module
880 outer_scope = context.find_submodule("__builtin__")
881 Scope.__init__(self, name, outer_scope, parent_module)
882 if name != "__init__":
883 self.module_name = name
885 # Treat Spam/__init__.pyx specially, so that when Python loads
886 # Spam/__init__.so, initSpam() is defined.
887 self.module_name = parent_module.module_name
888 self.module_name = EncodedString(self.module_name)
889 self.context = context
890 self.module_cname = Naming.module_cname
891 self.module_dict_cname = Naming.moddict_cname
892 self.method_table_cname = Naming.methtable_cname
894 self.doc_cname = Naming.moddoc_cname
895 self.utility_code_list = []
896 self.module_entries = {}
897 self.python_include_files = ["Python.h"]
898 self.include_files = []
899 self.type_names = dict(outer_scope.type_names)
900 self.pxd_file_loaded = 0
901 self.cimported_modules = []
902 self.types_imported = {}
903 self.included_files = []
904 self.has_extern_class = 0
905 self.cached_builtins = []
906 self.undeclared_cached_builtins = []
907 self.namespace_cname = self.module_cname
908 for name in ['__builtins__', '__name__', '__file__', '__doc__']:
909 self.declare_var(EncodedString(name), py_object_type, None)
911 def qualifying_scope(self):
912 return self.parent_module
914 def global_scope(self):
917 def lookup(self, name):
918 entry = self.lookup_here(name)
919 if entry is not None:
921 return self.outer_scope.lookup(name, language_level = self.context.language_level)
923 def declare_builtin(self, name, pos):
924 if not hasattr(builtins, name) \
925 and name not in Code.non_portable_builtins_map \
926 and name not in Code.uncachable_builtins:
927 if self.has_import_star:
928 entry = self.declare_var(name, py_object_type, pos)
931 if Options.error_on_unknown_names:
932 error(pos, "undeclared name not builtin: %s" % name)
934 warning(pos, "undeclared name not builtin: %s" % name, 2)
935 # unknown - assume it's builtin and look it up at runtime
936 entry = self.declare(name, None, py_object_type, pos, 'private')
939 if Options.cache_builtins:
940 for entry in self.cached_builtins:
941 if entry.name == name:
943 entry = self.declare(None, None, py_object_type, pos, 'private')
944 if Options.cache_builtins and name not in Code.uncachable_builtins:
946 entry.is_const = 1 # cached
948 entry.cname = Naming.builtin_prefix + name
949 self.cached_builtins.append(entry)
950 self.undeclared_cached_builtins.append(entry)
956 def find_module(self, module_name, pos):
957 # Find a module in the import namespace, interpreting
958 # relative imports relative to this module's parent.
959 # Finds and parses the module's .pxd file if the module
960 # has not been referenced before.
961 return self.global_scope().context.find_module(
962 module_name, relative_to = self.parent_module, pos = pos)
964 def find_submodule(self, name):
965 # Find and return scope for a submodule of this module,
966 # creating a new empty one if necessary. Doesn't parse .pxd.
967 scope = self.lookup_submodule(name)
969 scope = ModuleScope(name,
970 parent_module = self, context = self.context)
971 self.module_entries[name] = scope
974 def lookup_submodule(self, name):
975 # Return scope for submodule of this module, or None.
976 return self.module_entries.get(name, None)
978 def add_include_file(self, filename):
979 if filename not in self.python_include_files \
980 and filename not in self.include_files:
981 self.include_files.append(filename)
983 def add_imported_module(self, scope):
984 if scope not in self.cimported_modules:
985 for filename in scope.include_files:
986 self.add_include_file(filename)
987 self.cimported_modules.append(scope)
988 for m in scope.cimported_modules:
989 self.add_imported_module(m)
991 def add_imported_entry(self, name, entry, pos):
992 if entry not in self.entries:
993 self.entries[name] = entry
995 warning(pos, "'%s' redeclared " % name, 0)
997 def declare_module(self, name, scope, pos):
998 # Declare a cimported module. This is represented as a
999 # Python module-level variable entry with a module
1000 # scope attached to it. Reports an error and returns
1001 # None if previously declared as something else.
1002 entry = self.lookup_here(name)
1004 if entry.is_pyglobal and entry.as_module is scope:
1005 return entry # Already declared as the same module
1006 if not (entry.is_pyglobal and not entry.as_module):
1007 # SAGE -- I put this here so Pyrex
1008 # cimport's work across directories.
1009 # Currently it tries to multiply define
1010 # every module appearing in an import list.
1011 # It shouldn't be an error for a module
1012 # name to appear again, and indeed the generated
1013 # code compiles fine.
1015 warning(pos, "'%s' redeclared " % name, 0)
1018 entry = self.declare_var(name, py_object_type, pos)
1019 entry.as_module = scope
1020 self.add_imported_module(scope)
1023 def declare_var(self, name, type, pos,
1024 cname = None, visibility = 'private', api = 0, is_cdef = 0):
1025 # Add an entry for a global variable. If it is a Python
1026 # object type, and not declared with cdef, it will live
1027 # in the module dictionary, otherwise it will be a C
1029 entry = Scope.declare_var(self, name, type, pos,
1030 cname=cname, visibility=visibility, api=api, is_cdef=is_cdef)
1031 if not visibility in ('private', 'public', 'extern'):
1032 error(pos, "Module-level variable cannot be declared %s" % visibility)
1034 if type is unspecified_type:
1035 type = py_object_type
1036 if not (type.is_pyobject and not type.is_extension_type):
1037 raise InternalError(
1038 "Non-cdef global variable is not a generic Python object")
1039 entry.is_pyglobal = 1
1041 entry.is_cglobal = 1
1042 if entry.type.is_pyobject:
1044 self.var_entries.append(entry)
1047 def declare_global(self, name, pos):
1048 entry = self.lookup_here(name)
1050 self.declare_var(name, py_object_type, pos)
1052 def use_utility_code(self, new_code):
1053 if new_code is not None:
1054 self.utility_code_list.append(new_code)
1056 def declare_c_class(self, name, pos, defining = 0, implementing = 0,
1057 module_name = None, base_type = None, objstruct_cname = None,
1058 typeobj_cname = None, visibility = 'private', typedef_flag = 0, api = 0,
1059 buffer_defaults = None, shadow = 0):
1060 # If this is a non-extern typedef class, expose the typedef, but use
1061 # the non-typedef struct internally to avoid needing forward
1062 # declarations for anonymous structs.
1063 if typedef_flag and visibility != 'extern':
1064 if not (visibility == 'public' or api):
1065 warning(pos, "ctypedef only valid for 'extern' , 'public', and 'api'", 2)
1066 objtypedef_cname = objstruct_cname
1069 objtypedef_cname = None
1071 # Look for previous declaration as a type
1073 entry = self.lookup_here(name)
1074 if entry and not shadow:
1076 if not (entry.is_type and type.is_extension_type):
1077 entry = None # Will cause redeclaration and produce an error
1080 if typedef_flag and (not scope or scope.defined):
1081 self.check_previous_typedef_flag(entry, typedef_flag, pos)
1082 if (scope and scope.defined) or (base_type and type.base_type):
1083 if base_type and base_type is not type.base_type:
1084 error(pos, "Base type does not match previous declaration")
1085 if base_type and not type.base_type:
1086 type.base_type = base_type
1088 # Make a new entry if needed
1090 if not entry or shadow:
1091 type = PyrexTypes.PyExtensionType(name, typedef_flag, base_type, visibility == 'extern')
1093 type.buffer_defaults = buffer_defaults
1094 if objtypedef_cname is not None:
1095 type.objtypedef_cname = objtypedef_cname
1096 if visibility == 'extern':
1097 type.module_name = module_name
1099 type.module_name = self.qualified_name
1100 type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name)
1101 entry = self.declare_type(name, type, pos, visibility = visibility,
1102 defining = 0, shadow = shadow)
1103 entry.is_cclass = True
1105 type.objstruct_cname = objstruct_cname
1106 elif not entry.in_cinclude:
1107 type.objstruct_cname = self.mangle(Naming.objstruct_prefix, name)
1110 "Object name required for 'public' or 'extern' C class")
1111 self.attach_var_entry_to_c_class(entry)
1112 self.c_class_entries.append(entry)
1114 # Check for re-definition and create scope if needed
1117 if defining or implementing:
1118 scope = CClassScope(name = name, outer_scope = self,
1119 visibility = visibility)
1120 if base_type and base_type.scope:
1121 scope.declare_inherited_c_attributes(base_type.scope)
1122 type.set_scope(scope)
1123 self.type_entries.append(entry)
1125 self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos)
1127 if defining and type.scope.defined:
1128 error(pos, "C class '%s' already defined" % name)
1129 elif implementing and type.scope.implemented:
1130 error(pos, "C class '%s' already implemented" % name)
1132 # Fill in options, checking for compatibility with any previous declaration
1135 entry.defined_in_pxd = 1
1136 if implementing: # So that filenames in runtime exceptions refer to
1137 entry.pos = pos # the .pyx file and not the .pxd file
1138 if visibility != 'private' and entry.visibility != visibility:
1139 error(pos, "Class '%s' previously declared as '%s'"
1140 % (name, entry.visibility))
1144 if type.objstruct_cname and type.objstruct_cname != objstruct_cname:
1145 error(pos, "Object struct name differs from previous declaration")
1146 type.objstruct_cname = objstruct_cname
1148 if type.typeobj_cname and type.typeobj_cname != typeobj_cname:
1149 error(pos, "Type object name differs from previous declaration")
1150 type.typeobj_cname = typeobj_cname
1152 # Return new or existing entry
1156 def check_for_illegal_incomplete_ctypedef(self, typedef_flag, pos):
1157 if typedef_flag and not self.in_cinclude:
1158 error(pos, "Forward-referenced type must use 'cdef', not 'ctypedef'")
1160 def allocate_vtable_names(self, entry):
1161 # If extension type has a vtable, allocate vtable struct and
1162 # slot names for it.
1164 if type.base_type and type.base_type.vtabslot_cname:
1165 #print "...allocating vtabslot_cname because base type has one" ###
1166 type.vtabslot_cname = "%s.%s" % (
1167 Naming.obj_base_cname, type.base_type.vtabslot_cname)
1168 elif type.scope and type.scope.cfunc_entries:
1169 # one special case here: when inheriting from builtin
1170 # types, the methods may also be built-in, in which
1171 # case they won't need a vtable
1172 entry_count = len(type.scope.cfunc_entries)
1173 base_type = type.base_type
1175 # FIXME: this will break if we ever get non-inherited C methods
1176 if not base_type.scope or entry_count > len(base_type.scope.cfunc_entries):
1178 if base_type.is_builtin_type:
1179 # builtin base type defines all methods => no vtable needed
1181 base_type = base_type.base_type
1182 #print "...allocating vtabslot_cname because there are C methods" ###
1183 type.vtabslot_cname = Naming.vtabslot_cname
1184 if type.vtabslot_cname:
1185 #print "...allocating other vtable related cnames" ###
1186 type.vtabstruct_cname = self.mangle(Naming.vtabstruct_prefix, entry.name)
1187 type.vtabptr_cname = self.mangle(Naming.vtabptr_prefix, entry.name)
1189 def check_c_classes_pxd(self):
1190 # Performs post-analysis checking and finishing up of extension types
1191 # being implemented in this module. This is called only for the .pxd.
1193 # Checks all extension types declared in this scope to
1196 # * The extension type is fully declared
1198 # Also allocates a name for the vtable if needed.
1200 for entry in self.c_class_entries:
1202 if not entry.type.scope:
1203 error(entry.pos, "C class '%s' is declared but not defined" % entry.name)
1205 def check_c_class(self, entry):
1208 visibility = entry.visibility
1211 error(entry.pos, "C class '%s' is declared but not defined" % name)
1212 # Generate typeobj_cname
1213 if visibility != 'extern' and not type.typeobj_cname:
1214 type.typeobj_cname = self.mangle(Naming.typeobj_prefix, name)
1215 ## Generate typeptr_cname
1216 #type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name)
1217 # Check C methods defined
1219 for method_entry in type.scope.cfunc_entries:
1220 if not method_entry.is_inherited and not method_entry.func_cname:
1221 error(method_entry.pos, "C method '%s' is declared but not defined" %
1223 # Allocate vtable name if necessary
1224 if type.vtabslot_cname:
1225 #print "ModuleScope.check_c_classes: allocating vtable cname for", self ###
1226 type.vtable_cname = self.mangle(Naming.vtable_prefix, entry.name)
1228 def check_c_classes(self):
1229 # Performs post-analysis checking and finishing up of extension types
1230 # being implemented in this module. This is called only for the main
1231 # .pyx file scope, not for cimported .pxd scopes.
1233 # Checks all extension types declared in this scope to
1236 # * The extension type is implemented
1237 # * All required object and type names have been specified or generated
1238 # * All non-inherited C methods are implemented
1240 # Also allocates a name for the vtable if needed.
1242 debug_check_c_classes = 0
1243 if debug_check_c_classes:
1244 print("Scope.check_c_classes: checking scope " + self.qualified_name)
1245 for entry in self.c_class_entries:
1246 if debug_check_c_classes:
1247 print("...entry %s %s" % (entry.name, entry))
1248 print("......type = ", entry.type)
1249 print("......visibility = ", entry.visibility)
1250 self.check_c_class(entry)
1252 def check_c_functions(self):
1253 # Performs post-analysis checking making sure all
1254 # defined c functions are actually implemented.
1255 for name, entry in self.entries.items():
1256 if entry.is_cfunction:
1257 if (entry.defined_in_pxd
1258 and entry.scope is self
1259 and entry.visibility != 'extern'
1260 and not entry.in_cinclude
1261 and not entry.is_implemented):
1262 error(entry.pos, "Non-extern C function '%s' declared but not defined" % name)
1264 def attach_var_entry_to_c_class(self, entry):
1265 # The name of an extension class has to serve as both a type
1266 # name and a variable name holding the type object. It is
1267 # represented in the symbol table by a type entry with a
1268 # variable entry attached to it. For the variable entry,
1269 # we use a read-only C global variable whose name is an
1270 # expression that refers to the type object.
1272 var_entry = Entry(name = entry.name,
1273 type = Builtin.type_type,
1275 cname = "((PyObject*)%s)" % entry.type.typeptr_cname)
1276 var_entry.is_variable = 1
1277 var_entry.is_cglobal = 1
1278 var_entry.is_readonly = 1
1279 entry.as_variable = var_entry
1284 def infer_types(self):
1285 from TypeInference import PyObjectTypeInferer
1286 PyObjectTypeInferer().infer_types(self)
1288 class LocalScope(Scope):
1290 def __init__(self, name, outer_scope, parent_scope = None):
1291 if parent_scope is None:
1292 parent_scope = outer_scope
1293 Scope.__init__(self, name, outer_scope, parent_scope)
1295 def mangle(self, prefix, name):
1296 return prefix + name
1298 def declare_arg(self, name, type, pos):
1299 # Add an entry for an argument of a function.
1300 cname = self.mangle(Naming.var_prefix, name)
1301 entry = self.declare(name, cname, type, pos, 'private')
1302 entry.is_variable = 1
1303 if type.is_pyobject:
1306 #entry.borrowed = 1 # Not using borrowed arg refs for now
1307 self.arg_entries.append(entry)
1308 self.control_flow.set_state((), (name, 'source'), 'arg')
1311 def declare_var(self, name, type, pos,
1312 cname = None, visibility = 'private', api = 0, is_cdef = 0):
1313 # Add an entry for a local variable.
1314 if visibility in ('public', 'readonly'):
1315 error(pos, "Local variable cannot be declared %s" % visibility)
1316 entry = Scope.declare_var(self, name, type, pos,
1317 cname=cname, visibility=visibility, api=api, is_cdef=is_cdef)
1318 if type.is_pyobject and not Options.init_local_none:
1320 entry.init_to_none = (type.is_pyobject or type.is_unspecified) and Options.init_local_none
1322 self.var_entries.append(entry)
1325 def declare_global(self, name, pos):
1326 # Pull entry from global scope into local scope.
1327 if self.lookup_here(name):
1328 warning(pos, "'%s' redeclared ", 0)
1330 entry = self.global_scope().lookup_target(name)
1331 self.entries[name] = entry
1333 def declare_nonlocal(self, name, pos):
1334 # Pull entry from outer scope into local scope
1335 orig_entry = self.lookup_here(name)
1336 if orig_entry and orig_entry.scope is self and not orig_entry.from_closure:
1337 error(pos, "'%s' redeclared as nonlocal" % name)
1339 entry = self.lookup(name)
1340 if entry is None or not entry.from_closure:
1341 error(pos, "no binding for nonlocal '%s' found" % name)
1343 def lookup(self, name):
1344 # Look up name in this scope or an enclosing one.
1345 # Return None if not found.
1346 entry = Scope.lookup(self, name)
1347 if entry is not None:
1348 if entry.scope is not self and entry.scope.is_closure_scope:
1349 if hasattr(entry.scope, "scope_class"):
1350 raise InternalError, "lookup() after scope class created."
1351 # The actual c fragment for the different scopes differs
1352 # on the outside and inside, so we make a new entry
1353 entry.in_closure = True
1354 # Would it be better to declare_var here?
1355 inner_entry = Entry(entry.name, entry.cname, entry.type, entry.pos)
1356 inner_entry.scope = self
1357 inner_entry.is_variable = True
1358 inner_entry.outer_entry = entry
1359 inner_entry.from_closure = True
1360 inner_entry.is_declared_generic = entry.is_declared_generic
1361 self.entries[name] = inner_entry
1365 def mangle_closure_cnames(self, outer_scope_cname):
1366 for entry in self.entries.values():
1367 if entry.from_closure:
1368 cname = entry.outer_entry.cname
1369 if self.is_passthrough:
1372 if cname.startswith(Naming.cur_scope_cname):
1373 cname = cname[len(Naming.cur_scope_cname)+2:]
1374 entry.cname = "%s->%s" % (outer_scope_cname, cname)
1375 elif entry.in_closure:
1376 entry.original_cname = entry.cname
1377 entry.cname = "%s->%s" % (Naming.cur_scope_cname, entry.cname)
1379 class GeneratorExpressionScope(Scope):
1380 """Scope for generator expressions and comprehensions. As opposed
1381 to generators, these can be easily inlined in some cases, so all
1382 we really need is a scope that holds the loop variable(s).
1384 def __init__(self, outer_scope):
1385 name = outer_scope.global_scope().next_id(Naming.genexpr_id_ref)
1386 Scope.__init__(self, name, outer_scope, outer_scope)
1387 self.directives = outer_scope.directives
1388 self.genexp_prefix = "%s%d%s" % (Naming.pyrex_prefix, len(name), name)
1390 def mangle(self, prefix, name):
1391 return '%s%s' % (self.genexp_prefix, self.parent_scope.mangle(prefix, name))
1393 def declare_var(self, name, type, pos,
1394 cname = None, visibility = 'private', api = 0, is_cdef = True):
1395 if type is unspecified_type:
1396 # if the outer scope defines a type for this variable, inherit it
1397 outer_entry = self.outer_scope.lookup(name)
1398 if outer_entry and outer_entry.is_variable:
1399 type = outer_entry.type # may still be 'unspecified_type' !
1400 # the parent scope needs to generate code for the variable, but
1401 # this scope must hold its name exclusively
1402 cname = '%s%s' % (self.genexp_prefix, self.parent_scope.mangle(Naming.var_prefix, name))
1403 entry = self.declare(name, cname, type, pos, visibility)
1404 entry.is_variable = 1
1405 self.var_entries.append(entry)
1406 self.entries[name] = entry
1409 def declare_lambda_function(self, func_cname, pos):
1410 return self.outer_scope.declare_lambda_function(func_cname, pos)
1412 def add_lambda_def(self, def_node):
1413 return self.outer_scope.add_lambda_def(def_node)
1416 class ClosureScope(LocalScope):
1418 is_closure_scope = True
1420 def __init__(self, name, scope_name, outer_scope):
1421 LocalScope.__init__(self, name, outer_scope)
1422 self.closure_cname = "%s%s" % (Naming.closure_scope_prefix, scope_name)
1424 # def mangle_closure_cnames(self, scope_var):
1425 # for entry in self.entries.values() + self.temp_entries:
1426 # entry.in_closure = 1
1427 # LocalScope.mangle_closure_cnames(self, scope_var)
1429 # def mangle(self, prefix, name):
1430 # return "%s->%s" % (self.cur_scope_cname, name)
1431 # return "%s->%s" % (self.closure_cname, name)
1433 def declare_pyfunction(self, name, pos, allow_redefine=False):
1434 return LocalScope.declare_pyfunction(self, name, pos, allow_redefine, visibility='private')
1436 class StructOrUnionScope(Scope):
1437 # Namespace of a C struct or union.
1439 def __init__(self, name="?"):
1440 Scope.__init__(self, name, None, None)
1442 def declare_var(self, name, type, pos,
1443 cname = None, visibility = 'private', api = 0, is_cdef = 0, allow_pyobject = 0):
1444 # Add an entry for an attribute.
1447 if visibility == 'private':
1448 cname = c_safe_identifier(cname)
1449 if type.is_cfunction:
1450 type = PyrexTypes.CPtrType(type)
1451 entry = self.declare(name, cname, type, pos, visibility)
1452 entry.is_variable = 1
1453 self.var_entries.append(entry)
1454 if type.is_pyobject and not allow_pyobject:
1456 "C struct/union member cannot be a Python object")
1457 if visibility != 'private':
1459 "C struct/union member cannot be declared %s" % visibility)
1462 def declare_cfunction(self, name, type, pos,
1463 cname = None, visibility = 'private', defining = 0,
1464 api = 0, in_pxd = 0, modifiers = ()): # currently no utility code ...
1465 return self.declare_var(name, type, pos,
1466 cname=cname, visibility=visibility)
1468 class ClassScope(Scope):
1469 # Abstract base class for namespace of
1470 # Python class or extension type.
1472 # class_name string Pyrex name of the class
1473 # scope_prefix string Additional prefix for names
1474 # declared in the class
1475 # doc string or None Doc string
1477 def __init__(self, name, outer_scope):
1478 Scope.__init__(self, name, outer_scope, outer_scope)
1479 self.class_name = name
1482 def lookup(self, name):
1483 entry = Scope.lookup(self, name)
1486 if name == "classmethod":
1487 # We don't want to use the builtin classmethod here 'cause it won't do the
1488 # right thing in this scope (as the class memebers aren't still functions).
1489 # Don't want to add a cfunction to this scope 'cause that would mess with
1490 # the type definition, so we just return the right entry.
1491 self.use_utility_code(classmethod_utility_code)
1494 "__Pyx_Method_ClassMethod",
1495 PyrexTypes.CFuncType(
1497 [PyrexTypes.CFuncTypeArg("", py_object_type, None)], 0, 0))
1498 entry.is_cfunction = 1
1502 class PyClassScope(ClassScope):
1503 # Namespace of a Python class.
1505 # class_obj_cname string C variable holding class object
1507 is_py_class_scope = 1
1509 def declare_var(self, name, type, pos,
1510 cname = None, visibility = 'private', api = 0, is_cdef = 0):
1511 if type is unspecified_type:
1512 type = py_object_type
1513 # Add an entry for a class attribute.
1514 entry = Scope.declare_var(self, name, type, pos,
1515 cname=cname, visibility=visibility, api=api, is_cdef=is_cdef)
1516 entry.is_pyglobal = 1 # FIXME: WTF?
1517 entry.is_pyclass_attr = 1
1520 def declare_nonlocal(self, name, pos):
1521 # Pull entry from outer scope into local scope
1522 orig_entry = self.lookup_here(name)
1523 if orig_entry and orig_entry.scope is self and not orig_entry.from_closure:
1524 error(pos, "'%s' redeclared as nonlocal" % name)
1526 entry = self.lookup(name)
1528 error(pos, "no binding for nonlocal '%s' found" % name)
1530 # FIXME: this works, but it's unclear if it's the
1532 self.entries[name] = entry
1534 def add_default_value(self, type):
1535 return self.outer_scope.add_default_value(type)
1538 class CClassScope(ClassScope):
1539 # Namespace of an extension type.
1541 # parent_type CClassType
1542 # #typeobj_cname string or None
1543 # #objstruct_cname string
1544 # method_table_cname string
1545 # getset_table_cname string
1546 # has_pyobject_attrs boolean Any PyObject attributes?
1547 # property_entries [Entry]
1548 # defined boolean Defined in .pxd file
1549 # implemented boolean Defined in .pyx file
1550 # inherited_var_entries [Entry] Adapted var entries from base class
1552 is_c_class_scope = 1
1554 def __init__(self, name, outer_scope, visibility):
1555 ClassScope.__init__(self, name, outer_scope)
1556 if visibility != 'extern':
1557 self.method_table_cname = outer_scope.mangle(Naming.methtab_prefix, name)
1558 self.getset_table_cname = outer_scope.mangle(Naming.gstab_prefix, name)
1559 self.has_pyobject_attrs = 0
1560 self.property_entries = []
1561 self.inherited_var_entries = []
1563 self.implemented = 0
1566 # If the type or any of its base types have Python-valued
1567 # C attributes, then it needs to participate in GC.
1568 return self.has_pyobject_attrs or \
1569 (self.parent_type.base_type and
1570 self.parent_type.base_type.scope is not None and
1571 self.parent_type.base_type.scope.needs_gc())
1573 def declare_var(self, name, type, pos,
1574 cname = None, visibility = 'private', api = 0, is_cdef = 0):
1576 # Add an entry for an attribute.
1579 "C attributes cannot be added in implementation part of"
1580 " extension type defined in a pxd")
1581 if get_special_method_signature(name):
1583 "The name '%s' is reserved for a special method."
1587 if visibility == 'private':
1588 cname = c_safe_identifier(cname)
1589 if type.is_cpp_class and visibility != 'extern':
1590 error(pos, "C++ classes not allowed as members of an extension type, use a pointer or reference instead")
1591 entry = self.declare(name, cname, type, pos, visibility)
1592 entry.is_variable = 1
1593 self.var_entries.append(entry)
1594 if type.is_pyobject:
1595 self.has_pyobject_attrs = 1
1596 if visibility not in ('private', 'public', 'readonly'):
1598 "Attribute of extension type cannot be declared %s" % visibility)
1599 if visibility in ('public', 'readonly'):
1600 if name == "__weakref__":
1601 error(pos, "Special attribute __weakref__ cannot be exposed to Python")
1602 if not type.is_pyobject:
1603 if (not type.create_to_py_utility_code(self) or
1604 (visibility=='public' and not
1605 type.create_from_py_utility_code(self))):
1607 "C attribute of type '%s' cannot be accessed from Python" % type)
1610 if type is unspecified_type:
1611 type = py_object_type
1612 # Add an entry for a class attribute.
1613 entry = Scope.declare_var(self, name, type, pos,
1614 cname=cname, visibility=visibility, api=api, is_cdef=is_cdef)
1616 entry.is_pyglobal = 1 # xxx: is_pyglobal changes behaviour in so many places that
1617 # I keep it in for now. is_member should be enough
1619 self.namespace_cname = "(PyObject *)%s" % self.parent_type.typeptr_cname
1623 def declare_pyfunction(self, name, pos, allow_redefine=False):
1624 # Add an entry for a method.
1625 if name in ('__eq__', '__ne__', '__lt__', '__gt__', '__le__', '__ge__'):
1626 error(pos, "Special method %s must be implemented via __richcmp__" % name)
1627 if name == "__new__":
1628 error(pos, "__new__ method of extension type will change semantics "
1629 "in a future version of Pyrex and Cython. Use __cinit__ instead.")
1630 entry = self.declare_var(name, py_object_type, pos,
1631 visibility='extern')
1632 special_sig = get_special_method_signature(name)
1634 # Special methods get put in the method table with a particular
1635 # signature declared in advance.
1636 entry.signature = special_sig
1637 entry.is_special = 1
1639 entry.signature = pymethod_signature
1640 entry.is_special = 0
1642 self.pyfunc_entries.append(entry)
1645 def lookup_here(self, name):
1646 if name == "__new__":
1647 name = EncodedString("__cinit__")
1648 return ClassScope.lookup_here(self, name)
1650 def declare_cfunction(self, name, type, pos,
1651 cname = None, visibility = 'private',
1652 defining = 0, api = 0, in_pxd = 0, modifiers = (),
1653 utility_code = None):
1654 if get_special_method_signature(name):
1655 error(pos, "Special methods must be declared with 'def', not 'cdef'")
1658 error(pos, "C method has no self argument")
1659 elif not self.parent_type.assignable_from(args[0].type):
1660 error(pos, "Self argument (%s) of C method '%s' does not match parent type (%s)" %
1661 (args[0].type, name, self.parent_type))
1662 entry = self.lookup_here(name)
1664 if not entry.is_cfunction:
1665 warning(pos, "'%s' redeclared " % name, 0)
1667 if defining and entry.func_cname:
1668 error(pos, "'%s' already defined" % name)
1669 #print "CClassScope.declare_cfunction: checking signature" ###
1670 if type.same_c_signature_as(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil:
1672 elif type.compatible_signature_with(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil:
1673 entry = self.add_cfunction(name, type, pos, cname or name, visibility='ignore', modifiers=modifiers)
1676 error(pos, "Signature not compatible with previous declaration")
1677 error(entry.pos, "Previous declaration is here")
1681 "C method '%s' not previously declared in definition part of"
1682 " extension type" % name)
1683 entry = self.add_cfunction(name, type, pos, cname or name,
1684 visibility, modifiers)
1686 entry.func_cname = self.mangle(Naming.func_prefix, name)
1687 entry.utility_code = utility_code
1690 def add_cfunction(self, name, type, pos, cname, visibility, modifiers):
1691 # Add a cfunction entry without giving it a func_cname.
1692 prev_entry = self.lookup_here(name)
1693 entry = ClassScope.add_cfunction(self, name, type, pos, cname,
1694 visibility, modifiers)
1695 entry.is_cmethod = 1
1696 entry.prev_entry = prev_entry
1699 def declare_builtin_cfunction(self, name, type, cname, utility_code = None):
1700 # overridden methods of builtin types still have their Python
1701 # equivalent that must be accessible to support bound methods
1702 name = EncodedString(name)
1703 entry = self.declare_cfunction(name, type, None, cname, visibility='extern',
1704 utility_code = utility_code)
1705 var_entry = Entry(name, name, py_object_type)
1706 var_entry.is_variable = 1
1707 var_entry.is_builtin = 1
1708 var_entry.utility_code = utility_code
1709 entry.as_variable = var_entry
1712 def declare_property(self, name, doc, pos):
1713 entry = self.lookup_here(name)
1715 entry = self.declare(name, name, py_object_type, pos, 'private')
1716 entry.is_property = 1
1718 entry.scope = PropertyScope(name,
1719 outer_scope = self.global_scope(), parent_scope = self)
1720 entry.scope.parent_type = self.parent_type
1721 self.property_entries.append(entry)
1724 def declare_inherited_c_attributes(self, base_scope):
1725 # Declare entries for all the C attributes of an
1726 # inherited type, with cnames modified appropriately
1727 # to work with this type.
1729 return "%s.%s" % (Naming.obj_base_cname, base_entry.cname)
1731 base_scope.inherited_var_entries + base_scope.var_entries:
1732 entry = self.declare(base_entry.name, adapt(base_entry.cname),
1733 base_entry.type, None, 'private')
1734 entry.is_variable = 1
1735 self.inherited_var_entries.append(entry)
1736 for base_entry in base_scope.cfunc_entries:
1737 entry = self.add_cfunction(base_entry.name, base_entry.type,
1738 base_entry.pos, adapt(base_entry.cname),
1739 base_entry.visibility, base_entry.func_modifiers)
1740 entry.is_inherited = 1
1743 class CppClassScope(Scope):
1744 # Namespace of a C++ class.
1746 is_cpp_class_scope = 1
1748 default_constructor = None
1750 def __init__(self, name, outer_scope):
1751 Scope.__init__(self, name, outer_scope, None)
1752 self.directives = outer_scope.directives
1753 self.inherited_var_entries = []
1755 def declare_var(self, name, type, pos,
1756 cname = None, visibility = 'extern', api = 0,
1757 is_cdef = 0, allow_pyobject = 0):
1758 # Add an entry for an attribute.
1761 if type.is_cfunction:
1762 type = PyrexTypes.CPtrType(type)
1763 entry = self.declare(name, cname, type, pos, visibility)
1764 entry.is_variable = 1
1765 self.var_entries.append(entry)
1766 if type.is_pyobject and not allow_pyobject:
1768 "C++ class member cannot be a Python object")
1771 def check_base_default_constructor(self, pos):
1772 # Look for default constructors in all base classes.
1773 if self.default_constructor is None:
1774 entry = self.lookup(self.name)
1775 if len(entry.type.base_classes) == 0:
1776 self.default_constructor = True
1778 for base_class in entry.type.base_classes:
1779 temp_entry = base_class.scope.lookup_here("<init>")
1781 if temp_entry is None:
1783 for alternative in temp_entry.all_alternatives():
1784 type = alternative.type
1786 type = type.base_type
1787 if len(type.args) == 0:
1791 self.default_constructor = temp_entry.scope.name
1792 error(pos, "no matching function for call to " \
1793 "%s::%s()" % (temp_entry.scope.name, temp_entry.scope.name))
1794 elif not self.default_constructor:
1795 error(pos, "no matching function for call to %s::%s()" %
1796 (self.default_constructor, self.default_constructor))
1798 def declare_cfunction(self, name, type, pos, cname = None,
1799 visibility = 'extern', api = 0, defining = 0,
1800 in_pxd = 0, modifiers = (), utility_code = None):
1801 if name == self.name.split('::')[-1] and cname is None:
1802 self.check_base_default_constructor(pos)
1804 type.return_type = self.lookup(self.name).type
1805 prev_entry = self.lookup_here(name)
1806 entry = self.declare_var(name, type, pos,
1807 cname=cname, visibility=visibility)
1809 entry.overloaded_alternatives = prev_entry.all_alternatives()
1810 entry.utility_code = utility_code
1813 def declare_inherited_cpp_attributes(self, base_scope):
1814 # Declare entries for all the C++ attributes of an
1815 # inherited type, with cnames modified appropriately
1816 # to work with this type.
1818 base_scope.inherited_var_entries + base_scope.var_entries:
1819 #contructor is not inherited
1820 if base_entry.name == "<init>":
1822 #print base_entry.name, self.entries
1823 if base_entry.name in self.entries:
1825 entry = self.declare(base_entry.name, base_entry.cname,
1826 base_entry.type, None, 'extern')
1827 entry.is_variable = 1
1828 self.inherited_var_entries.append(entry)
1829 for base_entry in base_scope.cfunc_entries:
1830 entry = self.declare_cfunction(base_entry.name, base_entry.type,
1831 base_entry.pos, base_entry.cname,
1832 base_entry.visibility, 0,
1833 modifiers = base_entry.func_modifiers,
1834 utility_code = base_entry.utility_code)
1835 entry.is_inherited = 1
1837 def specialize(self, values):
1838 scope = CppClassScope(self.name, self.outer_scope)
1839 for entry in self.entries.values():
1841 scope.declare_type(entry.name,
1842 entry.type.specialize(values),
1846 # scope.declare_var(entry.name,
1847 # entry.type.specialize(values),
1851 for e in entry.all_alternatives():
1852 scope.declare_cfunction(e.name,
1853 e.type.specialize(values),
1856 utility_code = e.utility_code)
1859 def add_include_file(self, filename):
1860 self.outer_scope.add_include_file(filename)
1862 class PropertyScope(Scope):
1863 # Scope holding the __get__, __set__ and __del__ methods for
1864 # a property of an extension type.
1866 # parent_type PyExtensionType The type to which the property belongs
1868 is_property_scope = 1
1870 def declare_pyfunction(self, name, pos, allow_redefine=False):
1871 # Add an entry for a method.
1872 signature = get_property_accessor_signature(name)
1874 entry = self.declare(name, name, py_object_type, pos, 'private')
1875 entry.is_special = 1
1876 entry.signature = signature
1879 error(pos, "Only __get__, __set__ and __del__ methods allowed "
1880 "in a property declaration")
1884 # Should this go elsewhere (and then get imported)?
1885 #------------------------------------------------------------------------------------
1887 classmethod_utility_code = Code.UtilityCode(
1889 #include "descrobject.h"
1890 static PyObject* __Pyx_Method_ClassMethod(PyObject *method); /*proto*/
1893 static PyObject* __Pyx_Method_ClassMethod(PyObject *method) {
1894 /* It appears that PyMethodDescr_Type is not anywhere exposed in the Python/C API */
1895 static PyTypeObject *methoddescr_type = NULL;
1896 if (methoddescr_type == NULL) {
1897 PyObject *meth = __Pyx_GetAttrString((PyObject*)&PyList_Type, "append");
1898 if (!meth) return NULL;
1899 methoddescr_type = Py_TYPE(meth);
1902 if (PyObject_TypeCheck(method, methoddescr_type)) { /* cdef classes */
1903 PyMethodDescrObject *descr = (PyMethodDescrObject *)method;
1904 #if PY_VERSION_HEX < 0x03020000
1905 PyTypeObject *d_type = descr->d_type;
1907 PyTypeObject *d_type = descr->d_common.d_type;
1909 return PyDescr_NewClassMethod(d_type, descr->d_method);
1911 else if (PyMethod_Check(method)) { /* python classes */
1912 return PyClassMethod_New(PyMethod_GET_FUNCTION(method));
1914 else if (PyCFunction_Check(method)) {
1915 return PyClassMethod_New(method);
1917 #ifdef __pyx_binding_PyCFunctionType_USED
1918 else if (PyObject_TypeCheck(method, __pyx_binding_PyCFunctionType)) { /* binded CFunction */
1919 return PyClassMethod_New(method);
1922 PyErr_Format(PyExc_TypeError,
1923 "Class-level classmethod() can only be called on "
1924 "a method_descriptor or instance method.");
1929 #------------------------------------------------------------------------------------
1931 ERR_BUF_LOCALONLY = 'Buffer types only allowed as function local variables'