diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2019-04-01 06:16:35 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-01 06:16:35 (GMT) |
commit | 42a139ed88c487f325a241c6ee8b308b3c045975 (patch) | |
tree | de56527188eff240b06496c3451e525af959dcad /Lib/unittest | |
parent | 5f2c50810a67982b0c80f6d3258fee3647f67005 (diff) | |
download | cpython-42a139ed88c487f325a241c6ee8b308b3c045975.zip cpython-42a139ed88c487f325a241c6ee8b308b3c045975.tar.gz cpython-42a139ed88c487f325a241c6ee8b308b3c045975.tar.bz2 |
bpo-36492: Deprecate passing some arguments as keyword arguments. (GH-12637)
Deprecated passing the following arguments as keyword arguments:
- "func" in functools.partialmethod(), weakref.finalize(),
profile.Profile.runcall(), cProfile.Profile.runcall(),
bdb.Bdb.runcall(), trace.Trace.runfunc() and
curses.wrapper().
- "function" in unittest.addModuleCleanup() and
unittest.TestCase.addCleanup().
- "fn" in the submit() method of concurrent.futures.ThreadPoolExecutor
and concurrent.futures.ProcessPoolExecutor.
- "callback" in contextlib.ExitStack.callback(),
contextlib.AsyncExitStack.callback() and
contextlib.AsyncExitStack.push_async_callback().
- "c" and "typeid" in the create() method of multiprocessing.managers.Server
and multiprocessing.managers.SharedMemoryServer.
- "obj" in weakref.finalize().
Also allowed to pass arbitrary keyword arguments (even "self" and "func")
if the above arguments are passed as positional argument.
Diffstat (limited to 'Lib/unittest')
-rw-r--r-- | Lib/unittest/case.py | 44 | ||||
-rw-r--r-- | Lib/unittest/test/test_runner.py | 60 |
2 files changed, 101 insertions, 3 deletions
diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index a157ae8..972a465 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -86,9 +86,21 @@ def _id(obj): _module_cleanups = [] -def addModuleCleanup(function, *args, **kwargs): +def addModuleCleanup(*args, **kwargs): """Same as addCleanup, except the cleanup items are called even if setUpModule fails (unlike tearDownModule).""" + if args: + function, *args = args + elif 'function' in kwargs: + function = kwargs.pop('function') + import warnings + warnings.warn("Passing 'function' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + raise TypeError('addModuleCleanup expected at least 1 positional ' + 'argument, got %d' % (len(args)-1)) + args = tuple(args) + _module_cleanups.append((function, args, kwargs)) @@ -463,18 +475,44 @@ class TestCase(object): """ self._type_equality_funcs[typeobj] = function - def addCleanup(self, function, *args, **kwargs): + def addCleanup(*args, **kwargs): """Add a function, with arguments, to be called when the test is completed. Functions added are called on a LIFO basis and are called after tearDown on test failure or success. Cleanup items are called even if setUp fails (unlike tearDown).""" + if len(args) >= 2: + self, function, *args = args + elif not args: + raise TypeError("descriptor 'addCleanup' of 'TestCase' object " + "needs an argument") + elif 'function' in kwargs: + function = kwargs.pop('function') + self, *args = args + import warnings + warnings.warn("Passing 'function' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + raise TypeError('addCleanup expected at least 1 positional ' + 'argument, got %d' % (len(args)-1)) + args = tuple(args) + self._cleanups.append((function, args, kwargs)) @classmethod - def addClassCleanup(cls, function, *args, **kwargs): + def addClassCleanup(*args, **kwargs): """Same as addCleanup, except the cleanup items are called even if setUpClass fails (unlike tearDownClass).""" + if len(args) >= 2: + cls, function, *args = args + elif not args: + raise TypeError("descriptor 'addClassCleanup' of 'TestCase' object " + "needs an argument") + else: + raise TypeError('addClassCleanup expected at least 1 positional ' + 'argument, got %d' % (len(args)-1)) + args = tuple(args) + cls._class_cleanups.append((function, args, kwargs)) def setUp(self): diff --git a/Lib/unittest/test/test_runner.py b/Lib/unittest/test/test_runner.py index 2b475c2..443b689 100644 --- a/Lib/unittest/test/test_runner.py +++ b/Lib/unittest/test/test_runner.py @@ -403,6 +403,22 @@ class TestModuleCleanUp(unittest.TestCase): self.assertEqual(str(e.exception), 'CleanUpExc') self.assertEqual(unittest.case._module_cleanups, []) + def test_addModuleCleanup_arg_errors(self): + cleanups = [] + def cleanup(*args, **kwargs): + cleanups.append((args, kwargs)) + + class Module(object): + unittest.addModuleCleanup(cleanup, 1, 2, function='hello') + with self.assertWarns(DeprecationWarning): + unittest.addModuleCleanup(function=cleanup, arg='hello') + with self.assertRaises(TypeError): + unittest.addModuleCleanup() + unittest.case.doModuleCleanups() + self.assertEqual(cleanups, + [((), {'arg': 'hello'}), + ((1, 2), {'function': 'hello'})]) + def test_run_module_cleanUp(self): blowUp = True ordering = [] @@ -547,6 +563,50 @@ class TestModuleCleanUp(unittest.TestCase): 'tearDownModule', 'cleanup_good']) self.assertEqual(unittest.case._module_cleanups, []) + def test_addClassCleanup_arg_errors(self): + cleanups = [] + def cleanup(*args, **kwargs): + cleanups.append((args, kwargs)) + + class TestableTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.addClassCleanup(cleanup, 1, 2, function=3, cls=4) + with self.assertRaises(TypeError): + cls.addClassCleanup(function=cleanup, arg='hello') + def testNothing(self): + pass + + with self.assertRaises(TypeError): + TestableTest.addClassCleanup() + with self.assertRaises(TypeError): + unittest.TestCase.addCleanup(cls=TestableTest(), function=cleanup) + runTests(TestableTest) + self.assertEqual(cleanups, + [((1, 2), {'function': 3, 'cls': 4})]) + + def test_addCleanup_arg_errors(self): + cleanups = [] + def cleanup(*args, **kwargs): + cleanups.append((args, kwargs)) + + class TestableTest(unittest.TestCase): + def setUp(self2): + self2.addCleanup(cleanup, 1, 2, function=3, self=4) + with self.assertWarns(DeprecationWarning): + self2.addCleanup(function=cleanup, arg='hello') + def testNothing(self): + pass + + with self.assertRaises(TypeError): + TestableTest().addCleanup() + with self.assertRaises(TypeError): + unittest.TestCase.addCleanup(self=TestableTest(), function=cleanup) + runTests(TestableTest) + self.assertEqual(cleanups, + [((), {'arg': 'hello'}), + ((1, 2), {'function': 3, 'self': 4})]) + def test_with_errors_in_addClassCleanup(self): ordering = [] |