diff options
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/contextlib.py | 31 | ||||
-rw-r--r-- | Lib/decimal.py | 4 | ||||
-rw-r--r-- | Lib/test/test_contextlib.py | 46 |
3 files changed, 42 insertions, 39 deletions
diff --git a/Lib/contextlib.py b/Lib/contextlib.py index 157b4cc..b2902a4 100644 --- a/Lib/contextlib.py +++ b/Lib/contextlib.py @@ -2,10 +2,10 @@ import sys -__all__ = ["contextmanager", "nested", "closing"] +__all__ = ["contextfactory", "nested", "closing"] -class GeneratorContextManager(object): - """Helper for @contextmanager decorator.""" +class GeneratorContext(object): + """Helper for @contextfactory decorator.""" def __init__(self, gen): self.gen = gen @@ -48,8 +48,8 @@ class GeneratorContextManager(object): raise -def contextmanager(func): - """@contextmanager decorator. +def contextfactory(func): + """@contextfactory decorator. Typical usage: @@ -77,7 +77,7 @@ def contextmanager(func): """ def helper(*args, **kwds): - return GeneratorContextManager(func(*args, **kwds)) + return GeneratorContext(func(*args, **kwds)) try: helper.__name__ = func.__name__ helper.__doc__ = func.__doc__ @@ -87,7 +87,7 @@ def contextmanager(func): return helper -@contextmanager +@contextfactory def nested(*contexts): """Support multiple context managers in a single with-statement. @@ -133,9 +133,8 @@ def nested(*contexts): raise exc[0], exc[1], exc[2] -@contextmanager -def closing(thing): - """Context manager to automatically close something at the end of a block. +class closing(object): + """Context to automatically close something at the end of a block. Code like this: @@ -151,7 +150,11 @@ def closing(thing): f.close() """ - try: - yield thing - finally: - thing.close() + def __init__(self, thing): + self.thing = thing + def __context__(self): + return self + def __enter__(self): + return self.thing + def __exit__(self, *exc_info): + self.thing.close() diff --git a/Lib/decimal.py b/Lib/decimal.py index 967f101..875e38a 100644 --- a/Lib/decimal.py +++ b/Lib/decimal.py @@ -2173,7 +2173,7 @@ for name in rounding_functions: del name, val, globalname, rounding_functions -class ContextManager(object): +class WithStatementContext(object): """Helper class to simplify Context management. Sample usage: @@ -2249,7 +2249,7 @@ class Context(object): return ', '.join(s) + ')' def __context__(self): - return ContextManager(self.copy()) + return WithStatementContext(self.copy()) def clear_flags(self): """Reset all flags to zero""" diff --git a/Lib/test/test_contextlib.py b/Lib/test/test_contextlib.py index 1a70997..53f23b2 100644 --- a/Lib/test/test_contextlib.py +++ b/Lib/test/test_contextlib.py @@ -13,9 +13,9 @@ from test.test_support import run_suite class ContextManagerTestCase(unittest.TestCase): - def test_contextmanager_plain(self): + def test_contextfactory_plain(self): state = [] - @contextmanager + @contextfactory def woohoo(): state.append(1) yield 42 @@ -26,9 +26,9 @@ class ContextManagerTestCase(unittest.TestCase): state.append(x) self.assertEqual(state, [1, 42, 999]) - def test_contextmanager_finally(self): + def test_contextfactory_finally(self): state = [] - @contextmanager + @contextfactory def woohoo(): state.append(1) try: @@ -47,8 +47,8 @@ class ContextManagerTestCase(unittest.TestCase): self.fail("Expected ZeroDivisionError") self.assertEqual(state, [1, 42, 999]) - def test_contextmanager_no_reraise(self): - @contextmanager + def test_contextfactory_no_reraise(self): + @contextfactory def whee(): yield ctx = whee().__context__() @@ -56,8 +56,8 @@ class ContextManagerTestCase(unittest.TestCase): # Calling __exit__ should not result in an exception self.failIf(ctx.__exit__(TypeError, TypeError("foo"), None)) - def test_contextmanager_trap_yield_after_throw(self): - @contextmanager + def test_contextfactory_trap_yield_after_throw(self): + @contextfactory def whoo(): try: yield @@ -69,9 +69,9 @@ class ContextManagerTestCase(unittest.TestCase): RuntimeError, ctx.__exit__, TypeError, TypeError("foo"), None ) - def test_contextmanager_except(self): + def test_contextfactory_except(self): state = [] - @contextmanager + @contextfactory def woohoo(): state.append(1) try: @@ -86,14 +86,14 @@ class ContextManagerTestCase(unittest.TestCase): raise ZeroDivisionError(999) self.assertEqual(state, [1, 42, 999]) - def test_contextmanager_attribs(self): + def test_contextfactory_attribs(self): def attribs(**kw): def decorate(func): for k,v in kw.items(): setattr(func,k,v) return func return decorate - @contextmanager + @contextfactory @attribs(foo='bar') def baz(spam): """Whee!""" @@ -106,13 +106,13 @@ class NestedTestCase(unittest.TestCase): # XXX This needs more work def test_nested(self): - @contextmanager + @contextfactory def a(): yield 1 - @contextmanager + @contextfactory def b(): yield 2 - @contextmanager + @contextfactory def c(): yield 3 with nested(a(), b(), c()) as (x, y, z): @@ -122,14 +122,14 @@ class NestedTestCase(unittest.TestCase): def test_nested_cleanup(self): state = [] - @contextmanager + @contextfactory def a(): state.append(1) try: yield 2 finally: state.append(3) - @contextmanager + @contextfactory def b(): state.append(4) try: @@ -148,7 +148,7 @@ class NestedTestCase(unittest.TestCase): def test_nested_right_exception(self): state = [] - @contextmanager + @contextfactory def a(): yield 1 class b(object): @@ -172,10 +172,10 @@ class NestedTestCase(unittest.TestCase): self.fail("Didn't raise ZeroDivisionError") def test_nested_b_swallows(self): - @contextmanager + @contextfactory def a(): yield - @contextmanager + @contextfactory def b(): try: yield @@ -189,7 +189,7 @@ class NestedTestCase(unittest.TestCase): self.fail("Didn't swallow ZeroDivisionError") def test_nested_break(self): - @contextmanager + @contextfactory def a(): yield state = 0 @@ -201,7 +201,7 @@ class NestedTestCase(unittest.TestCase): self.assertEqual(state, 1) def test_nested_continue(self): - @contextmanager + @contextfactory def a(): yield state = 0 @@ -213,7 +213,7 @@ class NestedTestCase(unittest.TestCase): self.assertEqual(state, 3) def test_nested_return(self): - @contextmanager + @contextfactory def a(): try: yield |