[Python-ideas] Revised**12 PEP on Yield-From
Jacob Holm
jh at improva.dk
Sun Apr 19 15:46:28 CEST 2009
Greg Ewing wrote:
> Draft 13 of the PEP.
>
> Adjusted the expansion so as not to suggest that
> a throw or close attribute with the value None
> should be treated as a missing method.
>
A few more details about the expansion.
First a minor nit. There is no need to use getattr if the name is
constant and you are going to catch AttributeError anyway. Just use
_i.close and _i.throw.
Next a more serious issue. The current use of *sys.exc_info() in the
throw handling is actually wrong. Getting the "throw" attribute may run
arbitrary python code which could easily replace the exception.
We should probably add
_x = sys.exc_info()
as the first line in the "except BaseException as _e" block, and change
_y = _m(*sys.exc_info())
to:
_y = _m(*_x)
Alternatively, we could get the signature of throw() fixed so that it
matches the "raise" statement again. Then we can drop the use of
sys.exc_info(), and just use:
_y = _m(_e)
But that is probably out of scope for this PEP.
Other than that, I think the expansion matches what we have agreed on.
FWIW I still consider an expansion using functools.partial to be more
readable because it centralizes the StopIteration handling and reduces
the code nesting. Here is an updated version of such an expansion that
is semantically equivalent to the PEP rev 13 + my suggested fix for the
sys.exc_info() issue:
_i = iter(EXPR)
_p = functools.partial(next, _i)
while 1:
try:
_y = _p()
except StopIteration as _e:
_r = _e.value
break
try:
_s = yield _y
except GeneratorExit as _e:
try:
_m = _i.close
except AttributeError:
pass
else:
_m()
raise _e
except BaseException as _e:
_x = sys.exc_info()
try:
_m = _i.throw
except AttributeError:
raise _e
_p = functools.partial(_m, *_x)
else:
if _s is None:
_p = functools.partial(next, _i)
else:
_p = functools.partial(_i.send, _s)
RESULT = _r
If you don't like it, fine. Since it is only a presentation detail, I
won't push for it. I *would* like to hear your reasoning, but will
accept whatever conclusion you come to, I think :)
Anyway, it looks to me like we are almost done. What are the chances of
getting this into 3.1 and 2.7?
Hopefully-soon-using-yield-from-for-real-ly yours
- Jacob
More information about the Python-ideas
mailing list