]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-20503: Show how isinstance() works with ABC registered classes. (GH-25175) (GH...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 5 Apr 2021 20:11:50 +0000 (13:11 -0700)
committerGitHub <noreply@github.com>
Mon, 5 Apr 2021 20:11:50 +0000 (13:11 -0700)
Doc/faq/programming.rst

index fd59f68034776ce6be168f12b75dfaedfbbdb232..3c8aa14fad10af1a5b80a7f07008f60285e474bb 100644 (file)
@@ -1420,6 +1420,41 @@ single class, e.g. ``isinstance(obj, (class1, class2, ...))``, and can also
 check whether an object is one of Python's built-in types, e.g.
 ``isinstance(obj, str)`` or ``isinstance(obj, (int, float, complex))``.
 
+Note that :func:`isinstance` also checks for virtual inheritance from an
+:term:`abstract base class`.  So, the test will return ``True`` for a
+registered class even if hasn't directly or indirectly inherited from it.  To
+test for "true inheritance", scan the :term:`MRO` of the class:
+
+.. testcode::
+
+    from collections.abc import Mapping
+
+    class P:
+         pass
+
+    class C(P):
+        pass
+
+    Mapping.register(P)
+
+.. doctest::
+
+    >>> c = C()
+    >>> isinstance(c, C)        # direct
+    True
+    >>> isinstance(c, P)        # indirect
+    True
+    >>> isinstance(c, Mapping)  # virtual
+    True
+
+    # Actual inheritance chain
+    >>> type(c).__mro__
+    (<class 'C'>, <class 'P'>, <class 'object'>)
+
+    # Test for "true inheritance"
+    >>> Mapping in type(c).__mro__
+    False
+
 Note that most programs do not use :func:`isinstance` on user-defined classes
 very often.  If you are developing the classes yourself, a more proper
 object-oriented style is to define methods on the classes that encapsulate a