From 3c6f61e8b6f42dd8428bbf3da189cc9b84b7f35e Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 7 Jun 2024 21:49:05 +0300 Subject: [PATCH 1/2] gh-120242: Fix handling of `[setUp,tearDown]Class` in `test_datetime` --- Lib/test/test_datetime.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_datetime.py b/Lib/test/test_datetime.py index 3859733a4fe65b..3831b13713d970 100644 --- a/Lib/test/test_datetime.py +++ b/Lib/test/test_datetime.py @@ -37,18 +37,24 @@ def load_tests(loader, tests, pattern): test_classes.extend(type(test) for test in suit) test_classes = sorted(set(test_classes), key=lambda cls: cls.__qualname__) for cls in test_classes: + orig_setUpClass = getattr(cls, 'setUpClass', None) + orig_tearDownClass = getattr(cls, 'tearDownClass', None) cls.__name__ += suffix cls.__qualname__ += suffix @classmethod - def setUpClass(cls_, module=module): + def setUpClass(cls_, module=module, orig_setUpClass=orig_setUpClass): cls_._save_sys_modules = sys.modules.copy() sys.modules[TESTS] = module sys.modules['datetime'] = module.datetime_module if hasattr(module, '_pydatetime'): sys.modules['_pydatetime'] = module._pydatetime sys.modules['_strptime'] = module._strptime + if orig_setUpClass is not None: + orig_setUpClass() @classmethod - def tearDownClass(cls_): + def tearDownClass(cls_, orig_tearDownClass=orig_tearDownClass): + if orig_tearDownClass is not None: + orig_tearDownClass() sys.modules.clear() sys.modules.update(cls_._save_sys_modules) cls.setUpClass = setUpClass From 7c81c0c4031fab521adcdafb5dbb2044cd63b946 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 7 Jun 2024 22:56:14 +0300 Subject: [PATCH 2/2] Address review --- Lib/test/test_datetime.py | 42 +++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/Lib/test/test_datetime.py b/Lib/test/test_datetime.py index 3831b13713d970..005187f13e665f 100644 --- a/Lib/test/test_datetime.py +++ b/Lib/test/test_datetime.py @@ -1,5 +1,6 @@ import unittest import sys +import functools from test.support.import_helper import import_fresh_module @@ -37,29 +38,28 @@ def load_tests(loader, tests, pattern): test_classes.extend(type(test) for test in suit) test_classes = sorted(set(test_classes), key=lambda cls: cls.__qualname__) for cls in test_classes: - orig_setUpClass = getattr(cls, 'setUpClass', None) - orig_tearDownClass = getattr(cls, 'tearDownClass', None) cls.__name__ += suffix cls.__qualname__ += suffix - @classmethod - def setUpClass(cls_, module=module, orig_setUpClass=orig_setUpClass): - cls_._save_sys_modules = sys.modules.copy() - sys.modules[TESTS] = module - sys.modules['datetime'] = module.datetime_module - if hasattr(module, '_pydatetime'): - sys.modules['_pydatetime'] = module._pydatetime - sys.modules['_strptime'] = module._strptime - if orig_setUpClass is not None: - orig_setUpClass() - @classmethod - def tearDownClass(cls_, orig_tearDownClass=orig_tearDownClass): - if orig_tearDownClass is not None: - orig_tearDownClass() - sys.modules.clear() - sys.modules.update(cls_._save_sys_modules) - cls.setUpClass = setUpClass - cls.tearDownClass = tearDownClass - tests.addTests(loader.loadTestsFromTestCase(cls)) + + @functools.wraps(cls, updated=()) + class Wrapper(cls): + @classmethod + def setUpClass(cls_, module=module): + cls_._save_sys_modules = sys.modules.copy() + sys.modules[TESTS] = module + sys.modules['datetime'] = module.datetime_module + if hasattr(module, '_pydatetime'): + sys.modules['_pydatetime'] = module._pydatetime + sys.modules['_strptime'] = module._strptime + super().setUpClass() + + @classmethod + def tearDownClass(cls_): + super().tearDownClass() + sys.modules.clear() + sys.modules.update(cls_._save_sys_modules) + + tests.addTests(loader.loadTestsFromTestCase(Wrapper)) return tests