Commit 0bc33758 authored by Stefan Behnel's avatar Stefan Behnel

restrict "__dict__" property generation to declared "__dict__" attributes and...

restrict "__dict__" property generation to declared "__dict__" attributes and ignore everything else
parent 600fe084
...@@ -1993,8 +1993,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1993,8 +1993,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"};") "};")
def generate_dict_getter_function(self, scope, code): def generate_dict_getter_function(self, scope, code):
func_name = scope.mangle_internal("__dict__getter")
dict_attr = scope.lookup_here("__dict__") dict_attr = scope.lookup_here("__dict__")
if not dict_attr or not dict_attr.is_variable:
return
func_name = scope.mangle_internal("__dict__getter")
dict_name = dict_attr.cname dict_name = dict_attr.cname
code.putln("") code.putln("")
code.putln("static PyObject *%s(PyObject *o, CYTHON_UNUSED void *x) {" % func_name) code.putln("static PyObject *%s(PyObject *o, CYTHON_UNUSED void *x) {" % func_name)
......
...@@ -4609,7 +4609,7 @@ class CClassDefNode(ClassDefNode): ...@@ -4609,7 +4609,7 @@ class CClassDefNode(ClassDefNode):
if has_body: if has_body:
self.body.analyse_declarations(scope) self.body.analyse_declarations(scope)
dict_entry = self.scope.lookup_here("__dict__") dict_entry = self.scope.lookup_here("__dict__")
if dict_entry and (not scope.defined and not scope.implemented): if dict_entry and dict_entry.is_variable and (not scope.defined and not scope.implemented):
dict_entry.getter_cname = self.scope.mangle_internal("__dict__getter") dict_entry.getter_cname = self.scope.mangle_internal("__dict__getter")
self.scope.declare_property("__dict__", dict_entry.doc, dict_entry.pos) self.scope.declare_property("__dict__", dict_entry.doc, dict_entry.pos)
if self.in_pxd: if self.in_pxd:
......
...@@ -7,7 +7,7 @@ from __future__ import absolute_import ...@@ -7,7 +7,7 @@ from __future__ import absolute_import
from . import Naming from . import Naming
from . import PyrexTypes from . import PyrexTypes
from . import StringEncoding from .Errors import error
invisible = ['__cinit__', '__dealloc__', '__richcmp__', invisible = ['__cinit__', '__dealloc__', '__richcmp__',
'__nonzero__', '__bool__'] '__nonzero__', '__bool__']
...@@ -520,8 +520,8 @@ class DictOffsetSlot(SlotDescriptor): ...@@ -520,8 +520,8 @@ class DictOffsetSlot(SlotDescriptor):
def slot_code(self, scope): def slot_code(self, scope):
dict_entry = scope.lookup_here("__dict__") dict_entry = scope.lookup_here("__dict__")
if dict_entry: if dict_entry and dict_entry.is_variable:
if dict_entry.type.cname != 'PyDict_Type': if getattr(dict_entry.type, 'cname', None) != 'PyDict_Type':
error(dict_entry.pos, "__dict__ slot must be of type 'dict'") error(dict_entry.pos, "__dict__ slot must be of type 'dict'")
return "0" return "0"
type = scope.parent_type type = scope.parent_type
......
...@@ -14,6 +14,27 @@ cdef class MegaSpam: ...@@ -14,6 +14,27 @@ cdef class MegaSpam:
cdef public class UltraSpam [type UltraSpam_Type, object UltraSpam_Object]: cdef public class UltraSpam [type UltraSpam_Type, object UltraSpam_Object]:
cdef dict __dict__ cdef dict __dict__
cdef class OwnProperty1:
"""
>>> obj = OwnProperty1()
>>> assert obj.__dict__ == {'a': 123}
"""
@property
def __dict__(self):
return {'a': 123}
cdef class OwnProperty2:
"""
>>> obj = OwnProperty2()
>>> assert obj.__dict__ == {'a': 123}
"""
property __dict__:
def __get__(self):
return {'a': 123}
def test_class_attributes(): def test_class_attributes():
""" """
>>> test_class_attributes() >>> test_class_attributes()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment