Description
Bug report
Bug description:
During construction of a class Foo
, all objects in the class dictionary are checked to see if they have a __set_name__
attribute. If an object in the dictionary does have a __set_name__
attribute, it is called as part of the construction of Foo
:
>>> class Vanilla:
... def __set_name__(self, owner, name):
... print('set_name called')
...
>>> class Foo:
... attr = Vanilla()
...
set_name called
But what if an object in a class namespace is an instance of class that has a metaclass that raises a non-AttributeError
exception if __set_name__
is looked up on the class object? In this case, the exception is silently ignored when __set_name__
is looked up:
>>> class Meta(type):
... def __getattribute__(self, attr):
... if attr == "__set_name__":
... raise SystemExit('NO')
... return object.__getattribute__(self, attr)
...
>>> class Problematic(metaclass=Meta): pass
...
>>> try:
... Problematic.__set_name__
... except SystemExit:
... print('exception was raised')
...
exception was raised
>>> class Bar:
... attr = Problematic()
...
>>>
__set_name__
, like all dunders, is looked up on the Problematic
class object itself, rather than the instance of Problematic
found in the class dictionary of Foo
, so SystemExit
should be raised during the creation of the Bar
class when the interpreter tries to determine whether or not the Problematic
class has a __set_name__
attribute. Instead, however, the SystemExit
is silently swallowed.
I think the issue lies in this section of code here:
Lines 9989 to 9992 in d44ee42
I'm interested in working on this.
CPython versions tested on:
3.8, CPython main branch
Operating systems tested on:
Windows