gh-120381: Fix inspect.ismethoddescriptor() (#120383)

The `inspect.ismethoddescriptor()` function did not check for the lack of
`__delete__()` and, consequently, erroneously returned True when applied
to *data* descriptors with only `__get__()` and `__delete__()` defined.

Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
Co-authored-by: Alyssa Coghlan <ncoghlan@gmail.com>
This commit is contained in:
Jan Kaliszewski 2024-06-18 14:19:43 +02:00 committed by GitHub
parent 7c5da94b5d
commit dacc5ac71a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 135 additions and 10 deletions

View file

@ -307,9 +307,10 @@ def ismethoddescriptor(object):
But not if ismethod() or isclass() or isfunction() are true.
This is new in Python 2.2, and, for example, is true of int.__add__.
An object passing this test has a __get__ attribute but not a __set__
attribute, but beyond that the set of attributes varies. __name__ is
usually sensible, and __doc__ often is.
An object passing this test has a __get__ attribute, but not a
__set__ attribute or a __delete__ attribute. Beyond that, the set
of attributes varies; __name__ is usually sensible, and __doc__
often is.
Methods implemented via descriptors that also pass one of the other
tests return false from the ismethoddescriptor() test, simply because
@ -319,7 +320,9 @@ def ismethoddescriptor(object):
# mutual exclusion
return False
tp = type(object)
return hasattr(tp, "__get__") and not hasattr(tp, "__set__")
return (hasattr(tp, "__get__")
and not hasattr(tp, "__set__")
and not hasattr(tp, "__delete__"))
def isdatadescriptor(object):
"""Return true if the object is a data descriptor.