summaryrefslogtreecommitdiff
path: root/coverage/misc.py
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2021-10-05 19:43:00 -0400
committerNed Batchelder <ned@nedbatchelder.com>2021-10-06 07:20:22 -0400
commit613446ca9da592c6925329b869b9ef785d83f76e (patch)
treec522f410454e4fc61519598d4cda0f91843703d2 /coverage/misc.py
parent62116801c3ae2f7bfc6302836e46bdfac681c1a5 (diff)
downloadpython-coveragepy-git-613446ca9da592c6925329b869b9ef785d83f76e.tar.gz
fix: pretend we didn't import third-party packages we use. #1228
tomli couldn't use coverage themselves because we imported it early. Cleaning sys.modules means their own imports will actually execute after coverage has started, so their files will be properly measured.
Diffstat (limited to 'coverage/misc.py')
-rw-r--r--coverage/misc.py27
1 files changed, 27 insertions, 0 deletions
diff --git a/coverage/misc.py b/coverage/misc.py
index 11dad23e..cd4a7740 100644
--- a/coverage/misc.py
+++ b/coverage/misc.py
@@ -5,6 +5,7 @@
import errno
import hashlib
+import importlib
import importlib.util
import inspect
import locale
@@ -43,6 +44,32 @@ def isolate_module(mod):
os = isolate_module(os)
+def import_third_party(modname):
+ """Import a third-party module we need, but might not be installed.
+
+ This also cleans out the module after the import, so that coverage won't
+ appear to have imported it. This lets the third party use coverage for
+ their own tests.
+
+ Arguments:
+ modname (str): the name of the module to import.
+
+ Returns:
+ The imported module, or None if the module couldn't be imported.
+
+ """
+ try:
+ mod = importlib.import_module(modname)
+ except ImportError:
+ mod = None
+
+ imported = [m for m in sys.modules if m.startswith(modname)]
+ for name in imported:
+ del sys.modules[name]
+
+ return mod
+
+
def dummy_decorator_with_args(*args_unused, **kwargs_unused):
"""Dummy no-op implementation of a decorator with arguments."""
def _decorator(func):