Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When stashing the singleton to sys.modules, use an actual module object. #1399

Merged
merged 1 commit into from Jun 11, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 7 additions & 2 deletions coverage/debug.py
Expand Up @@ -12,6 +12,7 @@
import pprint
import reprlib
import sys
import types
import _thread

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

SYS_MOD_NAME = '$coverage.debug.DebugOutputFile.the_one'
SINGLETON_ATTR = 'the_one_and_is_interim'

@classmethod
def get_one(cls, fileobj=None, show_process=True, filters=(), interim=False):
Expand Down Expand Up @@ -310,7 +312,8 @@ def get_one(cls, fileobj=None, show_process=True, filters=(), interim=False):
# this class can be defined more than once. But we really want
# a process-wide singleton. So stash it in sys.modules instead of
# on a class attribute. Yes, this is aggressively gross.
the_one, is_interim = sys.modules.get(cls.SYS_MOD_NAME, (None, True))
singleton_module = sys.modules.get(cls.SYS_MOD_NAME)
the_one, is_interim = getattr(singleton_module, cls.SINGLETON_ATTR, (None, True))
if the_one is None or is_interim:
if fileobj is None:
debug_file_name = os.environ.get("COVERAGE_DEBUG_FILE", FORCED_DEBUG_FILE)
Expand All @@ -321,7 +324,9 @@ def get_one(cls, fileobj=None, show_process=True, filters=(), interim=False):
else:
fileobj = sys.stderr
the_one = cls(fileobj, show_process, filters)
sys.modules[cls.SYS_MOD_NAME] = (the_one, interim)
singleton_module = types.ModuleType(cls.SYS_MOD_NAME)
setattr(singleton_module, cls.SINGLETON_ATTR, (the_one, interim))
sys.modules[cls.SYS_MOD_NAME] = singleton_module
return the_one

def write(self, text):
Expand Down