Skip to content

Commit 87f8fc8

Browse files
zuopicnixz
andauthored
gh-122102: Fix/improve docs of descriptor-related tools in inspect (GH-122104)
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
1 parent 7486c7b commit 87f8fc8

2 files changed

Lines changed: 40 additions & 24 deletions

File tree

Doc/library/inspect.rst

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -635,19 +635,18 @@ attributes (see :ref:`import-mod-attrs` for module attributes):
635635
.. function:: ismethoddescriptor(object)
636636

637637
Return ``True`` if the object is a method descriptor, but not if
638-
:func:`ismethod`, :func:`isclass`, :func:`isfunction` or :func:`isbuiltin`
639-
are true.
638+
:func:`isclass`, :func:`ismethod` or :func:`isfunction` is true.
640639

641640
This, for example, is true of ``int.__add__``. An object passing this test
642641
has a :meth:`~object.__get__` method, but not a :meth:`~object.__set__`
643642
method or a :meth:`~object.__delete__` method. Beyond that, the set of
644643
attributes varies. A :attr:`~definition.__name__` attribute is usually
645644
sensible, and :attr:`~definition.__doc__` often is.
646645

647-
Methods implemented via descriptors that also pass one of the other tests
648-
return ``False`` from the :func:`ismethoddescriptor` test, simply because the
649-
other tests promise more -- you can, e.g., count on having the
650-
:attr:`~method.__func__` attribute (etc) when an object passes
646+
Method descriptors that also pass any of the other tests (:func:`!isclass`,
647+
:func:`!ismethod` or :func:`!isfunction`) make this function return ``False``,
648+
simply because those other tests promise more -- you can, for example, count
649+
on having the :attr:`~method.__func__` attribute when an object passes
651650
:func:`ismethod`.
652651

653652
.. versionchanged:: 3.13
@@ -658,16 +657,28 @@ attributes (see :ref:`import-mod-attrs` for module attributes):
658657

659658
.. function:: isdatadescriptor(object)
660659

661-
Return ``True`` if the object is a data descriptor.
660+
Return ``True`` if the object is a data descriptor, but not if
661+
:func:`isclass`, :func:`ismethod` or :func:`isfunction` is true.
662662

663-
Data descriptors have a :attr:`~object.__set__` or a :attr:`~object.__delete__` method.
664-
Examples are properties (defined in Python), getsets, and members. The
665-
latter two are defined in C and there are more specific tests available for
666-
those types, which is robust across Python implementations. Typically, data
667-
descriptors will also have :attr:`~definition.__name__` and :attr:`!__doc__` attributes
668-
(properties, getsets, and members have both of these attributes), but this is
669-
not guaranteed.
663+
Data descriptors always have a :meth:`~object.__set__` method and/or
664+
a :meth:`~object.__delete__` method. Optionally, they may also have a
665+
:meth:`~object.__get__` method.
670666

667+
Examples of data descriptors are :func:`properties <property>`, getsets and
668+
member descriptors. Note that for the latter two (defined only in C extension
669+
modules), more specific tests are available: :func:`isgetsetdescriptor` and
670+
:func:`ismemberdescriptor`, respectively.
671+
672+
While data descriptors may also have :attr:`~definition.__name__` and
673+
:attr:`!__doc__` attributes (as properties, getsets and member descriptors
674+
do), this is not necessarily the case in general.
675+
676+
.. versionchanged:: 3.8
677+
This function now reports objects with only a :meth:`~object.__set__` method
678+
as being data descriptors (the presence of :meth:`~object.__get__` is no
679+
longer required for that). Moreover, objects with :meth:`~object.__delete__`,
680+
but not :meth:`~object.__set__`, are now properly recognized as data
681+
descriptors as well, which was not the case previously.
671682

672683
.. function:: isgetsetdescriptor(object)
673684

Lib/inspect.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -196,18 +196,18 @@ def ispackage(object):
196196
def ismethoddescriptor(object):
197197
"""Return true if the object is a method descriptor.
198198
199-
But not if ismethod() or isclass() or isfunction() are true.
199+
But not if ismethod(), isclass() or isfunction() is true.
200200
201-
This is new in Python 2.2, and, for example, is true of int.__add__.
202-
An object passing this test has a __get__ attribute, but not a
203-
__set__ attribute or a __delete__ attribute. Beyond that, the set
204-
of attributes varies; __name__ is usually sensible, and __doc__
205-
often is.
201+
An object passing this test (for example, int.__add__) has a __get__
202+
attribute, but not a __set__ attribute or a __delete__ attribute.
203+
Beyond that, the set of attributes varies; __name__ is usually
204+
sensible, and __doc__ often is.
206205
207206
Methods implemented via descriptors that also pass one of the other
208-
tests return false from the ismethoddescriptor() test, simply because
209-
the other tests promise more -- you can, e.g., count on having the
210-
__func__ attribute (etc) when an object passes ismethod()."""
207+
tests (ismethod(), isclass(), isfunction()) make this function return
208+
false, simply because those other tests promise more -- you can, for
209+
example, count on having the __func__ attribute when an object passes
210+
ismethod()."""
211211
if isclass(object) or ismethod(object) or isfunction(object):
212212
# mutual exclusion
213213
return False
@@ -219,8 +219,13 @@ def ismethoddescriptor(object):
219219
def isdatadescriptor(object):
220220
"""Return true if the object is a data descriptor.
221221
222+
But not if ismethod(), isclass() or isfunction() is true.
223+
222224
Data descriptors have a __set__ or a __delete__ attribute. Examples are
223-
properties (defined in Python) and getsets and members (defined in C).
225+
properties, getsets, and members. For the latter two (defined only in C
226+
extension modules) more specific tests are available as well:
227+
isgetsetdescriptor() and ismemberdescriptor(), respectively.
228+
224229
Typically, data descriptors will also have __name__ and __doc__ attributes
225230
(properties, getsets, and members have both of these attributes), but this
226231
is not guaranteed."""

0 commit comments

Comments
 (0)