distinguish a class that inherits from an attrs class from a true (decorated) attrs class #1334
Description
This question is related to issue #1332, where I needed an __init_subclass__
to be run only once for subclasses of an attrs base class. The issue with using built-in __init_subclass__
is that it doesn't play well with decorated classes, such as attrs or dataclass classes. Hence the addition of a new __attrs_init_subclass__
classmethod.
However, this method (rightfully) only gets called for subclasses that are explicitly decorated as attrs classes. I need a way to run code in an __init_subclass__
method of an attrs class for both attrs and plain old Python (POP) subclasses. I first thought of checking attrs.has
on the subclass to see if it is an attrs or POP class. But of course the subclass inherits the __attrs_attrs__
field from the attrs base class, so this can't be used to make the distinction.
My question is thus: How can I distinguish a class that inherits from an attrs class from a true (decorated) attrs class? Some search suggests one way to achieve this is to check whether __attrs_attrs__
is in the class dict of the subclass.
from attrs import frozen
def is_directly_decorated(cls) -> bool:
return "__attrs_attrs__" in cls.__dict__
def print_if_directly_decorated(cls):
print(
f"{cls.__name__} "
+ ("is" if is_directly_decorated(cls) else "isn't")
+ " directly decorated"
)
@frozen
class BaseAttr: ...
class Sub(BaseAttr): ...
@frozen
class SubAttr(BaseAttr): ...
print_if_directly_decorated(Sub)
print_if_directly_decorated(SubAttr)
this gives
Sub isn't directly decorated
SubAttr is directly decorated
Is this a safe way to do this? Or can I exploit some built-in or attrs functions/methods to make this distinction?