Coverage for tests / test_venv.py: 100.000%
134 statements
« prev ^ index » next coverage.py v7.12.1a0.dev1, created at 2025-11-30 17:57 +0000
« prev ^ index » next coverage.py v7.12.1a0.dev1, created at 2025-11-30 17:57 +0000
1# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
2# For details: https://github.com/coveragepy/coveragepy/blob/main/NOTICE.txt
4"""Tests about understanding how third-party code is installed."""
6from __future__ import annotations 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
8import os 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
9import os.path 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
10import shutil 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
12from pathlib import Path 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
13from typing import cast 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
14from collections.abc import Iterable 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
16import pytest 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
18from coverage import env 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
20from tests import testenv 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
21from tests.coveragetest import CoverageTest, COVERAGE_INSTALL_ARGS 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
22from tests.helpers import change_dir, make_file 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
23from tests.helpers import re_lines, run_command 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
26def run_in_venv(cmd: str) -> str: 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
27 r"""Run `cmd` in the virtualenv at `venv`.
29 The first word of the command will be adjusted to run it from the
30 venv/bin or venv\Scripts directory.
32 Returns the text output of the command.
33 """
34 words = cmd.split() 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
35 if env.WINDOWS: 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
36 words[0] = rf"venv\Scripts\{words[0]}.exe" 1cDfGiJlMoPrUVu01x67A$%)
37 else:
38 words[0] = rf"venv/bin/{words[0]}" 1aBbCdEeFgHhIjKkLmNnOpQRqSTsWXtYZv23w45y89z!#'(
39 status, output = run_command(" ".join(words)) 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
40 # Print the output so if it fails, we can tell what happened.
41 print(output) 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
42 assert status == 0 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
43 return output 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
46@pytest.fixture(scope="session", name="venv_world") 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
47def venv_world_fixture(tmp_path_factory: pytest.TempPathFactory) -> Path: 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
48 """Create a virtualenv with a few test packages for VirtualenvTest to use.
50 Returns the directory containing the "venv" virtualenv.
51 """
53 venv_world = tmp_path_factory.mktemp("venv_world") 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
54 with change_dir(venv_world): 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
55 # Create a virtualenv.
56 run_command("python -m venv venv") 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
58 # A third-party package that installs a few different packages.
59 make_file( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
60 "third_pkg/third/__init__.py",
61 """\
62 import fourth
63 def third(x):
64 return 3 * x
65 """,
66 )
67 # Use plugin2.py as third.plugin
68 with open(os.path.join(os.path.dirname(__file__), "plugin2.py"), encoding="utf-8") as f: 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
69 make_file("third_pkg/third/plugin.py", f.read()) 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
70 # A render function for plugin2 to use for dynamic file names.
71 make_file( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
72 "third_pkg/third/render.py",
73 """\
74 def render(filename, linenum):
75 return "HTML: {}@{}".format(filename, linenum)
76 """,
77 )
78 # Another package that third can use.
79 make_file( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
80 "third_pkg/fourth/__init__.py",
81 """\
82 def fourth(x):
83 return 4 * x
84 """,
85 )
86 # Some namespace packages.
87 make_file( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
88 "third_pkg/nspkg/fifth/__init__.py",
89 """\
90 def fifth(x):
91 return 5 * x
92 """,
93 )
94 # The setup.py to install everything.
95 make_file( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
96 "third_pkg/setup.py",
97 """\
98 import setuptools
99 setuptools.setup(
100 name="third",
101 packages=["third", "fourth", "nspkg.fifth"],
102 )
103 """,
104 )
106 # Some namespace packages.
107 make_file( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
108 "another_pkg/nspkg/sixth/__init__.py",
109 """\
110 def sixth(x):
111 return 6 * x
112 """,
113 )
114 make_file( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
115 "another_pkg/setup.py",
116 """\
117 import setuptools
118 setuptools.setup(
119 name="another",
120 packages=["nspkg.sixth"],
121 )
122 """,
123 )
125 # Bug888 code.
126 make_file( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
127 "bug888/app/setup.py",
128 """\
129 from setuptools import setup
130 setup(
131 name='testcov',
132 packages=['testcov'],
133 )
134 """,
135 )
136 # https://packaging.python.org/en/latest/guides/packaging-namespace-packages/#pkgutil-style-namespace-packages
137 make_file( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
138 "bug888/app/testcov/__init__.py",
139 """\
140 __path__ = __import__('pkgutil').extend_path(__path__, __name__)
141 """,
142 )
143 get_plugins = "entry_points.select(group='plugins')" 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
144 make_file( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
145 "bug888/app/testcov/main.py",
146 f"""\
147 import importlib.metadata
148 entry_points = importlib.metadata.entry_points()
149 for entry_point in {get_plugins}:
150 entry_point.load()()
151 """,
152 )
153 make_file( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
154 "bug888/plugin/setup.py",
155 """\
156 from setuptools import setup
157 setup(
158 name='testcov-plugin',
159 packages=['testcov'],
160 entry_points={'plugins': ['testp = testcov.plugin:testp']},
161 )
162 """,
163 )
164 # https://packaging.python.org/en/latest/guides/packaging-namespace-packages/#pkgutil-style-namespace-packages
165 make_file( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
166 "bug888/plugin/testcov/__init__.py",
167 """\
168 __path__ = __import__('pkgutil').extend_path(__path__, __name__)
169 """,
170 )
171 make_file( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
172 "bug888/plugin/testcov/plugin.py",
173 """\
174 def testp():
175 print("Plugin here")
176 """,
177 )
179 # Install everything.
180 run_in_venv( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
181 "python -m pip install "
182 + "./third_pkg "
183 + "-e ./another_pkg "
184 + "-e ./bug888/app -e ./bug888/plugin "
185 + COVERAGE_INSTALL_ARGS,
186 )
187 shutil.rmtree("third_pkg") 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
189 return venv_world 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
192@pytest.fixture( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
193 params=[
194 "coverage",
195 "python -m coverage",
196 ],
197 name="coverage_command",
198)
199def coverage_command_fixture(request: pytest.FixtureRequest) -> str: 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
200 """Parametrized fixture to use multiple forms of "coverage" command."""
201 return cast(str, request.param) 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
204@pytest.mark.xdist_group(name="virtualenv_test") 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
205class VirtualenvTest(CoverageTest): 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
206 """Tests of virtualenv considerations."""
208 expected_stdout = "33\n110\n198\n1.5\n" 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
210 @pytest.fixture(autouse=True) 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
211 def in_venv_world_fixture(self, venv_world: Path) -> Iterable[None]: 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
212 """For running tests inside venv_world, and cleaning up made files."""
213 with change_dir(venv_world): 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
214 self.make_file( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
215 "myproduct.py",
216 """\
217 import colorsys
218 import third
219 import nspkg.fifth
220 import nspkg.sixth
221 print(third.third(11))
222 print(nspkg.fifth.fifth(22))
223 print(nspkg.sixth.sixth(33))
224 print(sum(colorsys.rgb_to_hls(1, 0, 0)))
225 """,
226 )
228 self.del_environ("COVERAGE_TESTING") # To get realistic behavior 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
229 self.set_environ("COVERAGE_DEBUG_FILE", "debug_out.txt") 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
230 self.set_environ("COVERAGE_DEBUG", "trace") 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
232 yield 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
234 for fname in os.listdir("."): 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
235 if fname not in {"venv", "another_pkg", "bug888"}: 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
236 os.remove(fname) 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
238 def get_trace_output(self) -> str: 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
239 """Get the debug output of coverage.py"""
240 with open("debug_out.txt", encoding="utf-8") as f: 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
241 return f.read() 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
243 @pytest.mark.parametrize("install_source_in_venv", [True, False]) 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
244 def test_third_party_venv_isnt_measured( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
245 self,
246 coverage_command: str,
247 install_source_in_venv: bool,
248 ) -> None:
249 if install_source_in_venv: 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
250 make_file( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
251 "setup.py",
252 """\
253 import setuptools
254 setuptools.setup(
255 name="myproduct",
256 py_modules = ["myproduct"],
257 )
258 """,
259 )
260 try: 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
261 run_in_venv("python -m pip install .") 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
262 finally:
263 shutil.rmtree("build", ignore_errors=True) 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
264 shutil.rmtree("myproduct.egg-info", ignore_errors=True) 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
265 # Ensure that coverage doesn't run the non-installed module.
266 os.remove("myproduct.py") 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
267 out = run_in_venv(coverage_command + " run --source=.,myproduct -m myproduct") 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
268 else:
269 out = run_in_venv(coverage_command + " run --source=. myproduct.py") 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
270 # In particular, this warning doesn't appear:
271 # Already imported a file that will be measured: .../coverage/__main__.py
272 assert out == self.expected_stdout 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
274 # Check that our tracing was accurate. Files are mentioned because
275 # --source refers to a file.
276 debug_out = self.get_trace_output() 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
277 assert re_lines( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
278 r"^Not tracing .*\bexecfile.py': inside --source, but is third-party",
279 debug_out,
280 )
281 assert re_lines(r"^Tracing .*\bmyproduct.py", debug_out) 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
282 assert re_lines( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
283 r"^Not tracing .*\bcolorsys.py': (module 'colorsys' |)?falls outside the --source spec",
284 debug_out,
285 )
287 out = run_in_venv(coverage_command + " report") 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
288 assert "myproduct.py" in out 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
289 assert "third" not in out 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
290 assert "coverage" not in out 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
291 assert "colorsys" not in out 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
293 def test_us_in_venv_isnt_measured(self, coverage_command: str) -> None: 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
294 out = run_in_venv(coverage_command + " run --source=third myproduct.py") 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
295 assert out == self.expected_stdout 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
297 # Check that our tracing was accurate. Modules are mentioned because
298 # --source refers to a module.
299 debug_out = self.get_trace_output() 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
300 assert re_lines( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
301 r"^Not tracing .*\bexecfile.py': "
302 + "module 'coverage.execfile' falls outside the --source spec",
303 debug_out,
304 )
305 assert re_lines( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
306 r"^Not tracing .*\bmyproduct.py': module 'myproduct' falls outside the --source spec",
307 debug_out,
308 )
309 assert re_lines( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
310 r"^Not tracing .*\bcolorsys.py': module 'colorsys' falls outside the --source spec",
311 debug_out,
312 )
314 out = run_in_venv(coverage_command + " report") 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
315 assert "myproduct.py" not in out 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
316 assert "third" in out 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
317 assert "coverage" not in out 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
318 assert "colorsys" not in out 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
320 def test_venv_isnt_measured(self, coverage_command: str) -> None: 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
321 out = run_in_venv(coverage_command + " run myproduct.py") 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
322 assert out == self.expected_stdout 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
324 debug_out = self.get_trace_output() 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
325 assert re_lines(r"^Not tracing .*\bexecfile.py': is part of coverage.py", debug_out) 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
326 assert re_lines(r"^Tracing .*\bmyproduct.py", debug_out) 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
327 assert re_lines(r"^Not tracing .*\bcolorsys.py': is in the stdlib", debug_out) 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
329 out = run_in_venv(coverage_command + " report") 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
330 assert "myproduct.py" in out 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
331 assert "third" not in out 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
332 assert "coverage" not in out 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
333 assert "colorsys" not in out 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
335 @pytest.mark.skipif(not testenv.C_TRACER, reason="No plugins with this core.") 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
336 def test_venv_with_dynamic_plugin(self, coverage_command: str) -> None: 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
337 # https://github.com/coveragepy/coveragepy/issues/1150
338 # Django coverage plugin was incorrectly getting warnings:
339 # "Already imported: ... django/template/blah.py"
340 # It happened because coverage imported the plugin, which imported
341 # Django, and then the Django files were reported as traceable.
342 self.make_file(".coveragerc", "[run]\nplugins=third.plugin\n") 1abcdefghijklmnopqrstuvwxyzA
343 self.make_file( 1abcdefghijklmnopqrstuvwxyzA
344 "myrender.py",
345 """\
346 import third.render
347 print(third.render.render("hello.html", 1723))
348 """,
349 )
350 out = run_in_venv(coverage_command + " run --source=. myrender.py") 1abcdefghijklmnopqrstuvwxyzA
351 # The output should not have this warning:
352 # Already imported a file that will be measured: ...third/render.py (already-imported)
353 assert out == "HTML: hello.html@1723\n" 1abcdefghijklmnopqrstuvwxyzA
355 def test_installed_namespace_packages(self, coverage_command: str) -> None: 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
356 # https://github.com/coveragepy/coveragepy/issues/1231
357 # When namespace packages were installed, they were considered
358 # third-party packages. Test that isn't still happening.
359 out = run_in_venv(coverage_command + " run --source=nspkg myproduct.py") 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
360 # In particular, this warning doesn't appear:
361 # Already imported a file that will be measured: .../coverage/__main__.py
362 assert out == self.expected_stdout 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
364 # Check that our tracing was accurate. Files are mentioned because
365 # --source refers to a file.
366 debug_out = self.get_trace_output() 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
367 assert re_lines( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
368 r"^Not tracing .*\bexecfile.py': "
369 + "module 'coverage.execfile' falls outside the --source spec",
370 debug_out,
371 )
372 assert re_lines( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
373 r"^Not tracing .*\bmyproduct.py': module 'myproduct' falls outside the --source spec",
374 debug_out,
375 )
376 assert re_lines( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
377 r"^Not tracing .*\bcolorsys.py': module 'colorsys' falls outside the --source spec",
378 debug_out,
379 )
381 out = run_in_venv(coverage_command + " report") 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
383 # Name Stmts Miss Cover
384 # ------------------------------------------------------------------------------
385 # another_pkg/nspkg/sixth/__init__.py 2 0 100%
386 # venv/lib/python3.9/site-packages/nspkg/fifth/__init__.py 2 0 100%
387 # ------------------------------------------------------------------------------
388 # TOTAL 4 0 100%
390 assert "myproduct.py" not in out 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
391 assert "third" not in out 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
392 assert "coverage" not in out 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
393 assert "colorsys" not in out 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
394 assert "fifth" in out 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
395 assert "sixth" in out 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
397 def test_bug_888(self, coverage_command: str) -> None: 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
398 out = run_in_venv( 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()
399 coverage_command + " run --source=bug888/app,bug888/plugin bug888/app/testcov/main.py",
400 )
401 # When the test fails, the output includes "Already imported a file that will be measured"
402 assert out == "Plugin here\n" 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()