[issue17853] Conflict between lexical scoping and name injection in __prepare__
Nick Coghlan added the comment: Aside from the spurious definition of CLASS_FREE, looks good to me. I did need to double check that PyDict_GetItem is the API that *doesn't* raise the error :) -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue17853 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue17853] Conflict between lexical scoping and name injection in __prepare__
Roundup Robot added the comment: New changeset cf65c7a75f55 by Benjamin Peterson in branch 'default': check local class namespace before reaching for cells (closes #17853) http://hg.python.org/cpython/rev/cf65c7a75f55 -- nosy: +python-dev resolution: - fixed stage: - committed/rejected status: open - closed ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue17853 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue17853] Conflict between lexical scoping and name injection in __prepare__
Changes by Alex Gaynor alex.gay...@gmail.com: -- nosy: +alex ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue17853 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue17853] Conflict between lexical scoping and name injection in __prepare__
Changes by Benjamin Peterson benja...@python.org: -- versions: +Python 3.4 -Python 3.2, Python 3.3 ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue17853 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue17853] Conflict between lexical scoping and name injection in __prepare__
Benjamin Peterson added the comment: Nick, care to review? -- keywords: +patch Added file: http://bugs.python.org/file30043/classderef.patch ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue17853 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue17853] Conflict between lexical scoping and name injection in __prepare__
Ethan Furman added the comment: Thanks, Benjamin. Looking at that patch I realize the fix was way beyond my current core-hacking skills. -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue17853 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue17853] Conflict between lexical scoping and name injection in __prepare__
Mark Dickinson added the comment: What's the purpose of the CLASS_FREE #definition? -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue17853 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue17853] Conflict between lexical scoping and name injection in __prepare__
Changes by Barry A. Warsaw ba...@python.org: -- nosy: +barry ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue17853 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue17853] Conflict between lexical scoping and name injection in __prepare__
Benjamin Peterson added the comment: That's superflous. -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue17853 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue17853] Conflict between lexical scoping and name injection in __prepare__
Nick Coghlan added the comment: Just to clarify, the problem here isn't to do with referencing the class name in particular, it's referencing *any* lexically scoped name from the class body, when a metaclass wants to inject that as variable name in the class namespace. Here's a case where it silently looks up the wrong value: class Meta(type): pass ... def f(): ... outer = lexically scoped ... class inner(metaclass=Meta): ... print(outer) ... f() lexically scoped class Meta(type): ... def __prepare__(*args): ... return dict(outer=from metaclass) ... f() lexically scoped That second one *should* say from metaclass, but it doesn't because the LOAD_DEREF completely ignores the local namespace. You can get the same exception noted above by moving the assignment after the inner class definition: def g(): ... class inner(metaclass=Meta): ... print(outer) ... outer = This causes an exception ... g() Traceback (most recent call last): File stdin, line 1, in module File stdin, line 2, in g File stdin, line 3, in inner NameError: free variable 'outer' referenced before assignment in enclosing scope We simply missed the fact that PEP 3115 and the __prepare__ method mean that using LOAD_DEREF to resolve lexically scoped names in a nested class is now wrong. Instead, we need a new opcode that first tries the class namespace and only if that fails does it fall back to looking it up in the lexically scoped cell reference. (I changed the affected versions, as even though this *is* a bug in all current Python 3 versions, there's no way we're going to change the behaviour of name resolution in a maintenance release) -- nosy: +ncoghlan title: class construction name resolution broken in functions - Conflict between lexical scoping and name injection in __prepare__ versions: +Python 3.4 -Python 3.2, Python 3.3 ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue17853 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue17853] Conflict between lexical scoping and name injection in __prepare__
Changes by Benjamin Peterson benja...@python.org: -- nosy: +benjamin.peterson versions: +Python 3.2, Python 3.3 -Python 3.4 ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue17853 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue17853] Conflict between lexical scoping and name injection in __prepare__
Ethan Furman added the comment: Perhaps you and Benjamin should discuss that. :) I just read a thread on core-mentors about when a bug is fixed or not -- considering that the behavior is plain wrong, that workarounds will still work even if the bug is fixed, why shouldn't we fix it even in a maintenance release? -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue17853 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue17853] Conflict between lexical scoping and name injection in __prepare__
Benjamin Peterson added the comment: There's no need for a discussion; the answer is no. -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue17853 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue17853] Conflict between lexical scoping and name injection in __prepare__
Nick Coghlan added the comment: In this case, we won't fix it in a maintenance release because of the kind of change required to eliminate the bug. Adding a new opcode is likely to be the simplest fix and that is necessarily a backwards incompatible change (since older versions won't understand the new opcode). Even if we find a solution that doesn't require a new opcode, fixing the problem is going to require changes to both the compiler and the eval loop, and we simply don't touch those in maintenance releases without a *really* compelling reason. Fixing an edge case related to the interaction between two features that are already somewhat obscure on their own doesn't qualify. If anyone does decide to tackle this, I'll note that my examples in my previous post may be useful as inspiration for a test case - the final versions of both f() and g() should report from metaclass as the value of outer inside the class body, and it should be simple enough to replace the print statements with self.assertEqual() in a unit test. -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue17853 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue17853] Conflict between lexical scoping and name injection in __prepare__
Ethan Furman added the comment: Nick, thanks for the explanation. Benjamin, I was referring to Nick taking 3.3 and 3.2 off the issue and leaving 3.4, and you reversing it. ;) Sorry for the confusion -- I just reread my post and the words there didn't match the ideas in my head at the time very well. -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue17853 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com