diff options
author | Michele Calgaro <michele.calgaro@yahoo.it> | 2024-09-24 22:32:48 +0900 |
---|---|---|
committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2024-09-24 22:32:48 +0900 |
commit | 6d225e65e158e6547cb863d5558e955b3355449d (patch) | |
tree | 5fa5a62db33edc47242886a852b82336d53bf686 /debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Symtab.py | |
parent | 2950a7d84514b9b2d9916afb06ff05fdabab3be7 (diff) | |
download | extra-dependencies-6d225e65e158e6547cb863d5558e955b3355449d.tar.gz extra-dependencies-6d225e65e158e6547cb863d5558e955b3355449d.zip |
Removed pyrex, which is no longer required
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Diffstat (limited to 'debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Symtab.py')
-rw-r--r-- | debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Symtab.py | 1342 |
1 files changed, 0 insertions, 1342 deletions
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Symtab.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Symtab.py deleted file mode 100644 index b56b8531..00000000 --- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Symtab.py +++ /dev/null @@ -1,1342 +0,0 @@ -# -# Pyrex - Symbol Table -# - -from Errors import warning, error, InternalError -import Options -import Naming -import PyrexTypes -from PyrexTypes import \ - py_object_type, py_type_type, \ - c_int_type, c_char_array_type, \ - CEnumType, CStructOrUnionType, PyExtensionType -from TypeSlots import \ - pyfunction_signature, pymethod_signature, \ - get_special_method_signature, get_property_accessor_signature - -class Entry: - # A symbol table entry in a Scope or ModuleNamespace. - # - # name string Python name of entity - # cname string C name of entity - # type PyrexType Type of entity - # ctype PyrexType Declared C type, if different from Pyrex type - # doc string Doc string - # init string Initial value - # visibility 'private' or 'public' or 'extern' - # is_builtin boolean Is an entry in the Python builtins dict - # is_cglobal boolean Is a C global variable - # is_pyglobal boolean Is a Python module-level variable or - # class attribute during class construction - # is_variable boolean Is a variable - # is_cfunction boolean Is a C function - # is_cmethod boolean Is a C method of an extension type - # is_builtin_method boolean Is a method corresponding to a Python/C API func - # is_type boolean Is a type definition - # is_const boolean Is a constant - # is_property boolean Is a property of an extension type: - # #doc_cname string or None C const holding the docstring - # getter_cname string C func for getting property - # setter_cname string C func for setting or deleting property - # is_self_arg boolean Is the "self" arg of an exttype method - # is_readonly boolean Can't be assigned to - # func_cname string C func implementing Python func - # pos position Source position where declared - # namespace_cname string If is_pyglobal, the C variable - # holding its home namespace - # pymethdef_cname string PyMethodDef structure - # signature Signature Arg & return types for Python func - # init_to_none boolean True if initial value should be None - # as_variable Entry Alternative interpretation of extension - # type name or builtin C function as a variable - # xdecref_cleanup boolean Use Py_XDECREF for error cleanup - # in_cinclude boolean Suppress C declaration code - # enum_values [Entry] For enum types, list of values - # qualified_name string "modname.funcname" or "modname.classname" - # or "modname.classname.funcname" - # is_declared_generic boolean Is declared as PyObject * even though its - # type is an extension type - # as_module None Module scope, if a cimported module - # is_inherited boolean Is an inherited attribute of an extension type - # #interned_cname string C name of interned name string - # pystring_cname string C name of Python version of string literal - # #is_interned boolean For string const entries, value is interned - # used boolean - # is_special boolean Is a special method or property accessor - # of an extension type - # defined_in_pxd boolean Is defined in a .pxd file (not just declared) - # api boolean Generate C API for C class or function - # utility_code string Utility code needed when this entry is used - - borrowed = 0 - init = "" - visibility = 'private' - ctype = None - is_builtin = 0 - is_cglobal = 0 - is_pyglobal = 0 - is_variable = 0 - is_cfunction = 0 - is_cmethod = 0 - is_builtin_method = 0 - is_type = 0 - is_const = 0 - is_property = 0 - doc_cname = None - getter_cname = None - setter_cname = None - is_self_arg = 0 - is_declared_generic = 0 - is_readonly = 0 - func_cname = None - doc = None - init_to_none = 0 - as_variable = None - xdecref_cleanup = 0 - in_cinclude = 0 - as_module = None - is_inherited = 0 - #interned_cname = None - pystring_cname = None - is_interned = 0 - used = 0 - is_special = 0 - defined_in_pxd = 0 - api = 0 - utility_code = None - - def __init__(self, name, cname, type, pos = None, init = None): - self.name = name - self.cname = cname - self.type = type - self.pos = pos - self.init = init - - def redeclared(self, pos): - error(pos, "'%s' does not match previous declaration" % self.name) - error(self.pos, "Previous declaration is here") - - -class Scope: - # name string Unqualified name - # outer_scope Scope or None Enclosing scope - # entries {string : Entry} Python name to entry, non-types - # const_entries [Entry] Constant entries - # type_entries [Entry] Struct/union/enum/typedef/exttype entries - # sue_entries [Entry] Struct/union/enum entries - # arg_entries [Entry] Function argument entries - # var_entries [Entry] User-defined variable entries - # pyfunc_entries [Entry] Python function entries - # cfunc_entries [Entry] C function entries - # c_class_entries [Entry] All extension type entries - # temp_entries [Entry] Temporary variable entries - # free_temp_entries [Entry] Temp variables currently unused - # temp_counter integer Counter for naming temp vars - # cname_to_entry {string : Entry} Temp cname to entry mapping - # pow_function_used boolean The C pow() function is used - # return_type PyrexType or None Return type of function owning scope - # is_py_class_scope boolean Is a Python class scope - # is_c_class_scope boolean Is an extension type scope - # scope_prefix string Disambiguator for C names - # in_cinclude boolean Suppress C declaration code - # qualified_name string "modname" or "modname.classname" - # #pystring_entries [Entry] String const entries newly used as - # # Python strings in this scope - # nogil boolean In a nogil section - # is_cplus boolean Is a C++ struct namespace - # reraise_used boolean Reraise statement encountered - - is_py_class_scope = 0 - is_c_class_scope = 0 - scope_prefix = "" - in_cinclude = 0 - nogil = 0 - return_type = None - reraise_used = 0 - - def __init__(self, name, outer_scope, parent_scope): - # The outer_scope is the next scope in the lookup chain. - # The parent_scope is used to derive the qualified name of this scope. - self.name = name - self.outer_scope = outer_scope - self.parent_scope = parent_scope - mangled_name = "%d%s_" % (len(name), name) - qual_scope = self.qualifying_scope() - if qual_scope: - self.qualified_name = qual_scope.qualify_name(name) - self.scope_prefix = qual_scope.scope_prefix + mangled_name - else: - self.qualified_name = name - self.scope_prefix = mangled_name - self.entries = {} - self.const_entries = [] - self.type_entries = [] - self.sue_entries = [] - self.arg_entries = [] - self.var_entries = [] - self.pyfunc_entries = [] - self.cfunc_entries = [] - self.c_class_entries = [] - self.defined_c_classes = [] - self.imported_c_classes = {} - self.temp_entries = [] - self.free_temp_entries = [] - self.temp_counter = 1 - self.cname_to_entry = {} - self.pow_function_used = 0 - #self.pystring_entries = [] - - def __str__(self): - return "<%s %s>" % (self.__class__.__name__, self.qualified_name) - -# def intern(self, name): -# return self.global_scope().intern(name) - - def qualifying_scope(self): - return self.parent_scope - - def mangle(self, prefix, name = None): - if name: - return "%s%s%s" % (prefix, self.scope_prefix, name) - else: - return self.parent_scope.mangle(prefix, self.name) - - def mangle_internal(self, name): - # Mangle an internal name so as not to clash with any - # user-defined name in this scope. - prefix = "%s%s_" % (Naming.pyrex_prefix, name) - return self.mangle(prefix) - #return self.parent_scope.mangle(prefix, self.name) - - def global_scope(self): - # Return the module-level scope containing this scope. - return self.outer_scope.global_scope() - - def declare(self, name, cname, type, pos): - # Create new entry, and add to dictionary if - # name is not None. Reports an error if already - # declared. - dict = self.entries - if name and dict.has_key(name): - error(pos, "'%s' already declared" % name) - entry = Entry(name, cname, type, pos = pos) - entry.in_cinclude = self.in_cinclude - if name: - entry.qualified_name = self.qualify_name(name) - dict[name] = entry - return entry - - def qualify_name(self, name): - return "%s.%s" % (self.qualified_name, name) - - def declare_const(self, name, type, value, pos, cname = None): - # Add an entry for a named constant. - if not cname: - if self.in_cinclude: - cname = name - else: - cname = self.mangle(Naming.enum_prefix, name) - entry = self.declare(name, cname, type, pos) - entry.is_const = 1 - entry.value = value - return entry - - def declare_type(self, name, type, pos, - cname = None, visibility = 'private', defining = 1): - # Add an entry for a type definition. - if not cname: - cname = name - entry = self.declare(name, cname, type, pos) - entry.visibility = visibility - entry.is_type = 1 - if defining: - self.type_entries.append(entry) - return entry - - def declare_typedef(self, name, base_type, pos, cname = None, - visibility = 'private'): - if not cname: - if self.in_cinclude or visibility == 'public': - cname = name - else: - cname = self.mangle(Naming.type_prefix, name) - type = PyrexTypes.CTypedefType(cname, base_type) - entry = self.declare_type(name, type, pos, cname, visibility) - type.qualified_name = entry.qualified_name - return entry - - def declare_struct_or_union(self, name, kind, scope, - typedef_flag, pos, cname = None, visibility = 'private'): - # Add an entry for a struct or union definition. - if not cname: - if self.in_cinclude or visibility == 'public': - cname = name - else: - cname = self.mangle(Naming.type_prefix, name) - entry = self.lookup_here(name) - if not entry: - type = CStructOrUnionType(name, kind, scope, typedef_flag, cname) - entry = self.declare_type(name, type, pos, cname, - visibility = visibility, defining = scope is not None) - self.sue_entries.append(entry) - else: - if not (entry.is_type and entry.type.is_struct_or_union - and entry.type.kind == kind): - entry.redeclared(pos) - elif scope and entry.type.scope: - error(pos, "'%s' already defined" % name) - else: - self.check_previous_typedef_flag(entry, typedef_flag, pos) - self.check_previous_visibility(entry, visibility, pos) - if scope: - entry.pos = pos - entry.type.set_scope(scope) - self.type_entries.append(entry) - if not scope and not entry.type.scope: - self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos) - return entry - - def check_previous_typedef_flag(self, entry, typedef_flag, pos): - if typedef_flag <> entry.type.typedef_flag: - error(pos, "'%s' previously declared using '%s'" % ( - entry.name, ("cdef", "ctypedef")[entry.type.typedef_flag])) - - def check_previous_visibility(self, entry, visibility, pos): - if entry.visibility <> visibility: - error(pos, "'%s' previously declared as '%s'" % ( - entry.name, entry.visibility)) - - def declare_enum(self, name, pos, cname, typedef_flag, - visibility = 'private'): - if name: - if not cname: - if self.in_cinclude or visibility == 'public': - cname = name - else: - cname = self.mangle(Naming.type_prefix, name) - type = CEnumType(name, cname, typedef_flag) - else: - type = PyrexTypes.c_anon_enum_type - entry = self.declare_type(name, type, pos, cname = cname, - visibility = visibility) - entry.enum_values = [] - self.sue_entries.append(entry) - return entry - - def declare_var(self, name, type, pos, - cname = None, visibility = 'private', is_cdef = 0): - # Add an entry for a variable. - if not cname: - if visibility <> 'private': - cname = name - else: - cname = self.mangle(Naming.var_prefix, name) - entry = self.declare(name, cname, type, pos) - entry.is_variable = 1 - entry.visibility = visibility - return entry - - def declare_builtin(self, name, pos): - return self.outer_scope.declare_builtin(name, pos) - - def declare_pyfunction(self, name, pos): - # Add an entry for a Python function. - entry = self.declare_var(name, py_object_type, pos) - entry.signature = pyfunction_signature - self.pyfunc_entries.append(entry) - return entry - - def register_pyfunction(self, entry): - self.pyfunc_entries.append(entry) - - def declare_cfunction(self, name, type, pos, - cname = None, visibility = 'private', defining = 0, api = 0, in_pxd = 0): - # Add an entry for a C function. - entry = self.lookup_here(name) - if entry: - if visibility <> 'private' and visibility <> entry.visibility: - error(pos, "Function '%s' previously declared as '%s'" % ( - name, entry.visibility)) - if not entry.type.same_as(type): - error(pos, "Function signature does not match previous declaration") - else: - if not cname: - if api or visibility <> 'private': - cname = name - else: - cname = self.mangle(Naming.func_prefix, name) - entry = self.add_cfunction(name, type, pos, cname, visibility) - entry.func_cname = cname - if in_pxd and visibility <> 'extern': - entry.defined_in_pxd = 1 - if api: - entry.api = 1 - if not defining and not in_pxd and visibility <> 'extern': - error(pos, "Non-extern C function declared but not defined") - return entry - - def add_cfunction(self, name, type, pos, cname, visibility = 'private'): - # Add a C function entry without giving it a func_cname. - entry = self.declare(name, cname, type, pos) - entry.is_cfunction = 1 - entry.visibility = visibility - self.cfunc_entries.append(entry) - return entry - - def attach_var_entry_to_c_class(self, entry): - # The name of an extension class has to serve as both a type name and a - # variable name holding the type object. It is represented in the symbol - # table by a type entry with a variable entry attached to it. For the - # variable entry, we use a read-only C global variable whose name is an - # expression that refers to the type object. - var_entry = Entry(name = entry.name, - #type = py_object_type, - type = py_type_type, - pos = entry.pos, - #cname = "((PyObject*)%s)" % entry.type.typeptr_cname - cname = entry.type.typeptr_cname) - var_entry.is_variable = 1 - var_entry.is_cglobal = 1 - var_entry.is_readonly = 1 - entry.as_variable = var_entry - - def find(self, name, pos): - # Look up name, report error if not found. - entry = self.lookup(name) - if entry: - return entry - else: - error(pos, "'%s' is not declared" % name) - - def find_imported_module(self, path, pos): - # Look up qualified name, must be a module, report error if not found. - # Path is a list of names. - scope = self - for name in path: - entry = scope.find(name, pos) - if not entry: - return None - if entry.as_module: - scope = entry.as_module - else: - error(pos, "'%s' is not a cimported module" % scope.qualified_name) - return None - return scope - - def find_qualified_name(self, module_and_name, pos): - # Look up qualified name, report error if not found. - # module_and_name = [path, name] where path is a list of names. - module_path, name = module_and_name - scope = self.find_imported_module(module_path, pos) - if scope: - entry = scope.lookup_here(name) - if not entry: - mess = "'%s' is not declared" % name - if module_path: - mess = "%s in module '%s'" % (mess, ".".join(module_path)) - error(pos, mess) - return entry - - def lookup(self, name): - # Look up name in this scope or an enclosing one. - # Return None if not found. - return (self.lookup_here(name) - or (self.outer_scope and self.outer_scope.lookup(name)) - or None) - - def lookup_here(self, name): - # Look up in this scope only, return None if not found. - return self.entries.get(name, None) - - def lookup_target(self, name): - # Look up name in this scope only. Declare as Python - # variable if not found. - entry = self.lookup_here(name) - if not entry: - entry = self.declare_var(name, py_object_type, None) - return entry - -# def add_string_const(self, value): -# # Add an entry for a string constant. -# cname = self.new_const_cname() -# entry = Entry("", cname, c_char_array_type, init = value) -# entry.used = 1 -# self.const_entries.append(entry) -# return entry - -# def get_string_const(self, value): -# # Get entry for string constant. Returns an existing -# # one if possible, otherwise creates a new one. -# genv = self.global_scope() -# entry = genv.string_to_entry.get(value) -# if not entry: -# entry = self.add_string_const(value) -# genv.string_to_entry[value] = entry -# return entry - -# def add_py_string(self, entry): -# # If not already done, allocate a C name for a Python version of -# # a string literal, and add it to the list of Python strings to -# # be created at module init time. If the string resembles a -# # Python identifier, it will be interned. -# if not entry.pystring_cname: -# value = entry.init -# if identifier_pattern.match(value): -# entry.pystring_cname = self.intern(value) -# entry.is_interned = 1 -# else: -# entry.pystring_cname = entry.cname + "p" -# self.pystring_entries.append(entry) -# self.global_scope().all_pystring_entries.append(entry) - -# def new_const_cname(self): -# # Create a new globally-unique name for a constant. -# return self.global_scope().new_const_cname() - - def allocate_temp(self, type): - # Allocate a temporary variable of the given type from the - # free list if available, otherwise create a new one. - # Returns the cname of the variable. - for entry in self.free_temp_entries: - if entry.type == type: - self.free_temp_entries.remove(entry) - return entry.cname - n = self.temp_counter - self.temp_counter = n + 1 - cname = "%s%d" % (Naming.pyrex_prefix, n) - entry = Entry("", cname, type) - entry.used = 1 - if type.is_pyobject: - entry.init = "0" - self.cname_to_entry[entry.cname] = entry - self.temp_entries.append(entry) - return entry.cname - - def allocate_temp_pyobject(self): - # Allocate a temporary PyObject variable. - return self.allocate_temp(py_object_type) - - def release_temp(self, cname): - # Release a temporary variable for re-use. - if not cname: # can happen when type of an expr is void - return - entry = self.cname_to_entry[cname] - if entry in self.free_temp_entries: - raise InternalError("Temporary variable %s released more than once" - % cname) - self.free_temp_entries.append(entry) - - def temps_in_use(self): - # Return a new list of temp entries currently in use. - return [entry for entry in self.temp_entries - if entry not in self.free_temp_entries] - -# def use_utility_code(self, new_code): -# self.global_scope().use_utility_code(new_code) - - def generate_library_function_declarations(self, code): - # Generate extern decls for C library funcs used. - #if self.pow_function_used: - # code.putln("%s double pow(double, double);" % Naming.extern_c_macro) - pass - - def defines_any(self, names): - # Test whether any of the given names are - # defined in this scope. - for name in names: - if name in self.entries: - return 1 - return 0 - - -class BuiltinScope(Scope): - # The builtin namespace. - # - # type_names {string : 1} Set of type names (used during parsing) - - def __init__(self): - Scope.__init__(self, "__builtin__", None, None) - self.type_names = {} - - def declare_builtin(self, name, pos): - entry = self.declare(name, name, py_object_type, pos) - entry.is_builtin = 1 - return entry - - def declare_builtin_constant(self, name, type, cname, ctype = None): - entry = self.declare(name, cname, type, None) - if ctype: - entry.ctype = ctype - entry.is_variable = 1 - entry.is_cglobal = 1 - entry.is_readonly = 1 - return entry - - def declare_builtin_c_type(self, name, type): - entry = self.declare_type(name, type, pos = None) - self.type_names[name] = 1 - return entry - - def declare_builtin_cfunction(self, name, type, cname, python_equiv = None, - utility_code = None): - # If python_equiv == "*", the Python equivalent has the same name - # as the entry, otherwise it has the name specified by python_equiv. - entry = self.declare_cfunction(name, type, None, cname) - entry.utility_code = utility_code - if python_equiv: - if python_equiv == "*": - python_equiv = name - var_entry = Entry(python_equiv, python_equiv, py_object_type) - var_entry.is_variable = 1 - var_entry.is_builtin = 1 - entry.as_variable = var_entry - return entry - - def declare_builtin_class(self, name, objstruct_cname, typeobj_cname): - type = PyExtensionType(name, typedef_flag = 1, base_type = None) - type.module_name = "__builtin__" - type.typeptr_cname = "(&%s)" % typeobj_cname - type.objstruct_cname = objstruct_cname - type.is_builtin = 1 - scope = CClassScope(name = name, outer_scope = self, visibility = "extern") - type.set_scope(scope) - entry = self.declare_type(name, type, pos = None, visibility = "extern", - defining = 0) - self.attach_var_entry_to_c_class(entry) - self.type_names[name] = 1 - return entry - - def find_type(self, name): - # Used internally during initialisation, always succeeds - entry = self.lookup_here(name) - return entry.type - - -class ModuleScope(Scope): - # module_name string Python name of the module - # module_cname string C name of Python module object - # #module_dict_cname string C name of module dict object - # method_table_cname string C name of method table - # doc string Module doc string - # python_include_files [string] Standard Python headers to be included - # include_files [string] Other C headers to be included - # context Context - # pxd_file_loaded boolean Corresponding .pxd file has been processed - # cimported_modules [ModuleScope] Modules imported with cimport - # types_imported {PyrexType : 1} Set of types for which import code generated - # type_names {string : 1} Set of type names (used during parsing) - # pyrex_include_files [string] Pyrex sources included with 'include' - # gil_used boolean True if GIL is acquired/released anywhere - - gil_used = 0 - - def __init__(self, name, parent_module, context): - outer_scope = context.find_submodule("__builtin__") - Scope.__init__(self, name, outer_scope, parent_module) - self.module_name = name - self.context = context - self.module_cname = Naming.module_cname - self.module_dict_cname = Naming.moddict_cname - self.method_table_cname = Naming.methtable_cname - self.doc = "" - self.python_include_files = ["Python.h", "structmember.h"] - self.include_files = [] - self.type_names = self.outer_scope.type_names.copy() - self.pxd_file_loaded = 0 - self.cimported_modules = [] - self.types_imported = {} - self.pyrex_include_files = [] - -# def qualifying_scope(self): -# return self.parent_module - - def global_scope(self): - return self - - def declare_builtin(self, name, pos): - entry = Scope.declare_builtin(self, name, pos) - #entry.interned_cname = self.intern(name) - return entry - -# def intern(self, name): -# intern_map = self.intern_map -# cname = intern_map.get(name) -# if not cname: -# cname = Naming.interned_prefix + name -# intern_map[name] = cname -# self.interned_names.append(name) -# return cname - - def add_include_file(self, filename): - if filename not in self.python_include_files \ - and filename not in self.include_files: - self.include_files.append(filename) - - def add_imported_module(self, scope): - #print "add_imported_module:", scope, "to", self ### - if scope not in self.cimported_modules: - self.cimported_modules.append(scope) - - def add_imported_entry(self, name, entry, pos): - if entry not in self.entries: - self.entries[name] = entry - else: - error(pos, "'%s' already declared" % name) - - def declare_module(self, name, scope, pos): - # Declare a cimported module. This is represented as a - # Python module-level variable entry with a module - # scope attached to it. Reports an error and returns - # None if previously declared as something else. - entry = self.lookup_here(name) - if entry: - if entry.is_pyglobal and entry.as_module is scope: - return entry # Already declared as the same module - if not (entry.is_pyglobal and not entry.as_module): - #error(pos, "'%s' redeclared" % name) - entry.redeclared(pos) - return None - else: - entry = self.declare_var(name, py_object_type, pos) - #print "declare_module:", scope, "in", self ### - entry.as_module = scope - #self.cimported_modules.append(scope) - return entry - - def declare_var(self, name, type, pos, - cname = None, visibility = 'private', is_cdef = 0): - # Add an entry for a global variable. If it is a Python - # object type, and not declared with cdef, it will live - # in the module dictionary, otherwise it will be a C - # global variable. - entry = Scope.declare_var(self, name, type, pos, - cname, visibility, is_cdef) - if not visibility in ('private', 'public', 'extern'): - error(pos, "Module-level variable cannot be declared %s" % visibility) - if not is_cdef: - if not (type.is_pyobject and not type.is_extension_type): - raise InternalError( - "Non-cdef global variable is not a generic Python object") - entry.is_pyglobal = 1 - entry.namespace_cname = self.module_cname - #if Options.intern_names: - # entry.interned_cname = self.intern(name) - else: - entry.is_cglobal = 1 - self.var_entries.append(entry) - return entry - - def declare_global(self, name, pos): - entry = self.lookup_here(name) - if not entry: - self.declare_var(name, py_object_type, pos) - - def add_default_value(self, type): - # Add an entry for holding a function argument - # default value. - cname = "%s%d" % (Naming.default_prefix, self.default_counter) - self.default_counter += 1 - entry = Entry("", cname, type) - self.default_entries.append(entry) - return entry - -# def new_const_cname(self): -# # Create a new globally-unique name for a constant. -# n = self.const_counter -# self.const_counter = n + 1 -# return "%s%d" % (Naming.const_prefix, n) - -# def use_utility_code(self, new_code): -# # Add string to list of utility code to be included, -# # if not already there (tested using 'is'). -# for old_code in self.utility_code_used: -# if old_code is new_code: -# return -# self.utility_code_used.append(new_code) - - def declare_c_class(self, name, pos, defining = 0, implementing = 0, - module_name = None, base_type = None, visibility = 'private', - typedef_flag = 0, api = 0, options = None): - # - # Look for previous declaration as a type - # - #print "declare_c_class:", name, "in", self ### - entry = self.lookup_here(name) - if entry: - type = entry.type - if not (entry.is_type and type.is_extension_type): - entry = None # Will cause redeclaration and produce an error - else: - scope = type.scope - defined = scope and scope.defined - definitive = defining or (implementing and not defined) - self.check_previous_typedef_flag(entry, typedef_flag, pos) - if base_type or definitive: - if type.base_type and base_type is not type.base_type: - error(pos, "Base type does not match previous declaration") - type.base_type = base_type - # - # Make a new entry if needed - # - if not entry: - type = PyExtensionType(name, typedef_flag, base_type) - if visibility == 'extern': - type.module_name = module_name - else: - type.module_name = self.qualified_name - type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name) - entry = self.declare_type(name, type, pos, visibility = visibility, - defining = 0) - if options and options.objstruct_cname: - type.objstruct_cname = options.objstruct_cname - elif not entry.in_cinclude: - type.objstruct_cname = self.mangle(Naming.objstruct_prefix, name) - else: - error(entry.pos, - "Object name required for 'public' or 'extern' C class") - self.attach_var_entry_to_c_class(entry) - self.c_class_entries.append(entry) - # - # Check for re-definition and create scope if needed - # - scope = type.scope - if not scope: - if defining or implementing: - scope = CClassScope(name = name, outer_scope = self, - visibility = visibility, no_gc = options.no_gc) - if base_type: - scope.declare_inherited_c_attributes(base_type.scope) - type.set_scope(scope) - self.type_entries.append(entry) - else: - self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos) - else: - if defining and scope.defined: - error(pos, "C class '%s' already defined" % name) - elif implementing and scope.implemented: - error(pos, "C class '%s' already implemented" % name) - scope.outer_scope = self - # - # Fill in options, checking for compatibility with any previous declaration - # - if defining: - entry.defined_in_pxd = 1 - if implementing: # So that filenames in runtime exceptions refer to - entry.pos = pos # the .pyx file and not the .pxd file - if visibility <> 'private' and entry.visibility <> visibility: - error(pos, "Class '%s' previously declared as '%s'" - % (name, entry.visibility)) - if api: - entry.api = 1 - if options: - if options.objstruct_cname: - if type.objstruct_cname and type.objstruct_cname <> options.objstruct_cname: - error(pos, "Object struct name differs from previous declaration") - type.objstruct_cname = options.objstruct_cname - if options.typeobj_cname: - if type.typeobj_cname and type.typeobj_cname <> options.typeobj_cname: - error(pos, "Type object name differs from previous declaration") - type.typeobj_cname = options.typeobj_cname - # - # Return new or existing entry - # - return entry - - def check_for_illegal_incomplete_ctypedef(self, typedef_flag, pos): - if typedef_flag and not self.in_cinclude: - error(pos, "Forward-referenced type must use 'cdef', not 'ctypedef'") - - def allocate_vtable_names(self, entry): - # If extension type has a vtable, allocate vtable struct and - # slot names for it. - type = entry.type - if type.base_type and type.base_type.vtabslot_cname: - #print "...allocating vtabslot_cname because base type has one" ### - type.vtabslot_cname = "%s.%s" % ( - Naming.obj_base_cname, type.base_type.vtabslot_cname) - elif type.scope and type.scope.cfunc_entries: - #print "...allocating vtabslot_cname because there are C methods" ### - type.vtabslot_cname = Naming.vtabslot_cname - if type.vtabslot_cname: - #print "...allocating other vtable related cnames" ### - type.vtabstruct_cname = self.mangle(Naming.vtabstruct_prefix, entry.name) - type.vtabptr_cname = self.mangle(Naming.vtabptr_prefix, entry.name) - - def check_c_classes(self): - # Performs post-analysis checking and finishing up of extension types - # being implemented in this module. This is called only for the main - # .pyx file scope and its associated .pxd scope, not for cimported .pxd - # scopes. - # - # Checks all extension types declared in this scope to - # make sure that: - # - # * The extension type is implemented - # * All required object and type names have been specified or generated - # * All non-inherited C methods are implemented - # - # Also allocates a name for the vtable if needed. - # - debug_check_c_classes = 0 - if debug_check_c_classes: - print "Scope.check_c_classes: checking scope", self.qualified_name - for entry in self.c_class_entries: - if debug_check_c_classes: - print "...entry", entry.name, entry - print "......type =", entry.type - print "......visibility =", entry.visibility - type = entry.type - name = entry.name - visibility = entry.visibility - # Check defined - if not type.scope: - error(entry.pos, "C class '%s' is declared but not defined" % name) - # Generate typeobj_cname - if visibility <> 'extern' and not type.typeobj_cname: - type.typeobj_cname = self.mangle(Naming.typeobj_prefix, name) - ## Generate typeptr_cname - #type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name) - # Check C methods defined - if type.scope: - for method_entry in type.scope.cfunc_entries: - if not method_entry.is_inherited and not method_entry.func_cname: - error(method_entry.pos, "C method '%s' is declared but not defined" % - method_entry.name) - # Allocate vtable name if necessary - if type.vtabslot_cname: - #print "ModuleScope.check_c_classes: allocating vtable cname for", self ### - type.vtable_cname = self.mangle(Naming.vtable_prefix, entry.name) - - -class DefinitionScope(ModuleScope): - # Scope for the definition part of a module (.pxd). - # - # parent_module Scope Parent in the import namespace - # module_entries {string : Entry} For cimport statements - - def __init__(self, name, parent_module, context): - ModuleScope.__init__(self, name, parent_module, context) - self.parent_module = parent_module - self.module_entries = {} - - def find_module(self, module_name, pos): - # Find a module in the import namespace, interpreting - # relative imports relative to this module's parent. - # Finds and parses the module's .pxd file if the module - # has not been referenced before. - return self.global_scope().context.find_module( - module_name, relative_to = self.parent_module, pos = pos) - - def find_submodule(self, name): - # Find and return the definition scope for a submodule of this module, - # creating a new empty one if necessary. Doesn't parse .pxd. - scope = self.lookup_submodule(name) - if not scope: - scope = DefinitionScope(name, - parent_module = self, context = self.context) - self.module_entries[name] = scope - return scope - - def lookup_submodule(self, name): - # Return scope for submodule of this module, or None. - return self.module_entries.get(name, None) - - -class ImplementationScope(ModuleScope): - # This scope is used to keep the names declared only in the implementation - # part of a module from being seen by other modules that cimport this - # module. Also holds information that is only relevant for the - # implementation part. When declaring or looking up a name, this scope - # behaves as though it and its corresponding definition_scope were a single - # scope. - # - # definition_scope ModuleScope Scope holding definitions from corresponding .pxd - # doc_cname string C name of module doc string - # default_counter string Counter for naming default values - # #const_counter integer Counter for naming constants - # #utility_code_used [string] Utility code to be included - # default_entries [Entry] Function argument default entries - # #string_to_entry {string : Entry} Map string const to entry - # #intern_map {string : string} Mapping from Python names to interned strs - # #interned_names [string] Interned names pending generation of declarations - # #all_pystring_entries [Entry] Python string consts from all scopes - - def __init__(self, def_scope): - ModuleScope.__init__(self, def_scope.name, def_scope.parent_scope, - def_scope.context) - self.definition_scope = def_scope - self.doc_cname = Naming.moddoc_cname - self.type_names = def_scope.type_names.copy() - self.default_counter = 1 - #self.const_counter = 1 - #self.utility_code_used = [] - self.default_entries = [] - #self.string_to_entry = {} - #self.intern_map = {} - #self.interned_names = [] - #self.all_pystring_entries = [] - - def lookup_here(self, name): - entry = Scope.lookup_here(self, name) - if not entry: - entry = self.definition_scope.lookup_here(name) - return entry - - def find_module(self, module_name, pos): - return self.definition_scope.find_module(module_name, pos) - - def check_c_classes(self): - self.definition_scope.check_c_classes() - ModuleScope.check_c_classes(self) - - -class LocalScope(Scope): - - def __init__(self, name, outer_scope): - Scope.__init__(self, name, outer_scope, outer_scope) - - def mangle(self, prefix, name): - return prefix + name - - def declare_arg(self, name, type, pos, readonly = 0): - # Add an entry for an argument of a function. - #print "LocalScope.declare_arg:", name, "readonly =", readonly ### - cname = self.mangle(Naming.var_prefix, name) - entry = self.declare(name, cname, type, pos) - entry.is_variable = 1 - entry.is_readonly = readonly - if type.is_pyobject: - entry.init = "0" - #entry.borrowed = 1 # Not using borrowed arg refs for now - self.arg_entries.append(entry) - return entry - - def declare_var(self, name, type, pos, - cname = None, visibility = 'private', is_cdef = 0): - # Add an entry for a local variable. - if visibility in ('public', 'readonly'): - error(pos, "Local variable cannot be declared %s" % visibility) - entry = Scope.declare_var(self, name, type, pos, - cname, visibility, is_cdef) - entry.init_to_none = type.is_pyobject - self.var_entries.append(entry) - return entry - - def declare_global(self, name, pos): - # Pull entry from global scope into local scope. - if self.lookup_here(name): - error(pos, "'%s' already declared") - else: - entry = self.global_scope().lookup_target(name) - self.entries[name] = entry - - -class StructOrUnionScope(Scope): - # Namespace of a C struct or union. - # - # cplus_constructors [CFuncType] C++ constructor signatures - - def __init__(self, is_cplus = False, base_scopes = []): - Scope.__init__(self, "?", None, None) - self.base_scopes = base_scopes - self.is_cplus = is_cplus - if is_cplus: - constructors = [] - for base in base_scopes: - constructors.extend(base.cplus_constructors) - self.cplus_constructors = constructors - - def lookup_here(self, name): - entry = Scope.lookup_here(self, name) - if not entry: - for base in self.base_scopes: - entry = base.lookup_here(name) - if entry: - break - return entry - - def declare_var(self, name, type, pos, - cname = None, visibility = 'private', **kwds): - # Add an entry for an attribute. - if not cname: - cname = name - entry = self.declare(name, cname, type, pos) - entry.is_variable = 1 - self.var_entries.append(entry) - if type.is_pyobject: - error(pos, - "C struct/union member cannot be a Python object") - if visibility <> 'private': - error(pos, - "C struct/union member cannot be declared %s" % visibility) - return entry - - def declare_cfunction(self, name, type, pos, **kwds): - #print "StructOrUnionScope.declare_cfunction:", name ### - if not self.is_cplus: - error(pos, "C struct/union member cannot be a function") - # Define it anyway to suppress further errors - elif name == "__init__": - type.pos = pos - self.cplus_constructors.append(type) - return - #kwds['defining'] = 1 - #Scope.declare_cfunction(self, name, type, pos, *args, **kwds) - self.declare_var(name, type, pos, **kwds) - - -class ClassScope(Scope): - # Abstract base class for namespace of - # Python class or extension type. - # - # class_name string Pyrex name of the class - # scope_prefix string Additional prefix for names - # declared in the class - # doc string or None Doc string - - def __init__(self, name, outer_scope): - Scope.__init__(self, name, outer_scope, outer_scope) - self.class_name = name - self.doc = None - - def add_string_const(self, value): - return self.outer_scope.add_string_const(value) - - -class PyClassScope(ClassScope): - # Namespace of a Python class. - # - # class_dict_cname string C variable holding class dict - # class_obj_cname string C variable holding class object - - is_py_class_scope = 1 - - def declare_var(self, name, type, pos, - cname = None, visibility = 'private', is_cdef = 0): - # Add an entry for a class attribute. - entry = Scope.declare_var(self, name, type, pos, - cname, visibility, is_cdef) - entry.is_pyglobal = 1 - entry.namespace_cname = self.class_obj_cname - #if Options.intern_names: - # entry.interned_cname = self.intern(name) - return entry - - def allocate_temp(self, type): - return self.outer_scope.allocate_temp(type) - - def release_temp(self, cname): - self.outer_scope.release_temp(cname) - - #def recycle_pending_temps(self): - # self.outer_scope.recycle_pending_temps() - - def add_default_value(self, type): - return self.outer_scope.add_default_value(type) - - -class CClassScope(ClassScope): - # Namespace of an extension type. - # - # parent_type CClassType - # #typeobj_cname string or None - # #objstruct_cname string - # method_table_cname string - # member_table_cname string - # getset_table_cname string - # has_pyobject_attrs boolean Any PyObject attributes? - # pyattr_entries [Entry] - # public_attr_entries boolean public/readonly attrs - # property_entries [Entry] - # defined boolean Defined in .pxd file - # implemented boolean Defined in .pyx file - # inherited_var_entries [Entry] Adapted var entries from base class - # no_gc boolean No GC even if there are Python attributes - - is_c_class_scope = 1 - - def __init__(self, name, outer_scope, visibility, no_gc = 0): - ClassScope.__init__(self, name, outer_scope) - if visibility <> 'extern': - self.method_table_cname = outer_scope.mangle(Naming.methtab_prefix, name) - self.member_table_cname = outer_scope.mangle(Naming.memtab_prefix, name) - self.getset_table_cname = outer_scope.mangle(Naming.gstab_prefix, name) - self.has_pyobject_attrs = 0 - self.pyattr_entries = [] - self.public_attr_entries = [] - self.property_entries = [] - self.inherited_var_entries = [] - self.defined = 0 - self.implemented = 0 - self.no_gc = no_gc - - def needs_gc(self): - # If the type or any of its base types have Python-valued - # C attributes, then it needs to participate in GC. - return self.has_pyobject_attrs or \ - (self.parent_type.base_type and \ - self.parent_type.base_type.scope.needs_gc()) - - def declare_builtin_var(self, name, type, cname): - entry = self.declare(name, cname or name, type, None) - entry.is_variable = 1 - return entry - - def declare_var(self, name, type, pos, - cname = None, visibility = 'private', is_cdef = 0): - # Add an entry for an attribute. - if self.defined: - error(pos, - "C attributes cannot be added in implementation part of" - " extension type") - if get_special_method_signature(name): - error(pos, - "The name '%s' is reserved for a special method." - % name) - if not cname: - cname = name - entry = self.declare(name, cname, type, pos) - entry.visibility = visibility - entry.is_variable = 1 - self.var_entries.append(entry) - if type.is_pyobject and name <> "__weakref__": - self.has_pyobject_attrs = 1 - self.pyattr_entries.append(entry) - if visibility not in ('private', 'public', 'readonly'): - error(pos, - "Attribute of extension type cannot be declared %s" % visibility) - if visibility in ('public', 'readonly'): - if type.pymemberdef_typecode: - self.public_attr_entries.append(entry) - if name == "__weakref__": - error(pos, "Special attribute __weakref__ cannot be exposed to Python") - else: - error(pos, - "C attribute of type '%s' cannot be accessed from Python" % type) - if visibility == 'public' and type.is_extension_type: - error(pos, - "Non-generic Python attribute cannot be exposed for writing from Python") - return entry - - def declare_pyfunction(self, name, pos): - # Add an entry for a method. - if name == "__new__": - error(pos, "__new__ method of extension type will change semantics " - "in a future version of Pyrex. Use __cinit__ instead.") - name = "__cinit__" - entry = self.lookup_here(name) - if entry and entry.is_builtin_method: - self.overriding_builtin_method(name, pos) - else: - entry = self.declare(name, name, py_object_type, pos) - special_sig = get_special_method_signature(name) - if special_sig: - entry.is_special = 1 - entry.signature = special_sig - # Special methods don't get put in the method table - else: - entry.signature = pymethod_signature - self.pyfunc_entries.append(entry) - return entry - - def overriding_builtin_method(self, name, pos): - error(pos, "Cannot override builtin method '%s' of class '%s'" % ( - name, self.parent_type.base_type.name)) - - def lookup_here(self, name): - if name == "__new__": - name = "__cinit__" - return ClassScope.lookup_here(self, name) - - def declare_builtin_method(self, name, type, cname): - entry = ClassScope.add_cfunction(self, name, type, None, cname) - entry.is_builtin_method = 1 - return entry - - def declare_cfunction(self, name, type, pos, - cname = None, visibility = 'private', defining = 0, api = 0, in_pxd = 0): - if get_special_method_signature(name): - error(pos, "Special methods must be declared with 'def', not 'cdef'") - args = type.args - if not args: - error(pos, "C method has no self argument") - elif not args[0].type.same_as(self.parent_type): - error(pos, "Self argument of C method does not match parent type") - entry = self.lookup_here(name) - if entry: - if not entry.is_cfunction: - entry.redeclared(pos) - elif entry.is_builtin_method: - self.overriding_builtin_method(name, pos) - else: - if defining and entry.func_cname: - error(pos, "'%s' already defined" % name) - if not entry.type.same_as(type, as_cmethod = 1): - error(pos, "Signature does not match previous declaration") - error(entry.pos, "Previous declaration is here") - else: - if self.defined: - error(pos, - "C method '%s' not previously declared in definition part of" - " extension type" % name) - entry = self.add_cfunction(name, type, pos, cname or name, visibility) - if defining: - entry.func_cname = self.mangle(Naming.func_prefix, name) - return entry - - def add_cfunction(self, name, type, pos, cname, visibility): - # Add a cfunction entry without giving it a func_cname. - entry = ClassScope.add_cfunction(self, name, type, pos, cname, visibility) - entry.is_cmethod = 1 - return entry - - def declare_property(self, name, doc, pos): - entry = self.declare(name, name, py_object_type, pos) - entry.is_property = 1 - entry.doc = doc - entry.scope = PropertyScope(name, - outer_scope = self.global_scope(), parent_scope = self) - entry.scope.parent_type = self.parent_type - self.property_entries.append(entry) - return entry - - def declare_inherited_c_attributes(self, base_scope): - # Declare entries for all the C attributes of an - # inherited type, with cnames modified appropriately - # to work with this type. - def adapt(cname): - return "%s.%s" % (Naming.obj_base_cname, base_entry.cname) - for base_entry in \ - base_scope.inherited_var_entries + base_scope.var_entries: - entry = self.declare(base_entry.name, adapt(base_entry.cname), - base_entry.type, None) - entry.is_variable = 1 - self.inherited_var_entries.append(entry) - for base_entry in base_scope.cfunc_entries: - cname = base_entry.cname - if base_entry.is_builtin_method: - self.entries[base_entry.name] = base_entry - else: - entry = self.add_cfunction(base_entry.name, base_entry.type, - base_entry.pos, adapt(base_entry.cname), base_entry.visibility) - entry.is_inherited = 1 - - -class PropertyScope(Scope): - # Scope holding the __get__, __set__ and __del__ methods for - # a property of an extension type. - # - # parent_type PyExtensionType The type to which the property belongs - - def declare_pyfunction(self, name, pos): - # Add an entry for a method. - entry = self.declare(name, name, py_object_type, pos) - signature = get_property_accessor_signature(name) - if signature: - entry.is_special = 1 - entry.signature = signature - else: - error(pos, "Only __get__, __set__ and __del__ methods allowed " - "in a property declaration") - entry.signature = pymethod_signature - return entry |