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:
|
assert d[42] == 42 given:
|
||||||
d = b
|
d = b
|
||||||
assert "d" not in locals()
|
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,
|
Most naive implementations will choke on the first complex assignment,
|
||||||
while less naive but still broken implementations will fail when
|
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,
|
And yes, that's a perfectly well-defined assignment statement. Insane,
|
||||||
you might rightly say, but legal::
|
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
|
* Return-based semantics struggle with complex assignment statements
|
||||||
like the one in the torture test
|
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
|
The most promising approach is one based on symtable analysis and
|
||||||
copy-in-copy-out referencing semantics to move any required name
|
copy-in-copy-out referencing semantics to move any required name
|
||||||
bindings between the inner and outer scopes. The torture test above
|
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)
|
# Nothing to copy out (not an assignment)
|
||||||
_anon2()
|
_anon2()
|
||||||
assert "d" not in locals()
|
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
|
However, as noted in the abstract, an actual implementation of
|
||||||
this idea has never been tried.
|
this idea has never been tried.
|
||||||
|
@ -417,7 +440,7 @@ Copyright
|
||||||
This document has been placed in the public domain.
|
This document has been placed in the public domain.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
..
|
..
|
||||||
Local Variables:
|
Local Variables:
|
||||||
mode: indented-text
|
mode: indented-text
|
||||||
|
|
Loading…
Reference in New Issue