Change the translation slightly.

ctx.__exit__ is now bound before ctx.__enter__;
ctx.__enter__ is still called before the try-block
is entered, but VAR is assigned *inside* the try-block.
Clarify what happens to break, continue, return.
This commit is contained in:
Guido van Rossum 2006-02-27 21:08:43 +00:00
parent dc9835bebb
commit 53c1f1795e
1 changed files with 16 additions and 7 deletions

View File

@ -225,25 +225,34 @@ Specification: The 'with' Statement
The translation of the above statement is:
abc = (EXPR).__context__()
ctx = (EXPR).__context__()
exit = exc.__exit__ # Not calling it yet
res = ctx.__enter__()
exc = (None, None, None)
VAR = abc.__enter__()
try:
try:
VAR = res # Only if "as VAR" is present
BLOCK
except:
exc = sys.exc_info()
raise
finally:
abc.__exit__(*exc)
exit(*exc)
Here, the variables 'abc' and 'exc' are internal variables and not
Here, the lowercase variables are internal variables and not
accessible to the user; they will most likely be implemented as
special registers or stack positions.
The above translation is fairly literal - if any of the relevant
methods are not found as expected, the interpreter will raise
AttributeError.
The details of the above translation are intended to prescribe the
exact semantics. If any of the relevant methods are not found as
expected, the interpreter will raise AttributeError, in the order
that they are tried (__context__, __exit__, __enter__).
Similarly, if any of the calls raises an exception, the effect is
exactly as it would be in the above code. Finally, if BLOCK
contains a break, continue or return statement, the __exit__()
method is called with three None arguments just as if BLOCK
completed normally. (I.e. these "pseudo-exceptions" are not seen
as exceptions by __exit__().)
The call to the __context__() method serves a similar purpose to
that of the __iter__() method of iterator and iterables. An