PEP 3135 (new super()) __class__ references broken in 3.3

PEP 3135 defines the new zero-argument form of super() as implicitly equivalent to super(__class__, <first argument>), and up until 3.2 has behaved accordingly: if you accessed __class__ from inside a method, you would receive a reference to the lexically containing class. In 3.3, that currently doesn't work: you get NameError instead (http://bugs.python.org/issue14857) While the 3.2 behaviour wasn't documented in the language reference, it's *definitely* documented in PEP 3135 (and my recent updates to the 3.3 version of the metaclass docs were written accordingly - that's how I discovered the problem) The error in the alpha releases appears to be a consequence of the attempt to fix a problem where the special treatment of __class__ meant that you couldn't properly set the __class__ attribute of the class itself in the class body (see http://bugs.python.org/issue12370). The fact that patch went in without causing a test failure means that this aspect of PEP 3135 has no explicit tests - it was only tested indirectly through the zero-argument super() construct. What I plan to do: 1. Revert the previous fix for #12370 2. Add tests for direct access to __class__ from methods 3. Create a *new* fix for #12370 that only affects the class scope, not the method bodies (this will be harder than the previous fix which affected the resolution of __class__ *everywhere* in the class body). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Sun, May 20, 2012 at 6:51 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:
Correction - I only plan to *reopen* #12370. I agree it's a legitimate problem with the PEP 3135 implementation, but at least it's not a regression for something that previously worked in 3.2. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Sun, May 20, 2012 at 11:03 PM, Antoine Pitrou <solipsis@pitrou.net> wrote:
Being able to deconstruct zero-argument super into something simpler (i.e. an implicit closure reference) makes it a *lot* more understandable, and lets people create their own variations on that theme rather than having it be completely opaque black magic (as it is now in 3.3). If __class__ had been covered by the test suite, then #12370 would never have been fixed the way it was. However, while it isn't mentioned in the language reference (well, not until I added a mention of it yesterday), PEP 3135 itself *was* updated to say "Every function will have a cell named __class__ that contains the class object that the function is defined in". The special variable is named as part of the specification section of the PEP. This contrasts with PEP 3115 and the __build_class__ builtin, where the latter isn't mentioned in the PEP at all - it's just a CPython implementation artifact. So this isn't a matter of "What's the use case for accessing __class__ directly?" - it's a matter of "We broke backwards compatibility for a documented (albeit only in the originating PEP) feature and the test suite didn't pick it up". Now, it isn't just a matter of reverting the old patch, because we need to bump the magic number for the bytecode again. But the fix for #12370 *is* broken, because it didn't just affect the __class__ references at class scope - it also changed them all at method scope. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

2012/5/20 Nick Coghlan <ncoghlan@gmail.com>:
I don't understand why PEP 3135 cares how it's implemented. It's silly enough that you can get the class by "using" super (even just referencing the name). Thus that you can get __class__ reeks of more an implementation detail than a feature to me. -- Regards, Benjamin

On Sun, May 20, 2012 at 4:28 PM, Benjamin Peterson <benjamin@python.org> wrote:
It made sense at the time to discuss the issues together. It was often wanted to reference the "current class" and super was simply the most common reason for this and, as was the point of the PEP in the first place, given an even more direct shortcut. I never would have considered __class__ a simple implementation detail.
-- Read my blog! I depend on your acceptance of my opinion! I am interesting! http://techblog.ironfroggy.com/ Follow me if you're into that sort of thing: http://www.twitter.com/ironfroggy
participants (4)
-
Antoine Pitrou
-
Benjamin Peterson
-
Calvin Spealman
-
Nick Coghlan