New submission from Nick Coghlan:
In http://bugs.python.org/issue28884#msg282535 Armin Rigo points out that the
zero-argument super() cell injection currently interacts a little strangely
with explicit "nonlocal __class__" statements in nested namespaces.
Specifically, it acts like a closure variable that isn't visible in its own
scope, but can be accessed via nonlocal in nested class scopes:
>>> class C_with_nested_nonlocal:
... class Inner:
... nonlocal __class__
... __class__ = 42
... print(locals())
...
{'__module__': '__main__', '__qualname__': 'C_with_nested_nonlocal', 'Inner':
<class '__main__.C_with_nested_nonlocal.Inner'>, '__class__': 42}
This weird behaviour is due to the way the CPython code generator injects
__class__ into the namespaces we track during symbol table generation
(specifically, it's made available as a free variable for nested namespaces to
reference without actually adding it to the local symbol namespace for the
class body). There's no requirement for other implementations to replicate the
full details of that idiosyncratic behaviour, but there is a requirement that
__class__ and (in 3.6+) __classcell__ not show up in locals() by default when
evaluating the class body.
And methods can similarly overwrite the interpreter provided reference to the
defining class:
>>> class C_with_method_assignment_to_class_cell:
... def bad_method(self):
... nonlocal __class__
... __class__ = 42
... def other_method(self):
... return __class__
... bad_method(None)
... print(locals()["__class__"])
...
42
>>> C_with_method_assignment_to_class_cell().other_method()
<class '__main__.C_with_method_assignment_to_class_cell'>
>>> C_with_method_assignment_to_class_cell().bad_method()
>>> C_with_method_assignment_to_class_cell().other_method()
42
One possible approach here would be to implement an outright language level ban
on the use of "__class__" in explicit "nonlocal" declarations, and then add a
test to Lib/test_super.py that ensures "__class__" and "__classcell__" don't
show up in the class locals() while the statement body is executing.
----------
messages: 282585
nosy: arigo, ncoghlan
priority: normal
severity: normal
stage: test needed
status: open
title: Standardise more behaviours for zero-argument super() __class__ and
__classcell__
type: behavior
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue28891>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com