diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index bd317aa9b0f2f3..9ec9bce2cf9083 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -822,6 +822,13 @@ def _get_field(cls, a_name, a_type, default_kw_only): # If the default value isn't derived from Field, then it's only a # normal default value. Convert it to a Field(). default = getattr(cls, a_name, MISSING) + # Check if default is a data descriptor that returns itself when + # accessed at the class level, meaning it is not providing a + # default value. + if (hasattr(default, "__get__") and default is cls.__dict__.get(a_name) + and (hasattr(default, "__set__") or hasattr(default, "__delete__"))): + default = MISSING + if isinstance(default, Field): f = default else: diff --git a/Lib/test/test_dataclasses/__init__.py b/Lib/test/test_dataclasses/__init__.py index a89999bb97938c..6c297b6ca8d441 100644 --- a/Lib/test/test_dataclasses/__init__.py +++ b/Lib/test/test_dataclasses/__init__.py @@ -4375,6 +4375,23 @@ class C: with self.assertRaisesRegex(TypeError, 'missing 1 required positional argument'): c = C() + def test_return_self_no_default_value(self): + class D: + def __get__(self, instance: Any, owner: object) -> Any: + if instance is None: + return self + return instance._x + + def __set__(self, instance: Any, value: int) -> None: + instance._x = value + + @dataclass + class C: + i: D = D() + + with self.assertRaisesRegex(TypeError, 'missing 1 required positional argument'): + c = C() + class TestStringAnnotations(unittest.TestCase): def test_classvar(self): # Some expressions recognized as ClassVar really aren't. But diff --git a/Misc/NEWS.d/next/Library/2026-02-17-23-50-41.gh-issue-144749.sv3Ztr.rst b/Misc/NEWS.d/next/Library/2026-02-17-23-50-41.gh-issue-144749.sv3Ztr.rst new file mode 100644 index 00000000000000..08911be699832d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-17-23-50-41.gh-issue-144749.sv3Ztr.rst @@ -0,0 +1,3 @@ +Previously, descriptors that return themselves from calls to :meth:`~object.__get__` were +treated as default values in :mod:`dataclasses`. Now, a :exc:`TypeError` is raised if no +initial value is provided to the :mod:`dataclass ` constructor.