Updated given statement torture test to show why renaming strategies are flawed
This commit is contained in:
parent
bba94bd03d
commit
4da3bbd1ac
27
pep-3150.txt
27
pep-3150.txt
|
@ -314,10 +314,19 @@ code at module, class and function scope::
|
|||
assert d[42] == 42 given:
|
||||
d = b
|
||||
assert "d" not in locals()
|
||||
y = y given:
|
||||
x = 42
|
||||
def f(): pass
|
||||
y = locals("x"), f.__name__
|
||||
assert "x" not in locals()
|
||||
assert "f" not in locals()
|
||||
assert y == (42, "f")
|
||||
|
||||
Most naive implementations will choke on the first complex assignment,
|
||||
while less naive but still broken implementations will fail when
|
||||
the torture test is executed at class scope.
|
||||
the torture test is executed at class scope. Renaming based strategies
|
||||
struggle to support ``locals()`` correctly and also have problems with
|
||||
class and function ``__name__`` attributes.
|
||||
|
||||
And yes, that's a perfectly well-defined assignment statement. Insane,
|
||||
you might rightly say, but legal::
|
||||
|
@ -349,6 +358,10 @@ two reasons mentioned in the Torture Test section above:
|
|||
* Return-based semantics struggle with complex assignment statements
|
||||
like the one in the torture test
|
||||
|
||||
The second thought is generally some kind of hidden renaming strategy. This
|
||||
also creates problems, as Python exposes variables names via the ``locals()``
|
||||
dictionary and class and function ``__name__`` attributes.
|
||||
|
||||
The most promising approach is one based on symtable analysis and
|
||||
copy-in-copy-out referencing semantics to move any required name
|
||||
bindings between the inner and outer scopes. The torture test above
|
||||
|
@ -371,6 +384,16 @@ would then translate to something like the following::
|
|||
# Nothing to copy out (not an assignment)
|
||||
_anon2()
|
||||
assert "d" not in locals()
|
||||
def _anon3() # Nothing to copy in (no references to other variables)
|
||||
x = 42
|
||||
def f(): pass
|
||||
y = locals("x"), f.__name__
|
||||
y = y # Assuming no optimisation of special cases
|
||||
return y # 'y' reference copied out
|
||||
y = _anon3()
|
||||
assert "x" not in locals()
|
||||
assert "f" not in locals()
|
||||
assert y == (42, "f")
|
||||
|
||||
However, as noted in the abstract, an actual implementation of
|
||||
this idea has never been tried.
|
||||
|
@ -417,7 +440,7 @@ Copyright
|
|||
This document has been placed in the public domain.
|
||||
|
||||
|
||||
|
||||
|
||||
..
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
|
|
Loading…
Reference in New Issue