diff options
| author | Aleksandr <[email protected]> | 2022-02-10 16:47:52 +0300 |
|---|---|---|
| committer | Daniil Cherednik <[email protected]> | 2022-02-10 16:47:52 +0300 |
| commit | b05913d1c3c02a773578bceb7285084d2933ae86 (patch) | |
| tree | c0748b5dcbade83af788c0abfa89c0383d6b779c /contrib/tools/cython/Cython/Compiler/Symtab.py | |
| parent | ea6c5b7f172becca389cacaff7d5f45f6adccbe6 (diff) | |
Restoring authorship annotation for Aleksandr <[email protected]>. Commit 2 of 2.
Diffstat (limited to 'contrib/tools/cython/Cython/Compiler/Symtab.py')
| -rw-r--r-- | contrib/tools/cython/Cython/Compiler/Symtab.py | 518 |
1 files changed, 259 insertions, 259 deletions
diff --git a/contrib/tools/cython/Cython/Compiler/Symtab.py b/contrib/tools/cython/Cython/Compiler/Symtab.py index 868f96ebf7f..7361a55aead 100644 --- a/contrib/tools/cython/Cython/Compiler/Symtab.py +++ b/contrib/tools/cython/Cython/Compiler/Symtab.py @@ -4,9 +4,9 @@ from __future__ import absolute_import -import re +import re import copy -import operator +import operator try: import __builtin__ as builtins @@ -18,9 +18,9 @@ from .StringEncoding import EncodedString from . import Options, Naming from . import PyrexTypes from .PyrexTypes import py_object_type, unspecified_type -from .TypeSlots import ( - pyfunction_signature, pymethod_signature, richcmp_special_methods, - get_special_method_signature, get_property_accessor_signature) +from .TypeSlots import ( + pyfunction_signature, pymethod_signature, richcmp_special_methods, + get_special_method_signature, get_property_accessor_signature) from . import Future from . import Code @@ -36,13 +36,13 @@ iso_c99_keywords = set( def c_safe_identifier(cname): # There are some C limitations on struct entry names. - if ((cname[:2] == '__' and not (cname.startswith(Naming.pyrex_prefix) - or cname in ('__weakref__', '__dict__'))) - or cname in iso_c99_keywords): + if ((cname[:2] == '__' and not (cname.startswith(Naming.pyrex_prefix) + or cname in ('__weakref__', '__dict__'))) + or cname in iso_c99_keywords): cname = Naming.pyrex_prefix + cname return cname - + class BufferAux(object): writable_needed = False @@ -61,7 +61,7 @@ class Entry(object): # cname string C name of entity # type PyrexType Type of entity # doc string Doc string - # annotation ExprNode PEP 484/526 annotation + # annotation ExprNode PEP 484/526 annotation # init string Initial value # visibility 'private' or 'public' or 'extern' # is_builtin boolean Is an entry in the Python builtins dict @@ -91,7 +91,7 @@ class Entry(object): # is_arg boolean Is the arg of a method # is_local boolean Is a local variable # in_closure boolean Is referenced in an inner scope - # in_subscope boolean Belongs to a generator expression scope + # in_subscope boolean Belongs to a generator expression scope # is_readonly boolean Can't be assigned to # func_cname string C func implementing Python func # func_modifiers [string] C function modifiers ('inline') @@ -123,7 +123,7 @@ class Entry(object): # # buffer_aux BufferAux or None Extra information needed for buffer variables # inline_func_in_pxd boolean Hacky special case for inline function in pxd file. - # Ideally this should not be necessary. + # Ideally this should not be necessary. # might_overflow boolean In an arithmetic expression that could cause # overflow (used for type inference). # utility_code_definition For some Cython builtins, the utility code @@ -140,7 +140,7 @@ class Entry(object): inline_func_in_pxd = False borrowed = 0 init = "" - annotation = None + annotation = None visibility = 'private' is_builtin = 0 is_cglobal = 0 @@ -168,7 +168,7 @@ class Entry(object): is_local = 0 in_closure = 0 from_closure = 0 - in_subscope = 0 + in_subscope = 0 is_declared_generic = 0 is_readonly = 0 pyfunc_cname = None @@ -219,12 +219,12 @@ class Entry(object): def __repr__(self): return "%s(<%x>, name=%s, type=%s)" % (type(self).__name__, id(self), self.name, self.type) - def already_declared_here(self): - error(self.pos, "Previous declaration is here") - + def already_declared_here(self): + error(self.pos, "Previous declaration is here") + def redeclared(self, pos): error(pos, "'%s' does not match previous declaration" % self.name) - self.already_declared_here() + self.already_declared_here() def all_alternatives(self): return [self] + self.overloaded_alternatives @@ -308,7 +308,7 @@ class Scope(object): is_py_class_scope = 0 is_c_class_scope = 0 is_closure_scope = 0 - is_genexpr_scope = 0 + is_genexpr_scope = 0 is_passthrough = 0 is_cpp_class_scope = 0 is_property_scope = 0 @@ -318,7 +318,7 @@ class Scope(object): in_cinclude = 0 nogil = 0 fused_to_specific = None - return_type = None + return_type = None def __init__(self, name, outer_scope, parent_scope): # The outer_scope is the next scope in the lookup chain. @@ -335,7 +335,7 @@ class Scope(object): self.qualified_name = EncodedString(name) self.scope_prefix = mangled_name self.entries = {} - self.subscopes = set() + self.subscopes = set() self.const_entries = [] self.type_entries = [] self.sue_entries = [] @@ -430,12 +430,12 @@ class Scope(object): """ Return the module-level scope containing this scope. """ return self.outer_scope.builtin_scope() - def iter_local_scopes(self): - yield self - if self.subscopes: - for scope in sorted(self.subscopes, key=operator.attrgetter('scope_prefix')): - yield scope - + def iter_local_scopes(self): + yield self + if self.subscopes: + for scope in sorted(self.subscopes, key=operator.attrgetter('scope_prefix')): + yield scope + def declare(self, name, cname, type, pos, visibility, shadow = 0, is_type = 0, create_wrapper = 0): # Create new entry, and add to dictionary if # name is not None. Reports a warning if already @@ -447,33 +447,33 @@ class Scope(object): warning(pos, "'%s' is a reserved name in C." % cname, -1) entries = self.entries if name and name in entries and not shadow: - old_entry = entries[name] - - # Reject redeclared C++ functions only if they have the same type signature. - cpp_override_allowed = False - if type.is_cfunction and old_entry.type.is_cfunction and self.is_cpp(): - for alt_entry in old_entry.all_alternatives(): - if type == alt_entry.type: - if name == '<init>' and not type.args: - # Cython pre-declares the no-args constructor - allow later user definitions. - cpp_override_allowed = True - break - else: - cpp_override_allowed = True - - if cpp_override_allowed: - # C++ function/method overrides with different signatures are ok. + old_entry = entries[name] + + # Reject redeclared C++ functions only if they have the same type signature. + cpp_override_allowed = False + if type.is_cfunction and old_entry.type.is_cfunction and self.is_cpp(): + for alt_entry in old_entry.all_alternatives(): + if type == alt_entry.type: + if name == '<init>' and not type.args: + # Cython pre-declares the no-args constructor - allow later user definitions. + cpp_override_allowed = True + break + else: + cpp_override_allowed = True + + if cpp_override_allowed: + # C++ function/method overrides with different signatures are ok. + pass + elif self.is_cpp_class_scope and entries[name].is_inherited: + # Likewise ignore inherited classes. pass - elif self.is_cpp_class_scope and entries[name].is_inherited: - # Likewise ignore inherited classes. - pass elif visibility == 'extern': - # Silenced outside of "cdef extern" blocks, until we have a safe way to - # prevent pxd-defined cpdef functions from ending up here. - warning(pos, "'%s' redeclared " % name, 1 if self.in_cinclude else 0) + # Silenced outside of "cdef extern" blocks, until we have a safe way to + # prevent pxd-defined cpdef functions from ending up here. + warning(pos, "'%s' redeclared " % name, 1 if self.in_cinclude else 0) elif visibility != 'ignore': error(pos, "'%s' redeclared " % name) - entries[name].already_declared_here() + entries[name].already_declared_here() entry = Entry(name, cname, type, pos = pos) entry.in_cinclude = self.in_cinclude entry.create_wrapper = create_wrapper @@ -605,7 +605,7 @@ class Scope(object): else: if not (entry.is_type and entry.type.is_cpp_class): error(pos, "'%s' redeclared " % name) - entry.already_declared_here() + entry.already_declared_here() return None elif scope and entry.type.scope: warning(pos, "'%s' already defined (ignoring second definition)" % name, 0) @@ -616,13 +616,13 @@ class Scope(object): if base_classes: if entry.type.base_classes and entry.type.base_classes != base_classes: error(pos, "Base type does not match previous declaration") - entry.already_declared_here() + entry.already_declared_here() else: entry.type.base_classes = base_classes if templates or entry.type.templates: if templates != entry.type.templates: error(pos, "Template parameters do not match previous declaration") - entry.already_declared_here() + entry.already_declared_here() def declare_inherited_attributes(entry, base_classes): for base_class in base_classes: @@ -632,7 +632,7 @@ class Scope(object): error(pos, "Cannot inherit from incomplete type") else: declare_inherited_attributes(entry, base_class.base_classes) - entry.type.scope.declare_inherited_cpp_attributes(base_class) + entry.type.scope.declare_inherited_cpp_attributes(base_class) if scope: declare_inherited_attributes(entry, base_classes) scope.declare_var(name="this", cname="this", type=PyrexTypes.CPtrType(entry.type), pos=entry.pos) @@ -773,10 +773,10 @@ class Scope(object): if overridable != entry.is_overridable: warning(pos, "Function '%s' previously declared as '%s'" % ( name, 'cpdef' if overridable else 'cdef'), 1) - if entry.type.same_as(type): - # Fix with_gil vs nogil. - entry.type = entry.type.with_with_gil(type.with_gil) - else: + if entry.type.same_as(type): + # Fix with_gil vs nogil. + entry.type = entry.type.with_with_gil(type.with_gil) + else: if visibility == 'extern' and entry.visibility == 'extern': can_override = False if self.is_cpp(): @@ -796,10 +796,10 @@ class Scope(object): else: warning(pos, "Function signature does not match previous declaration", 1) entry.type = type - elif not in_pxd and entry.defined_in_pxd and type.compatible_signature_with(entry.type): - # TODO: check that this was done by a signature optimisation and not a user error. - #warning(pos, "Function signature does not match previous declaration", 1) - entry.type = type + elif not in_pxd and entry.defined_in_pxd and type.compatible_signature_with(entry.type): + # TODO: check that this was done by a signature optimisation and not a user error. + #warning(pos, "Function signature does not match previous declaration", 1) + entry.type = type else: error(pos, "Function signature does not match previous declaration") else: @@ -830,23 +830,23 @@ class Scope(object): type.entry = entry return entry - def add_cfunction(self, name, type, pos, cname, visibility, modifiers, inherited=False): + def add_cfunction(self, name, type, pos, cname, visibility, modifiers, inherited=False): # Add a C function entry without giving it a func_cname. entry = self.declare(name, cname, type, pos, visibility) entry.is_cfunction = 1 if modifiers: entry.func_modifiers = modifiers - if inherited or type.is_fused: - self.cfunc_entries.append(entry) - else: - # For backwards compatibility reasons, we must keep all non-fused methods - # before all fused methods, but separately for each type. - i = len(self.cfunc_entries) - for cfunc_entry in reversed(self.cfunc_entries): - if cfunc_entry.is_inherited or not cfunc_entry.type.is_fused: - break - i -= 1 - self.cfunc_entries.insert(i, entry) + if inherited or type.is_fused: + self.cfunc_entries.append(entry) + else: + # For backwards compatibility reasons, we must keep all non-fused methods + # before all fused methods, but separately for each type. + i = len(self.cfunc_entries) + for cfunc_entry in reversed(self.cfunc_entries): + if cfunc_entry.is_inherited or not cfunc_entry.type.is_fused: + break + i -= 1 + self.cfunc_entries.insert(i, entry) return entry def find(self, name, pos): @@ -946,19 +946,19 @@ class Scope(object): self.global_scope().use_entry_utility_code(entry) def defines_any(self, names): - # Test whether any of the given names are defined in this scope. + # 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 - def defines_any_special(self, names): - # Test whether any of the given names are defined as special methods in this scope. - for name in names: - if name in self.entries and self.entries[name].is_special: - return 1 - return 0 - + def defines_any_special(self, names): + # Test whether any of the given names are defined as special methods in this scope. + for name in names: + if name in self.entries and self.entries[name].is_special: + return 1 + return 0 + def infer_types(self): from .TypeInference import get_type_inferer get_type_inferer().infer_types(self) @@ -1114,8 +1114,8 @@ class ModuleScope(Scope): # doc string Module doc string # doc_cname string C name of module doc string # utility_code_list [UtilityCode] Queuing utility codes for forwarding to Code.py - # c_includes {key: IncludeCode} C headers or verbatim code to be generated - # See process_include() for more documentation + # c_includes {key: IncludeCode} C headers or verbatim code to be generated + # See process_include() for more documentation # string_to_entry {string : Entry} Map string const to entry # identifier_to_entry {string : Entry} Map identifier string const to entry # context Context @@ -1158,7 +1158,7 @@ class ModuleScope(Scope): self.doc_cname = Naming.moddoc_cname self.utility_code_list = [] self.module_entries = {} - self.c_includes = {} + self.c_includes = {} self.type_names = dict(outer_scope.type_names) self.pxd_file_loaded = 0 self.cimported_modules = [] @@ -1169,10 +1169,10 @@ class ModuleScope(Scope): self.undeclared_cached_builtins = [] self.namespace_cname = self.module_cname self._cached_tuple_types = {} - for var_name in ['__builtins__', '__name__', '__file__', '__doc__', '__path__', - '__spec__', '__loader__', '__package__', '__cached__']: + for var_name in ['__builtins__', '__name__', '__file__', '__doc__', '__path__', + '__spec__', '__loader__', '__package__', '__cached__']: self.declare_var(EncodedString(var_name), py_object_type, None) - self.process_include(Code.IncludeCode("Python.h", initial=True)) + self.process_include(Code.IncludeCode("Python.h", initial=True)) def qualifying_scope(self): return self.parent_module @@ -1299,58 +1299,58 @@ class ModuleScope(Scope): module = module.lookup_submodule(submodule) return module - def add_include_file(self, filename, verbatim_include=None, late=False): - """ - Add `filename` as include file. Add `verbatim_include` as - verbatim text in the C file. - Both `filename` and `verbatim_include` can be `None` or empty. - """ - inc = Code.IncludeCode(filename, verbatim_include, late=late) - self.process_include(inc) - - def process_include(self, inc): - """ - Add `inc`, which is an instance of `IncludeCode`, to this - `ModuleScope`. This either adds a new element to the - `c_includes` dict or it updates an existing entry. - - In detail: the values of the dict `self.c_includes` are - instances of `IncludeCode` containing the code to be put in the - generated C file. The keys of the dict are needed to ensure - uniqueness in two ways: if an include file is specified in - multiple "cdef extern" blocks, only one `#include` statement is - generated. Second, the same include might occur multiple times - if we find it through multiple "cimport" paths. So we use the - generated code (of the form `#include "header.h"`) as dict key. - - If verbatim code does not belong to any include file (i.e. it - was put in a `cdef extern from *` block), then we use a unique - dict key: namely, the `sortkey()`. - - One `IncludeCode` object can contain multiple pieces of C code: - one optional "main piece" for the include file and several other - pieces for the verbatim code. The `IncludeCode.dict_update` - method merges the pieces of two different `IncludeCode` objects - if needed. - """ - key = inc.mainpiece() - if key is None: - key = inc.sortkey() - inc.dict_update(self.c_includes, key) - inc = self.c_includes[key] - + def add_include_file(self, filename, verbatim_include=None, late=False): + """ + Add `filename` as include file. Add `verbatim_include` as + verbatim text in the C file. + Both `filename` and `verbatim_include` can be `None` or empty. + """ + inc = Code.IncludeCode(filename, verbatim_include, late=late) + self.process_include(inc) + + def process_include(self, inc): + """ + Add `inc`, which is an instance of `IncludeCode`, to this + `ModuleScope`. This either adds a new element to the + `c_includes` dict or it updates an existing entry. + + In detail: the values of the dict `self.c_includes` are + instances of `IncludeCode` containing the code to be put in the + generated C file. The keys of the dict are needed to ensure + uniqueness in two ways: if an include file is specified in + multiple "cdef extern" blocks, only one `#include` statement is + generated. Second, the same include might occur multiple times + if we find it through multiple "cimport" paths. So we use the + generated code (of the form `#include "header.h"`) as dict key. + + If verbatim code does not belong to any include file (i.e. it + was put in a `cdef extern from *` block), then we use a unique + dict key: namely, the `sortkey()`. + + One `IncludeCode` object can contain multiple pieces of C code: + one optional "main piece" for the include file and several other + pieces for the verbatim code. The `IncludeCode.dict_update` + method merges the pieces of two different `IncludeCode` objects + if needed. + """ + key = inc.mainpiece() + if key is None: + key = inc.sortkey() + inc.dict_update(self.c_includes, key) + inc = self.c_includes[key] + def add_imported_module(self, scope): if scope not in self.cimported_modules: - for inc in scope.c_includes.values(): - self.process_include(inc) + for inc in scope.c_includes.values(): + self.process_include(inc) self.cimported_modules.append(scope) for m in scope.cimported_modules: self.add_imported_module(m) def add_imported_entry(self, name, entry, pos): - if entry.is_pyglobal: - # Allow cimports to follow imports. - entry.is_variable = True + if entry.is_pyglobal: + # Allow cimports to follow imports. + entry.is_variable = True if entry not in self.entries: self.entries[name] = entry else: @@ -1376,7 +1376,7 @@ class ModuleScope(Scope): return entry else: entry = self.declare_var(name, py_object_type, pos) - entry.is_variable = 0 + entry.is_variable = 0 entry.as_module = scope self.add_imported_module(scope) return entry @@ -1428,8 +1428,8 @@ class ModuleScope(Scope): api=api, in_pxd=in_pxd, is_cdef=is_cdef) if is_cdef: entry.is_cglobal = 1 - if entry.type.declaration_value: - entry.init = entry.type.declaration_value + if entry.type.declaration_value: + entry.init = entry.type.declaration_value self.var_entries.append(entry) else: entry.is_pyglobal = 1 @@ -1440,9 +1440,9 @@ class ModuleScope(Scope): def declare_cfunction(self, name, type, pos, cname=None, visibility='private', api=0, in_pxd=0, defining=0, modifiers=(), utility_code=None, overridable=False): - if not defining and 'inline' in modifiers: - # TODO(github/1736): Make this an error. - warning(pos, "Declarations should not be declared inline.", 1) + if not defining and 'inline' in modifiers: + # TODO(github/1736): Make this an error. + warning(pos, "Declarations should not be declared inline.", 1) # Add an entry for a C function. if not cname: if visibility == 'extern' or (visibility == 'public' and defining): @@ -1763,8 +1763,8 @@ class LocalScope(Scope): entry = Scope.declare_var(self, name, type, pos, cname=cname, visibility=visibility, api=api, in_pxd=in_pxd, is_cdef=is_cdef) - if entry.type.declaration_value: - entry.init = entry.type.declaration_value + if entry.type.declaration_value: + entry.init = entry.type.declaration_value entry.is_local = 1 entry.in_with_gil_block = self._in_with_gil_block @@ -1784,7 +1784,7 @@ class LocalScope(Scope): orig_entry = self.lookup_here(name) if orig_entry and orig_entry.scope is self and not orig_entry.from_closure: error(pos, "'%s' redeclared as nonlocal" % name) - orig_entry.already_declared_here() + orig_entry.already_declared_here() else: entry = self.lookup(name) if entry is None or not entry.from_closure: @@ -1795,10 +1795,10 @@ class LocalScope(Scope): # Return None if not found. entry = Scope.lookup(self, name) if entry is not None: - entry_scope = entry.scope - while entry_scope.is_genexpr_scope: - entry_scope = entry_scope.outer_scope - if entry_scope is not self and entry_scope.is_closure_scope: + entry_scope = entry.scope + while entry_scope.is_genexpr_scope: + entry_scope = entry_scope.outer_scope + if entry_scope is not self and entry_scope.is_closure_scope: if hasattr(entry.scope, "scope_class"): raise InternalError("lookup() after scope class created.") # The actual c fragment for the different scopes differs @@ -1811,19 +1811,19 @@ class LocalScope(Scope): return entry def mangle_closure_cnames(self, outer_scope_cname): - for scope in self.iter_local_scopes(): - for entry in scope.entries.values(): - if entry.from_closure: - cname = entry.outer_entry.cname - if self.is_passthrough: - entry.cname = cname - else: - if cname.startswith(Naming.cur_scope_cname): - cname = cname[len(Naming.cur_scope_cname)+2:] - entry.cname = "%s->%s" % (outer_scope_cname, cname) - elif entry.in_closure: - entry.original_cname = entry.cname - entry.cname = "%s->%s" % (Naming.cur_scope_cname, entry.cname) + for scope in self.iter_local_scopes(): + for entry in scope.entries.values(): + if entry.from_closure: + cname = entry.outer_entry.cname + if self.is_passthrough: + entry.cname = cname + else: + if cname.startswith(Naming.cur_scope_cname): + cname = cname[len(Naming.cur_scope_cname)+2:] + entry.cname = "%s->%s" % (outer_scope_cname, cname) + elif entry.in_closure: + entry.original_cname = entry.cname + entry.cname = "%s->%s" % (Naming.cur_scope_cname, entry.cname) class GeneratorExpressionScope(Scope): @@ -1831,25 +1831,25 @@ class GeneratorExpressionScope(Scope): to generators, these can be easily inlined in some cases, so all we really need is a scope that holds the loop variable(s). """ - is_genexpr_scope = True - + is_genexpr_scope = True + def __init__(self, outer_scope): - parent_scope = outer_scope - # TODO: also ignore class scopes? - while parent_scope.is_genexpr_scope: - parent_scope = parent_scope.parent_scope - name = parent_scope.global_scope().next_id(Naming.genexpr_id_ref) - Scope.__init__(self, name, outer_scope, parent_scope) + parent_scope = outer_scope + # TODO: also ignore class scopes? + while parent_scope.is_genexpr_scope: + parent_scope = parent_scope.parent_scope + name = parent_scope.global_scope().next_id(Naming.genexpr_id_ref) + Scope.__init__(self, name, outer_scope, parent_scope) self.directives = outer_scope.directives self.genexp_prefix = "%s%d%s" % (Naming.pyrex_prefix, len(name), name) - # Class/ExtType scopes are filled at class creation time, i.e. from the - # module init function or surrounding function. - while outer_scope.is_genexpr_scope or outer_scope.is_c_class_scope or outer_scope.is_py_class_scope: - outer_scope = outer_scope.outer_scope - self.var_entries = outer_scope.var_entries # keep declarations outside - outer_scope.subscopes.add(self) - + # Class/ExtType scopes are filled at class creation time, i.e. from the + # module init function or surrounding function. + while outer_scope.is_genexpr_scope or outer_scope.is_c_class_scope or outer_scope.is_py_class_scope: + outer_scope = outer_scope.outer_scope + self.var_entries = outer_scope.var_entries # keep declarations outside + outer_scope.subscopes.add(self) + def mangle(self, prefix, name): return '%s%s' % (self.genexp_prefix, self.parent_scope.mangle(prefix, name)) @@ -1865,12 +1865,12 @@ class GeneratorExpressionScope(Scope): # this scope must hold its name exclusively cname = '%s%s' % (self.genexp_prefix, self.parent_scope.mangle(Naming.var_prefix, name or self.next_id())) entry = self.declare(name, cname, type, pos, visibility) - entry.is_variable = True - if self.parent_scope.is_module_scope: - entry.is_cglobal = True - else: - entry.is_local = True - entry.in_subscope = True + entry.is_variable = True + if self.parent_scope.is_module_scope: + entry.is_cglobal = True + else: + entry.is_local = True + entry.in_subscope = True self.var_entries.append(entry) self.entries[name] = entry return entry @@ -1916,7 +1916,7 @@ class StructOrUnionScope(Scope): def declare_var(self, name, type, pos, cname = None, visibility = 'private', api = 0, in_pxd = 0, is_cdef = 0, - allow_pyobject=False, allow_memoryview=False): + allow_pyobject=False, allow_memoryview=False): # Add an entry for an attribute. if not cname: cname = name @@ -1928,12 +1928,12 @@ class StructOrUnionScope(Scope): entry.is_variable = 1 self.var_entries.append(entry) if type.is_pyobject and not allow_pyobject: - error(pos, "C struct/union member cannot be a Python object") - elif type.is_memoryviewslice and not allow_memoryview: - # Memory views wrap their buffer owner as a Python object. - error(pos, "C struct/union member cannot be a memory view") + error(pos, "C struct/union member cannot be a Python object") + elif type.is_memoryviewslice and not allow_memoryview: + # Memory views wrap their buffer owner as a Python object. + error(pos, "C struct/union member cannot be a memory view") if visibility != 'private': - error(pos, "C struct/union member cannot be declared %s" % visibility) + error(pos, "C struct/union member cannot be declared %s" % visibility) return entry def declare_cfunction(self, name, type, pos, @@ -2018,7 +2018,7 @@ class PyClassScope(ClassScope): orig_entry = self.lookup_here(name) if orig_entry and orig_entry.scope is self and not orig_entry.from_closure: error(pos, "'%s' redeclared as nonlocal" % name) - orig_entry.already_declared_here() + orig_entry.already_declared_here() else: entry = self.lookup(name) if entry is None: @@ -2058,7 +2058,7 @@ class CClassScope(ClassScope): # inherited_var_entries [Entry] Adapted var entries from base class is_c_class_scope = 1 - is_closure_class_scope = False + is_closure_class_scope = False has_pyobject_attrs = False has_memoryview_attrs = False @@ -2102,7 +2102,7 @@ class CClassScope(ClassScope): for entry in self.var_entries: if entry.type.is_pyobject: - if include_weakref or (self.is_closure_class_scope or entry.name != "__weakref__"): + if include_weakref or (self.is_closure_class_scope or entry.name != "__weakref__"): if include_gc_simple or not entry.type.is_gc_simple: py_attrs.append(entry) elif entry.type == PyrexTypes.c_py_buffer_type: @@ -2122,7 +2122,7 @@ class CClassScope(ClassScope): error(pos, "C attributes cannot be added in implementation part of" " extension type defined in a pxd") - if not self.is_closure_class_scope and get_special_method_signature(name): + if not self.is_closure_class_scope and get_special_method_signature(name): error(pos, "The name '%s' is reserved for a special method." % name) @@ -2140,7 +2140,7 @@ class CClassScope(ClassScope): self.has_memoryview_attrs = True elif type.is_cpp_class: self.has_cpp_class_attrs = True - elif type.is_pyobject and (self.is_closure_class_scope or name != '__weakref__'): + elif type.is_pyobject and (self.is_closure_class_scope or name != '__weakref__'): self.has_pyobject_attrs = True if (not type.is_builtin_type or not type.scope or type.scope.needs_gc()): @@ -2153,7 +2153,7 @@ class CClassScope(ClassScope): # so do conversion ourself rather than rely on the CPython mechanism (through # a property; made in AnalyseDeclarationsTransform). entry.needs_property = True - if not self.is_closure_class_scope and name == "__weakref__": + if not self.is_closure_class_scope and name == "__weakref__": error(pos, "Special attribute __weakref__ cannot be exposed to Python") if not (type.is_pyobject or type.can_coerce_to_pyobject(self)): # we're not testing for coercion *from* Python here - that would fail later @@ -2177,13 +2177,13 @@ class CClassScope(ClassScope): def declare_pyfunction(self, name, pos, allow_redefine=False): # Add an entry for a method. - if name in richcmp_special_methods: - if self.lookup_here('__richcmp__'): - error(pos, "Cannot define both % and __richcmp__" % name) - elif name == '__richcmp__': - for n in richcmp_special_methods: - if self.lookup_here(n): - error(pos, "Cannot define both % and __richcmp__" % n) + if name in richcmp_special_methods: + if self.lookup_here('__richcmp__'): + error(pos, "Cannot define both % and __richcmp__" % name) + elif name == '__richcmp__': + for n in richcmp_special_methods: + if self.lookup_here(n): + error(pos, "Cannot define both % and __richcmp__" % n) if name == "__new__": error(pos, "__new__ method of extension type will change semantics " "in a future version of Pyrex and Cython. Use __cinit__ instead.") @@ -2203,7 +2203,7 @@ class CClassScope(ClassScope): return entry def lookup_here(self, name): - if not self.is_closure_class_scope and name == "__new__": + if not self.is_closure_class_scope and name == "__new__": name = EncodedString("__cinit__") entry = ClassScope.lookup_here(self, name) if entry and entry.is_builtin_cmethod: @@ -2242,18 +2242,18 @@ class CClassScope(ClassScope): if entry.is_final_cmethod and entry.is_inherited: error(pos, "Overriding final methods is not allowed") elif type.same_c_signature_as(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil: - # Fix with_gil vs nogil. - entry.type = entry.type.with_with_gil(type.with_gil) + # Fix with_gil vs nogil. + entry.type = entry.type.with_with_gil(type.with_gil) elif type.compatible_signature_with(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil: - if (self.defined and not in_pxd - and not type.same_c_signature_as_resolved_type(entry.type, as_cmethod = 1, as_pxd_definition = 1)): - # TODO(robertwb): Make this an error. - warning(pos, - "Compatible but non-identical C method '%s' not redeclared " + if (self.defined and not in_pxd + and not type.same_c_signature_as_resolved_type(entry.type, as_cmethod = 1, as_pxd_definition = 1)): + # TODO(robertwb): Make this an error. + warning(pos, + "Compatible but non-identical C method '%s' not redeclared " "in definition part of extension type '%s'. " "This may cause incorrect vtables to be generated." % ( name, self.class_name), 2) - warning(entry.pos, "Previous declaration is here", 2) + warning(entry.pos, "Previous declaration is here", 2) entry = self.add_cfunction(name, type, pos, cname, visibility='ignore', modifiers=modifiers) else: error(pos, "Signature not compatible with previous declaration") @@ -2262,7 +2262,7 @@ class CClassScope(ClassScope): if self.defined: error(pos, "C method '%s' not previously declared in definition part of" - " extension type '%s'" % (name, self.class_name)) + " extension type '%s'" % (name, self.class_name)) entry = self.add_cfunction(name, type, pos, cname, visibility, modifiers) if defining: entry.func_cname = self.mangle(Naming.func_prefix, name) @@ -2279,11 +2279,11 @@ class CClassScope(ClassScope): return entry - def add_cfunction(self, name, type, pos, cname, visibility, modifiers, inherited=False): + def add_cfunction(self, name, type, pos, cname, visibility, modifiers, inherited=False): # Add a cfunction entry without giving it a func_cname. prev_entry = self.lookup_here(name) entry = ClassScope.add_cfunction(self, name, type, pos, cname, - visibility, modifiers, inherited=inherited) + visibility, modifiers, inherited=inherited) entry.is_cmethod = 1 entry.prev_entry = prev_entry return entry @@ -2345,7 +2345,7 @@ class CClassScope(ClassScope): cname = adapt(cname) entry = self.add_cfunction(base_entry.name, base_entry.type, base_entry.pos, cname, - base_entry.visibility, base_entry.func_modifiers, inherited=True) + base_entry.visibility, base_entry.func_modifiers, inherited=True) entry.is_inherited = 1 if base_entry.is_final_cmethod: entry.is_final_cmethod = True @@ -2380,18 +2380,18 @@ class CppClassScope(Scope): def declare_var(self, name, type, pos, cname = None, visibility = 'extern', - api = 0, in_pxd = 0, is_cdef = 0, defining = 0): + api = 0, in_pxd = 0, is_cdef = 0, defining = 0): # Add an entry for an attribute. if not cname: cname = name entry = self.lookup_here(name) if defining and entry is not None: - if entry.type.same_as(type): - # Fix with_gil vs nogil. - entry.type = entry.type.with_with_gil(type.with_gil) - elif type.is_cfunction and type.compatible_signature_with(entry.type): - entry.type = type - else: + if entry.type.same_as(type): + # Fix with_gil vs nogil. + entry.type = entry.type.with_with_gil(type.with_gil) + elif type.is_cfunction and type.compatible_signature_with(entry.type): + entry.type = type + else: error(pos, "Function signature does not match previous declaration") else: entry = self.declare(name, cname, type, pos, visibility) @@ -2406,31 +2406,31 @@ class CppClassScope(Scope): def declare_cfunction(self, name, type, pos, cname=None, visibility='extern', api=0, in_pxd=0, defining=0, modifiers=(), utility_code=None, overridable=False): - class_name = self.name.split('::')[-1] - if name in (class_name, '__init__') and cname is None: - cname = "%s__init__%s" % (Naming.func_prefix, class_name) + class_name = self.name.split('::')[-1] + if name in (class_name, '__init__') and cname is None: + cname = "%s__init__%s" % (Naming.func_prefix, class_name) name = '<init>' - type.return_type = PyrexTypes.CVoidType() - # This is called by the actual constructor, but need to support - # arguments that cannot by called by value. - type.original_args = type.args - def maybe_ref(arg): - if arg.type.is_cpp_class and not arg.type.is_reference: - return PyrexTypes.CFuncTypeArg( - arg.name, PyrexTypes.c_ref_type(arg.type), arg.pos) - else: - return arg - type.args = [maybe_ref(arg) for arg in type.args] + type.return_type = PyrexTypes.CVoidType() + # This is called by the actual constructor, but need to support + # arguments that cannot by called by value. + type.original_args = type.args + def maybe_ref(arg): + if arg.type.is_cpp_class and not arg.type.is_reference: + return PyrexTypes.CFuncTypeArg( + arg.name, PyrexTypes.c_ref_type(arg.type), arg.pos) + else: + return arg + type.args = [maybe_ref(arg) for arg in type.args] elif name == '__dealloc__' and cname is None: - cname = "%s__dealloc__%s" % (Naming.func_prefix, class_name) + cname = "%s__dealloc__%s" % (Naming.func_prefix, class_name) name = '<del>' - type.return_type = PyrexTypes.CVoidType() - if name in ('<init>', '<del>') and type.nogil: - for base in self.type.base_classes: - base_entry = base.scope.lookup(name) - if base_entry and not base_entry.type.nogil: - error(pos, "Constructor cannot be called without GIL unless all base constructors can also be called without GIL") - error(base_entry.pos, "Base constructor defined here.") + type.return_type = PyrexTypes.CVoidType() + if name in ('<init>', '<del>') and type.nogil: + for base in self.type.base_classes: + base_entry = base.scope.lookup(name) + if base_entry and not base_entry.type.nogil: + error(pos, "Constructor cannot be called without GIL unless all base constructors can also be called without GIL") + error(base_entry.pos, "Base constructor defined here.") prev_entry = self.lookup_here(name) entry = self.declare_var(name, type, pos, defining=defining, @@ -2441,22 +2441,22 @@ class CppClassScope(Scope): type.entry = entry return entry - def declare_inherited_cpp_attributes(self, base_class): - base_scope = base_class.scope - template_type = base_class - while getattr(template_type, 'template_type', None): - template_type = template_type.template_type - if getattr(template_type, 'templates', None): - base_templates = [T.name for T in template_type.templates] - else: - base_templates = () + def declare_inherited_cpp_attributes(self, base_class): + base_scope = base_class.scope + template_type = base_class + while getattr(template_type, 'template_type', None): + template_type = template_type.template_type + if getattr(template_type, 'templates', None): + base_templates = [T.name for T in template_type.templates] + else: + base_templates = () # Declare entries for all the C++ attributes of an # inherited type, with cnames modified appropriately # to work with this type. for base_entry in \ base_scope.inherited_var_entries + base_scope.var_entries: - #constructor/destructor is not inherited - if base_entry.name in ("<init>", "<del>"): + #constructor/destructor is not inherited + if base_entry.name in ("<init>", "<del>"): continue #print base_entry.name, self.entries if base_entry.name in self.entries: @@ -2464,7 +2464,7 @@ class CppClassScope(Scope): entry = self.declare(base_entry.name, base_entry.cname, base_entry.type, None, 'extern') entry.is_variable = 1 - entry.is_inherited = 1 + entry.is_inherited = 1 self.inherited_var_entries.append(entry) for base_entry in base_scope.cfunc_entries: entry = self.declare_cfunction(base_entry.name, base_entry.type, @@ -2473,12 +2473,12 @@ class CppClassScope(Scope): modifiers=base_entry.func_modifiers, utility_code=base_entry.utility_code) entry.is_inherited = 1 - for base_entry in base_scope.type_entries: - if base_entry.name not in base_templates: - entry = self.declare_type(base_entry.name, base_entry.type, - base_entry.pos, base_entry.cname, - base_entry.visibility) - entry.is_inherited = 1 + for base_entry in base_scope.type_entries: + if base_entry.name not in base_templates: + entry = self.declare_type(base_entry.name, base_entry.type, + base_entry.pos, base_entry.cname, + base_entry.visibility) + entry.is_inherited = 1 def specialize(self, values, type_entry): scope = CppClassScope(self.name, self.outer_scope) |
