diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index 730ced7299865e..e133260e972c3e 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -831,6 +831,11 @@ 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) + # First checks if default is a descriptor, + # then checks if there is no default value returned by default.__get__. + if hasattr(default, "__get__") and default is cls.__dict__.get(a_name): + 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 3b335429b98500..a0978e9ec7609d 100644 --- a/Lib/test/test_dataclasses/__init__.py +++ b/Lib/test/test_dataclasses/__init__.py @@ -4186,6 +4186,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..bf8e24f3994c4a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-17-23-50-41.gh-issue-144749.sv3Ztr.rst @@ -0,0 +1,4 @@ +Previously descriptors that return themselves from calls to ``__get__`` were +treated as default values in a dataclass. Now, a ``TypeError`` is raised if no +initial value is provided to the dataclass constructor. +