mirror of
https://github.com/jazzband/contextlib2.git
synced 2026-05-19 12:31:10 +00:00
Issue #3: Accept context managers in ContextStack.register_exit()
This commit is contained in:
parent
8e373d228e
commit
580d9bde76
4 changed files with 26 additions and 1 deletions
4
NEWS.rst
4
NEWS.rst
|
|
@ -5,18 +5,22 @@ Release History
|
||||||
0.3 (2012-01-XX)
|
0.3 (2012-01-XX)
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
* Issue #3: ContextStack.register_exit() now accepts objects with __exit__
|
||||||
|
attributes in addition to accepting exit callbacks directly
|
||||||
* Issue #1: Add ContextStack.preserve() to move all registered callbacks to
|
* Issue #1: Add ContextStack.preserve() to move all registered callbacks to
|
||||||
a new ContextStack object
|
a new ContextStack object
|
||||||
* Wrapped callbacks now use functools.wraps to aid in introspection
|
* Wrapped callbacks now use functools.wraps to aid in introspection
|
||||||
* Moved version number to a VERSION.txt file (read by both docs and setup.py)
|
* Moved version number to a VERSION.txt file (read by both docs and setup.py)
|
||||||
* Added NEWS.rst (and incorporated into documentation)
|
* Added NEWS.rst (and incorporated into documentation)
|
||||||
|
|
||||||
|
|
||||||
0.2 (2011-12-15)
|
0.2 (2011-12-15)
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
* Renamed CleanupManager to ContextStack (hopefully before anyone started
|
* Renamed CleanupManager to ContextStack (hopefully before anyone started
|
||||||
using the module for anything, since I didn't alias the old name at all)
|
using the module for anything, since I didn't alias the old name at all)
|
||||||
|
|
||||||
|
|
||||||
0.1 (2011-12-13)
|
0.1 (2011-12-13)
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -168,8 +168,15 @@ class ContextStack(object):
|
||||||
"""Registers a callback with the standard __exit__ method signature
|
"""Registers a callback with the standard __exit__ method signature
|
||||||
|
|
||||||
Can suppress exceptions the same way __exit__ methods can.
|
Can suppress exceptions the same way __exit__ methods can.
|
||||||
|
|
||||||
|
Also accepts any object with an __exit__ method (registering the
|
||||||
|
method instead of the object itself)
|
||||||
"""
|
"""
|
||||||
self._callbacks.append(callback)
|
try:
|
||||||
|
exit = callback.__exit__
|
||||||
|
except AttributeError:
|
||||||
|
exit = callback
|
||||||
|
self._callbacks.append(exit)
|
||||||
return callback # Allow use as a decorator
|
return callback # Allow use as a decorator
|
||||||
|
|
||||||
def register(self, callback, *args, **kwds):
|
def register(self, callback, *args, **kwds):
|
||||||
|
|
|
||||||
|
|
@ -237,6 +237,11 @@ API Reference
|
||||||
By returning true values, these callbacks can suppress exceptions the
|
By returning true values, these callbacks can suppress exceptions the
|
||||||
same way context manager :meth:`__exit__` methods can.
|
same way context manager :meth:`__exit__` methods can.
|
||||||
|
|
||||||
|
This method also accepts any object with an ``__exit__`` method, and
|
||||||
|
will register that method as the callback. This is mainly useful to
|
||||||
|
cover part of an :meth:`__enter__` implementation with a context
|
||||||
|
manager's own :meth:`__exit__` method.
|
||||||
|
|
||||||
.. method:: register(callback, *args, **kwds)
|
.. method:: register(callback, *args, **kwds)
|
||||||
|
|
||||||
Accepts an arbitrary callback function and arguments and adds it to
|
Accepts an arbitrary callback function and arguments and adds it to
|
||||||
|
|
|
||||||
|
|
@ -344,9 +344,18 @@ class TestContextStack(unittest.TestCase):
|
||||||
self.assertIsNone(exc_type)
|
self.assertIsNone(exc_type)
|
||||||
self.assertIsNone(exc)
|
self.assertIsNone(exc)
|
||||||
self.assertIsNone(exc_tb)
|
self.assertIsNone(exc_tb)
|
||||||
|
class ExitCM(object):
|
||||||
|
def __init__(self, check_exc):
|
||||||
|
self.check_exc = check_exc
|
||||||
|
def __enter__(self):
|
||||||
|
self.fail("Should not be called!")
|
||||||
|
def __exit__(self, *exc_details):
|
||||||
|
self.check_exc(*exc_details)
|
||||||
with ContextStack() as stack:
|
with ContextStack() as stack:
|
||||||
stack.register_exit(_expect_ok)
|
stack.register_exit(_expect_ok)
|
||||||
|
stack.register_exit(ExitCM(_expect_ok))
|
||||||
stack.register_exit(_suppress_exc)
|
stack.register_exit(_suppress_exc)
|
||||||
|
stack.register_exit(ExitCM(_expect_exc))
|
||||||
stack.register_exit(_expect_exc)
|
stack.register_exit(_expect_exc)
|
||||||
stack.register_exit(_expect_exc)
|
stack.register_exit(_expect_exc)
|
||||||
1/0
|
1/0
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue