bpo-41718: Reduce libregrtest runtest imports (GH-24980)
Move clear_caches() from libregrtest.refleak to libregrtest.utils to
avoid importing libregrtest.refleak when it's not needed.
clear_caches() now only calls re.purge() if 're' is in sys.modules.
diff --git a/Lib/test/libregrtest/refleak.py b/Lib/test/libregrtest/refleak.py
index 77298d3..7c7086a 100644
--- a/Lib/test/libregrtest/refleak.py
+++ b/Lib/test/libregrtest/refleak.py
@@ -5,6 +5,7 @@
from inspect import isabstract
from test import support
from test.support import os_helper
+from test.libregrtest.utils import clear_caches
try:
from _abc import _get_dump
@@ -181,102 +182,6 @@ def dash_R_cleanup(fs, ps, pic, zdc, abcs):
clear_caches()
-def clear_caches():
- # Clear the warnings registry, so they can be displayed again
- for mod in sys.modules.values():
- if hasattr(mod, '__warningregistry__'):
- del mod.__warningregistry__
-
- # Flush standard output, so that buffered data is sent to the OS and
- # associated Python objects are reclaimed.
- for stream in (sys.stdout, sys.stderr, sys.__stdout__, sys.__stderr__):
- if stream is not None:
- stream.flush()
-
- # Clear assorted module caches.
- # Don't worry about resetting the cache if the module is not loaded
- try:
- distutils_dir_util = sys.modules['distutils.dir_util']
- except KeyError:
- pass
- else:
- distutils_dir_util._path_created.clear()
- re.purge()
-
- try:
- _strptime = sys.modules['_strptime']
- except KeyError:
- pass
- else:
- _strptime._regex_cache.clear()
-
- try:
- urllib_parse = sys.modules['urllib.parse']
- except KeyError:
- pass
- else:
- urllib_parse.clear_cache()
-
- try:
- urllib_request = sys.modules['urllib.request']
- except KeyError:
- pass
- else:
- urllib_request.urlcleanup()
-
- try:
- linecache = sys.modules['linecache']
- except KeyError:
- pass
- else:
- linecache.clearcache()
-
- try:
- mimetypes = sys.modules['mimetypes']
- except KeyError:
- pass
- else:
- mimetypes._default_mime_types()
-
- try:
- filecmp = sys.modules['filecmp']
- except KeyError:
- pass
- else:
- filecmp._cache.clear()
-
- try:
- struct = sys.modules['struct']
- except KeyError:
- pass
- else:
- struct._clearcache()
-
- try:
- doctest = sys.modules['doctest']
- except KeyError:
- pass
- else:
- doctest.master = None
-
- try:
- ctypes = sys.modules['ctypes']
- except KeyError:
- pass
- else:
- ctypes._reset_cache()
-
- try:
- typing = sys.modules['typing']
- except KeyError:
- pass
- else:
- for f in typing._cleanups:
- f()
-
- support.gc_collect()
-
-
def warm_caches():
# char cache
s = bytes(range(256))
diff --git a/Lib/test/libregrtest/runtest.py b/Lib/test/libregrtest/runtest.py
index b4ef9fb..470d7dd 100644
--- a/Lib/test/libregrtest/runtest.py
+++ b/Lib/test/libregrtest/runtest.py
@@ -13,7 +13,7 @@
from test import support
from test.support import import_helper
from test.support import os_helper
-from test.libregrtest.refleak import dash_R, clear_caches
+from test.libregrtest.utils import clear_caches
from test.libregrtest.save_env import saved_test_environment
from test.libregrtest.utils import format_duration, print_warning
@@ -226,6 +226,9 @@ def _runtest_inner2(ns, test_name):
the_module = importlib.import_module(abstest)
+ if ns.huntrleaks:
+ from test.libregrtest.refleak import dash_R
+
# If the test has a test_main, that will run the appropriate
# tests. If not, use normal unittest test loading.
test_runner = getattr(the_module, "test_main", None)
diff --git a/Lib/test/libregrtest/utils.py b/Lib/test/libregrtest/utils.py
index 71f538f..13efdb4 100644
--- a/Lib/test/libregrtest/utils.py
+++ b/Lib/test/libregrtest/utils.py
@@ -84,3 +84,105 @@ def setup_unraisable_hook():
global orig_unraisablehook
orig_unraisablehook = sys.unraisablehook
sys.unraisablehook = regrtest_unraisable_hook
+
+
+def clear_caches():
+ # Clear the warnings registry, so they can be displayed again
+ for mod in sys.modules.values():
+ if hasattr(mod, '__warningregistry__'):
+ del mod.__warningregistry__
+
+ # Flush standard output, so that buffered data is sent to the OS and
+ # associated Python objects are reclaimed.
+ for stream in (sys.stdout, sys.stderr, sys.__stdout__, sys.__stderr__):
+ if stream is not None:
+ stream.flush()
+
+ # Clear assorted module caches.
+ # Don't worry about resetting the cache if the module is not loaded
+ try:
+ distutils_dir_util = sys.modules['distutils.dir_util']
+ except KeyError:
+ pass
+ else:
+ distutils_dir_util._path_created.clear()
+
+ try:
+ re = sys.modules['re']
+ except KeyError:
+ pass
+ else:
+ re.purge()
+
+ try:
+ _strptime = sys.modules['_strptime']
+ except KeyError:
+ pass
+ else:
+ _strptime._regex_cache.clear()
+
+ try:
+ urllib_parse = sys.modules['urllib.parse']
+ except KeyError:
+ pass
+ else:
+ urllib_parse.clear_cache()
+
+ try:
+ urllib_request = sys.modules['urllib.request']
+ except KeyError:
+ pass
+ else:
+ urllib_request.urlcleanup()
+
+ try:
+ linecache = sys.modules['linecache']
+ except KeyError:
+ pass
+ else:
+ linecache.clearcache()
+
+ try:
+ mimetypes = sys.modules['mimetypes']
+ except KeyError:
+ pass
+ else:
+ mimetypes._default_mime_types()
+
+ try:
+ filecmp = sys.modules['filecmp']
+ except KeyError:
+ pass
+ else:
+ filecmp._cache.clear()
+
+ try:
+ struct = sys.modules['struct']
+ except KeyError:
+ pass
+ else:
+ struct._clearcache()
+
+ try:
+ doctest = sys.modules['doctest']
+ except KeyError:
+ pass
+ else:
+ doctest.master = None
+
+ try:
+ ctypes = sys.modules['ctypes']
+ except KeyError:
+ pass
+ else:
+ ctypes._reset_cache()
+
+ try:
+ typing = sys.modules['typing']
+ except KeyError:
+ pass
+ else:
+ for f in typing._cleanups:
+ f()
+
+ support.gc_collect()