From: Raymond Hettinger Date: Mon, 5 Apr 2021 19:48:24 +0000 (-0700) Subject: bpo-20503: Show how isinstance() works with ABC registered classes. (GH-25175) X-Git-Tag: v3.10.0b1~403 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7bc25ec7276db2a81e7823671a74eeb8aa6b4542;p=thirdparty%2FPython%2Fcpython.git bpo-20503: Show how isinstance() works with ABC registered classes. (GH-25175) --- diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 93ffd36d0e1b..514ca04ab3c5 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -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__ + (, , ) + + # 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