2021-12-27 08:29:09 +00:00
|
|
|
# SPDX-License-Identifier: MIT
|
|
|
|
|
2017-10-26 10:55:34 +00:00
|
|
|
"""
|
2023-06-27 05:12:37 +00:00
|
|
|
Tests for `__init_subclass__` related functionality.
|
2017-10-26 10:55:34 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
import attr
|
|
|
|
|
|
|
|
|
|
|
|
def test_init_subclass_vanilla(slots):
|
|
|
|
"""
|
|
|
|
`super().__init_subclass__` can be used if the subclass is not an attrs
|
2019-02-25 15:09:57 +00:00
|
|
|
class both with dict and slotted classes.
|
2017-10-26 10:55:34 +00:00
|
|
|
"""
|
2018-06-10 17:40:07 +00:00
|
|
|
|
2017-10-26 10:55:34 +00:00
|
|
|
@attr.s(slots=slots)
|
|
|
|
class Base:
|
|
|
|
def __init_subclass__(cls, param, **kw):
|
|
|
|
super().__init_subclass__(**kw)
|
|
|
|
cls.param = param
|
|
|
|
|
|
|
|
class Vanilla(Base, param="foo"):
|
|
|
|
pass
|
|
|
|
|
|
|
|
assert "foo" == Vanilla().param
|
|
|
|
|
|
|
|
|
|
|
|
def test_init_subclass_attrs():
|
|
|
|
"""
|
|
|
|
`__init_subclass__` works with attrs classes as long as slots=False.
|
|
|
|
"""
|
2018-06-10 17:40:07 +00:00
|
|
|
|
2017-10-26 10:55:34 +00:00
|
|
|
@attr.s(slots=False)
|
|
|
|
class Base:
|
|
|
|
def __init_subclass__(cls, param, **kw):
|
|
|
|
super().__init_subclass__(**kw)
|
|
|
|
cls.param = param
|
|
|
|
|
|
|
|
@attr.s
|
|
|
|
class Attrs(Base, param="foo"):
|
|
|
|
pass
|
|
|
|
|
|
|
|
assert "foo" == Attrs().param
|
2023-06-27 05:12:37 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_init_subclass_slots_workaround():
|
|
|
|
"""
|
|
|
|
`__init_subclass__` works with modern APIs if care is taken around classes
|
|
|
|
existing twice.
|
|
|
|
"""
|
|
|
|
subs = {}
|
|
|
|
|
|
|
|
@attr.define
|
|
|
|
class Base:
|
|
|
|
def __init_subclass__(cls):
|
|
|
|
subs[cls.__qualname__] = cls
|
|
|
|
|
|
|
|
@attr.define
|
|
|
|
class Sub1(Base):
|
|
|
|
x: int
|
|
|
|
|
|
|
|
@attr.define
|
|
|
|
class Sub2(Base):
|
|
|
|
y: int
|
|
|
|
|
|
|
|
assert (Sub1, Sub2) == tuple(subs.values())
|