From 20b62f771ff0e76c4cfec1993d7e573c53b3aaa8 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 9 May 2026 10:58:41 -0700 Subject: [PATCH 1/2] gh-149083: Use sentinel for os.path.{ALLOW_MISSING,ALL_BUT_LAST} --- Doc/library/os.path.rst | 4 ++-- Lib/genericpath.py | 22 +++++-------------- ...-05-09-10-58-34.gh-issue-149083.I53mx4.rst | 2 ++ 3 files changed, 9 insertions(+), 19 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-05-09-10-58-34.gh-issue-149083.I53mx4.rst diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst index 808187061733be..3026b1de616d09 100644 --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -482,13 +482,13 @@ the :mod:`glob` module.) .. data:: ALL_BUT_LAST - Special value used for the *strict* argument in :func:`realpath`. + :class:`sentinel` used for the *strict* argument in :func:`realpath`. .. versionadded:: 3.15 .. data:: ALLOW_MISSING - Special value used for the *strict* argument in :func:`realpath`. + :class:`sentinel` used for the *strict* argument in :func:`realpath`. .. versionadded:: 3.15 diff --git a/Lib/genericpath.py b/Lib/genericpath.py index 71ae19190839ae..5c666e233c3229 100644 --- a/Lib/genericpath.py +++ b/Lib/genericpath.py @@ -201,20 +201,8 @@ def _check_arg_types(funcname, *args): raise TypeError("Can't mix strings and bytes in path components") from None -# Singletons with a true boolean value. - -@object.__new__ -class ALL_BUT_LAST: - """Special value for use in realpath().""" - def __repr__(self): - return 'os.path.ALL_BUT_LAST' - def __reduce__(self): - return self.__class__.__name__ - -@object.__new__ -class ALLOW_MISSING: - """Special value for use in realpath().""" - def __repr__(self): - return 'os.path.ALLOW_MISSING' - def __reduce__(self): - return self.__class__.__name__ +# Sentinels. +ALL_BUT_LAST = sentinel('ALL_BUT_LAST') +"""Special value for use in realpath().""" +ALLOW_MISSING = sentinel('ALLOW_MISSING') +"""Special value for use in realpath().""" diff --git a/Misc/NEWS.d/next/Library/2026-05-09-10-58-34.gh-issue-149083.I53mx4.rst b/Misc/NEWS.d/next/Library/2026-05-09-10-58-34.gh-issue-149083.I53mx4.rst new file mode 100644 index 00000000000000..19d2fed6a4e6b7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-05-09-10-58-34.gh-issue-149083.I53mx4.rst @@ -0,0 +1,2 @@ +:data:`os.path.ALLOW_MISSING` and :data:`os.path.ALL_BUT_LAST` are now +instances of :class:`sentinel`. From 71b5fee3ec270a086585226203f8cfac5d049a5e Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 9 May 2026 11:16:19 -0700 Subject: [PATCH 2/2] update test --- Lib/test/test_genericpath.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py index 10d3f409d883c5..fe08eee916cf5c 100644 --- a/Lib/test/test_genericpath.py +++ b/Lib/test/test_genericpath.py @@ -330,8 +330,8 @@ def test_realpath_mode_values(self): for name in 'ALL_BUT_LAST', 'ALLOW_MISSING': with self.subTest(name): mode = getattr(self.pathmodule, name) - self.assertEqual(repr(mode), 'os.path.' + name) - self.assertEqual(str(mode), 'os.path.' + name) + self.assertEqual(repr(mode), name) + self.assertEqual(str(mode), name) self.assertTrue(mode) self.assertIs(copy.copy(mode), mode) self.assertIs(copy.deepcopy(mode), mode)