Skip to content

Commit d0fc548

Browse files
authored
fix: when stashing the singleton to sys.modules, use an actual module object. (#1399)
At least this won't trip anyone iterating through sys.modules and expects the values are actual modules.
1 parent f4273f8 commit d0fc548

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

coverage/debug.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import pprint
1313
import reprlib
1414
import sys
15+
import types
1516
import _thread
1617

1718
from coverage.misc import isolate_module
@@ -282,6 +283,7 @@ def __init__(self, outfile, show_process, filters):
282283
self.write(f"New process: pid: {os.getpid()!r}, parent pid: {os.getppid()!r}\n")
283284

284285
SYS_MOD_NAME = '$coverage.debug.DebugOutputFile.the_one'
286+
SINGLETON_ATTR = 'the_one_and_is_interim'
285287

286288
@classmethod
287289
def get_one(cls, fileobj=None, show_process=True, filters=(), interim=False):
@@ -310,7 +312,8 @@ def get_one(cls, fileobj=None, show_process=True, filters=(), interim=False):
310312
# this class can be defined more than once. But we really want
311313
# a process-wide singleton. So stash it in sys.modules instead of
312314
# on a class attribute. Yes, this is aggressively gross.
313-
the_one, is_interim = sys.modules.get(cls.SYS_MOD_NAME, (None, True))
315+
singleton_module = sys.modules.get(cls.SYS_MOD_NAME)
316+
the_one, is_interim = getattr(singleton_module, cls.SINGLETON_ATTR, (None, True))
314317
if the_one is None or is_interim:
315318
if fileobj is None:
316319
debug_file_name = os.environ.get("COVERAGE_DEBUG_FILE", FORCED_DEBUG_FILE)
@@ -321,7 +324,9 @@ def get_one(cls, fileobj=None, show_process=True, filters=(), interim=False):
321324
else:
322325
fileobj = sys.stderr
323326
the_one = cls(fileobj, show_process, filters)
324-
sys.modules[cls.SYS_MOD_NAME] = (the_one, interim)
327+
singleton_module = types.ModuleType(cls.SYS_MOD_NAME)
328+
setattr(singleton_module, cls.SINGLETON_ATTR, (the_one, interim))
329+
sys.modules[cls.SYS_MOD_NAME] = singleton_module
325330
return the_one
326331

327332
def write(self, text):

0 commit comments

Comments
 (0)