New submission from Joshua Arnold <josharnol...@gmail.com>:

In 'Doc/reference/datamodel.rst', the 'Invoking Descriptors' documentation 
specifies the following behavior for super objects:

[snip]
Super Binding
   If ``a`` is an instance of :class:`super`, then the binding ``super(B,
   obj).m()`` searches ``obj.__class__.__mro__`` for the base class ``A``
   immediately preceding ``B`` and then invokes the descriptor with the call:
   ``A.__dict__['m'].__get__(obj, A)``.
[snip]

In the above paragrah, the call:

   A.__dict__['m'].__get__(obj, A)
   
is incorrect.  In reality, the descriptor is invoked via:

   A.__dict__['m'].__get__(obj, obj.__class__)
   
Loosely speaking, the 'owner' argument is set to the subclass associated with 
the super object, not the superclass.  There is a similar error in the 
'Descriptor HowTo Guide' under 'Invoking Descriptors'

(Strictly speaking, the specification is inaccurate on some other points.  It 
assumes obj is not a class and doesn't state that the entire mro preceding 'B' 
is searched for 'm'.  But those may be considered simplifications for the sake 
of brevity)

I considered reporting this as a bug in the implementation rather than the 
specification.  But I think the implementation's algorithm is the correct one.  
In particular, it yields the desired behavior for classmethods   In any case, 
the current behavior has been around for a while (it was the fix for issue 
#535444, dating back to 2.2)

Code demonstrating the current behavior:

class Desc(object):
    def __get__(self, instance, owner):
        return owner

class A(object):
    attr = Desc()

class B(A):
    pass

class C(B):
    pass

instance = C()

assert super(B,instance).attr == C
assert super(B,C).attr == C

#According to the specification, the assertions should be:
#assert super(B,instance).attr == A
#assert super(B,C).attr == A

----------
assignee: docs@python
components: Documentation
messages: 126895
nosy: Joshua.Arnold, docs@python
priority: normal
severity: normal
status: open
title: Descriptor protocol documentation for super bindings is incorrect
versions: Python 2.5, Python 2.6, Python 2.7, Python 3.1, Python 3.2

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue10988>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to