Open
Description
Bug report
When one puts __dict__
as a class attribute, the behavior becomes very odd:
>>> class A:
... __dict__ = {'a': 1}
... def __init__(self):
... self.b = 2
...
>>> a = A()
>>> print("a.b:", a.b)
a.b: 2
>>> print("a.__dict__", a.__dict__)
a.__dict__ {'a': 1}
>>> print("a has a", hasattr(a, 'a'))
a has a False
>>> print("a has b", hasattr(a, 'b'))
a has b True
>>> print("dir(a)", dir(a))
dir(a) ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a']
>>> print("a.a", a.a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'a'
Moving it to be an instance attribute, does what one expects:
>>> class A:
... def __init__(self):
... self.__dict__ = {'a': 1}
... self.b = 2
...
>>> a = A()
>>> print("a.b:", a.b)
a.b: 2
>>> print("a.__dict__", a.__dict__)
a.__dict__ {'a': 1, 'b': 2}
>>> print("a has a", hasattr(a, 'a'))
a has a True
>>> print("a has b", hasattr(a, 'b'))
a has b True
>>> print("dir(a)", dir(a))
dir(a) ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a', 'b']
>>> print("a.a", a.a)
a.a 1
I know one shouldn't have a __dict__
as a class attribute, but I think it would be nice to either have a good error message when that happens, or to make things more consistent, i.e. all([hasattr(a, x) for x in dir(a)])
should be true maybe?
We encountered this issue since certain pickle
related logic was changed in 3.11: scikit-learn/scikit-learn#25188 (comment)
Your environment
- CPython versions tested on: Python 3.11.0 | packaged by conda-forge | (main, Oct 25 2022, 06:24:40) [GCC 10.4.0] on linux
- Operating system and architecture: archlinux, x86_64