6 from Cython import Utils
7 from Errors import warning, error, InternalError
8 from StringEncoding import EncodedString
11 from PyrexTypes import py_object_type
13 from TypeSlots import \
14 pyfunction_signature, pymethod_signature, \
15 get_special_method_signature, get_property_accessor_signature
21 from sets import Set as set
23 possible_identifier = re.compile(ur"(?![0-9])\w+$", re.U).match
24 nice_identifier = re.compile('^[a-zA-Z0-0_]+$').match
26 iso_c99_keywords = set(
27 ['auto', 'break', 'case', 'char', 'const', 'continue', 'default', 'do',
28 'double', 'else', 'enum', 'extern', 'float', 'for', 'goto', 'if',
29 'int', 'long', 'register', 'return', 'short', 'signed', 'sizeof',
30 'static', 'struct', 'switch', 'typedef', 'union', 'unsigned', 'void',
32 '_Bool', '_Complex'', _Imaginary', 'inline', 'restrict'])
34 def c_safe_identifier(cname):
35 # There are some C limitations on struct entry names.
36 if ((cname[:2] == '__'
37 and not (cname.startswith(Naming.pyrex_prefix)
38 or cname == '__weakref__'))
39 or cname in iso_c99_keywords):
40 cname = Naming.pyrex_prefix + cname
43 class BufferAux(object):
44 writable_needed = False
46 def __init__(self, buffer_info_var, stridevars, shapevars,
48 self.buffer_info_var = buffer_info_var
49 self.stridevars = stridevars
50 self.shapevars = shapevars
51 self.suboffsetvars = suboffsetvars
54 return "<BufferAux %r>" % self.__dict__
57 # A symbol table entry in a Scope or ModuleNamespace.
59 # name string Python name of entity
60 # cname string C name of entity
61 # type PyrexType Type of entity
62 # doc string Doc string
63 # init string Initial value
64 # visibility 'private' or 'public' or 'extern'
65 # is_builtin boolean Is an entry in the Python builtins dict
66 # is_cglobal boolean Is a C global variable
67 # is_pyglobal boolean Is a Python module-level variable
68 # or class attribute during
70 # is_member boolean Is an assigned class member
71 # is_variable boolean Is a variable
72 # is_cfunction boolean Is a C function
73 # is_cmethod boolean Is a C method of an extension type
74 # is_unbound_cmethod boolean Is an unbound C method of an extension type
75 # is_type boolean Is a type definition
76 # is_cclass boolean Is an extension class
77 # is_cpp_class boolean Is a C++ class
78 # is_const boolean Is a constant
79 # is_property boolean Is a property of an extension type:
80 # doc_cname string or None C const holding the docstring
81 # getter_cname string C func for getting property
82 # setter_cname string C func for setting or deleting property
83 # is_self_arg boolean Is the "self" arg of an exttype method
84 # is_arg boolean Is the arg of a method
85 # is_local boolean Is a local variable
86 # in_closure boolean Is referenced in an inner scope
87 # is_readonly boolean Can't be assigned to
88 # func_cname string C func implementing Python func
89 # func_modifiers [string] C function modifiers ('inline')
90 # pos position Source position where declared
91 # namespace_cname string If is_pyglobal, the C variable
92 # holding its home namespace
93 # pymethdef_cname string PyMethodDef structure
94 # signature Signature Arg & return types for Python func
95 # init_to_none boolean True if initial value should be None
96 # as_variable Entry Alternative interpretation of extension
97 # type name or builtin C function as a variable
98 # xdecref_cleanup boolean Use Py_XDECREF for error cleanup
99 # in_cinclude boolean Suppress C declaration code
100 # enum_values [Entry] For enum types, list of values
101 # qualified_name string "modname.funcname" or "modname.classname"
102 # or "modname.classname.funcname"
103 # is_declared_generic boolean Is declared as PyObject * even though its
104 # type is an extension type
105 # as_module None Module scope, if a cimported module
106 # is_inherited boolean Is an inherited attribute of an extension type
107 # pystring_cname string C name of Python version of string literal
108 # is_interned boolean For string const entries, value is interned
109 # is_identifier boolean For string const entries, value is an identifier
111 # is_special boolean Is a special method or property accessor
112 # of an extension type
113 # defined_in_pxd boolean Is defined in a .pxd file (not just declared)
114 # api boolean Generate C API for C class or function
115 # utility_code string Utility code needed when this entry is used
117 # buffer_aux BufferAux or None Extra information needed for buffer variables
118 # inline_func_in_pxd boolean Hacky special case for inline function in pxd file.
119 # Ideally this should not be necesarry.
121 inline_func_in_pxd = False
124 visibility = 'private'
132 is_unbound_cmethod = 0
145 is_declared_generic = 0
156 pystring_cname = None
169 def __init__(self, name, cname, type, pos = None, init = None):
175 self.overloaded_alternatives = []
177 def redeclared(self, pos):
178 error(pos, "'%s' does not match previous declaration" % self.name)
179 error(self.pos, "Previous declaration is here")
181 def all_alternatives(self):
182 return [self] + self.overloaded_alternatives
185 # name string Unqualified name
186 # outer_scope Scope or None Enclosing scope
187 # entries {string : Entry} Python name to entry, non-types
188 # const_entries [Entry] Constant entries
189 # type_entries [Entry] Struct/union/enum/typedef/exttype entries
190 # sue_entries [Entry] Struct/union/enum entries
191 # arg_entries [Entry] Function argument entries
192 # var_entries [Entry] User-defined variable entries
193 # pyfunc_entries [Entry] Python function entries
194 # cfunc_entries [Entry] C function entries
195 # c_class_entries [Entry] All extension type entries
196 # temp_entries [Entry] Temporary variable entries
197 # free_temp_entries [Entry] Temp variables currently unused
198 # temp_counter integer Counter for naming temp vars
199 # cname_to_entry {string : Entry} Temp cname to entry mapping
200 # int_to_entry {int : Entry} Temp cname to entry mapping
201 # return_type PyrexType or None Return type of function owning scope
202 # is_py_class_scope boolean Is a Python class scope
203 # is_c_class_scope boolean Is an extension type scope
204 # scope_prefix string Disambiguator for C names
205 # in_cinclude boolean Suppress C declaration code
206 # qualified_name string "modname" or "modname.classname"
207 # pystring_entries [Entry] String const entries newly used as
208 # Python strings in this scope
209 # control_flow ControlFlow Used for keeping track of environment state
210 # nogil boolean In a nogil section
211 # directives dict Helper variable for the recursive
212 # analysis, contains directive values.
214 is_py_class_scope = 0
221 temp_prefix = Naming.pyrex_prefix
223 def __init__(self, name, outer_scope, parent_scope):
224 # The outer_scope is the next scope in the lookup chain.
225 # The parent_scope is used to derive the qualified name of this scope.
227 self.outer_scope = outer_scope
228 self.parent_scope = parent_scope
229 mangled_name = "%d%s_" % (len(name), name)
230 qual_scope = self.qualifying_scope()
232 self.qualified_name = qual_scope.qualify_name(name)
233 self.scope_prefix = qual_scope.scope_prefix + mangled_name
235 self.qualified_name = name
236 self.scope_prefix = mangled_name
238 self.const_entries = []
239 self.type_entries = []
240 self.sue_entries = []
241 self.arg_entries = []
242 self.var_entries = []
243 self.pyfunc_entries = []
244 self.cfunc_entries = []
245 self.c_class_entries = []
246 self.defined_c_classes = []
247 self.imported_c_classes = {}
248 self.temp_entries = []
249 self.free_temp_entries = []
250 #self.pending_temp_entries = [] # TEMPORARY
251 self.temp_counter = 1
252 self.cname_to_entry = {}
253 self.string_to_entry = {}
254 self.identifier_to_entry = {}
255 self.num_to_entry = {}
256 self.obj_to_entry = {}
257 self.pystring_entries = []
258 self.buffer_entries = []
259 self.control_flow = ControlFlow.LinearControlFlow()
261 def start_branching(self, pos):
262 self.control_flow = self.control_flow.start_branch(pos)
264 def next_branch(self, pos):
265 self.control_flow = self.control_flow.next_branch(pos)
267 def finish_branching(self, pos):
268 self.control_flow = self.control_flow.finish_branch(pos)
271 return "<%s %s>" % (self.__class__.__name__, self.qualified_name)
273 def intern_identifier(self, name):
274 return self.global_scope().intern_identifier(name)
276 def qualifying_scope(self):
277 return self.parent_scope
279 def mangle(self, prefix, name = None):
281 return "%s%s%s" % (prefix, self.scope_prefix, name)
283 return self.parent_scope.mangle(prefix, self.name)
285 def mangle_internal(self, name):
286 # Mangle an internal name so as not to clash with any
287 # user-defined name in this scope.
288 prefix = "%s%s_" % (Naming.pyrex_prefix, name)
289 return self.mangle(prefix)
290 #return self.parent_scope.mangle(prefix, self.name)
292 def global_scope(self):
293 # Return the module-level scope containing this scope.
294 return self.outer_scope.global_scope()
296 def builtin_scope(self):
297 # Return the module-level scope containing this scope.
298 return self.outer_scope.builtin_scope()
300 def declare(self, name, cname, type, pos, visibility):
301 # Create new entry, and add to dictionary if
302 # name is not None. Reports a warning if already
304 if type.is_buffer and not isinstance(self, LocalScope):
305 error(pos, ERR_BUF_LOCALONLY)
306 if not self.in_cinclude and cname and re.match("^_[_A-Z]+$", cname):
307 # See http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html#Reserved-Names
308 warning(pos, "'%s' is a reserved name in C." % cname, -1)
309 entries = self.entries
310 if name and name in entries:
311 if visibility == 'extern':
312 warning(pos, "'%s' redeclared " % name, 0)
313 elif visibility != 'ignore':
314 error(pos, "'%s' redeclared " % name)
315 entry = Entry(name, cname, type, pos = pos)
316 entry.in_cinclude = self.in_cinclude
318 entry.qualified_name = self.qualify_name(name)
319 if name in entries and self.is_cpp():
320 entries[name].overloaded_alternatives.append(entry)
322 entries[name] = entry
324 entry.visibility = visibility
327 def qualify_name(self, name):
328 return "%s.%s" % (self.qualified_name, name)
330 def declare_const(self, name, type, value, pos, cname = None, visibility = 'private'):
331 # Add an entry for a named constant.
333 if self.in_cinclude or visibility == 'public':
336 cname = self.mangle(Naming.enum_prefix, name)
337 entry = self.declare(name, cname, type, pos, visibility)
342 def declare_type(self, name, type, pos,
343 cname = None, visibility = 'private', defining = 1):
344 # Add an entry for a type definition.
347 entry = self.declare(name, cname, type, pos, visibility)
350 self.type_entries.append(entry)
351 # here we would set as_variable to an object representing this type
354 def declare_typedef(self, name, base_type, pos, cname = None,
355 visibility = 'private'):
357 if self.in_cinclude or visibility == 'public':
360 cname = self.mangle(Naming.type_prefix, name)
361 type = PyrexTypes.CTypedefType(cname, base_type, (visibility == 'extern'))
362 entry = self.declare_type(name, type, pos, cname, visibility)
363 type.qualified_name = entry.qualified_name
366 def declare_struct_or_union(self, name, kind, scope,
367 typedef_flag, pos, cname = None, visibility = 'private',
369 # Add an entry for a struct or union definition.
371 if self.in_cinclude or visibility == 'public':
374 cname = self.mangle(Naming.type_prefix, name)
375 entry = self.lookup_here(name)
377 type = PyrexTypes.CStructOrUnionType(
378 name, kind, scope, typedef_flag, cname, packed)
379 entry = self.declare_type(name, type, pos, cname,
380 visibility = visibility, defining = scope is not None)
381 self.sue_entries.append(entry)
383 if not (entry.is_type and entry.type.is_struct_or_union
384 and entry.type.kind == kind):
385 warning(pos, "'%s' redeclared " % name, 0)
386 elif scope and entry.type.scope:
387 warning(pos, "'%s' already defined (ignoring second definition)" % name, 0)
389 self.check_previous_typedef_flag(entry, typedef_flag, pos)
390 self.check_previous_visibility(entry, visibility, pos)
392 entry.type.scope = scope
393 self.type_entries.append(entry)
394 if not scope and not entry.type.scope:
395 self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos)
398 def check_previous_typedef_flag(self, entry, typedef_flag, pos):
399 if typedef_flag != entry.type.typedef_flag:
400 error(pos, "'%s' previously declared using '%s'" % (
401 entry.name, ("cdef", "ctypedef")[entry.type.typedef_flag]))
403 def check_previous_visibility(self, entry, visibility, pos):
404 if entry.visibility != visibility:
405 error(pos, "'%s' previously declared as '%s'" % (
406 entry.name, entry.visibility))
408 def declare_enum(self, name, pos, cname, typedef_flag,
409 visibility = 'private'):
412 if self.in_cinclude or visibility == 'public':
415 cname = self.mangle(Naming.type_prefix, name)
416 type = PyrexTypes.CEnumType(name, cname, typedef_flag)
418 type = PyrexTypes.c_anon_enum_type
419 entry = self.declare_type(name, type, pos, cname = cname,
420 visibility = visibility)
421 entry.enum_values = []
422 self.sue_entries.append(entry)
425 def declare_var(self, name, type, pos,
426 cname = None, visibility = 'private', is_cdef = 0):
427 # Add an entry for a variable.
429 if visibility != 'private':
432 cname = self.mangle(Naming.var_prefix, name)
433 entry = self.declare(name, cname, type, pos, visibility)
434 entry.is_variable = 1
435 self.control_flow.set_state((), (name, 'initalized'), False)
438 def declare_builtin(self, name, pos):
439 return self.outer_scope.declare_builtin(name, pos)
441 def declare_pyfunction(self, name, pos):
442 # Add an entry for a Python function.
443 entry = self.lookup_here(name)
444 if entry and not entry.type.is_cfunction:
445 # This is legal Python, but for now will produce invalid C.
446 error(pos, "'%s' already declared" % name)
447 entry = self.declare_var(name, py_object_type, pos, visibility='extern')
448 entry.signature = pyfunction_signature
449 self.pyfunc_entries.append(entry)
452 def register_pyfunction(self, entry):
453 self.pyfunc_entries.append(entry)
455 def declare_cfunction(self, name, type, pos,
456 cname = None, visibility = 'private', defining = 0,
457 api = 0, in_pxd = 0, modifiers = ()):
458 # Add an entry for a C function.
460 if api or visibility != 'private':
463 cname = self.mangle(Naming.func_prefix, name)
464 entry = self.lookup_here(name)
466 if visibility != 'private' and visibility != entry.visibility:
467 warning(pos, "Function '%s' previously declared as '%s'" % (name, entry.visibility), 1)
468 if not entry.type.same_as(type):
469 if visibility == 'extern' and entry.visibility == 'extern':
471 temp = self.add_cfunction(name, type, pos, cname, visibility, modifiers)
472 entry.overloaded_alternatives.append(temp)
475 warning(pos, "Function signature does not match previous declaration", 1)
478 error(pos, "Function signature does not match previous declaration")
480 entry = self.add_cfunction(name, type, pos, cname, visibility, modifiers)
481 entry.func_cname = cname
482 if in_pxd and visibility != 'extern':
483 entry.defined_in_pxd = 1
486 if not defining and not in_pxd and visibility != 'extern':
487 error(pos, "Non-extern C function '%s' declared but not defined" % name)
489 entry.is_implemented = True
491 entry.func_modifiers = modifiers
494 def add_cfunction(self, name, type, pos, cname, visibility, modifiers):
495 # Add a C function entry without giving it a func_cname.
496 entry = self.declare(name, cname, type, pos, visibility)
497 entry.is_cfunction = 1
499 entry.func_modifiers = modifiers
500 self.cfunc_entries.append(entry)
503 def find(self, name, pos):
504 # Look up name, report error if not found.
505 entry = self.lookup(name)
509 error(pos, "'%s' is not declared" % name)
511 def find_imported_module(self, path, pos):
512 # Look up qualified name, must be a module, report error if not found.
513 # Path is a list of names.
516 entry = scope.find(name, pos)
520 scope = entry.as_module
522 error(pos, "'%s' is not a cimported module" % scope.qualified_name)
526 def lookup(self, name):
527 # Look up name in this scope or an enclosing one.
528 # Return None if not found.
529 return (self.lookup_here(name)
530 or (self.outer_scope and self.outer_scope.lookup_from_inner(name))
533 def lookup_from_inner(self, name):
534 # Look up name in this scope or an enclosing one.
535 # This is only called from enclosing scopes.
536 return (self.lookup_here(name)
537 or (self.outer_scope and self.outer_scope.lookup_from_inner(name))
540 def lookup_here(self, name):
541 # Look up in this scope only, return None if not found.
542 return self.entries.get(name, None)
544 def lookup_target(self, name):
545 # Look up name in this scope only. Declare as Python
546 # variable if not found.
547 entry = self.lookup_here(name)
549 entry = self.declare_var(name, py_object_type, None)
552 def lookup_type(self, name):
553 entry = self.lookup(name)
554 if entry and entry.is_type:
557 def add_string_const(self, value, identifier = False):
558 # Add an entry for a string constant.
560 cname = self.new_string_const_cname(value)
562 cname = self.new_const_cname()
564 c_type = PyrexTypes.c_utf8_char_array_type
565 value = value.utf8encode()
567 c_type = PyrexTypes.c_char_array_type
568 value = value.byteencode()
569 entry = Entry("", cname, c_type, init = value)
571 self.const_entries.append(entry)
574 def get_string_const(self, value, identifier = False):
575 # Get entry for string constant. Returns an existing
576 # one if possible, otherwise creates a new one.
577 genv = self.global_scope()
579 string_map = genv.identifier_to_entry
581 string_map = genv.string_to_entry
582 entry = string_map.get(value)
584 entry = self.add_string_const(value, identifier)
585 entry.is_identifier = identifier
586 string_map[value] = entry
589 def add_py_string(self, entry, identifier = None):
590 # If not already done, allocate a C name for a Python version of
591 # a string literal, and add it to the list of Python strings to
592 # be created at module init time. If the string resembles a
593 # Python identifier, it will be interned.
594 if entry.pystring_cname:
597 entry.pystring_cname = Naming.py_const_prefix + entry.cname[len(Naming.const_prefix):]
598 self.pystring_entries.append(entry)
599 self.global_scope().all_pystring_entries.append(entry)
600 if identifier or (identifier is None and possible_identifier(value)):
601 entry.is_interned = 1
602 self.global_scope().new_interned_string_entries.append(entry)
604 def add_py_num(self, value):
605 # Add an entry for an int constant.
606 cname = "%s%s" % (Naming.interned_num_prefix, value)
607 cname = cname.replace('-', 'neg_').replace('.','_')
608 entry = Entry("", cname, py_object_type, init = value)
610 entry.is_interned = 1
611 self.const_entries.append(entry)
612 self.interned_nums.append(entry)
615 def get_py_num(self, value, longness):
616 # Get entry for int constant. Returns an existing
617 # one if possible, otherwise creates a new one.
618 if longness or Utils.long_literal(value):
620 genv = self.global_scope()
621 entry = genv.num_to_entry.get(value)
623 entry = genv.add_py_num(value)
624 genv.num_to_entry[value] = entry
625 genv.pynum_entries.append(entry)
628 def get_py_obj(self, obj, c_prefix=''):
629 # Get entry for a generic constant. Returns an existing
630 # one if possible, otherwise creates a new one.
631 genv = self.global_scope()
632 entry = genv.obj_to_entry.get(obj)
634 entry = genv.add_py_num(obj, c_prefix)
635 genv.obj_to_entry[obj] = entry
638 def new_string_const_cname(self, value):
639 # Create a new globally-unique nice name for a string constant.
640 if len(value) < 20 and nice_identifier(value):
641 return "%s%s" % (Naming.const_prefix, value)
643 return self.global_scope().new_const_cname()
645 def new_const_cname(self):
646 # Create a new globally-unique name for a constant.
647 return self.global_scope().new_const_cname()
649 def allocate_temp(self, type):
650 # Allocate a temporary variable of the given type from the
651 # free list if available, otherwise create a new one.
652 # Returns the cname of the variable.
653 for entry in self.free_temp_entries:
654 if entry.type == type:
655 self.free_temp_entries.remove(entry)
657 n = self.temp_counter
658 self.temp_counter = n + 1
659 cname = "%s%d" % (self.temp_prefix, n)
660 entry = Entry("", cname, type)
662 if type.is_pyobject or type == PyrexTypes.c_py_ssize_t_type:
664 self.cname_to_entry[entry.cname] = entry
665 self.temp_entries.append(entry)
668 def allocate_temp_pyobject(self):
669 # Allocate a temporary PyObject variable.
670 return self.allocate_temp(py_object_type)
672 def release_temp(self, cname):
673 # Release a temporary variable for re-use.
674 if not cname: # can happen when type of an expr is void
676 entry = self.cname_to_entry[cname]
677 if entry in self.free_temp_entries:
678 raise InternalError("Temporary variable %s released more than once"
680 self.free_temp_entries.append(entry)
682 def temps_in_use(self):
683 # Return a new list of temp entries currently in use.
684 return [entry for entry in self.temp_entries
685 if entry not in self.free_temp_entries]
687 def use_utility_code(self, new_code, name=None):
688 self.global_scope().use_utility_code(new_code, name)
690 def generate_library_function_declarations(self, code):
691 # Generate extern decls for C library funcs used.
694 def defines_any(self, names):
695 # Test whether any of the given names are
696 # defined in this scope.
698 if name in self.entries:
703 outer = self.outer_scope
707 return outer.is_cpp()
709 class PreImportScope(Scope):
711 namespace_cname = Naming.preimport_cname
714 Scope.__init__(self, Options.pre_import, None, None)
716 def declare_builtin(self, name, pos):
717 entry = self.declare(name, name, py_object_type, pos, 'private')
718 entry.is_variable = True
719 entry.is_pyglobal = True
723 class BuiltinScope(Scope):
724 # The builtin namespace.
727 if Options.pre_import is None:
728 Scope.__init__(self, "__builtin__", None, None)
730 Scope.__init__(self, "__builtin__", PreImportScope(), None)
733 for name, definition in self.builtin_entries.iteritems():
734 cname, type = definition
735 self.declare_var(name, type, None, cname)
737 def declare_builtin(self, name, pos):
738 if not hasattr(__builtin__, name):
739 if self.outer_scope is not None:
740 return self.outer_scope.declare_builtin(name, pos)
742 error(pos, "undeclared name not builtin: %s"%name)
744 def declare_builtin_cfunction(self, name, type, cname, python_equiv = None,
745 utility_code = None):
746 # If python_equiv == "*", the Python equivalent has the same name
747 # as the entry, otherwise it has the name specified by python_equiv.
748 name = EncodedString(name)
749 entry = self.declare_cfunction(name, type, None, cname, visibility='extern')
750 entry.utility_code = utility_code
752 if python_equiv == "*":
755 python_equiv = EncodedString(python_equiv)
756 var_entry = Entry(python_equiv, python_equiv, py_object_type)
757 var_entry.is_variable = 1
758 var_entry.is_builtin = 1
759 entry.as_variable = var_entry
762 def declare_builtin_type(self, name, cname, utility_code = None):
763 name = EncodedString(name)
764 type = PyrexTypes.BuiltinObjectType(name, cname)
765 type.set_scope(CClassScope(name, outer_scope=None, visibility='extern'))
766 self.type_names[name] = 1
767 entry = self.declare_type(name, type, None, visibility='extern')
769 var_entry = Entry(name = entry.name,
770 type = self.lookup('type').type, # make sure "type" is the first type declared...
772 cname = "((PyObject*)%s)" % entry.type.typeptr_cname)
773 var_entry.is_variable = 1
774 var_entry.is_cglobal = 1
775 var_entry.is_readonly = 1
776 var_entry.utility_code = utility_code
777 entry.as_variable = var_entry
781 def builtin_scope(self):
786 "type": ["((PyObject*)&PyType_Type)", py_object_type],
788 "bool": ["((PyObject*)&PyBool_Type)", py_object_type],
789 "int": ["((PyObject*)&PyInt_Type)", py_object_type],
790 "long": ["((PyObject*)&PyLong_Type)", py_object_type],
791 "float": ["((PyObject*)&PyFloat_Type)", py_object_type],
792 "complex":["((PyObject*)&PyComplex_Type)", py_object_type],
794 "bytes": ["((PyObject*)&PyBytes_Type)", py_object_type],
795 "str": ["((PyObject*)&PyString_Type)", py_object_type],
796 "unicode":["((PyObject*)&PyUnicode_Type)", py_object_type],
798 "tuple": ["((PyObject*)&PyTuple_Type)", py_object_type],
799 "list": ["((PyObject*)&PyList_Type)", py_object_type],
800 "dict": ["((PyObject*)&PyDict_Type)", py_object_type],
801 "set": ["((PyObject*)&PySet_Type)", py_object_type],
802 "frozenset": ["((PyObject*)&PyFrozenSet_Type)", py_object_type],
804 "slice": ["((PyObject*)&PySlice_Type)", py_object_type],
805 "file": ["((PyObject*)&PyFile_Type)", py_object_type],
807 "None": ["Py_None", py_object_type],
808 "False": ["Py_False", py_object_type],
809 "True": ["Py_True", py_object_type],
812 const_counter = 1 # As a temporary solution for compiling code in pxds
814 class ModuleScope(Scope):
815 # module_name string Python name of the module
816 # module_cname string C name of Python module object
817 # #module_dict_cname string C name of module dict object
818 # method_table_cname string C name of method table
819 # doc string Module doc string
820 # doc_cname string C name of module doc string
821 # const_counter integer Counter for naming constants (PS: MOVED TO GLOBAL)
822 # utility_code_list [(UtilityCode, string)] Queuing utility codes for forwarding to Code.py
823 # default_entries [Entry] Function argument default entries
824 # python_include_files [string] Standard Python headers to be included
825 # include_files [string] Other C headers to be included
826 # string_to_entry {string : Entry} Map string const to entry
827 # identifier_to_entry {string : Entry} Map identifier string const to entry
829 # parent_module Scope Parent in the import namespace
830 # module_entries {string : Entry} For cimport statements
831 # type_names {string : 1} Set of type names (used during parsing)
832 # included_files [string] Cython sources included with 'include'
833 # pxd_file_loaded boolean Corresponding .pxd file has been processed
834 # cimported_modules [ModuleScope] Modules imported with cimport
835 # new_interned_string_entries [Entry] New interned strings waiting to be declared
836 # interned_nums [int/long] Interned numeric constants
837 # all_pystring_entries [Entry] Python string consts from all scopes
838 # types_imported {PyrexType : 1} Set of types for which import code generated
839 # has_import_star boolean Module contains import *
840 # cpp boolean Compiling a C++ file
845 def __init__(self, name, parent_module, context):
846 self.parent_module = parent_module
847 outer_scope = context.find_submodule("__builtin__")
848 Scope.__init__(self, name, outer_scope, parent_module)
849 if name != "__init__":
850 self.module_name = name
852 # Treat Spam/__init__.pyx specially, so that when Python loads
853 # Spam/__init__.so, initSpam() is defined.
854 self.module_name = parent_module.module_name
855 self.context = context
856 self.module_cname = Naming.module_cname
857 self.module_dict_cname = Naming.moddict_cname
858 self.method_table_cname = Naming.methtable_cname
860 self.doc_cname = Naming.moddoc_cname
861 self.utility_code_list = []
862 self.default_entries = []
863 self.module_entries = {}
864 self.python_include_files = ["Python.h", "structmember.h"]
865 self.include_files = []
866 self.type_names = dict(outer_scope.type_names)
867 self.pxd_file_loaded = 0
868 self.cimported_modules = []
869 self.new_interned_string_entries = []
870 self.interned_nums = []
871 self.interned_objs = []
872 self.all_pystring_entries = []
873 self.types_imported = {}
874 self.included_files = []
875 self.pynum_entries = []
876 self.has_extern_class = 0
877 self.cached_builtins = []
878 self.undeclared_cached_builtins = []
879 self.namespace_cname = self.module_cname
880 for name in ['__builtins__', '__name__', '__file__', '__doc__']:
881 self.declare_var(EncodedString(name), py_object_type, None)
883 def qualifying_scope(self):
884 return self.parent_module
886 def global_scope(self):
889 def declare_builtin(self, name, pos):
890 if not hasattr(__builtin__, name):
891 if self.has_import_star:
892 entry = self.declare_var(name, py_object_type, pos)
894 elif self.outer_scope is not None:
895 return self.outer_scope.declare_builtin(name, pos)
897 error(pos, "undeclared name not builtin: %s"%name)
898 if Options.cache_builtins:
899 for entry in self.cached_builtins:
900 if entry.name == name:
902 entry = self.declare(None, None, py_object_type, pos, 'private')
903 if Options.cache_builtins:
907 entry.cname = Naming.builtin_prefix + name
908 self.cached_builtins.append(entry)
909 self.undeclared_cached_builtins.append(entry)
914 def intern_identifier(self, name):
915 string_entry = self.get_string_const(name, identifier = True)
916 self.add_py_string(string_entry, identifier = 1)
917 return string_entry.pystring_cname
919 def find_module(self, module_name, pos):
920 # Find a module in the import namespace, interpreting
921 # relative imports relative to this module's parent.
922 # Finds and parses the module's .pxd file if the module
923 # has not been referenced before.
924 return self.global_scope().context.find_module(
925 module_name, relative_to = self.parent_module, pos = pos)
927 def find_submodule(self, name):
928 # Find and return scope for a submodule of this module,
929 # creating a new empty one if necessary. Doesn't parse .pxd.
930 scope = self.lookup_submodule(name)
932 scope = ModuleScope(name,
933 parent_module = self, context = self.context)
934 self.module_entries[name] = scope
937 def lookup_submodule(self, name):
938 # Return scope for submodule of this module, or None.
939 return self.module_entries.get(name, None)
941 def add_include_file(self, filename):
942 if filename not in self.python_include_files \
943 and filename not in self.include_files:
944 self.include_files.append(filename)
946 def add_imported_module(self, scope):
947 if scope not in self.cimported_modules:
948 for filename in scope.include_files:
949 self.add_include_file(filename)
950 self.cimported_modules.append(scope)
951 for m in scope.cimported_modules:
952 self.add_imported_module(m)
954 def add_imported_entry(self, name, entry, pos):
955 if entry not in self.entries:
956 self.entries[name] = entry
958 warning(pos, "'%s' redeclared " % name, 0)
960 def declare_module(self, name, scope, pos):
961 # Declare a cimported module. This is represented as a
962 # Python module-level variable entry with a module
963 # scope attached to it. Reports an error and returns
964 # None if previously declared as something else.
965 entry = self.lookup_here(name)
967 if entry.is_pyglobal and entry.as_module is scope:
968 return entry # Already declared as the same module
969 if not (entry.is_pyglobal and not entry.as_module):
970 # SAGE -- I put this here so Pyrex
971 # cimport's work across directories.
972 # Currently it tries to multiply define
973 # every module appearing in an import list.
974 # It shouldn't be an error for a module
975 # name to appear again, and indeed the generated
976 # code compiles fine.
978 warning(pos, "'%s' redeclared " % name, 0)
981 entry = self.declare_var(name, py_object_type, pos)
982 entry.as_module = scope
983 self.add_imported_module(scope)
986 def declare_var(self, name, type, pos,
987 cname = None, visibility = 'private', is_cdef = 0):
988 # Add an entry for a global variable. If it is a Python
989 # object type, and not declared with cdef, it will live
990 # in the module dictionary, otherwise it will be a C
992 entry = Scope.declare_var(self, name, type, pos,
993 cname, visibility, is_cdef)
994 if not visibility in ('private', 'public', 'extern'):
995 error(pos, "Module-level variable cannot be declared %s" % visibility)
997 if not (type.is_pyobject and not type.is_extension_type):
999 "Non-cdef global variable is not a generic Python object")
1000 entry.is_pyglobal = 1
1002 entry.is_cglobal = 1
1003 if entry.type.is_pyobject:
1005 self.var_entries.append(entry)
1008 def declare_global(self, name, pos):
1009 entry = self.lookup_here(name)
1011 self.declare_var(name, py_object_type, pos)
1013 def add_default_value(self, type):
1014 # Add an entry for holding a function argument
1016 cname = self.new_const_cname()
1017 entry = Entry("", cname, type)
1018 self.default_entries.append(entry)
1021 def new_const_cname(self):
1022 global const_counter
1023 # Create a new globally-unique name for a constant.
1026 const_counter = n + 1
1027 return "%s%s%d" % (Naming.const_prefix, prefix, n)
1029 def use_utility_code(self, new_code, name=None):
1030 if new_code is not None:
1031 self.utility_code_list.append((new_code, name))
1033 def declare_c_class(self, name, pos, defining = 0, implementing = 0,
1034 module_name = None, base_type = None, objstruct_cname = None,
1035 typeobj_cname = None, visibility = 'private', typedef_flag = 0, api = 0,
1036 buffer_defaults = None):
1038 # Look for previous declaration as a type
1040 entry = self.lookup_here(name)
1043 if not (entry.is_type and type.is_extension_type):
1044 entry = None # Will cause redeclaration and produce an error
1047 if typedef_flag and (not scope or scope.defined):
1048 self.check_previous_typedef_flag(entry, typedef_flag, pos)
1049 if (scope and scope.defined) or (base_type and type.base_type):
1050 if base_type and base_type is not type.base_type:
1051 error(pos, "Base type does not match previous declaration")
1052 if base_type and not type.base_type:
1053 type.base_type = base_type
1055 # Make a new entry if needed
1058 type = PyrexTypes.PyExtensionType(name, typedef_flag, base_type)
1060 type.buffer_defaults = buffer_defaults
1061 if visibility == 'extern':
1062 type.module_name = module_name
1064 type.module_name = self.qualified_name
1065 type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name)
1066 entry = self.declare_type(name, type, pos, visibility = visibility,
1068 entry.is_cclass = True
1070 type.objstruct_cname = objstruct_cname
1071 elif not entry.in_cinclude:
1072 type.objstruct_cname = self.mangle(Naming.objstruct_prefix, name)
1075 "Object name required for 'public' or 'extern' C class")
1076 self.attach_var_entry_to_c_class(entry)
1077 self.c_class_entries.append(entry)
1079 # Check for re-definition and create scope if needed
1082 if defining or implementing:
1083 scope = CClassScope(name = name, outer_scope = self,
1084 visibility = visibility)
1085 if base_type and base_type.scope:
1086 scope.declare_inherited_c_attributes(base_type.scope)
1087 type.set_scope(scope)
1088 self.type_entries.append(entry)
1090 self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos)
1092 if defining and type.scope.defined:
1093 error(pos, "C class '%s' already defined" % name)
1094 elif implementing and type.scope.implemented:
1095 error(pos, "C class '%s' already implemented" % name)
1097 # Fill in options, checking for compatibility with any previous declaration
1100 entry.defined_in_pxd = 1
1101 if implementing: # So that filenames in runtime exceptions refer to
1102 entry.pos = pos # the .pyx file and not the .pxd file
1103 if visibility != 'private' and entry.visibility != visibility:
1104 error(pos, "Class '%s' previously declared as '%s'"
1105 % (name, entry.visibility))
1109 if type.objstruct_cname and type.objstruct_cname != objstruct_cname:
1110 error(pos, "Object struct name differs from previous declaration")
1111 type.objstruct_cname = objstruct_cname
1113 if type.typeobj_cname and type.typeobj_cname != typeobj_cname:
1114 error(pos, "Type object name differs from previous declaration")
1115 type.typeobj_cname = typeobj_cname
1117 # Return new or existing entry
1121 def check_for_illegal_incomplete_ctypedef(self, typedef_flag, pos):
1122 if typedef_flag and not self.in_cinclude:
1123 error(pos, "Forward-referenced type must use 'cdef', not 'ctypedef'")
1125 def declare_cpp_class(self, name, scope,
1126 pos, cname = None, base_classes = [],
1127 visibility = 'extern', templates = None):
1128 if visibility != 'extern':
1129 error(pos, "C++ classes may only be extern")
1132 entry = self.lookup(name)
1134 type = PyrexTypes.CppClassType(
1135 name, scope, cname, base_classes, templates = templates)
1136 entry = self.declare_type(name, type, pos, cname,
1137 visibility = visibility, defining = scope is not None)
1139 if not (entry.is_type and entry.type.is_cpp_class):
1140 warning(pos, "'%s' redeclared " % name, 0)
1141 elif scope and entry.type.scope:
1142 warning(pos, "'%s' already defined (ignoring second definition)" % name, 0)
1145 entry.type.scope = scope
1146 self.type_entries.append(entry)
1147 if not scope and not entry.type.scope:
1148 entry.type.scope = CppClassScope(name, self)
1149 if templates is not None:
1151 template_entry = entry.type.scope.declare(T.name, T.name, T, None, 'extern')
1152 template_entry.is_type = 1
1154 def declare_inherited_attributes(entry, base_classes):
1155 for base_class in base_classes:
1156 declare_inherited_attributes(entry, base_class.base_classes)
1157 entry.type.scope.declare_inherited_cpp_attributes(base_class.scope)
1158 declare_inherited_attributes(entry, base_classes)
1161 def allocate_vtable_names(self, entry):
1162 # If extension type has a vtable, allocate vtable struct and
1163 # slot names for it.
1165 if type.base_type and type.base_type.vtabslot_cname:
1166 #print "...allocating vtabslot_cname because base type has one" ###
1167 type.vtabslot_cname = "%s.%s" % (
1168 Naming.obj_base_cname, type.base_type.vtabslot_cname)
1169 elif type.scope and type.scope.cfunc_entries:
1170 #print "...allocating vtabslot_cname because there are C methods" ###
1171 type.vtabslot_cname = Naming.vtabslot_cname
1172 if type.vtabslot_cname:
1173 #print "...allocating other vtable related cnames" ###
1174 type.vtabstruct_cname = self.mangle(Naming.vtabstruct_prefix, entry.name)
1175 type.vtabptr_cname = self.mangle(Naming.vtabptr_prefix, entry.name)
1177 def check_c_classes(self):
1178 # Performs post-analysis checking and finishing up of extension types
1179 # being implemented in this module. This is called only for the main
1180 # .pyx file scope, not for cimported .pxd scopes.
1182 # Checks all extension types declared in this scope to
1185 # * The extension type is implemented
1186 # * All required object and type names have been specified or generated
1187 # * All non-inherited C methods are implemented
1189 # Also allocates a name for the vtable if needed.
1191 debug_check_c_classes = 0
1192 if debug_check_c_classes:
1193 print("Scope.check_c_classes: checking scope " + self.qualified_name)
1194 for entry in self.c_class_entries:
1195 if debug_check_c_classes:
1196 print("...entry %s %s" % (entry.name, entry))
1197 print("......type = ", entry.type)
1198 print("......visibility = ", entry.visibility)
1201 visibility = entry.visibility
1204 error(entry.pos, "C class '%s' is declared but not defined" % name)
1205 # Generate typeobj_cname
1206 if visibility != 'extern' and not type.typeobj_cname:
1207 type.typeobj_cname = self.mangle(Naming.typeobj_prefix, name)
1208 ## Generate typeptr_cname
1209 #type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name)
1210 # Check C methods defined
1212 for method_entry in type.scope.cfunc_entries:
1213 if not method_entry.is_inherited and not method_entry.func_cname:
1214 error(method_entry.pos, "C method '%s' is declared but not defined" %
1216 # Allocate vtable name if necessary
1217 if type.vtabslot_cname:
1218 #print "ModuleScope.check_c_classes: allocating vtable cname for", self ###
1219 type.vtable_cname = self.mangle(Naming.vtable_prefix, entry.name)
1221 def check_c_functions(self):
1222 # Performs post-analysis checking making sure all
1223 # defined c functions are actually implemented.
1224 for name, entry in self.entries.items():
1225 if entry.is_cfunction:
1226 if (entry.defined_in_pxd
1227 and entry.scope is self
1228 and entry.visibility != 'extern'
1229 and not entry.in_cinclude
1230 and not entry.is_implemented):
1231 error(entry.pos, "Non-extern C function '%s' declared but not defined" % name)
1233 def attach_var_entry_to_c_class(self, entry):
1234 # The name of an extension class has to serve as both a type
1235 # name and a variable name holding the type object. It is
1236 # represented in the symbol table by a type entry with a
1237 # variable entry attached to it. For the variable entry,
1238 # we use a read-only C global variable whose name is an
1239 # expression that refers to the type object.
1241 var_entry = Entry(name = entry.name,
1242 type = Builtin.type_type,
1244 cname = "((PyObject*)%s)" % entry.type.typeptr_cname)
1245 var_entry.is_variable = 1
1246 var_entry.is_cglobal = 1
1247 var_entry.is_readonly = 1
1248 entry.as_variable = var_entry
1253 class LocalScope(Scope):
1255 def __init__(self, name, outer_scope):
1256 Scope.__init__(self, name, outer_scope, outer_scope)
1258 def mangle(self, prefix, name):
1259 return prefix + name
1261 def declare_arg(self, name, type, pos):
1262 # Add an entry for an argument of a function.
1263 cname = self.mangle(Naming.var_prefix, name)
1264 entry = self.declare(name, cname, type, pos, 'private')
1265 entry.is_variable = 1
1266 if type.is_pyobject:
1269 #entry.borrowed = 1 # Not using borrowed arg refs for now
1270 self.arg_entries.append(entry)
1271 self.control_flow.set_state((), (name, 'source'), 'arg')
1274 def declare_var(self, name, type, pos,
1275 cname = None, visibility = 'private', is_cdef = 0):
1276 # Add an entry for a local variable.
1277 if visibility in ('public', 'readonly'):
1278 error(pos, "Local variable cannot be declared %s" % visibility)
1279 entry = Scope.declare_var(self, name, type, pos,
1280 cname, visibility, is_cdef)
1281 if type.is_pyobject and not Options.init_local_none:
1283 entry.init_to_none = type.is_pyobject and Options.init_local_none
1285 self.var_entries.append(entry)
1288 def declare_global(self, name, pos):
1289 # Pull entry from global scope into local scope.
1290 if self.lookup_here(name):
1291 warning(pos, "'%s' redeclared ", 0)
1293 entry = self.global_scope().lookup_target(name)
1294 self.entries[name] = entry
1296 def lookup_from_inner(self, name):
1297 entry = self.lookup_here(name)
1299 entry.in_closure = 1
1302 return (self.outer_scope and self.outer_scope.lookup_from_inner(name)) or None
1304 def mangle_closure_cnames(self, scope_var):
1305 for entry in self.entries.values():
1306 if entry.in_closure:
1307 if not hasattr(entry, 'orig_cname'):
1308 entry.orig_cname = entry.cname
1309 entry.cname = scope_var + "->" + entry.cname
1312 class GeneratorLocalScope(LocalScope):
1314 temp_prefix = Naming.cur_scope_cname + "->" + LocalScope.temp_prefix
1316 def mangle_closure_cnames(self, scope_var):
1317 for entry in self.entries.values() + self.temp_entries:
1318 entry.in_closure = 1
1319 LocalScope.mangle_closure_cnames(self, scope_var)
1321 # def mangle(self, prefix, name):
1322 # return "%s->%s" % (Naming.scope_obj_cname, name)
1324 class StructOrUnionScope(Scope):
1325 # Namespace of a C struct or union.
1327 def __init__(self, name="?"):
1328 Scope.__init__(self, name, None, None)
1330 def declare_var(self, name, type, pos,
1331 cname = None, visibility = 'private', is_cdef = 0, allow_pyobject = 0):
1332 # Add an entry for an attribute.
1335 if visibility == 'private':
1336 cname = c_safe_identifier(cname)
1337 if type.is_cfunction:
1338 type = PyrexTypes.CPtrType(type)
1339 entry = self.declare(name, cname, type, pos, visibility)
1340 entry.is_variable = 1
1341 self.var_entries.append(entry)
1342 if type.is_pyobject and not allow_pyobject:
1344 "C struct/union member cannot be a Python object")
1345 if visibility != 'private':
1347 "C struct/union member cannot be declared %s" % visibility)
1350 def declare_cfunction(self, name, type, pos,
1351 cname = None, visibility = 'private', defining = 0,
1352 api = 0, in_pxd = 0, modifiers = ()):
1353 self.declare_var(name, type, pos, cname, visibility)
1355 class ClassScope(Scope):
1356 # Abstract base class for namespace of
1357 # Python class or extension type.
1359 # class_name string Pyrex name of the class
1360 # scope_prefix string Additional prefix for names
1361 # declared in the class
1362 # doc string or None Doc string
1364 def __init__(self, name, outer_scope):
1365 Scope.__init__(self, name, outer_scope, outer_scope)
1366 self.class_name = name
1369 def add_string_const(self, value, identifier = False):
1370 return self.outer_scope.add_string_const(value, identifier)
1372 def lookup(self, name):
1373 if name == "classmethod":
1374 # We don't want to use the builtin classmethod here 'cause it won't do the
1375 # right thing in this scope (as the class memebers aren't still functions).
1376 # Don't want to add a cfunction to this scope 'cause that would mess with
1377 # the type definition, so we just return the right entry.
1378 self.use_utility_code(classmethod_utility_code)
1381 "__Pyx_Method_ClassMethod",
1382 PyrexTypes.CFuncType(
1384 [PyrexTypes.CFuncTypeArg("", py_object_type, None)], 0, 0))
1385 entry.is_cfunction = 1
1388 return Scope.lookup(self, name)
1391 class PyClassScope(ClassScope):
1392 # Namespace of a Python class.
1394 # class_dict_cname string C variable holding class dict
1395 # class_obj_cname string C variable holding class object
1397 is_py_class_scope = 1
1399 def declare_var(self, name, type, pos,
1400 cname = None, visibility = 'private', is_cdef = 0):
1401 # Add an entry for a class attribute.
1402 entry = Scope.declare_var(self, name, type, pos,
1403 cname, visibility, is_cdef)
1404 entry.is_pyglobal = 1
1407 def allocate_temp(self, type):
1408 return self.outer_scope.allocate_temp(type)
1410 def release_temp(self, cname):
1411 self.outer_scope.release_temp(cname)
1413 #def recycle_pending_temps(self):
1414 # self.outer_scope.recycle_pending_temps()
1416 def add_default_value(self, type):
1417 return self.outer_scope.add_default_value(type)
1420 class CClassScope(ClassScope):
1421 # Namespace of an extension type.
1423 # parent_type CClassType
1424 # #typeobj_cname string or None
1425 # #objstruct_cname string
1426 # method_table_cname string
1427 # member_table_cname string
1428 # getset_table_cname string
1429 # has_pyobject_attrs boolean Any PyObject attributes?
1430 # public_attr_entries boolean public/readonly attrs
1431 # property_entries [Entry]
1432 # defined boolean Defined in .pxd file
1433 # implemented boolean Defined in .pyx file
1434 # inherited_var_entries [Entry] Adapted var entries from base class
1436 is_c_class_scope = 1
1438 def __init__(self, name, outer_scope, visibility):
1439 ClassScope.__init__(self, name, outer_scope)
1440 if visibility != 'extern':
1441 self.method_table_cname = outer_scope.mangle(Naming.methtab_prefix, name)
1442 self.member_table_cname = outer_scope.mangle(Naming.memtab_prefix, name)
1443 self.getset_table_cname = outer_scope.mangle(Naming.gstab_prefix, name)
1444 self.has_pyobject_attrs = 0
1445 self.public_attr_entries = []
1446 self.property_entries = []
1447 self.inherited_var_entries = []
1449 self.implemented = 0
1452 # If the type or any of its base types have Python-valued
1453 # C attributes, then it needs to participate in GC.
1454 return self.has_pyobject_attrs or \
1455 (self.parent_type.base_type and \
1456 self.parent_type.base_type.scope.needs_gc())
1458 def declare_var(self, name, type, pos,
1459 cname = None, visibility = 'private', is_cdef = 0):
1461 # Add an entry for an attribute.
1464 "C attributes cannot be added in implementation part of"
1466 if get_special_method_signature(name):
1468 "The name '%s' is reserved for a special method."
1472 if visibility == 'private':
1473 cname = c_safe_identifier(cname)
1474 entry = self.declare(name, cname, type, pos, visibility)
1475 entry.is_variable = 1
1476 self.var_entries.append(entry)
1477 if type.is_pyobject:
1478 self.has_pyobject_attrs = 1
1479 if visibility not in ('private', 'public', 'readonly'):
1481 "Attribute of extension type cannot be declared %s" % visibility)
1482 if visibility in ('public', 'readonly'):
1483 if type.pymemberdef_typecode:
1484 self.public_attr_entries.append(entry)
1485 if name == "__weakref__":
1486 error(pos, "Special attribute __weakref__ cannot be exposed to Python")
1489 "C attribute of type '%s' cannot be accessed from Python" % type)
1490 if visibility == 'public' and type.is_extension_type:
1492 "Non-generic Python attribute cannot be exposed for writing from Python")
1495 # Add an entry for a class attribute.
1496 entry = Scope.declare_var(self, name, type, pos,
1497 cname, visibility, is_cdef)
1499 entry.is_pyglobal = 1 # xxx: is_pyglobal changes behaviour in so many places that
1500 # I keep it in for now. is_member should be enough
1502 self.namespace_cname = "(PyObject *)%s" % self.parent_type.typeptr_cname
1503 entry.interned_cname = self.intern_identifier(name)
1507 def declare_pyfunction(self, name, pos):
1508 # Add an entry for a method.
1509 if name in ('__eq__', '__ne__', '__lt__', '__gt__', '__le__', '__ge__'):
1510 error(pos, "Special method %s must be implemented via __richcmp__" % name)
1511 if name == "__new__":
1512 warning(pos, "__new__ method of extension type will change semantics "
1513 "in a future version of Pyrex and Cython. Use __cinit__ instead.")
1514 name = EncodedString("__cinit__")
1515 entry = self.declare_var(name, py_object_type, pos, visibility='extern')
1516 special_sig = get_special_method_signature(name)
1518 # Special methods get put in the method table with a particular
1519 # signature declared in advance.
1520 entry.signature = special_sig
1521 entry.is_special = 1
1523 entry.signature = pymethod_signature
1524 entry.is_special = 0
1526 self.pyfunc_entries.append(entry)
1529 def lookup_here(self, name):
1530 if name == "__new__":
1531 name = EncodedString("__cinit__")
1532 return ClassScope.lookup_here(self, name)
1534 def declare_cfunction(self, name, type, pos,
1535 cname = None, visibility = 'private',
1536 defining = 0, api = 0, in_pxd = 0, modifiers = ()):
1537 if get_special_method_signature(name):
1538 error(pos, "Special methods must be declared with 'def', not 'cdef'")
1541 error(pos, "C method has no self argument")
1542 elif not args[0].type.same_as(self.parent_type):
1543 error(pos, "Self argument (%s) of C method '%s' does not match parent type (%s)" %
1544 (args[0].type, name, self.parent_type))
1545 entry = self.lookup_here(name)
1547 if not entry.is_cfunction:
1548 warning(pos, "'%s' redeclared " % name, 0)
1550 if defining and entry.func_cname:
1551 error(pos, "'%s' already defined" % name)
1552 #print "CClassScope.declare_cfunction: checking signature" ###
1553 if type.same_c_signature_as(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil:
1555 elif type.compatible_signature_with(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil:
1556 entry = self.add_cfunction(name, type, pos, cname or name, visibility='ignore', modifiers=modifiers)
1559 error(pos, "Signature not compatible with previous declaration")
1560 error(entry.pos, "Previous declaration is here")
1564 "C method '%s' not previously declared in definition part of"
1565 " extension type" % name)
1566 entry = self.add_cfunction(name, type, pos, cname or name,
1567 visibility, modifiers)
1569 entry.func_cname = self.mangle(Naming.func_prefix, name)
1572 def add_cfunction(self, name, type, pos, cname, visibility, modifiers):
1573 # Add a cfunction entry without giving it a func_cname.
1574 prev_entry = self.lookup_here(name)
1575 entry = ClassScope.add_cfunction(self, name, type, pos, cname,
1576 visibility, modifiers)
1577 entry.is_cmethod = 1
1578 entry.prev_entry = prev_entry
1581 def declare_property(self, name, doc, pos):
1582 entry = self.lookup_here(name)
1584 entry = self.declare(name, name, py_object_type, pos, 'private')
1585 entry.is_property = 1
1587 entry.scope = PropertyScope(name,
1588 outer_scope = self.global_scope(), parent_scope = self)
1589 entry.scope.parent_type = self.parent_type
1590 self.property_entries.append(entry)
1593 def declare_inherited_c_attributes(self, base_scope):
1594 # Declare entries for all the C attributes of an
1595 # inherited type, with cnames modified appropriately
1596 # to work with this type.
1598 return "%s.%s" % (Naming.obj_base_cname, base_entry.cname)
1600 base_scope.inherited_var_entries + base_scope.var_entries:
1601 entry = self.declare(base_entry.name, adapt(base_entry.cname),
1602 base_entry.type, None, 'private')
1603 entry.is_variable = 1
1604 self.inherited_var_entries.append(entry)
1605 for base_entry in base_scope.cfunc_entries:
1606 entry = self.add_cfunction(base_entry.name, base_entry.type,
1607 base_entry.pos, adapt(base_entry.cname),
1608 base_entry.visibility, base_entry.func_modifiers)
1609 entry.is_inherited = 1
1611 def allocate_temp(self, type):
1612 return Scope.allocate_temp(self.global_scope(), type)
1614 def release_temp(self, cname):
1615 return Scope.release_temp(self.global_scope(), cname)
1618 class CppClassScope(Scope):
1619 # Namespace of a C++ class.
1620 inherited_var_entries = []
1622 def __init__(self, name, outer_scope):
1623 Scope.__init__(self, name, outer_scope, None)
1624 self.directives = outer_scope.directives
1626 def declare_var(self, name, type, pos,
1627 cname = None, visibility = 'extern', is_cdef = 0, allow_pyobject = 0):
1628 # Add an entry for an attribute.
1631 if type.is_cfunction:
1632 type = PyrexTypes.CPtrType(type)
1633 entry = self.declare(name, cname, type, pos, visibility)
1634 entry.is_variable = 1
1635 self.var_entries.append(entry)
1636 if type.is_pyobject and not allow_pyobject:
1638 "C++ class member cannot be a Python object")
1641 def declare_cfunction(self, name, type, pos,
1642 cname = None, visibility = 'extern', defining = 0,
1643 api = 0, in_pxd = 0, modifiers = ()):
1644 if name == self.name.split('::')[-1] and cname is None:
1646 entry = self.declare_var(name, type, pos, cname, visibility)
1648 def declare_inherited_cpp_attributes(self, base_scope):
1649 # Declare entries for all the C++ attributes of an
1650 # inherited type, with cnames modified appropriately
1651 # to work with this type.
1653 base_scope.inherited_var_entries + base_scope.var_entries:
1654 entry = self.declare(base_entry.name, base_entry.cname,
1655 base_entry.type, None, 'extern')
1656 entry.is_variable = 1
1657 self.inherited_var_entries.append(entry)
1658 for base_entry in base_scope.cfunc_entries:
1659 entry = self.declare_cfunction(base_entry.name, base_entry.type,
1660 base_entry.pos, base_entry.cname,
1661 base_entry.visibility, base_entry.func_modifiers)
1662 entry.is_inherited = 1
1664 def specialize(self, values):
1665 scope = CppClassScope(self.name, self.outer_scope)
1666 for entry in self.entries.values():
1667 scope.declare_var(entry.name,
1668 entry.type.specialize(values),
1675 class PropertyScope(Scope):
1676 # Scope holding the __get__, __set__ and __del__ methods for
1677 # a property of an extension type.
1679 # parent_type PyExtensionType The type to which the property belongs
1681 def declare_pyfunction(self, name, pos):
1682 # Add an entry for a method.
1683 signature = get_property_accessor_signature(name)
1685 entry = self.declare(name, name, py_object_type, pos, 'private')
1686 entry.is_special = 1
1687 entry.signature = signature
1690 error(pos, "Only __get__, __set__ and __del__ methods allowed "
1691 "in a property declaration")
1695 # Should this go elsewhere (and then get imported)?
1696 #------------------------------------------------------------------------------------
1698 classmethod_utility_code = Utils.UtilityCode(
1700 #include "descrobject.h"
1701 static PyObject* __Pyx_Method_ClassMethod(PyObject *method); /*proto*/
1704 static PyObject* __Pyx_Method_ClassMethod(PyObject *method) {
1705 /* It appears that PyMethodDescr_Type is not anywhere exposed in the Python/C API */
1706 /* if (!PyObject_TypeCheck(method, &PyMethodDescr_Type)) { */
1707 if (__Pyx_StrEq(Py_TYPE(method)->tp_name, "method_descriptor")) { /* cdef classes */
1708 PyMethodDescrObject *descr = (PyMethodDescrObject *)method;
1709 return PyDescr_NewClassMethod(descr->d_type, descr->d_method);
1711 else if (PyMethod_Check(method)) { /* python classes */
1712 return PyClassMethod_New(PyMethod_GET_FUNCTION(method));
1714 else if (PyCFunction_Check(method)) {
1715 return PyClassMethod_New(method);
1717 PyErr_Format(PyExc_TypeError, "Class-level classmethod() can only be called on a method_descriptor or instance method.");
1722 #------------------------------------------------------------------------------------
1724 ERR_BUF_LOCALONLY = 'Buffer types only allowed as function local variables'