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

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 

3 

4"""Tests about understanding how third-party code is installed.""" 

5 

6from __future__ import annotations 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()

7 

8import os 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()

9import os.path 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()

10import shutil 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()

11 

12from pathlib import Path 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()

13from typing import cast 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()

14from collections.abc import Iterable 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()

15 

16import pytest 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()

17 

18from coverage import env 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()

19 

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$%'()

24 

25 

26def run_in_venv(cmd: str) -> str: 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()

27 r"""Run `cmd` in the virtualenv at `venv`. 

28 

29 The first word of the command will be adjusted to run it from the 

30 venv/bin or venv\Scripts directory. 

31 

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$%'()

44 

45 

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. 

49 

50 Returns the directory containing the "venv" virtualenv. 

51 """ 

52 

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$%'()

57 

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 ) 

105 

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 ) 

124 

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 ) 

178 

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$%'()

188 

189 return venv_world 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()

190 

191 

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$%'()

202 

203 

204@pytest.mark.xdist_group(name="virtualenv_test") 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()

205class VirtualenvTest(CoverageTest): 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()

206 """Tests of virtualenv considerations.""" 

207 

208 expected_stdout = "33\n110\n198\n1.5\n" 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()

209 

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 ) 

227 

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$%'()

231 

232 yield 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()

233 

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$%'()

237 

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$%'()

242 

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$%'()

273 

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 ) 

286 

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$%'()

292 

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$%'()

296 

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 ) 

313 

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$%'()

319 

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$%'()

323 

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$%'()

328 

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$%'()

334 

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

354 

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$%'()

363 

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 ) 

380 

381 out = run_in_venv(coverage_command + " report") 1aBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQRqSTrUVsWXtYZu01v23w45x67y89z!#A$%'()

382 

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% 

389 

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$%'()

396 

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$%'()