On 2012-10-28, at 1:55 AM, Greg Ewing
Yury Selivanov wrote:
In the above example scheduler *can* safely interrupt "c2" when it is invoked from "c1" at "p2". I.e. scheduler can't interrupt the coroutine when it is itself in its finally statement, but it's fine to interrupt it when it is not, even if it is invoked from other coroutine's finally block.
I'm confused about the relationship between c1 and c2 here, and what you mean by one coroutine "invoking" another.
Can you post a version that uses yield-from instead of yielding objects with unknown (to me) semantics?
The reason I kept using my version is because I'm not sure how we will set timeouts for yield-from style coroutines. But let's assume that we can do that with a context manager. Let's also assume that generator object has 'in_finally()' method, as you defined: "Something like an in_finally() method that looks along the yield-from chain and returns true if any of the generators are in a finally section." def coro1(): try: with timeout(1.0): yield from coro2() # 1 finally: try: with timeout(1.0): yield from coro2() # 2 except TimeoutError: pass def coro2(): try: block() yield # 3 action() finally: block() yield # 4 another_action() Now, if "coro2" is suspended at #4 -- it shouldn't be interrupted with TimeoutError. If, however, "coro2" is at #3 -- it can be, and it doesn't matter was it called from #1 or #2. IIUC, yield-from supporting scheduler, won't know about "coro2". All it will have is a generator for "coro1". All dispatching will be handled by "yield from" statement automatically. In this case, you can't rely on "coro1.in_finally()", because it will return: - True, when "coro1" is at #1 & "coro2" is at #4 (it's unsafe to interrupt) - True, when "coro1" is at #2 & "coro2" is at #3 (safe to interrupt) The fundamental problem here, is that scheduler knows nothing about coroutines call chain. It doesn't even know at what generator 'with timeout' was called. - Yury