summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsobolevn <mail@sobolevn.me>2024-09-01 10:25:34 (GMT)
committerGitHub <noreply@github.com>2024-09-01 10:25:34 (GMT)
commit75e72822a390df81ca11355d8e0aac88e4046c27 (patch)
treef5705299e65037cc2f63c4cf2bcc8d53d8e9ad9d
parentd9439a205acf3d6ed64fc54239249e16b14f9e69 (diff)
downloadcpython-75e72822a390df81ca11355d8e0aac88e4046c27.zip
cpython-75e72822a390df81ca11355d8e0aac88e4046c27.tar.gz
cpython-75e72822a390df81ca11355d8e0aac88e4046c27.tar.bz2
gh-91126: Docs and tests for slotted dataclasses with `__init_subclass__` (#123342)
-rw-r--r--Doc/library/dataclasses.rst19
-rw-r--r--Lib/test/test_dataclasses/__init__.py32
2 files changed, 47 insertions, 4 deletions
diff --git a/Doc/library/dataclasses.rst b/Doc/library/dataclasses.rst
index c892c5c..324403f 100644
--- a/Doc/library/dataclasses.rst
+++ b/Doc/library/dataclasses.rst
@@ -185,10 +185,21 @@ Module contents
- *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.
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
- 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.
+ is raised.
+
+ .. warning::
+ 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
diff --git a/Lib/test/test_dataclasses/__init__.py b/Lib/test/test_dataclasses/__init__.py
index b93c99d..da696ad 100644
--- a/Lib/test/test_dataclasses/__init__.py
+++ b/Lib/test/test_dataclasses/__init__.py
@@ -3664,6 +3664,38 @@ class TestSlots(unittest.TestCase):
self.assertEqual(A().__dict__, {})
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):
def test_set_name(self):