diff --git a/peps/pep-0661.rst b/peps/pep-0661.rst
index 1d9e00917..c639ea5b4 100644
--- a/peps/pep-0661.rst
+++ b/peps/pep-0661.rst
@@ -33,11 +33,12 @@ programming. They have many uses, such as for:
Python has the special value ``None``, which is intended to be used as such
a sentinel value in most cases. However, sometimes an alternative sentinel
-value is needed, usually when it needs to be distinct from ``None``. These
-cases are common enough that several idioms for implementing such sentinels
-have arisen over the years, but uncommon enough that there hasn't been a
-clear need for standardization. However, the common implementations,
-including some in the stdlib, suffer from several significant drawbacks.
+value is needed, usually when it needs to be distinct from ``None`` since
+``None`` is a valid value in that context. Such cases are common enough that
+several idioms for implementing such sentinels have arisen over the years, but
+uncommon enough that there hasn't been a clear need for standardization.
+However, the common implementations, including some in the stdlib, suffer from
+several significant drawbacks.
This PEP proposes adding a utility for defining sentinel values, to be used
in the stdlib and made publicly available as part of the stdlib.
@@ -70,10 +71,10 @@ function's signature to be overly long and hard to read::
Additionally, two other drawbacks of many existing sentinels were brought up
in the discussion:
-1. Not having a distinct type, hence it being impossible to define clear
- type signatures for functions with sentinels as default values
-2. Incorrect behavior after being copied or unpickled, due to a separate
- instance being created and thus comparisons using ``is`` failing
+1. Some do not have a distinct type, hence it is impossible to define clear
+ type signatures for functions with such sentinels as default values.
+2. They behave unexpectedly after being copied or unpickled, due to a separate
+ instance being created and thus comparisons using ``is`` failing.
In the ensuing discussion, Victor Stinner supplied a list of currently used
sentinel values in the Python standard library [2]_. This showed that the
@@ -84,14 +85,15 @@ least one of the three above drawbacks.
The discussion did not lead to any clear consensus on whether a standard
implementation method is needed or desirable, whether the drawbacks mentioned
are significant, nor which kind of implementation would be good. The author
-of this PEP created an issue on bugs.python.org [3]_ suggesting options for
-improvement, but that focused on only a single problematic aspect of a few
-cases, and failed to gather any support.
+of this PEP created an issue on bugs.python.org (now a GitHub issue [3]_)
+suggesting options for improvement, but that focused on only a single
+problematic aspect of a few cases, and failed to gather any support.
A poll [4]_ was created on discuss.python.org to get a clearer sense of
-the community's opinions. The poll's results were not conclusive, with 40%
-voting for "The status-quo is fine / there’s no need for consistency in
-this", but most voters voting for one or more standardized solutions.
+the community's opinions. After nearly two weeks, significant further,
+discussion, and 39 votes, the poll's results were not conclusive. 40% had
+voted for "The status-quo is fine / there’s no need for consistency in
+this", but most voters had voted for one or more standardized solutions.
Specifically, 37% of the voters chose "Consistent use of a new, dedicated
sentinel factory / class / meta-class, also made publicly available in the
stdlib".
@@ -142,8 +144,8 @@ Specification
A new ``Sentinel`` class will be added to a new ``sentinels`` module.
Its initializer will accept a single required argument, the name of the
-sentinel object, and two optional arguments: the repr of the object, and the
-name of its module::
+sentinel object, and three optional arguments: the repr of the object, its
+boolean value, and the name of its module::
>>> from sentinels import Sentinel
>>> NotGiven = Sentinel('NotGiven')
@@ -160,7 +162,9 @@ operator, as is recommended for ``None``. Equality checks using ``==`` will
also work as expected, returning ``True`` only when the object is compared
with itself. Identity checks such as ``if value is MISSING:`` should usually
be used rather than boolean checks such as ``if value:`` or ``if not value:``.
-Sentinel instances are truthy by default, unlike ``None``.
+
+Sentinel instances are truthy by default, unlike ``None``. This parallels the
+default for arbitrary classes, as well as the boolean value of ``Ellipsis``.
The names of sentinels are unique within each module. When calling
``Sentinel()`` in a module where a sentinel with that name was already
@@ -183,9 +187,12 @@ automatic recognition does not work as intended, such as perhaps when using
Jython or IronPython. This parallels the designs of ``Enum`` and
``namedtuple``. For more details, see :pep:`435`.
-The ``Sentinel`` class may be sub-classed. Instances of each sub-class will
-be unique, even if using the same name and module. This allows for
-customizing the behavior of sentinels, such as controlling their truthiness.
+The ``Sentinel`` class may not be sub-classed, to avoid overly-clever uses
+based on it, such as attempts to use it as a base for implementing singletons.
+It is considered important that the addition of Sentinel to the stdlib should
+add minimal complexity.
+
+Ordering comparisons are undefined for sentinel objects.
Reference Implementation
@@ -359,7 +366,22 @@ Additional Notes
identical. If distinct sentinel objects are needed, make sure to use
distinct names.
-* There was a discussion on the typing-sig mailing list [8]_ about the typing
+* There is no single desirable value for the "truthiness" of sentinels, i.e.
+ their boolean value. It is sometimes useful for the boolean value to be
+ ``True``, and sometimes ``False``. Of the built-in sentinels in Python,
+ ``None`` evaluates to ``False``, while ``Ellipsis`` (a.k.a. ``...``)
+ evaluates to ``True``. The desire for this to be set as needed came up in
+ discussions as well.
+
+* The boolean value of ``NotImplemented`` is ``True``, but using this is
+ deprecated since Python 3.9 (doing so generates a deprecation warning.)
+ This deprecation is due to issues specific to ``NotImplemented``, as
+ described in bpo-35712 [8]_.
+
+* To define multiple, related sentinel values, possibly with a defined
+ ordering among them, one should instead use ``Enum`` or something similar.
+
+* There was a discussion on the typing-sig mailing list [9]_ about the typing
for these sentinels, where different options were discussed.
@@ -368,12 +390,13 @@ References
.. [1] Python-Dev mailing list: `The repr of a sentinel `_
.. [2] Python-Dev mailing list: `"The stdlib contains tons of sentinels" `_
-.. [3] `bpo-44123: Make function parameter sentinel values true singletons `_
+.. [3] `bpo-44123: Make function parameter sentinel values true singletons `_
.. [4] discuss.python.org Poll: `Sentinel Values in the Stdlib `_
.. [5] `The "sentinels" package on PyPI `_
.. [6] `The "sentinel" package on PyPI `_
.. [7] `Reference implementation at the taleinat/python-stdlib-sentinels GitHub repo `_
-.. [8] `Discussion thread about type signatures for these sentinels on the typing-sig mailing list `_
+.. [8] `bpo-35712: Make NotImplemented unusable in boolean context `_
+.. [9] `Discussion thread about type signatures for these sentinels on the typing-sig mailing list `_
Copyright