diff options
| author | Stefan Behnel <stefan_ml@behnel.de> | 2017-07-25 14:49:49 +0200 |
|---|---|---|
| committer | Stefan Behnel <stefan_ml@behnel.de> | 2017-07-25 14:49:49 +0200 |
| commit | fb5e92001fe31a49227378e90a77bc5f4e2a83ff (patch) | |
| tree | fcd4b4fc7ea273b6c071c761598e77a2dff20982 /Cython | |
| parent | 66dc4405ddbc43730417c22e44626869aadce193 (diff) | |
| download | cython-fb5e92001fe31a49227378e90a77bc5f4e2a83ff.tar.gz | |
Suppress special casing of attribute names in closure classes since they are not user defined and any local variable name is allowed without being special.
Closes #1797.
Diffstat (limited to 'Cython')
| -rw-r--r-- | Cython/Compiler/ModuleNode.py | 8 | ||||
| -rw-r--r-- | Cython/Compiler/ParseTreeTransforms.py | 1 | ||||
| -rw-r--r-- | Cython/Compiler/Symtab.py | 11 | ||||
| -rw-r--r-- | Cython/Compiler/TypeSlots.py | 2 |
4 files changed, 12 insertions, 10 deletions
diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 2949ceeb6..311afcfb9 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -1334,11 +1334,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): is_final_type = scope.parent_type.is_final_type needs_gc = scope.needs_gc() - weakref_slot = scope.lookup_here("__weakref__") + weakref_slot = scope.lookup_here("__weakref__") if not scope.is_closure_class_scope else None if weakref_slot not in scope.var_entries: weakref_slot = None - dict_slot = scope.lookup_here("__dict__") + dict_slot = scope.lookup_here("__dict__") if not scope.is_closure_class_scope else None if dict_slot not in scope.var_entries: dict_slot = None @@ -2800,7 +2800,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): scope.class_name, typeobj_cname, code.error_goto(entry.pos))) - weakref_entry = scope.lookup_here("__weakref__") + weakref_entry = scope.lookup_here("__weakref__") if not scope.is_closure_class_scope else None if weakref_entry: if weakref_entry.type is py_object_type: tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname @@ -2815,7 +2815,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): weakref_entry.cname)) else: error(weakref_entry.pos, "__weakref__ slot must be of type 'object'") - if scope.lookup_here("__reduce_cython__"): + if scope.lookup_here("__reduce_cython__") if not scope.is_closure_class_scope else None: # Unfortunately, we cannot reliably detect whether a # superclass defined __reduce__ at compile time, so we must # do so at runtime. diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py index 49b280389..e7ba2c55b 100644 --- a/Cython/Compiler/ParseTreeTransforms.py +++ b/Cython/Compiler/ParseTreeTransforms.py @@ -2632,6 +2632,7 @@ class CreateClosureClasses(CythonTransform): func_scope.scope_class = entry class_scope = entry.type.scope class_scope.is_internal = True + class_scope.is_closure_class_scope = True if Options.closure_freelist_size: class_scope.directives['freelist'] = Options.closure_freelist_size diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py index 248e6c4bb..3ed21a47e 100644 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py @@ -1917,6 +1917,7 @@ class CClassScope(ClassScope): # inherited_var_entries [Entry] Adapted var entries from base class is_c_class_scope = 1 + is_closure_class_scope = False has_pyobject_attrs = False has_memoryview_attrs = False @@ -1960,7 +1961,7 @@ class CClassScope(ClassScope): for entry in self.var_entries: if entry.type.is_pyobject: - if include_weakref 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: @@ -1980,7 +1981,7 @@ class CClassScope(ClassScope): error(pos, "C attributes cannot be added in implementation part of" " extension type defined in a pxd") - if 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) @@ -1998,7 +1999,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 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()): @@ -2011,7 +2012,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 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 @@ -2056,7 +2057,7 @@ class CClassScope(ClassScope): return entry def lookup_here(self, name): - if 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: diff --git a/Cython/Compiler/TypeSlots.py b/Cython/Compiler/TypeSlots.py index b25b4adb8..c764f7261 100644 --- a/Cython/Compiler/TypeSlots.py +++ b/Cython/Compiler/TypeSlots.py @@ -519,7 +519,7 @@ class DictOffsetSlot(SlotDescriptor): # Slot descriptor for a class' dict offset, for dynamic attributes. def slot_code(self, scope): - dict_entry = scope.lookup_here("__dict__") + dict_entry = scope.lookup_here("__dict__") if not scope.is_closure_class_scope else None if dict_entry and dict_entry.is_variable: if getattr(dict_entry.type, 'cname', None) != 'PyDict_Type': error(dict_entry.pos, "__dict__ slot must be of type 'dict'") |
