bpo-20503: Show how isinstance() works with ABC registered classes. (GH-25175)
https://github.com/python/cpython/commit/7bc25ec7276db2a81e7823671a74eeb8aa6... commit: 7bc25ec7276db2a81e7823671a74eeb8aa6b4542 branch: master author: Raymond Hettinger <rhettinger@users.noreply.github.com> committer: rhettinger <rhettinger@users.noreply.github.com> date: 2021-04-05T12:48:24-07:00 summary: bpo-20503: Show how isinstance() works with ABC registered classes. (GH-25175) files: M Doc/faq/programming.rst diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 93ffd36d0e1b4..514ca04ab3c52 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__ + (<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
participants (1)
-
rhettinger