From 074ac1f72e392a576516639f650bac0519d1cb52 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 4 Sep 2023 13:04:32 +0300 Subject: [PATCH] bpo-45229: Make ElementTree tests discoverable (GH-108859) --- Lib/test/test_xml_etree.py | 66 ++++++++++-------------------------- Lib/test/test_xml_etree_c.py | 27 +++++++++------ 2 files changed, 33 insertions(+), 60 deletions(-) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index da2828c3b53..6d413aa68a3 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -365,6 +365,7 @@ class ElementTreeTest(unittest.TestCase): from xml.etree import ElementPath elem = ET.XML(SAMPLE_XML) + ElementPath._cache.clear() for i in range(10): ET.ElementTree(elem).find('./'+str(i)) cache_len_10 = len(ElementPath._cache) for i in range(10): ET.ElementTree(elem).find('./'+str(i)) @@ -3926,8 +3927,9 @@ class KeywordArgsTest(unittest.TestCase): # -------------------------------------------------------------------- class NoAcceleratorTest(unittest.TestCase): - def setUp(self): - if not pyET: + @classmethod + def setUpClass(cls): + if ET is not pyET: raise unittest.SkipTest('only for the Python version') # Test that the C accelerator was not imported for pyET @@ -4192,8 +4194,7 @@ class C14NTest(unittest.TestCase): # -------------------------------------------------------------------- - -def test_main(module=None): +def setUpModule(module=None): # When invoked without a module, runs the Python ET tests by loading pyET. # Otherwise, uses the given module as the ET. global pyET @@ -4205,63 +4206,30 @@ def test_main(module=None): global ET ET = module - test_classes = [ - ModuleTest, - ElementSlicingTest, - BasicElementTest, - BadElementTest, - BadElementPathTest, - ElementTreeTest, - IOTest, - ParseErrorTest, - XIncludeTest, - ElementTreeTypeTest, - ElementFindTest, - ElementIterTest, - TreeBuilderTest, - XMLParserTest, - XMLPullParserTest, - BugsTest, - KeywordArgsTest, - BoolTest, - C14NTest, - ] - - # These tests will only run for the pure-Python version that doesn't import - # _elementtree. We can't use skipUnless here, because pyET is filled in only - # after the module is loaded. - if pyET is not ET: - test_classes.extend([ - NoAcceleratorTest, - ]) + # don't interfere with subsequent tests + def cleanup(): + global ET, pyET + ET = pyET = None + unittest.addModuleCleanup(cleanup) # Provide default namespace mapping and path cache. from xml.etree import ElementPath nsmap = ET.register_namespace._namespace_map # Copy the default namespace mapping nsmap_copy = nsmap.copy() + unittest.addModuleCleanup(nsmap.update, nsmap_copy) + unittest.addModuleCleanup(nsmap.clear) + # Copy the path cache (should be empty) path_cache = ElementPath._cache + unittest.addModuleCleanup(setattr, ElementPath, "_cache", path_cache) ElementPath._cache = path_cache.copy() + # Align the Comment/PI factories. if hasattr(ET, '_set_factories'): old_factories = ET._set_factories(ET.Comment, ET.PI) - else: - old_factories = None - - try: - return support.run_unittest(*test_classes) - finally: - from xml.etree import ElementPath - # Restore mapping and path cache - nsmap.clear() - nsmap.update(nsmap_copy) - ElementPath._cache = path_cache - if old_factories is not None: - ET._set_factories(*old_factories) - # don't interfere with subsequent tests - ET = pyET = None + unittest.addModuleCleanup(ET._set_factories, *old_factories) if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py index fd27b575ec8..3a0fc572f45 100644 --- a/Lib/test/test_xml_etree_c.py +++ b/Lib/test/test_xml_etree_c.py @@ -254,20 +254,25 @@ class SizeofTest(unittest.TestCase): self.check_sizeof(e, self.elementsize + self.extra + struct.calcsize('8P')) -def test_main(): + +def install_tests(): + # Test classes should have __module__ referring to this module. from test import test_xml_etree + for name, base in vars(test_xml_etree).items(): + if isinstance(base, type) and issubclass(base, unittest.TestCase): + class Temp(base): + pass + Temp.__name__ = Temp.__qualname__ = name + Temp.__module__ = __name__ + assert name not in globals() + globals()[name] = Temp - # Run the tests specific to the C implementation - support.run_unittest( - MiscTests, - TestAliasWorking, - TestAcceleratorImported, - SizeofTest, - ) +install_tests() - # Run the same test suite as the Python module - test_xml_etree.test_main(module=cET) +def setUpModule(): + from test import test_xml_etree + test_xml_etree.setUpModule(module=cET) if __name__ == '__main__': - test_main() + unittest.main()