6 from Errors import warning, error, InternalError
10 from PyrexTypes import *
12 from TypeSlots import \
13 pyfunction_signature, pymethod_signature, \
14 get_special_method_signature, get_property_accessor_signature
17 identifier_pattern = re.compile(r"[A-Za-z_][A-Za-z0-9_]*$")
20 # A symbol table entry in a Scope or ModuleNamespace.
22 # name string Python name of entity
23 # cname string C name of entity
24 # type PyrexType Type of entity
25 # doc string Doc string
26 # init string Initial value
27 # visibility 'private' or 'public' or 'extern'
28 # is_builtin boolean Is an entry in the Python builtins dict
29 # is_cglobal boolean Is a C global variable
30 # is_pyglobal boolean Is a Python module-level variable
31 # or class attribute during
33 # is_member boolean Is an assigned class member
34 # is_variable boolean Is a variable
35 # is_cfunction boolean Is a C function
36 # is_cmethod boolean Is a C method of an extension type
37 # is_unbound_cmethod boolean Is an unbound C method of an extension type
38 # is_type boolean Is a type definition
39 # is_const boolean Is a constant
40 # is_property boolean Is a property of an extension type:
41 # doc_cname string or None C const holding the docstring
42 # getter_cname string C func for getting property
43 # setter_cname string C func for setting or deleting property
44 # is_self_arg boolean Is the "self" arg of an exttype method
45 # is_arg boolean Is the arg of a method
46 # is_readonly boolean Can't be assigned to
47 # func_cname string C func implementing Python func
48 # pos position Source position where declared
49 # namespace_cname string If is_pyglobal, the C variable
50 # holding its home namespace
51 # pymethdef_cname string PyMethodDef structure
52 # signature Signature Arg & return types for Python func
53 # init_to_none boolean True if initial value should be None
54 # as_variable Entry Alternative interpretation of extension
55 # type name or builtin C function as a variable
56 # xdecref_cleanup boolean Use Py_XDECREF for error cleanup
57 # in_cinclude boolean Suppress C declaration code
58 # enum_values [Entry] For enum types, list of values
59 # qualified_name string "modname.funcname" or "modname.classname"
60 # or "modname.classname.funcname"
61 # is_declared_generic boolean Is declared as PyObject * even though its
62 # type is an extension type
63 # as_module None Module scope, if a cimported module
64 # is_inherited boolean Is an inherited attribute of an extension type
65 # #interned_cname string C name of interned name string
66 # pystring_cname string C name of Python version of string literal
67 # is_interned boolean For string const entries, value is interned
69 # is_special boolean Is a special method or property accessor
70 # of an extension type
71 # defined_in_pxd boolean Is defined in a .pxd file (not just declared)
72 # api boolean Generate C API for C class or function
73 # utility_code string Utility code needed when this entry is used
77 visibility = 'private'
85 is_unbound_cmethod = 0
94 is_declared_generic = 0
104 #interned_cname = None
105 pystring_cname = None
114 def __init__(self, name, cname, type, pos = None, init = None):
123 # name string Unqualified name
124 # outer_scope Scope or None Enclosing scope
125 # entries {string : Entry} Python name to entry, non-types
126 # const_entries [Entry] Constant entries
127 # type_entries [Entry] Struct/union/enum/typedef/exttype entries
128 # sue_entries [Entry] Struct/union/enum entries
129 # arg_entries [Entry] Function argument entries
130 # var_entries [Entry] User-defined variable entries
131 # pyfunc_entries [Entry] Python function entries
132 # cfunc_entries [Entry] C function entries
133 # c_class_entries [Entry] All extension type entries
134 # temp_entries [Entry] Temporary variable entries
135 # free_temp_entries [Entry] Temp variables currently unused
136 # temp_counter integer Counter for naming temp vars
137 # cname_to_entry {string : Entry} Temp cname to entry mapping
138 # int_to_entry {int : Entry} Temp cname to entry mapping
139 # pow_function_used boolean The C pow() function is used
140 # return_type PyrexType or None Return type of function owning scope
141 # is_py_class_scope boolean Is a Python class scope
142 # is_c_class_scope boolean Is an extension type scope
143 # scope_prefix string Disambiguator for C names
144 # in_cinclude boolean Suppress C declaration code
145 # qualified_name string "modname" or "modname.classname"
146 # pystring_entries [Entry] String const entries newly used as
147 # Python strings in this scope
149 is_py_class_scope = 0
155 def __init__(self, name, outer_scope, parent_scope):
156 # The outer_scope is the next scope in the lookup chain.
157 # The parent_scope is used to derive the qualified name of this scope.
159 self.outer_scope = outer_scope
160 self.parent_scope = parent_scope
161 mangled_name = "%d%s_" % (len(name), name)
162 qual_scope = self.qualifying_scope()
164 self.qualified_name = qual_scope.qualify_name(name)
165 self.scope_prefix = qual_scope.scope_prefix + mangled_name
167 self.qualified_name = name
168 self.scope_prefix = mangled_name
170 self.const_entries = []
171 self.type_entries = []
172 self.sue_entries = []
173 self.arg_entries = []
174 self.var_entries = []
175 self.pyfunc_entries = []
176 self.cfunc_entries = []
177 self.c_class_entries = []
178 self.defined_c_classes = []
179 self.imported_c_classes = {}
180 self.temp_entries = []
181 self.free_temp_entries = []
182 #self.pending_temp_entries = [] # TEMPORARY
183 self.temp_counter = 1
184 self.cname_to_entry = {}
185 self.pow_function_used = 0
186 self.string_to_entry = {}
187 self.num_to_entry = {}
188 self.obj_to_entry = {}
189 self.pystring_entries = []
192 return "<%s %s>" % (self.__class__.__name__, self.qualified_name)
194 def intern(self, name):
195 return self.global_scope().intern(name)
197 def qualifying_scope(self):
198 return self.parent_scope
200 def mangle(self, prefix, name = None):
202 return "%s%s%s" % (prefix, self.scope_prefix, name)
204 return self.parent_scope.mangle(prefix, self.name)
206 def mangle_internal(self, name):
207 # Mangle an internal name so as not to clash with any
208 # user-defined name in this scope.
209 prefix = "%s%s_" % (Naming.pyrex_prefix, name)
210 return self.mangle(prefix)
211 #return self.parent_scope.mangle(prefix, self.name)
213 def global_scope(self):
214 # Return the module-level scope containing this scope.
215 return self.outer_scope.global_scope()
217 def builtin_scope(self):
218 # Return the module-level scope containing this scope.
219 return self.outer_scope.builtin_scope()
221 def declare(self, name, cname, type, pos):
222 # Create new entry, and add to dictionary if
223 # name is not None. Reports a warning if already
225 if not self.in_cinclude and cname and re.match("^_[_A-Z]+$", cname):
226 # See http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html#Reserved-Names
227 warning(pos, "'%s' is a reserved name in C." % cname, -1)
229 if name and dict.has_key(name):
230 warning(pos, "'%s' redeclared " % name, 0)
231 entry = Entry(name, cname, type, pos = pos)
232 entry.in_cinclude = self.in_cinclude
234 entry.qualified_name = self.qualify_name(name)
238 def qualify_name(self, name):
239 return "%s.%s" % (self.qualified_name, name)
241 def declare_const(self, name, type, value, pos, cname = None):
242 # Add an entry for a named constant.
247 cname = self.mangle(Naming.enum_prefix, name)
248 entry = self.declare(name, cname, type, pos)
253 def declare_type(self, name, type, pos,
254 cname = None, visibility = 'private', defining = 1):
255 # Add an entry for a type definition.
258 entry = self.declare(name, cname, type, pos)
259 entry.visibility = visibility
262 self.type_entries.append(entry)
265 def declare_typedef(self, name, base_type, pos, cname = None,
266 visibility = 'private'):
268 if self.in_cinclude or visibility == 'public':
271 cname = self.mangle(Naming.type_prefix, name)
272 type = PyrexTypes.CTypedefType(cname, base_type)
273 entry = self.declare_type(name, type, pos, cname, visibility)
274 type.qualified_name = entry.qualified_name
277 def declare_struct_or_union(self, name, kind, scope,
278 typedef_flag, pos, cname = None, visibility = 'private'):
279 # Add an entry for a struct or union definition.
281 if self.in_cinclude or visibility == 'public':
284 cname = self.mangle(Naming.type_prefix, name)
285 entry = self.lookup_here(name)
287 type = CStructOrUnionType(name, kind, scope, typedef_flag, cname)
288 entry = self.declare_type(name, type, pos, cname,
289 visibility = visibility, defining = scope is not None)
290 self.sue_entries.append(entry)
292 if not (entry.is_type and entry.type.is_struct_or_union):
293 warning(pos, "'%s' redeclared " % name, 0)
294 elif scope and entry.type.scope:
295 warning(pos, "'%s' already defined (ignoring second definition)" % name, 0)
297 self.check_previous_typedef_flag(entry, typedef_flag, pos)
298 self.check_previous_visibility(entry, visibility, pos)
300 entry.type.scope = scope
301 self.type_entries.append(entry)
302 if not scope and not entry.type.scope:
303 self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos)
306 def check_previous_typedef_flag(self, entry, typedef_flag, pos):
307 if typedef_flag <> entry.type.typedef_flag:
308 error(pos, "'%s' previously declared using '%s'" % (
309 entry.name, ("cdef", "ctypedef")[entry.type.typedef_flag]))
311 def check_previous_visibility(self, entry, visibility, pos):
312 if entry.visibility <> visibility:
313 error(pos, "'%s' previously declared as '%s'" % (
314 entry.name, entry.visibility))
316 def declare_enum(self, name, pos, cname, typedef_flag,
317 visibility = 'private'):
320 if self.in_cinclude or visibility == 'public':
323 cname = self.mangle(Naming.type_prefix, name)
324 type = CEnumType(name, cname, typedef_flag)
326 type = PyrexTypes.c_anon_enum_type
327 entry = self.declare_type(name, type, pos, cname = cname,
328 visibility = visibility)
329 entry.enum_values = []
330 self.sue_entries.append(entry)
333 def declare_var(self, name, type, pos,
334 cname = None, visibility = 'private', is_cdef = 0):
335 # Add an entry for a variable.
337 if visibility <> 'private':
340 cname = self.mangle(Naming.var_prefix, name)
341 entry = self.declare(name, cname, type, pos)
342 entry.is_variable = 1
343 entry.visibility = visibility
346 def declare_builtin(self, name, pos):
347 return self.outer_scope.declare_builtin(name, pos)
349 def declare_pyfunction(self, name, pos):
350 # Add an entry for a Python function.
351 entry = self.declare_var(name, py_object_type, pos)
352 entry.signature = pyfunction_signature
353 self.pyfunc_entries.append(entry)
356 def register_pyfunction(self, entry):
357 self.pyfunc_entries.append(entry)
359 def declare_cfunction(self, name, type, pos,
360 cname = None, visibility = 'private', defining = 0, api = 0, in_pxd = 0):
361 # Add an entry for a C function.
362 entry = self.lookup_here(name)
364 if visibility <> 'private' and visibility <> entry.visibility:
365 warning(pos, "Function '%s' previously declared as '%s'" % (name, entry.visibility), 1)
366 if not entry.type.same_as(type):
367 warning(pos, "Function signature does not match previous declaration", 1)
371 if api or visibility <> 'private':
374 cname = self.mangle(Naming.func_prefix, name)
375 entry = self.add_cfunction(name, type, pos, cname, visibility)
376 entry.func_cname = cname
377 if in_pxd and visibility <> 'extern':
378 entry.defined_in_pxd = 1
381 if not defining and not in_pxd and visibility <> 'extern':
382 error(pos, "Non-extern C function declared but not defined")
385 def add_cfunction(self, name, type, pos, cname, visibility):
386 # Add a C function entry without giving it a func_cname.
387 entry = self.declare(name, cname, type, pos)
388 entry.is_cfunction = 1
389 entry.visibility = visibility
390 self.cfunc_entries.append(entry)
393 def find(self, name, pos):
394 # Look up name, report error if not found.
395 entry = self.lookup(name)
399 error(pos, "'%s' is not declared" % name)
401 def lookup(self, name):
402 # Look up name in this scope or an enclosing one.
403 # Return None if not found.
404 return (self.lookup_here(name)
405 or (self.outer_scope and self.outer_scope.lookup(name))
408 def lookup_here(self, name):
409 # Look up in this scope only, return None if not found.
410 return self.entries.get(name, None)
412 def lookup_target(self, name):
413 # Look up name in this scope only. Declare as Python
414 # variable if not found.
415 entry = self.lookup_here(name)
417 entry = self.declare_var(name, py_object_type, None)
420 def add_string_const(self, value):
421 # Add an entry for a string constant.
422 cname = self.new_const_cname()
423 entry = Entry("", cname, c_char_array_type, init = value)
425 self.const_entries.append(entry)
428 def get_string_const(self, value):
429 # Get entry for string constant. Returns an existing
430 # one if possible, otherwise creates a new one.
431 genv = self.global_scope()
432 entry = genv.string_to_entry.get(value)
434 entry = self.add_string_const(value)
435 genv.string_to_entry[value] = entry
438 def add_py_string(self, entry):
439 # If not already done, allocate a C name for a Python version of
440 # a string literal, and add it to the list of Python strings to
441 # be created at module init time. If the string resembles a
442 # Python identifier, it will be interned.
443 if not entry.pystring_cname:
445 if identifier_pattern.match(value):
446 entry.pystring_cname = self.intern(value)
447 entry.is_interned = 1
449 entry.pystring_cname = entry.cname + "p"
450 self.pystring_entries.append(entry)
451 self.global_scope().all_pystring_entries.append(entry)
453 def add_py_num(self, value):
454 # Add an entry for an int constant.
455 cname = "%s%s" % (Naming.interned_num_prefix, value)
456 cname = cname.replace('-', 'neg_').replace('.','_')
457 entry = Entry("", cname, py_object_type, init = value)
459 entry.is_interned = 1
460 self.const_entries.append(entry)
461 self.interned_nums.append(entry)
464 def get_py_num(self, value):
465 # Get entry for int constant. Returns an existing
466 # one if possible, otherwise creates a new one.
467 genv = self.global_scope()
468 entry = genv.num_to_entry.get(value)
470 entry = genv.add_py_num(value)
471 genv.num_to_entry[value] = entry
472 genv.pynum_entries.append(entry)
475 def add_py_obj(self, obj, c_prefix=''):
477 cname = self.new_const_cname(c_prefix)
478 entry = Entry("", cname, py_object_type, init = value)
480 entry.is_interned = 1
481 self.const_entries.append(entry)
482 self.interned_objs.append(entry)
485 def get_py_obj(self, obj, c_prefix=''):
486 # Get entry for a generic constant. Returns an existing
487 # one if possible, otherwise creates a new one.
488 genv = self.global_scope()
489 entry = genv.obj_to_entry.get(obj)
491 entry = genv.add_py_num(obj, c_prefix)
492 genv.obj_to_entry[obj] = entry
496 def new_const_cname(self):
497 # Create a new globally-unique name for a constant.
498 return self.global_scope().new_const_cname()
500 def allocate_temp(self, type):
501 # Allocate a temporary variable of the given type from the
502 # free list if available, otherwise create a new one.
503 # Returns the cname of the variable.
504 for entry in self.free_temp_entries:
505 if entry.type == type:
506 self.free_temp_entries.remove(entry)
508 n = self.temp_counter
509 self.temp_counter = n + 1
510 cname = "%s%d" % (Naming.pyrex_prefix, n)
511 entry = Entry("", cname, type)
513 if type.is_pyobject or type == c_py_ssize_t_type:
515 self.cname_to_entry[entry.cname] = entry
516 self.temp_entries.append(entry)
519 def allocate_temp_pyobject(self):
520 # Allocate a temporary PyObject variable.
521 return self.allocate_temp(py_object_type)
523 def release_temp(self, cname):
524 # Release a temporary variable for re-use.
525 if not cname: # can happen when type of an expr is void
527 entry = self.cname_to_entry[cname]
528 if entry in self.free_temp_entries:
529 raise InternalError("Temporary variable %s released more than once"
531 self.free_temp_entries.append(entry)
533 def temps_in_use(self):
534 # Return a new list of temp entries currently in use.
535 return [entry for entry in self.temp_entries
536 if entry not in self.free_temp_entries]
538 #def recycle_pending_temps(self):
542 def use_utility_code(self, new_code):
543 self.global_scope().use_utility_code(new_code)
545 def generate_library_function_declarations(self, code):
546 # Generate extern decls for C library funcs used.
547 #if self.pow_function_used:
548 # code.putln("%s double pow(double, double);" % Naming.extern_c_macro)
551 def defines_any(self, names):
552 # Test whether any of the given names are
553 # defined in this scope.
555 if name in self.entries:
559 class PreImportScope(Scope):
561 Scope.__init__(self, Options.pre_import, None, None)
563 def declare_builtin(self, name, pos):
564 entry = self.declare(name, name, py_object_type, pos)
565 entry.is_variable = True
566 entry.is_pyglobal = True
567 entry.namespace_cname = Naming.preimport_cname
571 class BuiltinScope(Scope):
572 # The builtin namespace.
575 if Options.pre_import is None:
576 Scope.__init__(self, "__builtin__", None, None)
578 Scope.__init__(self, "__builtin__", PreImportScope(), None)
580 for name, definition in self.builtin_entries.iteritems():
581 cname, type = definition
582 self.declare_var(name, type, None, cname)
584 def declare_builtin(self, name, pos):
585 if not hasattr(__builtin__, name):
586 if self.outer_scope is not None:
587 return self.outer_scope.declare_builtin(name, pos)
589 error(pos, "undeclared name not builtin: %s"%name)
591 def declare_builtin_cfunction(self, name, type, cname, python_equiv = None,
592 utility_code = None):
593 # If python_equiv == "*", the Python equivalent has the same name
594 # as the entry, otherwise it has the name specified by python_equiv.
595 entry = self.declare_cfunction(name, type, None, cname)
596 entry.utility_code = utility_code
598 if python_equiv == "*":
600 var_entry = Entry(python_equiv, python_equiv, py_object_type)
601 var_entry.is_variable = 1
602 var_entry.is_builtin = 1
603 entry.as_variable = var_entry
606 def builtin_scope(self):
610 "int": ["((PyObject*)&PyInt_Type)", py_object_type],
611 "long": ["((PyObject*)&PyLong_Type)", py_object_type],
612 "float": ["((PyObject*)&PyFloat_Type)", py_object_type],
614 "str": ["((PyObject*)&PyString_Type)", py_object_type],
615 "unicode":["((PyObject*)&PyUnicode_Type)", py_object_type],
616 "tuple": ["((PyObject*)&PyTuple_Type)", py_object_type],
617 "list": ["((PyObject*)&PyList_Type)", py_object_type],
618 "dict": ["((PyObject*)&PyDict_Type)", py_object_type],
619 "set": ["((PyObject*)&PySet_Type)", py_object_type],
620 "frozenset": ["((PyObject*)&PyFrozenSet_Type)", py_object_type],
622 "type": ["((PyObject*)&PyType_Type)", py_object_type],
623 "slice": ["((PyObject*)&PySlice_Type)", py_object_type],
624 "file": ["((PyObject*)&PyFile_Type)", py_object_type],
626 "None": ["Py_None", py_object_type],
627 "False": ["Py_False", py_object_type],
628 "True": ["Py_True", py_object_type],
631 class ModuleScope(Scope):
632 # module_name string Python name of the module
633 # module_cname string C name of Python module object
634 # #module_dict_cname string C name of module dict object
635 # method_table_cname string C name of method table
636 # doc string Module doc string
637 # doc_cname string C name of module doc string
638 # const_counter integer Counter for naming constants
639 # utility_code_used [string] Utility code to be included
640 # default_entries [Entry] Function argument default entries
641 # python_include_files [string] Standard Python headers to be included
642 # include_files [string] Other C headers to be included
643 # string_to_entry {string : Entry} Map string const to entry
645 # parent_module Scope Parent in the import namespace
646 # module_entries {string : Entry} For cimport statements
647 # type_names {string : 1} Set of type names (used during parsing)
648 # pxd_file_loaded boolean Corresponding .pxd file has been processed
649 # cimported_modules [ModuleScope] Modules imported with cimport
650 # intern_map {string : string} Mapping from Python names to interned strs
651 # interned_names [string] Interned names pending generation of declarations
652 # interned_nums [int/long] Interned numeric constants
653 # all_pystring_entries [Entry] Python string consts from all scopes
654 # types_imported {PyrexType : 1} Set of types for which import code generated
658 def __init__(self, name, parent_module, context):
659 self.parent_module = parent_module
660 outer_scope = context.find_submodule("__builtin__")
661 Scope.__init__(self, name, outer_scope, parent_module)
662 self.module_name = name
663 self.context = context
664 self.module_cname = Naming.module_cname
665 self.module_dict_cname = Naming.moddict_cname
666 self.method_table_cname = Naming.methtable_cname
668 self.doc_cname = Naming.moddoc_cname
669 self.const_counter = 1
670 self.utility_code_used = []
671 self.default_entries = []
672 self.module_entries = {}
673 self.python_include_files = ["Python.h", "structmember.h"]
674 self.include_files = []
676 self.pxd_file_loaded = 0
677 self.cimported_modules = []
679 self.interned_names = []
680 self.interned_nums = []
681 self.interned_objs = []
682 self.all_pystring_entries = []
683 self.types_imported = {}
684 self.pynum_entries = []
685 self.has_extern_class = 0
686 self.cached_builtins = []
687 self.undeclared_cached_builtins = []
689 def qualifying_scope(self):
690 return self.parent_module
692 def global_scope(self):
695 def declare_builtin(self, name, pos):
696 if not hasattr(__builtin__, name):
697 if self.outer_scope is not None:
698 return self.outer_scope.declare_builtin(name, pos)
700 error(pos, "undeclared name not builtin: %s"%name)
701 if Options.cache_builtins:
702 for entry in self.cached_builtins:
703 if entry.name == name:
705 entry = self.declare(None, None, py_object_type, pos)
706 if Options.cache_builtins:
710 entry.cname = Naming.builtin_prefix + name
711 self.cached_builtins.append(entry)
712 self.undeclared_cached_builtins.append(entry)
717 def intern(self, name):
718 intern_map = self.intern_map
719 cname = intern_map.get(name)
721 cname = Naming.interned_prefix + name
722 intern_map[name] = cname
723 self.interned_names.append(name)
726 def find_module(self, module_name, pos):
727 # Find a module in the import namespace, interpreting
728 # relative imports relative to this module's parent.
729 # Finds and parses the module's .pxd file if the module
730 # has not been referenced before.
731 return self.global_scope().context.find_module(
732 module_name, relative_to = self.parent_module, pos = pos)
734 def find_submodule(self, name):
735 # Find and return scope for a submodule of this module,
736 # creating a new empty one if necessary. Doesn't parse .pxd.
737 scope = self.lookup_submodule(name)
739 scope = ModuleScope(name,
740 parent_module = self, context = self.context)
741 self.module_entries[name] = scope
744 def lookup_submodule(self, name):
745 # Return scope for submodule of this module, or None.
746 return self.module_entries.get(name, None)
748 def add_include_file(self, filename):
749 if filename not in self.python_include_files \
750 and filename not in self.include_files:
751 self.include_files.append(filename)
753 def add_imported_module(self, scope):
754 if scope not in self.cimported_modules:
755 self.cimported_modules.append(scope)
757 def add_imported_entry(self, name, entry, pos):
758 if entry not in self.entries:
759 self.entries[name] = entry
761 warning(pos, "'%s' redeclared " % name, 0)
763 def declare_module(self, name, scope, pos):
764 # Declare a cimported module. This is represented as a
765 # Python module-level variable entry with a module
766 # scope attached to it. Reports an error and returns
767 # None if previously declared as something else.
768 entry = self.lookup_here(name)
770 if entry.is_pyglobal and entry.as_module is scope:
771 return entry # Already declared as the same module
772 if not (entry.is_pyglobal and not entry.as_module):
773 # SAGE -- I put this here so Pyrex
774 # cimport's work across directories.
775 # Currently it tries to multiply define
776 # every module appearing in an import list.
777 # It shouldn't be an error for a module
778 # name to appear again, and indeed the generated
779 # code compiles fine.
781 warning(pos, "'%s' redeclared " % name, 0)
784 entry = self.declare_var(name, py_object_type, pos)
785 entry.as_module = scope
786 self.cimported_modules.append(scope)
789 def declare_var(self, name, type, pos,
790 cname = None, visibility = 'private', is_cdef = 0):
791 # Add an entry for a global variable. If it is a Python
792 # object type, and not declared with cdef, it will live
793 # in the module dictionary, otherwise it will be a C
795 entry = Scope.declare_var(self, name, type, pos,
796 cname, visibility, is_cdef)
797 if not visibility in ('private', 'public', 'extern'):
798 error(pos, "Module-level variable cannot be declared %s" % visibility)
800 if not (type.is_pyobject and not type.is_extension_type):
802 "Non-cdef global variable is not a generic Python object")
803 entry.is_pyglobal = 1
804 entry.namespace_cname = self.module_cname
805 #if Options.intern_names:
806 # entry.interned_cname = self.intern(name)
809 self.var_entries.append(entry)
812 def declare_global(self, name, pos):
813 entry = self.lookup_here(name)
815 self.declare_var(name, py_object_type, pos)
817 def add_default_value(self, type):
818 # Add an entry for holding a function argument
820 cname = self.new_const_cname()
821 entry = Entry("", cname, type)
822 self.default_entries.append(entry)
825 def new_const_cname(self, prefix=''):
826 # Create a new globally-unique name for a constant.
827 n = self.const_counter
828 self.const_counter = n + 1
829 return "%s%s_%d" % (Naming.const_prefix, prefix, n)
831 def use_utility_code(self, new_code):
832 # Add string to list of utility code to be included,
833 # if not already there (tested using 'is').
834 for old_code in self.utility_code_used:
835 if old_code is new_code:
837 self.utility_code_used.append(new_code)
839 def declare_c_class(self, name, pos, defining, implementing,
840 module_name, base_type, objstruct_cname, typeobj_cname,
841 visibility, typedef_flag, api):
843 # Look for previous declaration as a type
845 entry = self.lookup_here(name)
848 if not (entry.is_type and type.is_extension_type):
849 entry = None # Will cause an error when we redeclare it
851 self.check_previous_typedef_flag(entry, typedef_flag, pos)
852 if base_type <> type.base_type:
853 error(pos, "Base type does not match previous declaration")
855 # Make a new entry if needed
858 type = PyExtensionType(name, typedef_flag, base_type)
860 if visibility == 'extern':
861 type.module_name = module_name
863 type.module_name = self.qualified_name
864 type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name)
865 entry = self.declare_type(name, type, pos, visibility = visibility,
868 type.objstruct_cname = objstruct_cname
869 elif not entry.in_cinclude:
870 type.objstruct_cname = self.mangle(Naming.objstruct_prefix, name)
873 "Object name required for 'public' or 'extern' C class")
874 self.attach_var_entry_to_c_class(entry)
875 self.c_class_entries.append(entry)
877 # Check for re-definition and create scope if needed
880 if defining or implementing:
881 scope = CClassScope(name = name, outer_scope = self,
882 visibility = visibility)
884 scope.declare_inherited_c_attributes(base_type.scope)
885 type.set_scope(scope)
886 self.type_entries.append(entry)
888 self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos)
890 if defining and type.scope.defined:
891 error(pos, "C class '%s' already defined" % name)
892 elif implementing and type.scope.implemented:
893 error(pos, "C class '%s' already implemented" % name)
895 # Fill in options, checking for compatibility with any previous declaration
898 entry.defined_in_pxd = 1
899 if implementing: # So that filenames in runtime exceptions refer to
900 entry.pos = pos # the .pyx file and not the .pxd file
901 if visibility <> 'private' and entry.visibility <> visibility:
902 error(pos, "Class '%s' previously declared as '%s'"
903 % (name, entry.visibility))
907 if type.objstruct_cname and type.objstruct_cname <> objstruct_cname:
908 error(pos, "Object struct name differs from previous declaration")
909 type.objstruct_cname = objstruct_cname
911 if type.typeobj_cname and type.typeobj_cname <> typeobj_cname:
912 error(pos, "Type object name differs from previous declaration")
913 type.typeobj_cname = typeobj_cname
915 # Return new or existing entry
919 def check_for_illegal_incomplete_ctypedef(self, typedef_flag, pos):
920 if typedef_flag and not self.in_cinclude:
921 error(pos, "Forward-referenced type must use 'cdef', not 'ctypedef'")
923 def allocate_vtable_names(self, entry):
924 # If extension type has a vtable, allocate vtable struct and
927 if type.base_type and type.base_type.vtabslot_cname:
928 #print "...allocating vtabslot_cname because base type has one" ###
929 type.vtabslot_cname = "%s.%s" % (
930 Naming.obj_base_cname, type.base_type.vtabslot_cname)
931 elif type.scope and type.scope.cfunc_entries:
932 #print "...allocating vtabslot_cname because there are C methods" ###
933 type.vtabslot_cname = Naming.vtabslot_cname
934 if type.vtabslot_cname:
935 #print "...allocating other vtable related cnames" ###
936 type.vtabstruct_cname = self.mangle(Naming.vtabstruct_prefix, entry.name)
937 type.vtabptr_cname = self.mangle(Naming.vtabptr_prefix, entry.name)
939 def check_c_classes(self):
940 # Performs post-analysis checking and finishing up of extension types
941 # being implemented in this module. This is called only for the main
942 # .pyx file scope, not for cimported .pxd scopes.
944 # Checks all extension types declared in this scope to
947 # * The extension type is implemented
948 # * All required object and type names have been specified or generated
949 # * All non-inherited C methods are implemented
951 # Also allocates a name for the vtable if needed.
953 debug_check_c_classes = 0
954 if debug_check_c_classes:
955 print "Scope.check_c_classes: checking scope", self.qualified_name
956 for entry in self.c_class_entries:
957 if debug_check_c_classes:
958 print "...entry", entry.name, entry
959 print "......type =", entry.type
960 print "......visibility =", entry.visibility
963 visibility = entry.visibility
966 error(entry.pos, "C class '%s' is declared but not defined" % name)
967 # Generate typeobj_cname
968 if visibility <> 'extern' and not type.typeobj_cname:
969 type.typeobj_cname = self.mangle(Naming.typeobj_prefix, name)
970 ## Generate typeptr_cname
971 #type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name)
972 # Check C methods defined
974 for method_entry in type.scope.cfunc_entries:
975 if not method_entry.is_inherited and not method_entry.func_cname:
976 error(method_entry.pos, "C method '%s' is declared but not defined" %
978 # Allocate vtable name if necessary
979 if type.vtabslot_cname:
980 #print "ModuleScope.check_c_classes: allocating vtable cname for", self ###
981 type.vtable_cname = self.mangle(Naming.vtable_prefix, entry.name)
983 def attach_var_entry_to_c_class(self, entry):
984 # The name of an extension class has to serve as both a type
985 # name and a variable name holding the type object. It is
986 # represented in the symbol table by a type entry with a
987 # variable entry attached to it. For the variable entry,
988 # we use a read-only C global variable whose name is an
989 # expression that refers to the type object.
990 var_entry = Entry(name = entry.name,
991 type = py_object_type,
993 cname = "((PyObject*)%s)" % entry.type.typeptr_cname)
994 var_entry.is_variable = 1
995 var_entry.is_cglobal = 1
996 var_entry.is_readonly = 1
997 entry.as_variable = var_entry
1000 class LocalScope(Scope):
1002 def __init__(self, name, outer_scope):
1003 Scope.__init__(self, name, outer_scope, outer_scope)
1005 def mangle(self, prefix, name):
1006 return prefix + name
1008 def declare_arg(self, name, type, pos):
1009 # Add an entry for an argument of a function.
1010 cname = self.mangle(Naming.var_prefix, name)
1011 entry = self.declare(name, cname, type, pos)
1012 entry.is_variable = 1
1013 if type.is_pyobject:
1016 #entry.borrowed = 1 # Not using borrowed arg refs for now
1017 self.arg_entries.append(entry)
1020 def declare_var(self, name, type, pos,
1021 cname = None, visibility = 'private', is_cdef = 0):
1022 # Add an entry for a local variable.
1023 if visibility in ('public', 'readonly'):
1024 error(pos, "Local variable cannot be declared %s" % visibility)
1025 entry = Scope.declare_var(self, name, type, pos,
1026 cname, visibility, is_cdef)
1027 entry.init_to_none = type.is_pyobject
1028 self.var_entries.append(entry)
1031 def declare_global(self, name, pos):
1032 # Pull entry from global scope into local scope.
1033 if self.lookup_here(name):
1034 warning(pos, "'%s' redeclared ", 0)
1036 entry = self.global_scope().lookup_target(name)
1037 self.entries[name] = entry
1040 class StructOrUnionScope(Scope):
1041 # Namespace of a C struct or union.
1044 Scope.__init__(self, "?", None, None)
1046 def declare_var(self, name, type, pos,
1047 cname = None, visibility = 'private', is_cdef = 0, allow_pyobject = 0):
1048 # Add an entry for an attribute.
1051 entry = self.declare(name, cname, type, pos)
1052 entry.is_variable = 1
1053 self.var_entries.append(entry)
1054 if type.is_pyobject and not allow_pyobject:
1056 "C struct/union member cannot be a Python object")
1057 if visibility <> 'private':
1059 "C struct/union member cannot be declared %s" % visibility)
1062 def declare_cfunction(self, name, type, pos,
1063 cname = None, visibility = 'private', defining = 0, api = 0, in_pxd = 0):
1064 self.declare_var(name, type, pos, cname, visibility)
1066 class ClassScope(Scope):
1067 # Abstract base class for namespace of
1068 # Python class or extension type.
1070 # class_name string Pyrex name of the class
1071 # scope_prefix string Additional prefix for names
1072 # declared in the class
1073 # doc string or None Doc string
1075 def __init__(self, name, outer_scope):
1076 Scope.__init__(self, name, outer_scope, outer_scope)
1077 self.class_name = name
1080 def add_string_const(self, value):
1081 return self.outer_scope.add_string_const(value)
1083 def lookup(self, name):
1084 if name == "classmethod":
1085 # We don't want to use the builtin classmethod here 'cause it won't do the
1086 # right thing in this scope (as the class memebers aren't still functions).
1087 # Don't want to add a cfunction to this scope 'cause that would mess with
1088 # the type definition, so we just return the right entry.
1089 self.use_utility_code(classmethod_utility_code)
1090 entry = Entry("classmethod",
1091 "__Pyx_Method_ClassMethod",
1092 CFuncType(py_object_type, [CFuncTypeArg("", py_object_type, None)], 0, 0))
1093 entry.is_cfunction = 1
1096 return Scope.lookup(self, name)
1099 class PyClassScope(ClassScope):
1100 # Namespace of a Python class.
1102 # class_dict_cname string C variable holding class dict
1103 # class_obj_cname string C variable holding class object
1105 is_py_class_scope = 1
1107 def declare_var(self, name, type, pos,
1108 cname = None, visibility = 'private', is_cdef = 0):
1109 # Add an entry for a class attribute.
1110 entry = Scope.declare_var(self, name, type, pos,
1111 cname, visibility, is_cdef)
1112 entry.is_pyglobal = 1
1113 entry.namespace_cname = self.class_obj_cname
1114 #if Options.intern_names:
1115 # entry.interned_cname = self.intern(name)
1118 def allocate_temp(self, type):
1119 return self.outer_scope.allocate_temp(type)
1121 def release_temp(self, cname):
1122 self.outer_scope.release_temp(cname)
1124 #def recycle_pending_temps(self):
1125 # self.outer_scope.recycle_pending_temps()
1127 def add_default_value(self, type):
1128 return self.outer_scope.add_default_value(type)
1131 class CClassScope(ClassScope):
1132 # Namespace of an extension type.
1134 # parent_type CClassType
1135 # #typeobj_cname string or None
1136 # #objstruct_cname string
1137 # method_table_cname string
1138 # member_table_cname string
1139 # getset_table_cname string
1140 # has_pyobject_attrs boolean Any PyObject attributes?
1141 # public_attr_entries boolean public/readonly attrs
1142 # property_entries [Entry]
1143 # defined boolean Defined in .pxd file
1144 # implemented boolean Defined in .pyx file
1145 # inherited_var_entries [Entry] Adapted var entries from base class
1147 is_c_class_scope = 1
1149 def __init__(self, name, outer_scope, visibility):
1150 ClassScope.__init__(self, name, outer_scope)
1151 if visibility <> 'extern':
1152 self.method_table_cname = outer_scope.mangle(Naming.methtab_prefix, name)
1153 self.member_table_cname = outer_scope.mangle(Naming.memtab_prefix, name)
1154 self.getset_table_cname = outer_scope.mangle(Naming.gstab_prefix, name)
1155 self.has_pyobject_attrs = 0
1156 self.public_attr_entries = []
1157 self.property_entries = []
1158 self.inherited_var_entries = []
1160 self.implemented = 0
1163 # If the type or any of its base types have Python-valued
1164 # C attributes, then it needs to participate in GC.
1165 return self.has_pyobject_attrs or \
1166 (self.parent_type.base_type and \
1167 self.parent_type.base_type.scope.needs_gc())
1169 def declare_var(self, name, type, pos,
1170 cname = None, visibility = 'private', is_cdef = 0):
1172 # Add an entry for an attribute.
1175 "C attributes cannot be added in implementation part of"
1177 if get_special_method_signature(name):
1179 "The name '%s' is reserved for a special method."
1183 entry = self.declare(name, cname, type, pos)
1184 entry.visibility = visibility
1185 entry.is_variable = 1
1186 self.var_entries.append(entry)
1187 if type.is_pyobject:
1188 self.has_pyobject_attrs = 1
1189 if visibility not in ('private', 'public', 'readonly'):
1191 "Attribute of extension type cannot be declared %s" % visibility)
1192 if visibility in ('public', 'readonly'):
1193 if type.pymemberdef_typecode:
1194 self.public_attr_entries.append(entry)
1195 if name == "__weakref__":
1196 error(pos, "Special attribute __weakref__ cannot be exposed to Python")
1199 "C attribute of type '%s' cannot be accessed from Python" % type)
1200 if visibility == 'public' and type.is_extension_type:
1202 "Non-generic Python attribute cannot be exposed for writing from Python")
1205 # Add an entry for a class attribute.
1206 entry = Scope.declare_var(self, name, type, pos,
1207 cname, visibility, is_cdef)
1209 entry.is_pyglobal = 1 # xxx: is_pyglobal changes behaviour in so many places that
1210 # I keep it in for now. is_member should be enough
1212 entry.namespace_cname = "(PyObject *)%s" % self.parent_type.typeptr_cname
1213 if Options.intern_names:
1214 entry.interned_cname = self.intern(name)
1218 def declare_pyfunction(self, name, pos):
1219 # Add an entry for a method.
1220 if name in ('__eq__', '__ne__', '__lt__', '__gt__', '__le__', '__ge__'):
1221 error(pos, "Special method %s must be implemented via __richcmp__" % name)
1222 if name == "__new__":
1223 warning(pos, "__new__ method of extension type will change semantics "
1224 "in a future version of Pyrex and Cython. Use __cinit__ instead.")
1226 entry = self.declare_var(name, py_object_type, pos)
1227 special_sig = get_special_method_signature(name)
1229 # Special methods get put in the method table with a particular
1230 # signature declared in advance.
1231 entry.signature = special_sig
1232 entry.is_special = 1
1234 entry.signature = pymethod_signature
1235 entry.is_special = 0
1237 self.pyfunc_entries.append(entry)
1240 def lookup_here(self, name):
1241 if name == "__new__":
1243 return ClassScope.lookup_here(self, name)
1245 def declare_cfunction(self, name, type, pos,
1246 cname = None, visibility = 'private', defining = 0, api = 0, in_pxd = 0):
1247 if get_special_method_signature(name):
1248 error(pos, "Special methods must be declared with 'def', not 'cdef'")
1251 error(pos, "C method has no self argument")
1252 elif not args[0].type.same_as(self.parent_type):
1253 error(pos, "Self argument of C method does not match parent type")
1254 entry = self.lookup_here(name)
1256 if not entry.is_cfunction:
1257 warning(pos, "'%s' redeclared " % name, 0)
1259 if defining and entry.func_cname:
1260 error(pos, "'%s' already defined" % name)
1261 #print "CClassScope.declare_cfunction: checking signature" ###
1262 if type.same_c_signature_as(entry.type, as_cmethod = 1):
1264 elif type.compatible_signature_with(entry.type, as_cmethod = 1):
1265 if type.optional_arg_count and not type.original_sig.optional_arg_count:
1266 # Need to put a wrapper taking no optional arguments
1267 # into the method table.
1268 wrapper_func_cname = self.mangle(Naming.func_prefix, name) + Naming.no_opt_args
1269 wrapper_func_name = name + Naming.no_opt_args
1270 if entry.type.optional_arg_count:
1271 old_entry = self.lookup_here(wrapper_func_name)
1272 old_entry.func_cname = wrapper_func_cname
1274 entry.func_cname = wrapper_func_cname
1275 entry.name = wrapper_func_name
1276 entry = self.add_cfunction(name, type, pos, cname or name, visibility)
1279 # if type.narrower_c_signature_than(entry.type, as_cmethod = 1):
1282 error(pos, "Signature not compatible with previous declaration")
1286 "C method '%s' not previously declared in definition part of"
1287 " extension type" % name)
1288 entry = self.add_cfunction(name, type, pos, cname or name, visibility)
1290 entry.func_cname = self.mangle(Naming.func_prefix, name)
1293 def add_cfunction(self, name, type, pos, cname, visibility):
1294 # Add a cfunction entry without giving it a func_cname.
1295 entry = ClassScope.add_cfunction(self, name, type, pos, cname, visibility)
1296 entry.is_cmethod = 1
1299 def declare_property(self, name, doc, pos):
1300 entry = self.declare(name, name, py_object_type, pos)
1301 entry.is_property = 1
1303 entry.scope = PropertyScope(name,
1304 outer_scope = self.global_scope(), parent_scope = self)
1305 entry.scope.parent_type = self.parent_type
1306 self.property_entries.append(entry)
1309 def declare_inherited_c_attributes(self, base_scope):
1310 # Declare entries for all the C attributes of an
1311 # inherited type, with cnames modified appropriately
1312 # to work with this type.
1314 return "%s.%s" % (Naming.obj_base_cname, base_entry.cname)
1316 base_scope.inherited_var_entries + base_scope.var_entries:
1317 entry = self.declare(base_entry.name, adapt(base_entry.cname),
1318 base_entry.type, None)
1319 entry.is_variable = 1
1320 self.inherited_var_entries.append(entry)
1321 for base_entry in base_scope.cfunc_entries:
1322 entry = self.add_cfunction(base_entry.name, base_entry.type, None,
1323 adapt(base_entry.cname), base_entry.visibility)
1324 entry.is_inherited = 1
1326 def allocate_temp(self, type):
1327 return Scope.allocate_temp(self.global_scope(), type)
1329 def release_temp(self, cname):
1330 return Scope.release_temp(self.global_scope(), cname)
1333 class PropertyScope(Scope):
1334 # Scope holding the __get__, __set__ and __del__ methods for
1335 # a property of an extension type.
1337 # parent_type PyExtensionType The type to which the property belongs
1339 def declare_pyfunction(self, name, pos):
1340 # Add an entry for a method.
1341 signature = get_property_accessor_signature(name)
1343 entry = self.declare(name, name, py_object_type, pos)
1344 entry.is_special = 1
1345 entry.signature = signature
1348 error(pos, "Only __get__, __set__ and __del__ methods allowed "
1349 "in a property declaration")
1353 # Should this go elsewhere (and then get imported)?
1354 #------------------------------------------------------------------------------------
1356 classmethod_utility_code = [
1358 #include "descrobject.h"
1359 static PyObject* __Pyx_Method_ClassMethod(PyObject *method); /*proto*/
1361 static PyObject* __Pyx_Method_ClassMethod(PyObject *method) {
1362 /* It appears that PyMethodDescr_Type is not anywhere exposed in the Python/C API */
1363 /* if (!PyObject_TypeCheck(method, &PyMethodDescr_Type)) { */
1364 if (strcmp(method->ob_type->tp_name, "method_descriptor") == 0) { /* cdef classes */
1365 PyMethodDescrObject *descr = (PyMethodDescrObject *)method;
1366 return PyDescr_NewClassMethod(descr->d_type, descr->d_method);
1368 else if (PyMethod_Check(method)) { /* python classes */
1369 return PyClassMethod_New(PyMethod_GET_FUNCTION(method));
1371 PyErr_Format(PyExc_TypeError, "Class-level classmethod() can only be called on a method_descriptor or instance method.");