[Python-Dev] PEP 343 - Abstract Block Redux
Nick Coghlan
ncoghlan at gmail.com
Sun May 15 03:12:41 CEST 2005
Guido van Rossum wrote:
> [Nick Coghlan]
>
>>Also, the call to __enter__() needs to be before the try/finally block (as it is
>>in PEP 310). Otherwise we get the "releasing a lock you failed to acquire" problem.
>
>
> I did that on purpose. There's a separate object ('abc' in the
> pseudo-code of the translation) whose __enter__ and __exit__ methods
> are called, and in __enter__ it can keep track of the reversible
> actions it has taken.
>
> Consider an application where you have to acquire *two* locks regularly:
>
> def lockBoth():
> got1 = got2 = False
> lock1.acquire(); got1 = True
> lock2.acquire(); got2 = True
> yield None
> if got2: lock2.release()
> if got1: lock1.release()
>
> If this gets interrupted after locking lock1 but before locking lock2,
> it still has some cleanup to do.
>
> I know that this complicates simpler use cases, and I'm not 100% sure
> this is the right solution; but I don't know how else to handle this
> use case.
>
If we retained the ability to inject exceptions into generators, this would be
written with the extremely natural:
@with template:
def lockboth():
lock1.acquire()
try:
lock2.acquire()
try:
yield
finally:
lock2.release()
finally:
lock1.release()
Or, even more simply:
@with_template:
def lockboth():
with lock1:
with lock2:
yield
I think Fredrik's intuition is on to something - PEP 343 has scaled the idea
back *too* far by throwing away the injection of exceptions into generator
templates, when the only major objection was to the looping nature of the proposal.
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.blogspot.com
More information about the Python-Dev
mailing list