[issue31735] Documentation incorrectly states how descriptors are invoked

2021-12-03 Thread Raymond Hettinger


Raymond Hettinger  added the comment:

> it should have
>
> d.__get__(obj, type(obj)) instead of d.__get__(obj)


The objtype argument is optional as shown in all of the examples.  The call 
from object.__getattribute__() always passes in both parameters, even though 
only the first is required.
  

# Demonstration of __get__() being called with one or two params

class A:
def __init__(self, x):
self.x = x
def m(self, y):
return self.x * y

>>> a = A(10)
>>> a.m(5)
50
>>> vars(A)['m'].__get__(a)(5) # objtype is not required
50
>>> vars(A)['m'].__get__(a, A)(5)  # objtype may be used
50



# Demonstration of object.__getattribute__ supplying both args

class Desc:
def __get__(self, *args):
return args
  
class B:
z = Desc()
 
>>> b = B()
>>> b.z
(<__main__.B object at 0x109156110>, )

--
resolution:  -> not a bug
stage:  -> resolved
status: open -> closed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue31735] Documentation incorrectly states how descriptors are invoked

2021-12-03 Thread Irit Katriel


Change by Irit Katriel :


--
versions: +Python 3.10, Python 3.11, Python 3.9 -Python 2.7, Python 3.4, Python 
3.5, Python 3.6, Python 3.7, Python 3.8

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue31735] Documentation incorrectly states how descriptors are invoked

2021-12-03 Thread Raymond Hettinger


Change by Raymond Hettinger :


--
assignee: docs@python -> rhettinger

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue31735] Documentation incorrectly states how descriptors are invoked

2021-12-03 Thread Irit Katriel


Irit Katriel  added the comment:

See also Issue20751

--
nosy: +iritkatriel, rhettinger

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue31735] Documentation incorrectly states how descriptors are invoked

2017-10-10 Thread Henk-Jaap Wagenaar

Henk-Jaap Wagenaar  added the comment:

I do think though that

"If d defines the method __get__(), then d.__get__(obj) is invoked according to 
the precedence rules listed below."

seems to contain a mistake in that it should have

d.__get__(obj, type(obj)) instead of d.__get__(obj)

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue31735] Documentation incorrectly states how descriptors are invoked

2017-10-10 Thread Henk-Jaap Wagenaar

Henk-Jaap Wagenaar  added the comment:

"We know this doesn't happen because nothing is printed to stdout."

Try running Obj().d, you will get output.

Obj.d does not work because it is on a *class*, and so it runs, per the docs:

'Obj.__dict__['d'].__get__(None, Obj)'

whereas you consider running it on an instance to get:

b = Obj()
b.d
# equivalent to
type(b).__dict__['d'].__get__(b, type(b))

and you will get output twice.

[Note, on python2 you will get an error, I think this is because your class 
does not inherit from object.]

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue31735] Documentation incorrectly states how descriptors are invoked

2017-10-09 Thread Paul Pinterits

Paul Pinterits  added the comment:

If we take this class:

class Obj:
@property
def d(self):
print('called')

And we access Obj.d:

_ = Obj.d

According to the docs, the following should happen:

# obj.d looks up d in the dictionary of obj
d = Obj.__dict__['d']

# If d defines the method __get__(),
if hasattr(d, '__get__'):

# then d.__get__(obj) is invoked
d.__get__(Obj)

We know this doesn't happen because nothing is printed to stdout.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue31735] Documentation incorrectly states how descriptors are invoked

2017-10-09 Thread Paul Pinterits

Paul Pinterits  added the comment:

I'm aware that descriptors have to exist on the class in order to work. The 
point is that the documentation states "If d defines the method __get__(), then 
d.__get__(obj) is invoked" (where d is obj.d), which is simply not true.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue31735] Documentation incorrectly states how descriptors are invoked

2017-10-09 Thread Henk-Jaap Wagenaar

Henk-Jaap Wagenaar  added the comment:

You get what you should get: when you print obj.d, Obj.d, you will get:



which is exactly what you expect:
- in the first case, you assigned a property object to the dictionary at 
obj.__dict__, so that's what you get back when you run obj.d.
- you defined a property on a class called d, and you get it when you run Obj.d

If you run print(Obj().d) you will get a TypeError: your lambda should read:

lambda self: print('called')

Properties should be added to the class not the instance, see 
https://stackoverflow.com/questions/1325673/how-to-add-property-to-a-class-dynamically
 and https://eev.ee/blog/2012/05/23/python-faq-descriptors/

--
nosy: +Henk-Jaap Wagenaar

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue31735] Documentation incorrectly states how descriptors are invoked

2017-10-09 Thread Paul Pinterits

New submission from Paul Pinterits :

The [descriptor 
howto](https://docs.python.org/3/howto/descriptor.html#invoking-descriptors) 
states:

"For example, obj.d looks up d in the dictionary of obj. If d defines the 
method __get__(), then d.__get__(obj) is invoked [...]"

This is not true - the descriptor obtained from obj's dictionary is never 
invoked. If it was, the following two snippets would produce output:


class Class:
pass

obj = Class()
obj.__dict__['d'] = property(lambda: print('called'))

_ = obj.d  # nothing is printed.


class Obj:
@property
def d(self):
print('called')

_ = Obj.d  # nothing is printed.

--
assignee: docs@python
components: Documentation
messages: 303968
nosy: Paul Pinterits, docs@python
priority: normal
severity: normal
status: open
title: Documentation incorrectly states how descriptors are invoked
versions: Python 2.7, Python 3.4, Python 3.5, Python 3.6, Python 3.7, Python 3.8

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com