[issue27411] Possible different behaviour of explicit and implicit __dict__ accessing when involving builtin types' __dict__ descriptors
Xiang Zhang
report at bugs.python.org
Wed Jun 29 05:57:04 EDT 2016
New submission from Xiang Zhang:
Usually when we access an object's __dict__, it will finally reach
subtype_dict[0]. When involving builtin base, it may delegates to the
base's __dict__ descriptor. In such a case, it is possible for the
__dict__ descriptor to initialize the dict object if it's NULL. This is
what PyObject_GenericGetDict does. But if the __dict__ descriptor
initialize dict to other mapping objects instead of dict object,
accessing __dict__ explicitly first or implicitly by attribute setting
will result in different behaviours. If we first access obj.__dict__,
obj.__dict__ will set to the mapping object, otherwise it will be set
to a dict.
Let's make a example. For convenience I alter BaseException's __dict__
descriptor, changing PyObject_GenericGetDict to custom_getdict:
PyObject *
custom_getdict(PyObject *obj, void *context)
{
PyObject *dict, **dictptr = _PyObject_GetDictPtr(obj);
dict = *dictptr;
if (dict == NULL) {
*dictptr = dict = PyDict_New();
PyDict_SetItemString(dict, "test", PyDict_New());
}
Py_XINCREF(dict);
return dict;
}
And then the use case:
>>> BaseException().__dict__
{'test': {}}
>>> class A:
... pass
...
>>> class B(A, BaseException):
... def __init__(self):
... self.__dict__['a'] = 1
... self.b = 2
...
>>> class C(A, BaseException):
... def __init__(self):
... self.a = 1
... self.__dict__['b'] = 2
...
>>> B().__dict__
{'b': 2, 'test': {}, 'a': 1}
>>> C().__dict__
{'a': 1, 'b': 2}
Since a and b are not descriptors, I think B().__dict__ and C().__dict__ should lead to same result but they are not. I think it's
because PyObject_GenericSetAttr doesn't go the same way as subtype_dict
so when it finds __dict__ is not initialized it always assign it a new
dict.
I am not sure this is a bug or a case worth fixing or is designed deliberately. BTW, subtype_dict was introduced in [1].
[0] https://hg.python.org/cpython/file/tip/Objects/typeobject.c#l2069
[1] http://bugs.python.org/issue1303614
----------
components: Interpreter Core
messages: 269470
nosy: rhettinger, serhiy.storchaka, xiang.zhang
priority: normal
severity: normal
status: open
title: Possible different behaviour of explicit and implicit __dict__ accessing when involving builtin types' __dict__ descriptors
type: behavior
versions: Python 3.6
_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue27411>
_______________________________________
More information about the Python-bugs-list
mailing list