bpo-36743: __get__ is sometimes called without the owner argument (GH-12992) (GH-15589)
(cherry picked from commit 0dac68f1e5
)
Co-authored-by: Raymond Hettinger <rhettinger@users.noreply.github.com>
This commit is contained in:
parent
0d45d50e42
commit
c71ae1a45b
|
@ -1618,21 +1618,32 @@ refers to the attribute whose name is the key of the property in the owner
|
||||||
class' :attr:`~object.__dict__`.
|
class' :attr:`~object.__dict__`.
|
||||||
|
|
||||||
|
|
||||||
.. method:: object.__get__(self, instance, owner)
|
.. method:: object.__get__(self, instance, owner=None)
|
||||||
|
|
||||||
Called to get the attribute of the owner class (class attribute access) or of an
|
Called to get the attribute of the owner class (class attribute access) or
|
||||||
instance of that class (instance attribute access). *owner* is always the owner
|
of an instance of that class (instance attribute access). The optional
|
||||||
class, while *instance* is the instance that the attribute was accessed through,
|
*owner* argument is the owner class, while *instance* is the instance that
|
||||||
or ``None`` when the attribute is accessed through the *owner*. This method
|
the attribute was accessed through, or ``None`` when the attribute is
|
||||||
should return the (computed) attribute value or raise an :exc:`AttributeError`
|
accessed through the *owner*.
|
||||||
exception.
|
|
||||||
|
|
||||||
|
This method should return the computed attribute value or raise an
|
||||||
|
:exc:`AttributeError` exception.
|
||||||
|
|
||||||
|
:PEP:`252` specifies that :meth:`__get__` is callable with one or two
|
||||||
|
arguments. Python's own built-in descriptors support this specification;
|
||||||
|
however, it is likely that some third-party tools have descriptors
|
||||||
|
that require both arguments. Python's own :meth:`__getattribute__`
|
||||||
|
implementation always passes in both arguments whether they are required
|
||||||
|
or not.
|
||||||
|
|
||||||
.. method:: object.__set__(self, instance, value)
|
.. method:: object.__set__(self, instance, value)
|
||||||
|
|
||||||
Called to set the attribute on an instance *instance* of the owner class to a
|
Called to set the attribute on an instance *instance* of the owner class to a
|
||||||
new value, *value*.
|
new value, *value*.
|
||||||
|
|
||||||
|
Note, adding :meth:`__set__` or :meth:`__delete__` changes the kind of
|
||||||
|
descriptor to a "data descriptor". See :ref:`descriptor-invocation` for
|
||||||
|
more details.
|
||||||
|
|
||||||
.. method:: object.__delete__(self, instance)
|
.. method:: object.__delete__(self, instance)
|
||||||
|
|
||||||
|
|
|
@ -281,7 +281,7 @@ except AttributeError:
|
||||||
class DocDescriptor:
|
class DocDescriptor:
|
||||||
"""Helper for builtins.open.__doc__
|
"""Helper for builtins.open.__doc__
|
||||||
"""
|
"""
|
||||||
def __get__(self, obj, typ):
|
def __get__(self, obj, typ=None):
|
||||||
return (
|
return (
|
||||||
"open(file, mode='r', buffering=-1, encoding=None, "
|
"open(file, mode='r', buffering=-1, encoding=None, "
|
||||||
"errors=None, newline=None, closefd=True)\n\n" +
|
"errors=None, newline=None, closefd=True)\n\n" +
|
||||||
|
|
|
@ -400,7 +400,7 @@ class partialmethod(object):
|
||||||
_method._partialmethod = self
|
_method._partialmethod = self
|
||||||
return _method
|
return _method
|
||||||
|
|
||||||
def __get__(self, obj, cls):
|
def __get__(self, obj, cls=None):
|
||||||
get = getattr(self.func, "__get__", None)
|
get = getattr(self.func, "__get__", None)
|
||||||
result = None
|
result = None
|
||||||
if get is not None:
|
if get is not None:
|
||||||
|
@ -905,7 +905,7 @@ class singledispatchmethod:
|
||||||
"""
|
"""
|
||||||
return self.dispatcher.register(cls, func=method)
|
return self.dispatcher.register(cls, func=method)
|
||||||
|
|
||||||
def __get__(self, obj, cls):
|
def __get__(self, obj, cls=None):
|
||||||
def _method(*args, **kwargs):
|
def _method(*args, **kwargs):
|
||||||
method = self.dispatcher.dispatch(args[0].__class__)
|
method = self.dispatcher.dispatch(args[0].__class__)
|
||||||
return method.__get__(obj, cls)(*args, **kwargs)
|
return method.__get__(obj, cls)(*args, **kwargs)
|
||||||
|
@ -943,7 +943,7 @@ class cached_property:
|
||||||
f"({self.attrname!r} and {name!r})."
|
f"({self.attrname!r} and {name!r})."
|
||||||
)
|
)
|
||||||
|
|
||||||
def __get__(self, instance, owner):
|
def __get__(self, instance, owner=None):
|
||||||
if instance is None:
|
if instance is None:
|
||||||
return self
|
return self
|
||||||
if self.attrname is None:
|
if self.attrname is None:
|
||||||
|
|
|
@ -2806,7 +2806,7 @@ class PropertyMock(Mock):
|
||||||
def _get_child_mock(self, /, **kwargs):
|
def _get_child_mock(self, /, **kwargs):
|
||||||
return MagicMock(**kwargs)
|
return MagicMock(**kwargs)
|
||||||
|
|
||||||
def __get__(self, obj, obj_type):
|
def __get__(self, obj, obj_type=None):
|
||||||
return self()
|
return self()
|
||||||
def __set__(self, obj, val):
|
def __set__(self, obj, val):
|
||||||
self(val)
|
self(val)
|
||||||
|
|
|
@ -78,7 +78,7 @@ class EiffelDescriptor:
|
||||||
self.__name__ = func.__name__
|
self.__name__ = func.__name__
|
||||||
self.__doc__ = func.__doc__
|
self.__doc__ = func.__doc__
|
||||||
|
|
||||||
def __get__(self, obj, cls):
|
def __get__(self, obj, cls=None):
|
||||||
return EiffelMethodWrapper(obj, self)
|
return EiffelMethodWrapper(obj, self)
|
||||||
|
|
||||||
def callmethod(self, inst, args, kwargs):
|
def callmethod(self, inst, args, kwargs):
|
||||||
|
|
Loading…
Reference in New Issue