homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: super() broken with classmethods
Type: Stage:
Components: Interpreter Core Versions: Python 2.2
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: gvanrossum Nosy List: gvanrossum, loewis, mwh, pje
Priority: normal Keywords:

Created on 2002年03月26日 22:13 by pje, last changed 2022年04月10日 16:05 by admin. This issue is now closed.

Messages (10)
msg9995 - (view) Author: PJ Eby (pje) * (Python committer) Date: 2002年03月26日 22:13
Using super() in a classmethod breaks in Python 2.2. 
Apparently, when super looks up an attribute from the
__mro__ sequence, it calls the found descriptor's
__get__ with the descriptor itself as the 'type'
argument, which breaks horribly with class methods
(which always binds to the type argument).
Presumably, the fix is to pass a NULL type argument,
which should work with the recent fixes to the
classmethod's __get__ logic. In other words, this code
in the super_getattro function Objects/typeobject.c:
tmp = f(res, su->obj, res);
should probably actually read:
tmp = f(res, su->obj, NULL);
msg9996 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2002年03月27日 12:26
Logged In: YES 
user_id=21627
Can you give an example of how to break it? Please also
report what your example does when you run it.
msg9997 - (view) Author: PJ Eby (pje) * (Python committer) Date: 2002年03月27日 13:06
Logged In: YES 
user_id=56214
class cm1(object):
 def cmm(klass):
 print klass
 cmm = classmethod(cmm)
class cm2(cm1):
 def cmm(klass):
 super(cm2,klass).cmm()
 cmm = classmethod(cmm)
cm2.cmm()
The above code prints "<classmethod object at 0x00A9B930>",
demonstrating that super(cm2,klass).cmm is bound improperly.
 (It should print <class '__main__.cm2'>, analagous to how
calling cm1.cmm() directly prints <class '__main__.cm1'>.) 
You can more specifically verify this like so:
>>> cm1.cmm.im_self
<class '__main__.cm1'>
>>> cm2.cmm.im_self
<class '__main__.cm2'>
>>> super(cm2,cm2).cmm.im_self
<classmethod object at 0x00A9B930>
>>> 
The last item's im_self should of course be <class
'__main__.cm2'>. As I said, the problem is that
super_getattro incorrectly asks the classmethod descriptor
to bind to *itself*, rather than to a type.
Note that if you use the pure Python example version of
"super" defined in the python.org/2.2/descrintro.html
document, the above examples work correctly as long as you
use a version of Python that has the "classmethod core dump"
problem fixed. However, the builtin super() never works
correctly for classmethods, whether the "classmethod core
dump" is fixed or not.
msg9998 - (view) Author: PJ Eby (pje) * (Python committer) Date: 2002年03月27日 13:38
Logged In: YES 
user_id=56214
Ugh. I just realized that my "presumable fix" is actually
wrong. I checked back on my "Python super" workaround, and
realized I modified Guido's example slightly, to call
__get__(self.__obj__,starttype), instead of
__get__(self.__obj__). This implies that the fix to
super_getattro is a little more complicated, since
super_getattro doesn't have a C variable equivalent to
starttype in the Python version of super. :(
msg9999 - (view) Author: Michael Hudson (mwh) (Python committer) Date: 2002年03月31日 20:19
Logged In: YES 
user_id=6656
Unless someone can come up with a obviously correct patch 
(and convince Guido that it's obviously correct) very soon, 
this isn't going to go into 2.2.1.
msg10000 - (view) Author: PJ Eby (pje) * (Python committer) Date: 2002年03月31日 23:17
Logged In: YES 
user_id=56214
Patch #537536 submitted to fix this. "make test" output is
same as before the patch. If someone can give me an idea of
where/how to insert a regression test for the bug being
fixed, I'll submit a patch for that, too. Thanks.
msg10001 - (view) Author: Michael Hudson (mwh) (Python committer) Date: 2002年04月01日 09:36
Logged In: YES 
user_id=6656
Assign to Guido.
Bearing in mind that I haven't even tried to understand this 
bug, the fact that you can't come up with a test case stands 
against you... if you're just asking where to put it, stick 
it in test_descr.
msg10002 - (view) Author: PJ Eby (pje) * (Python committer) Date: 2002年04月01日 19:46
Logged In: YES 
user_id=56214
I was indeed just asking where to put it, and how to
*insert* the test. Anyway, I found that most of what was
needed for the test was already in
test_descr.classmethods(), there were just a few conditions
using super() that needed adding. I've uploaded the patch
for test_descr to the patch #537536 for this bug.
By the way, the bug/patch submission guidelines were a
little unclear to me; specifically whether I was supposed to
put the patch with the bug or the bug with the patch or
upload everything to both or what. Hope my ignorance hasn't
inconvenienced anyone; this is my first time submitting
Python bugs and fixes. Also, I hadn't worked with the test
framework used in Python's test suite before, although I've
done quite a bit with unittest in my own code.
msg10003 - (view) Author: Michael Hudson (mwh) (Python committer) Date: 2002年04月01日 20:50
Logged In: YES 
user_id=6656
OK, you've found the right place, good.
The bug/patch guidlines are probably confusing because, 
unless you're part of the Python project I think you can't 
attach a file to a report you didn't submit. Generally I 
prefer patches to be attached to bugs, but that's just my 
opinion, I don't know what other developers think. I also 
think the whole bug/patch division is misguided, but that's 
another rant entirely.
I think you're doing fine! Now we just wait for Guido to 
stop changing nappies :)
msg10004 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2002年04月02日 21:27
Logged In: YES 
user_id=6380
I should probably mention that I checked in Phillip's patch
537536, closing this issue.
History
Date User Action Args
2022年04月10日 16:05:09adminsetgithub: 36335
2002年03月26日 22:13:29pjecreate

AltStyle によって変換されたページ (->オリジナル) /