[docs] [issue36743] Docs: Descript __get__ signature defined differently across the docs

Raymond Hettinger report at bugs.python.org
Thu Aug 29 00:51:58 EDT 2019

Raymond Hettinger <raymond.hettinger at gmail.com> added the comment:

Collecting various factlets on this topic

PEP 252 gives the specification for the descriptor protocol: "__get__(): a function callable with one or two arguments that retrieves the attribute value from an object."

function_get, property_get, classmethod_get, and staticmethod_get all support calls with one or two arguments:

    >>> a = A()
    >>> class A:
            def m(self):
                return 42
            def p(self):
                return 43
            def c(cls):
                return 44
            def s():
                return 45
    >>> a = A()
    >>> vars(A)['m'].__get__(a)()
    >>> vars(A)['m'].__get__(a, A)()
    >>> vars(A)['p'].__get__(a)
    >>> vars(A)['p'].__get__(a, A)
    >>> vars(A)['c'].__get__(a)()
    >>> vars(A)['c'].__get__(a, A)()
    >>> vars(A)['s'].__get__(a)()
    >>> vars(A)['s'].__get__(a, A)()

Python functions that comply with the specification should also do the same (as taught by the descriptor HOWTO).  That said, I have found multiple Python functions that aren't providing the None default.  I will fix those as I find them.

type.__getattribute__, object.__getattribute__ and super.__getattribute__ always call __get__ with both attributes specified:

    >>> class D:
            def __get__(*args):

    >>> class C:
            d = D()

    >>> class S(C):
            def f(self):
                return super().d
    >>> C.d
    (<__main__.D object at 0x104d967f0>, None, <class '__main__.C'>)
    >>> C().d
    (<__main__.D object at 0x104d967f0>, <__main__.C object at 0x104df77c0>, <class '__main__.C'>)
    >>> S().f()
    (<__main__.D object at 0x104d967f0>, <__main__.S object at 0x104df7580>, <class '__main__.S'>


Python tracker <report at bugs.python.org>

More information about the docs mailing list