Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/pytest_cov/embed.py : 8%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""Activate coverage at python startup if appropriate.
3The python site initialisation will ensure that anything we import
4will be removed and not visible at the end of python startup. However
5we minimise all work by putting these init actions in this separate
6module and only importing what is needed when needed.
8For normal python startup when coverage should not be activated the pth
9file checks a single env var and does not import or call the init fn
10here.
12For python startup when an ancestor process has set the env indicating
13that code coverage is being collected we activate coverage based on
14info passed via env vars.
15"""
16import atexit
17import os
18import signal
20_active_cov = None
23def multiprocessing_start(_):
24 global _active_cov
25 cov = init()
26 if cov:
27 _active_cov = cov
28 multiprocessing.util.Finalize(None, cleanup, exitpriority=1000)
31try:
32 import multiprocessing.util
33except ImportError:
34 pass
35else:
36 multiprocessing.util.register_after_fork(multiprocessing_start, multiprocessing_start)
39def init():
40 # Only continue if ancestor process has set everything needed in
41 # the env.
42 global _active_cov
44 cov_source = os.environ.get('COV_CORE_SOURCE')
45 cov_config = os.environ.get('COV_CORE_CONFIG')
46 cov_datafile = os.environ.get('COV_CORE_DATAFILE')
47 cov_branch = True if os.environ.get('COV_CORE_BRANCH') == 'enabled' else None
48 cov_context = os.environ.get('COV_CORE_CONTEXT')
50 if cov_datafile:
51 if _active_cov:
52 cleanup()
53 # Import what we need to activate coverage.
54 import coverage
56 # Determine all source roots.
57 if cov_source in os.pathsep:
58 cov_source = None
59 else:
60 cov_source = cov_source.split(os.pathsep)
61 if cov_config == os.pathsep:
62 cov_config = True
64 # Activate coverage for this process.
65 cov = _active_cov = coverage.Coverage(
66 source=cov_source,
67 branch=cov_branch,
68 data_suffix=True,
69 config_file=cov_config,
70 auto_data=True,
71 data_file=cov_datafile
72 )
73 cov.load()
74 cov.start()
75 if cov_context:
76 cov.switch_context(cov_context)
77 cov._warn_no_data = False
78 cov._warn_unimported_source = False
79 return cov
82def _cleanup(cov):
83 if cov is not None:
84 cov.stop()
85 cov.save()
86 cov._auto_save = False # prevent autosaving from cov._atexit in case the interpreter lacks atexit.unregister
87 try:
88 atexit.unregister(cov._atexit)
89 except Exception:
90 pass
93def cleanup():
94 global _active_cov
95 global _cleanup_in_progress
96 global _pending_signal
98 _cleanup_in_progress = True
99 _cleanup(_active_cov)
100 _active_cov = None
101 _cleanup_in_progress = False
102 if _pending_signal:
103 pending_singal = _pending_signal
104 _pending_signal = None
105 _signal_cleanup_handler(*pending_singal)
108multiprocessing_finish = cleanup # in case someone dared to use this internal
110_previous_handlers = {}
111_pending_signal = None
112_cleanup_in_progress = False
115def _signal_cleanup_handler(signum, frame):
116 global _pending_signal
117 if _cleanup_in_progress:
118 _pending_signal = signum, frame
119 return
120 cleanup()
121 _previous_handler = _previous_handlers.get(signum)
122 if _previous_handler == signal.SIG_IGN:
123 return
124 elif _previous_handler and _previous_handler is not _signal_cleanup_handler:
125 _previous_handler(signum, frame)
126 elif signum == signal.SIGTERM:
127 os._exit(128 + signum)
128 elif signum == signal.SIGINT:
129 raise KeyboardInterrupt()
132def cleanup_on_signal(signum):
133 previous = signal.getsignal(signum)
134 if previous is not _signal_cleanup_handler:
135 _previous_handlers[signum] = previous
136 signal.signal(signum, _signal_cleanup_handler)
139def cleanup_on_sigterm():
140 cleanup_on_signal(signal.SIGTERM)