]> granicus.if.org Git - python/commitdiff
Issue #24336: The contextmanager decorator now works with functions with
authorSerhiy Storchaka <storchaka@gmail.com>
Sun, 28 Jun 2015 14:06:07 +0000 (17:06 +0300)
committerSerhiy Storchaka <storchaka@gmail.com>
Sun, 28 Jun 2015 14:06:07 +0000 (17:06 +0300)
keyword arguments called "func" and "self".  Patch by Martin Panter.

Lib/contextlib.py
Lib/test/test_contextlib.py
Lib/test/test_with.py
Misc/NEWS

index 82ee955a8b2d54b0448a52626d96cbc30f20067f..07b226111501612b8b416b2aa9f9d4745186ebb6 100644 (file)
@@ -34,7 +34,7 @@ class ContextDecorator(object):
 class _GeneratorContextManager(ContextDecorator):
     """Helper for @contextmanager decorator."""
 
-    def __init__(self, func, *args, **kwds):
+    def __init__(self, func, args, kwds):
         self.gen = func(*args, **kwds)
         self.func, self.args, self.kwds = func, args, kwds
         # Issue 19330: ensure context manager instances have good docstrings
@@ -52,7 +52,7 @@ class _GeneratorContextManager(ContextDecorator):
         # _GCM instances are one-shot context managers, so the
         # CM must be recreated each time a decorated function is
         # called
-        return self.__class__(self.func, *self.args, **self.kwds)
+        return self.__class__(self.func, self.args, self.kwds)
 
     def __enter__(self):
         try:
@@ -123,7 +123,7 @@ def contextmanager(func):
     """
     @wraps(func)
     def helper(*args, **kwds):
-        return _GeneratorContextManager(func, *args, **kwds)
+        return _GeneratorContextManager(func, args, kwds)
     return helper
 
 
index 39cc776dbcafa743d46080a57e9243e2c9ed8520..8f849ae5604ec52a8c71480c4b6dc4a35a10868b 100644 (file)
@@ -111,6 +111,14 @@ class ContextManagerTestCase(unittest.TestCase):
         baz = self._create_contextmanager_attribs()(None)
         self.assertEqual(baz.__doc__, "Whee!")
 
+    def test_keywords(self):
+        # Ensure no keyword arguments are inhibited
+        @contextmanager
+        def woohoo(self, func, args, kwds):
+            yield (self, func, args, kwds)
+        with woohoo(self=11, func=22, args=33, kwds=44) as target:
+            self.assertEqual(target, (11, 22, 33, 44))
+
 
 class ClosingTestCase(unittest.TestCase):
 
index 7068a809702d03d8e045e11bc8c1938cd19cca27..cbaafcf9230c6d5872687572f1eafc0693b8155f 100644 (file)
@@ -12,8 +12,8 @@ from test.support import run_unittest
 
 
 class MockContextManager(_GeneratorContextManager):
-    def __init__(self, func, *args, **kwds):
-        super().__init__(func, *args, **kwds)
+    def __init__(self, *args):
+        super().__init__(*args)
         self.enter_called = False
         self.exit_called = False
         self.exit_args = None
@@ -31,7 +31,7 @@ class MockContextManager(_GeneratorContextManager):
 
 def mock_contextmanager(func):
     def helper(*args, **kwds):
-        return MockContextManager(func, *args, **kwds)
+        return MockContextManager(func, args, kwds)
     return helper
 
 
index c8c455c977462104391ff33201ad961dc076769e..02b129a508359d8535d2bd474837f9c6bf625de0 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -60,6 +60,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #24336: The contextmanager decorator now works with functions with
+  keyword arguments called "func" and "self".  Patch by Martin Panter.
+
 - Issue #24489: ensure a previously set C errno doesn't disturb cmath.polar().
 
 - Issue #5633: Fixed timeit when the statement is a string and the setup is not.