mirror of
https://github.com/python/cpython.git
synced 2025-10-03 21:55:41 +00:00
[3.12] gh-91126: Docs and tests for slotted dataclasses with __init_subclass__
(GH-123342) (#123569)
gh-91126: Docs and tests for slotted dataclasses with `__init_subclass__` (GH-123342)
(cherry picked from commit 75e72822a3
)
Co-authored-by: sobolevn <mail@sobolevn.me>
This commit is contained in:
parent
e3d8ccc89d
commit
12db938d43
2 changed files with 47 additions and 4 deletions
|
@ -185,10 +185,21 @@ Module contents
|
||||||
- *slots*: If true (the default is ``False``), :attr:`~object.__slots__` attribute
|
- *slots*: If true (the default is ``False``), :attr:`~object.__slots__` attribute
|
||||||
will be generated and new class will be returned instead of the original one.
|
will be generated and new class will be returned instead of the original one.
|
||||||
If :attr:`!__slots__` is already defined in the class, then :exc:`TypeError`
|
If :attr:`!__slots__` is already defined in the class, then :exc:`TypeError`
|
||||||
is raised. Calling no-arg :func:`super` in dataclasses using ``slots=True`` will result in
|
is raised.
|
||||||
the following exception being raised:
|
|
||||||
``TypeError: super(type, obj): obj must be an instance or subtype of type``.
|
.. warning::
|
||||||
The two-arg :func:`super` is a valid workaround. See :gh:`90562` for full details.
|
Calling no-arg :func:`super` in dataclasses using ``slots=True``
|
||||||
|
will result in the following exception being raised:
|
||||||
|
``TypeError: super(type, obj): obj must be an instance or subtype of type``.
|
||||||
|
The two-arg :func:`super` is a valid workaround.
|
||||||
|
See :gh:`90562` for full details.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
Passing parameters to a base class :meth:`~object.__init_subclass__`
|
||||||
|
when using ``slots=True`` will result in a :exc:`TypeError`.
|
||||||
|
Either use ``__init_subclass__`` with no parameters
|
||||||
|
or use default values as a workaround.
|
||||||
|
See :gh:`91126` for full details.
|
||||||
|
|
||||||
.. versionadded:: 3.10
|
.. versionadded:: 3.10
|
||||||
|
|
||||||
|
|
|
@ -3560,6 +3560,38 @@ class TestSlots(unittest.TestCase):
|
||||||
self.assertEqual(A().__dict__, {})
|
self.assertEqual(A().__dict__, {})
|
||||||
A()
|
A()
|
||||||
|
|
||||||
|
@support.cpython_only
|
||||||
|
def test_slots_with_wrong_init_subclass(self):
|
||||||
|
# TODO: This test is for a kinda-buggy behavior.
|
||||||
|
# Ideally, it should be fixed and `__init_subclass__`
|
||||||
|
# should be fully supported in the future versions.
|
||||||
|
# See https://github.com/python/cpython/issues/91126
|
||||||
|
class WrongSuper:
|
||||||
|
def __init_subclass__(cls, arg):
|
||||||
|
pass
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(
|
||||||
|
TypeError,
|
||||||
|
"missing 1 required positional argument: 'arg'",
|
||||||
|
):
|
||||||
|
@dataclass(slots=True)
|
||||||
|
class WithWrongSuper(WrongSuper, arg=1):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class CorrectSuper:
|
||||||
|
args = []
|
||||||
|
def __init_subclass__(cls, arg="default"):
|
||||||
|
cls.args.append(arg)
|
||||||
|
|
||||||
|
@dataclass(slots=True)
|
||||||
|
class WithCorrectSuper(CorrectSuper):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# __init_subclass__ is called twice: once for `WithCorrectSuper`
|
||||||
|
# and once for `WithCorrectSuper__slots__` new class
|
||||||
|
# that we create internally.
|
||||||
|
self.assertEqual(CorrectSuper.args, ["default", "default"])
|
||||||
|
|
||||||
|
|
||||||
class TestDescriptors(unittest.TestCase):
|
class TestDescriptors(unittest.TestCase):
|
||||||
def test_set_name(self):
|
def test_set_name(self):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue