Updated given statement torture test to show why renaming strategies are flawed

This commit is contained in:
Nick Coghlan 2011-04-10 22:05:30 +10:00
parent bba94bd03d
commit 4da3bbd1ac
1 changed files with 26 additions and 3 deletions

View File

@ -314,16 +314,25 @@ 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::
>>> def f(x): return x
...
...
>>> x = 42
>>> b = {}
>>> a = b[f(a)] = x
@ -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