distinguish a class that inherits from an attrs class from a true (decorated) attrs class
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 25/100
- Issue type
- Documentation
- Clarity
- Needs clarification
- Activity status
- Stale
- Tech stack
- python
- Domain
- documentation
Research direction
Start by reviewing issue 1332 and the documented attrs_init_subclass behavior, then inspect how attrs.has and attrs_attrs are described. Compare the shown cls.dict check for plain and decorated subclasses. Done means establishing whether this distinction is supported and documenting the safe, recommended approach or identifying the needed API clarification.
Written by the indexing model from the issue text.
Description
This question is related to issue https://github.com/python-attrs/attrs/issues/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?
- Dominant language
- Python
- Stars
- 5.8k
- Forks
- 480
- Avg merge
- 2h 15m
- Merged PRs (30d)
- 2
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from python-attrs/attrs
-
Difficulty 5/5 Over a week Newbie friendliness 20/100
python-attrs/attrs#1620 ·
-
Difficulty 3/5 1-2 days Newbie friendliness 55/100
python-attrs/attrs#1596 · 2 comments · 1 reaction ·
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
python-attrs/attrs#1549 · 3 comments ·
-
Difficulty 4/5 3-5 days Newbie friendliness 38/100
python-attrs/attrs#1543 · 2 comments ·
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
python-attrs/attrs#1532 ·
All issues in python-attrs/attrs
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100