Issue 36743: Docs: Descript get signature defined differently across the docs (original) (raw)

Created on 2019-04-27 17:56 by jdufresne, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (7)

msg341004 - (view)

Author: Jon Dufresne (jdufresne) *

Date: 2019-04-27 17:56

Here: https://docs.python.org/3/reference/datamodel.html#object.get

The get signature is defined as:

object.get(self, instance, owner)

But here: https://docs.python.org/3/howto/descriptor.html#descriptor-protocol

It is defined as:

descr.get(self, obj, type=None)

It is not clear to me as a reader if all descriptors should have the owner/type argument default to None or if it should be required. If it should default to None, I think all doc examples should follow this expectation to make it clear to someone implementing a descriptor for the first time. As best I can tell, the owner/type is always passed. So perhaps the =None shouldn't be there.

Grepping the CPython code, I see lots of definitions for both required and optional, adding more confusion for me.

If there is a definitive answer, I'm happy to follow through by updating the docs.

msg341023 - (view)

Author: Raymond Hettinger (rhettinger) * (Python committer)

Date: 2019-04-28 07:12

Perhaps the datamodel docs can be clarified to note that callers are allowed to omit the third argument (which usually only makes sense when the second argument is not None). FWIW, section 3.3.2.3 already has an example of a direct call to a get descriptor with only the obj argument.

msg341333 - (view)

Author: Jeroen Demeyer (jdemeyer) * (Python triager)

Date: 2019-05-03 12:27

Personally, I have always found "instance" and "owner" very confusing names for these arguments. If you want to change the documentation, I would recommend changing those names too. Better names would be "obj" and "cls" or something like that.

msg341334 - (view)

Author: Jeroen Demeyer (jdemeyer) * (Python triager)

Date: 2019-05-03 12:42

Perhaps the datamodel docs can be clarified to note that callers are allowed to omit the third argument

That's not true in general, only when get is a slot wrapper (i.e. for classes implemented in C). When get is a Python function, nothing special is done, it's just a Python function.

msg350708 - (view)

Author: Raymond Hettinger (rhettinger) * (Python committer)

Date: 2019-08-29 04:51

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
        @property
        def p(self):
            return 43
        @classmethod
        def c(cls):
            return 44
        @staticmethod
        def s():
            return 45
        
>>> a = A()
>>> vars(A)['m'].__get__(a)()
42
>>> vars(A)['m'].__get__(a, A)()
42
>>> vars(A)['p'].__get__(a)
43
>>> vars(A)['p'].__get__(a, A)
43
>>> vars(A)['c'].__get__(a)()
44
>>> vars(A)['c'].__get__(a, A)()
44
>>> vars(A)['s'].__get__(a)()
45
>>> vars(A)['s'].__get__(a, A)()
45

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):
            print(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'>

msg350755 - (view)

Author: Raymond Hettinger (rhettinger) * (Python committer)

Date: 2019-08-29 08:27

New changeset 0dac68f1e593c11612ed54af9edb865d398f3b05 by Raymond Hettinger in branch 'master': bpo-36743: get is sometimes called without the owner argument (#12992) https://github.com/python/cpython/commit/0dac68f1e593c11612ed54af9edb865d398f3b05

msg350759 - (view)

Author: Raymond Hettinger (rhettinger) * (Python committer)

Date: 2019-08-29 09:02

New changeset c71ae1a45bd6e6d0f5aebc470b35f5a7dc0d8078 by Raymond Hettinger (Miss Islington (bot)) in branch '3.8': bpo-36743: get is sometimes called without the owner argument (GH-12992) (GH-15589) https://github.com/python/cpython/commit/c71ae1a45bd6e6d0f5aebc470b35f5a7dc0d8078

History

Date

User

Action

Args

2022-04-11 14:59:14

admin

set

github: 80924

2019-08-29 09:02:55

rhettinger

set

messages: +

2019-08-29 08:28:45

rhettinger

set

status: open -> closed
resolution: fixed
stage: patch review -> resolved

2019-08-29 08:27:54

miss-islington

set

pull_requests: + <pull%5Frequest15265>

2019-08-29 08:27:45

rhettinger

set

messages: +

2019-08-29 04:51:58

rhettinger

set

messages: +

2019-05-03 12:42:13

jdemeyer

set

messages: +

2019-05-03 12:27:51

jdemeyer

set

nosy: + jdemeyer
messages: +

2019-04-28 08:11:19

rhettinger

set

keywords: + patch
stage: patch review
pull_requests: + <pull%5Frequest12915>

2019-04-28 07:12:09

rhettinger

set

assignee: docs@python -> rhettinger
messages: +
versions: - Python 2.7, Python 3.5, Python 3.6, Python 3.9

2019-04-27 18:06:22

xtreak

set

nosy: + rhettinger

2019-04-27 17:56:43

jdufresne

create