From 16952218d0535904236e8a39851133688c9ce1f0 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Wed, 29 Apr 2026 19:39:29 -0700 Subject: [PATCH] gh-149083: Convert dataclasses.MISSING and dataclasses.KW_ONLY to sentinels (#149086) There were comments claiming these were implemented as custom classes to give a nicer repr(), but the repr() wasn't all that nice: >>> repr(dataclasses.MISSING) '' >>> repr(dataclasses.KW_ONLY) '' Sentinels are conceptually the right tool for these, so let's use them. This does change the repr() of these two objects. --- Lib/dataclasses.py | 13 ++++--------- Lib/test/test_dataclasses/__init__.py | 2 +- .../2026-04-27-20-15-54.gh-issue-149083.BdrpU8.rst | 2 ++ 3 files changed, 7 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-04-27-20-15-54.gh-issue-149083.BdrpU8.rst diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index df192763c5bd15..e9810d6bd5d57b 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -178,17 +178,12 @@ def __repr__(self): return '' _HAS_DEFAULT_FACTORY = _HAS_DEFAULT_FACTORY_CLASS() -# A sentinel object to detect if a parameter is supplied or not. Use -# a class to give it a better repr. -class _MISSING_TYPE: - pass -MISSING = _MISSING_TYPE() +# A sentinel object to detect if a parameter is supplied or not. +MISSING = sentinel("MISSING") # A sentinel object to indicate that following fields are keyword-only by -# default. Use a class to give it a better repr. -class _KW_ONLY_TYPE: - pass -KW_ONLY = _KW_ONLY_TYPE() +# default. +KW_ONLY = sentinel("KW_ONLY") # Since most per-field metadata will be unused, create an empty # read-only dictionary that can be shared among all fields. diff --git a/Lib/test/test_dataclasses/__init__.py b/Lib/test/test_dataclasses/__init__.py index 5eec9e23cd414b..8a0a7d12c04aa4 100644 --- a/Lib/test/test_dataclasses/__init__.py +++ b/Lib/test/test_dataclasses/__init__.py @@ -995,7 +995,7 @@ class D: self.assertNotIn('x', D.__dict__) def test_missing_repr(self): - self.assertIn('MISSING_TYPE object', repr(MISSING)) + self.assertEqual(repr(MISSING), 'MISSING') def test_dont_include_other_annotations(self): @dataclass diff --git a/Misc/NEWS.d/next/Library/2026-04-27-20-15-54.gh-issue-149083.BdrpU8.rst b/Misc/NEWS.d/next/Library/2026-04-27-20-15-54.gh-issue-149083.BdrpU8.rst new file mode 100644 index 00000000000000..7ad81616802116 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-04-27-20-15-54.gh-issue-149083.BdrpU8.rst @@ -0,0 +1,2 @@ +:data:`dataclasses.MISSING` and :data:`dataclasses.KW_ONLY` are now +instances of :class:`sentinel`.