PEP 343 -- the with-statement.
This was started by Mike Bland and completed by Guido
(with help from Neal).
This still needs a __future__ statement added;
Thomas is working on Michael's patch for that aspect.
There's a small amount of code cleanup and refactoring
in ast.c, compile.c and ceval.c (I fixed the lltrace
behavior when EXT_POP is used -- however I had to make
lltrace a static global).
diff --git a/Lib/test/contextmanager.py b/Lib/test/contextmanager.py
new file mode 100644
index 0000000..0ebf646
--- /dev/null
+++ b/Lib/test/contextmanager.py
@@ -0,0 +1,34 @@
+class GeneratorContextManager(object):
+ def __init__(self, gen):
+ self.gen = gen
+
+ def __context__(self):
+ return self
+
+ def __enter__(self):
+ try:
+ return self.gen.next()
+ except StopIteration:
+ raise RuntimeError("generator didn't yield")
+
+ def __exit__(self, type, value, traceback):
+ if type is None:
+ try:
+ self.gen.next()
+ except StopIteration:
+ return
+ else:
+ raise RuntimeError("generator didn't stop")
+ else:
+ try:
+ self.gen.throw(type, value, traceback)
+ except (type, StopIteration):
+ return
+ else:
+ raise RuntimeError("generator caught exception")
+
+def contextmanager(func):
+ def helper(*args, **kwds):
+ return GeneratorContextManager(func(*args, **kwds))
+ return helper
+