8000 [3.13] gh-91126: Docs and tests for slotted dataclasses with `__init_… · python/cpython@cfdf376 · GitHub
[go: up one dir, main page]

Skip to content

Commit cfdf376

Browse files
[3.13] gh-91126: Docs and tests for slotted dataclasses with __init_subclass__ (GH-123342) (#123568)
gh-91126: Docs and tests for slotted dataclasses with `__init_subclass__` (GH-123342) (cherry picked from commit 75e7282) Co-authored-by: sobolevn <mail@sobolevn.me>
1 parent b0a50a6 commit cfdf376

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

Doc/library/dataclasses.rst

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,21 @@ Module contents
185185
- *slots*: If true (the default is ``False``), :attr:`~object.__slots__` attribute
186186
will be generated and new class will be returned instead of the original one.
187187
If :attr:`!__slots__` is already defined in the class, then :exc:`TypeError`
188-
is raised. Calling no-arg :func:`super` in dataclasses using ``slots=True`` will result in
189-
the following exception being raised:
190-
``TypeError: super(type, obj): obj must be an instance or subtype of type``.
191-
The two-arg :func:`super` is a valid workaround. See :gh:`90562` for full details.
188+
is raised.
189+
190+
.. warning::
191+
Calling no-arg :func:`super` in dataclasses using ``slots=True``
192+
will result in the following exception being raised:
193+
``TypeError: super(type, obj): obj must be an instance or subtype of type``.
194+
The two-arg :func:`super` is a valid workaround.
195+
See :gh:`90562` for full details.
196+
197+
.. warning::
198+
Passing parameters to a base class :meth:`~object.__init_subclass__`
199+
when using ``slots=True`` will result in a :exc:`TypeError`.
200+
Either use ``__init_subclass__`` with no parameters
201+
or use default values as a workaround.
202+
See :gh:`91126` for full details.
192203

193204
.. versionadded:: 3.10
194205

Lib/test/test_dataclasses/__init__.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3664,6 +3664,38 @@ class A(WithDictSlot): ...
36643664
self.assertEqual(A().__dict__, {})
36653665
A()
36663666

3667+
@support.cpython_only
3668+
def test_slots_with_wrong_init_subclass(self):
3669+
# TODO: This test is for a kinda-buggy behavior.
3670+
# Ideally, it should be fixed and `__init_subclass__`
3671+
# should be fully supported in the future versions.
3672+
# See https://github.com/python/cpython/issues/91126
3673+
class WrongSuper:
3674+
def __init_subclass__(cls, arg):
3675+
pass
3676+
3677+
with self.assertRaisesRegex(
3678+
TypeError,
3679+
"missing 1 required positional argument: 'arg'",
3680+
):
3681+
@dataclass(slots=True)
3682+
class WithWrongSuper(WrongSuper, arg=1):
3683+
pass
3684+
3685+
class CorrectSuper:
3686+
args = []
3687+
def __init_subclass__(cls, arg="default"):
3688+
cls.args.append(arg)
3689+
3690+
@dataclass(slots=True)
3691+
class WithCorrectSuper(CorrectSuper):
3692+
pass
3693+
3694+
# __init_subclass__ is called twice: once for `WithCorrectSuper`
3695+
# and once for `WithCorrectSuper__slots__` new class
3696+
# that we create internally.
3697+
self.assertEqual(CorrectSuper.args, ["default", "default"])
3698+
36673699

36683700
class TestDescriptors(unittest.TestCase):
36693701
def test_set_name(self):

0 commit comments

Comments
 (0)
0