summaryrefslogtreecommitdiffstats
path: root/Doc
diff options
context:
space:
mode:
authorRaymond Hettinger <rhettinger@users.noreply.github.com>2021-04-04 02:54:49 (GMT)
committerGitHub <noreply@github.com>2021-04-04 02:54:49 (GMT)
commitf8775e4f72240faba3947eea8efdd83ee56ae1fd (patch)
treeefc37102dd4ecb53d16200b2b164e896bf403b68 /Doc
parent35715d1e72b7e15e337087863c75af447199e0fb (diff)
downloadcpython-f8775e4f72240faba3947eea8efdd83ee56ae1fd.zip
cpython-f8775e4f72240faba3947eea8efdd83ee56ae1fd.tar.gz
cpython-f8775e4f72240faba3947eea8efdd83ee56ae1fd.tar.bz2
bpo-43325: Add FAQ entry for identity tests (GH-25168)
Diffstat (limited to 'Doc')
-rw-r--r--Doc/faq/programming.rst87
-rw-r--r--Doc/tutorial/datastructures.rst5
2 files changed, 89 insertions, 3 deletions
diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst
index b75c60a..93ffd36 100644
--- a/Doc/faq/programming.rst
+++ b/Doc/faq/programming.rst
@@ -1701,6 +1701,93 @@ to the object:
13891296
+When can I rely on identity tests with the *is* operator?
+---------------------------------------------------------
+
+The ``is`` operator tests for object identity. The test ``a is b`` is
+equivalent to ``id(a) == id(b)``.
+
+The most important property of an identity test is that an object is always
+identical to itself, ``a is a`` always returns ``True``. Identity tests are
+usually faster than equality tests. And unlike equality tests, identity tests
+are guaranteed to return a boolean ``True`` or ``False``.
+
+However, identity tests can *only* be substituted for equality tests when
+object identity is assured. Generally, there are three circumstances where
+identity is guaranteed:
+
+1) Assignments create new names but do not change object identity. After the
+assignment ``new = old``, it is guaranteed that ``new is old``.
+
+2) Putting an object in a container that stores object references does not
+change object identity. After the list assignment ``s[0] = x``, it is
+guaranteed that ``s[0] is x``.
+
+3) If an object is a singleton, it means that only one instance of that object
+can exist. After the assignments ``a = None`` and ``b = None``, it is
+guaranteed that ``a is b`` because ``None`` is a singleton.
+
+In most other circumstances, identity tests are inadvisable and equality tests
+are preferred. In particular, identity tests should not be used to check
+constants such as :class:`int` and :class:`str` which aren't guaranteed to be
+singletons::
+
+ >>> a = 1000
+ >>> b = 500
+ >>> c = b + 500
+ >>> a is c
+ False
+
+ >>> a = 'Python'
+ >>> b = 'Py'
+ >>> c = b + 'thon'
+ >>> a is c
+ False
+
+Likewise, new instances of mutable containers are never identical::
+
+ >>> a = []
+ >>> b = []
+ >>> a is b
+ False
+
+In the standard library code, you will see several common patterns for
+correctly using identity tests:
+
+1) As recommended by :pep:`8`, an identity test is the preferred way to check
+for ``None``. This reads like plain English in code and avoids confusion with
+other objects that may have boolean values that evaluate to false.
+
+2) Detecting optional arguments can be tricky when ``None`` is a valid input
+value. In those situations, you can create an singleton sentinel object
+guaranteed to be distinct from other objects. For example, here is how
+to implement a method that behaves like :meth:`dict.pop`::
+
+ _sentinel = object()
+
+ def pop(self, key, default=_sentinel):
+ if key in self:
+ value = self[key]
+ del self[key]
+ return value
+ if default is _sentinel:
+ raise KeyError(key)
+ return default
+
+3) Container implementations sometimes need to augment equality tests with
+identity tests. This prevents the code from being confused by objects such as
+``float('NaN')`` that are not equal to themselves.
+
+For example, here is the implementation of
+:meth:`collections.abc.Sequence.__contains__`::
+
+ def __contains__(self, value):
+ for v in self:
+ if v is value or v == value:
+ return True
+ return False
+
+
Modules
=======
diff --git a/Doc/tutorial/datastructures.rst b/Doc/tutorial/datastructures.rst
index 5c6b65f..e42b380 100644
--- a/Doc/tutorial/datastructures.rst
+++ b/Doc/tutorial/datastructures.rst
@@ -661,9 +661,8 @@ operators, not just comparisons.
The comparison operators ``in`` and ``not in`` check whether a value occurs
(does not occur) in a sequence. The operators ``is`` and ``is not`` compare
-whether two objects are really the same object; this only matters for mutable
-objects like lists. All comparison operators have the same priority, which is
-lower than that of all numerical operators.
+whether two objects are really the same object. All comparison operators have
+the same priority, which is lower than that of all numerical operators.
Comparisons can be chained. For example, ``a < b == c`` tests whether ``a`` is
less than ``b`` and moreover ``b`` equals ``c``.