coverage 7.6.10__cp312-cp312-musllinux_1_2_aarch64.whl → 7.12.0__cp312-cp312-musllinux_1_2_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- coverage/__init__.py +3 -1
- coverage/__main__.py +3 -1
- coverage/annotate.py +2 -3
- coverage/bytecode.py +178 -4
- coverage/cmdline.py +330 -155
- coverage/collector.py +32 -43
- coverage/config.py +167 -63
- coverage/context.py +5 -6
- coverage/control.py +165 -86
- coverage/core.py +71 -34
- coverage/data.py +4 -5
- coverage/debug.py +113 -57
- coverage/disposition.py +2 -1
- coverage/env.py +29 -78
- coverage/exceptions.py +29 -7
- coverage/execfile.py +19 -14
- coverage/files.py +24 -19
- coverage/html.py +118 -75
- coverage/htmlfiles/coverage_html.js +12 -10
- coverage/htmlfiles/index.html +45 -10
- coverage/htmlfiles/pyfile.html +2 -2
- coverage/htmlfiles/style.css +54 -6
- coverage/htmlfiles/style.scss +85 -3
- coverage/inorout.py +62 -45
- coverage/jsonreport.py +22 -9
- coverage/lcovreport.py +16 -18
- coverage/misc.py +51 -47
- coverage/multiproc.py +12 -7
- coverage/numbits.py +4 -5
- coverage/parser.py +150 -251
- coverage/patch.py +166 -0
- coverage/phystokens.py +25 -26
- coverage/plugin.py +14 -14
- coverage/plugin_support.py +37 -36
- coverage/python.py +13 -14
- coverage/pytracer.py +31 -33
- coverage/regions.py +3 -2
- coverage/report.py +60 -44
- coverage/report_core.py +7 -10
- coverage/results.py +152 -68
- coverage/sqldata.py +261 -211
- coverage/sqlitedb.py +37 -29
- coverage/sysmon.py +237 -162
- coverage/templite.py +19 -7
- coverage/tomlconfig.py +13 -13
- coverage/tracer.cpython-312-aarch64-linux-musl.so +0 -0
- coverage/tracer.pyi +3 -1
- coverage/types.py +26 -23
- coverage/version.py +4 -19
- coverage/xmlreport.py +17 -14
- {coverage-7.6.10.dist-info → coverage-7.12.0.dist-info}/METADATA +50 -28
- coverage-7.12.0.dist-info/RECORD +59 -0
- {coverage-7.6.10.dist-info → coverage-7.12.0.dist-info}/WHEEL +1 -1
- coverage-7.6.10.dist-info/RECORD +0 -58
- {coverage-7.6.10.dist-info → coverage-7.12.0.dist-info}/entry_points.txt +0 -0
- {coverage-7.6.10.dist-info → coverage-7.12.0.dist-info/licenses}/LICENSE.txt +0 -0
- {coverage-7.6.10.dist-info → coverage-7.12.0.dist-info}/top_level.txt +0 -0
coverage/htmlfiles/style.css
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
@charset "UTF-8";
|
|
2
2
|
/* Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 */
|
|
3
|
-
/* For details: https://github.com/
|
|
3
|
+
/* For details: https://github.com/coveragepy/coveragepy/blob/main/NOTICE.txt */
|
|
4
4
|
/* Don't edit this .css file. Edit the .scss file instead! */
|
|
5
5
|
html, body, h1, h2, h3, p, table, td, th { margin: 0; padding: 0; border: 0; font-weight: inherit; font-style: inherit; font-size: 100%; font-family: inherit; vertical-align: baseline; }
|
|
6
6
|
|
|
@@ -200,9 +200,9 @@ kbd { border: 1px solid black; border-color: #888 #333 #333 #888; padding: .1em
|
|
|
200
200
|
|
|
201
201
|
#source p .t .key { font-weight: bold; line-height: 1px; }
|
|
202
202
|
|
|
203
|
-
#source p .t .str { color: #0451a5; }
|
|
203
|
+
#source p .t .str, #source p .t .fst { color: #0451a5; }
|
|
204
204
|
|
|
205
|
-
@media (prefers-color-scheme: dark) { #source p .t .str { color: #9cdcfe; } }
|
|
205
|
+
@media (prefers-color-scheme: dark) { #source p .t .str, #source p .t .fst { color: #9cdcfe; } }
|
|
206
206
|
|
|
207
207
|
#source p.mis .t { border-left: 0.2em solid #ff0000; }
|
|
208
208
|
|
|
@@ -214,6 +214,16 @@ kbd { border: 1px solid black; border-color: #888 #333 #333 #888; padding: .1em
|
|
|
214
214
|
|
|
215
215
|
@media (prefers-color-scheme: dark) { #source p.mis.show_mis .t:hover { background: #532323; } }
|
|
216
216
|
|
|
217
|
+
#source p.mis.mis2 .t { border-left: 0.2em dotted #ff0000; }
|
|
218
|
+
|
|
219
|
+
#source p.mis.mis2.show_mis .t { background: #ffeeee; }
|
|
220
|
+
|
|
221
|
+
@media (prefers-color-scheme: dark) { #source p.mis.mis2.show_mis .t { background: #351b1b; } }
|
|
222
|
+
|
|
223
|
+
#source p.mis.mis2.show_mis .t:hover { background: #f2d2d2; }
|
|
224
|
+
|
|
225
|
+
@media (prefers-color-scheme: dark) { #source p.mis.mis2.show_mis .t:hover { background: #532323; } }
|
|
226
|
+
|
|
217
227
|
#source p.run .t { border-left: 0.2em solid #00dd00; }
|
|
218
228
|
|
|
219
229
|
#source p.run.show_run .t { background: #dfd; }
|
|
@@ -224,6 +234,16 @@ kbd { border: 1px solid black; border-color: #888 #333 #333 #888; padding: .1em
|
|
|
224
234
|
|
|
225
235
|
@media (prefers-color-scheme: dark) { #source p.run.show_run .t:hover { background: #404633; } }
|
|
226
236
|
|
|
237
|
+
#source p.run.run2 .t { border-left: 0.2em dotted #00dd00; }
|
|
238
|
+
|
|
239
|
+
#source p.run.run2.show_run .t { background: #eeffee; }
|
|
240
|
+
|
|
241
|
+
@media (prefers-color-scheme: dark) { #source p.run.run2.show_run .t { background: #2b2e24; } }
|
|
242
|
+
|
|
243
|
+
#source p.run.run2.show_run .t:hover { background: #d2f2d2; }
|
|
244
|
+
|
|
245
|
+
@media (prefers-color-scheme: dark) { #source p.run.run2.show_run .t:hover { background: #404633; } }
|
|
246
|
+
|
|
227
247
|
#source p.exc .t { border-left: 0.2em solid #808080; }
|
|
228
248
|
|
|
229
249
|
#source p.exc.show_exc .t { background: #eee; }
|
|
@@ -234,6 +254,16 @@ kbd { border: 1px solid black; border-color: #888 #333 #333 #888; padding: .1em
|
|
|
234
254
|
|
|
235
255
|
@media (prefers-color-scheme: dark) { #source p.exc.show_exc .t:hover { background: #3c3c3c; } }
|
|
236
256
|
|
|
257
|
+
#source p.exc.exc2 .t { border-left: 0.2em dotted #808080; }
|
|
258
|
+
|
|
259
|
+
#source p.exc.exc2.show_exc .t { background: #f7f7f7; }
|
|
260
|
+
|
|
261
|
+
@media (prefers-color-scheme: dark) { #source p.exc.exc2.show_exc .t { background: #292929; } }
|
|
262
|
+
|
|
263
|
+
#source p.exc.exc2.show_exc .t:hover { background: #e2e2e2; }
|
|
264
|
+
|
|
265
|
+
@media (prefers-color-scheme: dark) { #source p.exc.exc2.show_exc .t:hover { background: #3c3c3c; } }
|
|
266
|
+
|
|
237
267
|
#source p.par .t { border-left: 0.2em solid #bbbb00; }
|
|
238
268
|
|
|
239
269
|
#source p.par.show_par .t { background: #ffa; }
|
|
@@ -244,6 +274,16 @@ kbd { border: 1px solid black; border-color: #888 #333 #333 #888; padding: .1em
|
|
|
244
274
|
|
|
245
275
|
@media (prefers-color-scheme: dark) { #source p.par.show_par .t:hover { background: #6d5d0c; } }
|
|
246
276
|
|
|
277
|
+
#source p.par.par2 .t { border-left: 0.2em dotted #bbbb00; }
|
|
278
|
+
|
|
279
|
+
#source p.par.par2.show_par .t { background: #ffffd5; }
|
|
280
|
+
|
|
281
|
+
@media (prefers-color-scheme: dark) { #source p.par.par2.show_par .t { background: #423a0f; } }
|
|
282
|
+
|
|
283
|
+
#source p.par.par2.show_par .t:hover { background: #f2f2a2; }
|
|
284
|
+
|
|
285
|
+
@media (prefers-color-scheme: dark) { #source p.par.par2.show_par .t:hover { background: #6d5d0c; } }
|
|
286
|
+
|
|
247
287
|
#source p .r { position: absolute; top: 0; right: 2.5em; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; }
|
|
248
288
|
|
|
249
289
|
#source p .annotate { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; color: #666; padding-right: .5em; }
|
|
@@ -288,13 +328,19 @@ kbd { border: 1px solid black; border-color: #888 #333 #333 #888; padding: .1em
|
|
|
288
328
|
|
|
289
329
|
#index table.index { margin-left: -.5em; }
|
|
290
330
|
|
|
291
|
-
#index td, #index th { text-align: right; padding: .25em .5em; border-bottom: 1px solid #eee; }
|
|
331
|
+
#index td, #index th { text-align: right; vertical-align: baseline; padding: .25em .5em; border-bottom: 1px solid #eee; }
|
|
292
332
|
|
|
293
333
|
@media (prefers-color-scheme: dark) { #index td, #index th { border-color: #333; } }
|
|
294
334
|
|
|
295
335
|
#index td.name, #index th.name { text-align: left; width: auto; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; min-width: 15em; }
|
|
296
336
|
|
|
297
|
-
#index
|
|
337
|
+
#index td.left, #index th.left { text-align: left; }
|
|
338
|
+
|
|
339
|
+
#index td.spacer, #index th.spacer { border: none; padding: 0; }
|
|
340
|
+
|
|
341
|
+
#index td.spacer:hover, #index th.spacer:hover { background: inherit; }
|
|
342
|
+
|
|
343
|
+
#index th { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; font-style: italic; color: #333; border-color: #ccc; cursor: pointer; }
|
|
298
344
|
|
|
299
345
|
@media (prefers-color-scheme: dark) { #index th { color: #ddd; } }
|
|
300
346
|
|
|
@@ -312,13 +358,15 @@ kbd { border: 1px solid black; border-color: #888 #333 #333 #888; padding: .1em
|
|
|
312
358
|
|
|
313
359
|
#index th[aria-sort="descending"] .arrows::after { content: " ▼"; }
|
|
314
360
|
|
|
361
|
+
#index tr.grouphead th { cursor: default; font-style: normal; border-color: #999; }
|
|
362
|
+
|
|
315
363
|
#index td.name { font-size: 1.15em; }
|
|
316
364
|
|
|
317
365
|
#index td.name a { text-decoration: none; color: inherit; }
|
|
318
366
|
|
|
319
367
|
#index td.name .no-noun { font-style: italic; }
|
|
320
368
|
|
|
321
|
-
#index tr.total td, #index tr.total_dynamic td { font-weight: bold; border-
|
|
369
|
+
#index tr.total td, #index tr.total_dynamic td { font-weight: bold; border-bottom: none; }
|
|
322
370
|
|
|
323
371
|
#index tr.region:hover { background: #eee; }
|
|
324
372
|
|
coverage/htmlfiles/style.scss
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 */
|
|
2
|
-
/* For details: https://github.com/
|
|
2
|
+
/* For details: https://github.com/coveragepy/coveragepy/blob/main/NOTICE.txt */
|
|
3
3
|
|
|
4
4
|
// CSS styles for coverage.py HTML reports.
|
|
5
5
|
|
|
@@ -27,6 +27,7 @@ $font-code: SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
|
27
27
|
|
|
28
28
|
$off-button-lighten: 50%;
|
|
29
29
|
$hover-dark-amt: 95%;
|
|
30
|
+
$multi-dim-amt: 50%;
|
|
30
31
|
|
|
31
32
|
$focus-color: #007acc;
|
|
32
33
|
|
|
@@ -501,7 +502,7 @@ $border-indicator-width: .2em;
|
|
|
501
502
|
font-weight: bold;
|
|
502
503
|
line-height: 1px;
|
|
503
504
|
}
|
|
504
|
-
.str {
|
|
505
|
+
.str, .fst {
|
|
505
506
|
color: $light-token-str;
|
|
506
507
|
@include color-dark($dark-token-str);
|
|
507
508
|
}
|
|
@@ -521,6 +522,22 @@ $border-indicator-width: .2em;
|
|
|
521
522
|
@include background-dark(mix($dark-mis-bg, $dark-fg, $hover-dark-amt));
|
|
522
523
|
}
|
|
523
524
|
}
|
|
525
|
+
|
|
526
|
+
&.mis2 {
|
|
527
|
+
.t {
|
|
528
|
+
border-left: $border-indicator-width dotted $mis-color;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
&.show_mis .t {
|
|
532
|
+
background: mix($light-mis-bg, $light-bg, $multi-dim-amt);
|
|
533
|
+
@include background-dark(mix($dark-mis-bg, $dark-bg, $multi-dim-amt));
|
|
534
|
+
|
|
535
|
+
&:hover {
|
|
536
|
+
background: mix($light-mis-bg, $light-fg, $hover-dark-amt);
|
|
537
|
+
@include background-dark(mix($dark-mis-bg, $dark-fg, $hover-dark-amt));
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}
|
|
524
541
|
}
|
|
525
542
|
|
|
526
543
|
&.run {
|
|
@@ -537,6 +554,22 @@ $border-indicator-width: .2em;
|
|
|
537
554
|
@include background-dark(mix($dark-run-bg, $dark-fg, $hover-dark-amt));
|
|
538
555
|
}
|
|
539
556
|
}
|
|
557
|
+
|
|
558
|
+
&.run2 {
|
|
559
|
+
.t {
|
|
560
|
+
border-left: $border-indicator-width dotted $run-color;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
&.show_run .t {
|
|
564
|
+
background: mix($light-run-bg, $light-bg, $multi-dim-amt);
|
|
565
|
+
@include background-dark(mix($dark-run-bg, $dark-bg, $multi-dim-amt));
|
|
566
|
+
|
|
567
|
+
&:hover {
|
|
568
|
+
background: mix($light-run-bg, $light-fg, $hover-dark-amt);
|
|
569
|
+
@include background-dark(mix($dark-run-bg, $dark-fg, $hover-dark-amt));
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
540
573
|
}
|
|
541
574
|
|
|
542
575
|
&.exc {
|
|
@@ -553,6 +586,22 @@ $border-indicator-width: .2em;
|
|
|
553
586
|
@include background-dark(mix($dark-exc-bg, $dark-fg, $hover-dark-amt));
|
|
554
587
|
}
|
|
555
588
|
}
|
|
589
|
+
|
|
590
|
+
&.exc2 {
|
|
591
|
+
.t {
|
|
592
|
+
border-left: $border-indicator-width dotted $exc-color;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
&.show_exc .t {
|
|
596
|
+
background: mix($light-exc-bg, $light-bg, $multi-dim-amt);
|
|
597
|
+
@include background-dark(mix($dark-exc-bg, $dark-bg, $multi-dim-amt));
|
|
598
|
+
|
|
599
|
+
&:hover {
|
|
600
|
+
background: mix($light-exc-bg, $light-fg, $hover-dark-amt);
|
|
601
|
+
@include background-dark(mix($dark-exc-bg, $dark-fg, $hover-dark-amt));
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
}
|
|
556
605
|
}
|
|
557
606
|
|
|
558
607
|
&.par {
|
|
@@ -570,6 +619,21 @@ $border-indicator-width: .2em;
|
|
|
570
619
|
}
|
|
571
620
|
}
|
|
572
621
|
|
|
622
|
+
&.par2 {
|
|
623
|
+
.t {
|
|
624
|
+
border-left: $border-indicator-width dotted $par-color;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
&.show_par .t {
|
|
628
|
+
background: mix($light-par-bg, $light-bg, $multi-dim-amt);
|
|
629
|
+
@include background-dark(mix($dark-par-bg, $dark-bg, $multi-dim-amt));
|
|
630
|
+
|
|
631
|
+
&:hover {
|
|
632
|
+
background: mix($light-par-bg, $light-fg, $hover-dark-amt);
|
|
633
|
+
@include background-dark(mix($dark-par-bg, $dark-fg, $hover-dark-amt));
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
}
|
|
573
637
|
}
|
|
574
638
|
|
|
575
639
|
.r {
|
|
@@ -669,6 +733,7 @@ $border-indicator-width: .2em;
|
|
|
669
733
|
}
|
|
670
734
|
td, th {
|
|
671
735
|
text-align: right;
|
|
736
|
+
vertical-align: baseline;
|
|
672
737
|
padding: .25em .5em;
|
|
673
738
|
border-bottom: 1px solid $light-gray2;
|
|
674
739
|
@include border-color-dark($dark-gray2);
|
|
@@ -678,12 +743,23 @@ $border-indicator-width: .2em;
|
|
|
678
743
|
font-family: $font-normal;
|
|
679
744
|
min-width: 15em;
|
|
680
745
|
}
|
|
746
|
+
&.left {
|
|
747
|
+
text-align: left;
|
|
748
|
+
}
|
|
749
|
+
&.spacer {
|
|
750
|
+
border: none;
|
|
751
|
+
padding: 0;
|
|
752
|
+
&:hover {
|
|
753
|
+
background: inherit;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
681
756
|
}
|
|
682
757
|
th {
|
|
683
758
|
font-family: $font-normal;
|
|
684
759
|
font-style: italic;
|
|
685
760
|
color: $light-gray6;
|
|
686
761
|
@include color-dark($dark-gray6);
|
|
762
|
+
border-color: #ccc;
|
|
687
763
|
cursor: pointer;
|
|
688
764
|
&:hover {
|
|
689
765
|
background: $light-gray2;
|
|
@@ -709,6 +785,13 @@ $border-indicator-width: .2em;
|
|
|
709
785
|
content: " ▼";
|
|
710
786
|
}
|
|
711
787
|
}
|
|
788
|
+
tr.grouphead {
|
|
789
|
+
th {
|
|
790
|
+
cursor: default;
|
|
791
|
+
font-style: normal;
|
|
792
|
+
border-color: #999;
|
|
793
|
+
}
|
|
794
|
+
}
|
|
712
795
|
td.name {
|
|
713
796
|
font-size: 1.15em;
|
|
714
797
|
a {
|
|
@@ -723,7 +806,6 @@ $border-indicator-width: .2em;
|
|
|
723
806
|
tr.total td,
|
|
724
807
|
tr.total_dynamic td {
|
|
725
808
|
font-weight: bold;
|
|
726
|
-
border-top: 1px solid #ccc;
|
|
727
809
|
border-bottom: none;
|
|
728
810
|
}
|
|
729
811
|
tr.region:hover {
|
coverage/inorout.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
|
|
2
|
-
# For details: https://github.com/
|
|
2
|
+
# For details: https://github.com/coveragepy/coveragepy/blob/main/NOTICE.txt
|
|
3
3
|
|
|
4
4
|
"""Determining whether files are being measured/reported or not."""
|
|
5
5
|
|
|
@@ -15,51 +15,54 @@ import re
|
|
|
15
15
|
import sys
|
|
16
16
|
import sysconfig
|
|
17
17
|
import traceback
|
|
18
|
-
|
|
19
|
-
from types import FrameType, ModuleType
|
|
20
|
-
from typing import (
|
|
21
|
-
cast, Any, TYPE_CHECKING,
|
|
22
|
-
)
|
|
23
18
|
from collections.abc import Iterable
|
|
19
|
+
from types import FrameType, ModuleType
|
|
20
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
24
21
|
|
|
25
22
|
from coverage import env
|
|
26
23
|
from coverage.disposition import FileDisposition, disposition_init
|
|
27
|
-
from coverage.exceptions import CoverageException, PluginError
|
|
28
|
-
from coverage.files import
|
|
29
|
-
|
|
24
|
+
from coverage.exceptions import ConfigError, CoverageException, PluginError
|
|
25
|
+
from coverage.files import (
|
|
26
|
+
GlobMatcher,
|
|
27
|
+
ModuleMatcher,
|
|
28
|
+
TreeMatcher,
|
|
29
|
+
canonical_filename,
|
|
30
|
+
find_python_files,
|
|
31
|
+
prep_patterns,
|
|
32
|
+
)
|
|
30
33
|
from coverage.misc import isolate_module, sys_modules_saved
|
|
31
34
|
from coverage.python import source_for_file, source_for_morf
|
|
32
|
-
from coverage.types import TFileDisposition, TMorf, TWarnFn
|
|
35
|
+
from coverage.types import TDebugCtl, TFileDisposition, TMorf, TWarnFn
|
|
33
36
|
|
|
34
37
|
if TYPE_CHECKING:
|
|
35
38
|
from coverage.config import CoverageConfig
|
|
36
39
|
from coverage.plugin_support import Plugins
|
|
37
40
|
|
|
38
41
|
|
|
39
|
-
# Pypy has some unusual stuff in the "stdlib". Consider those locations
|
|
40
|
-
# when deciding where the stdlib is. These modules are not used for anything,
|
|
41
|
-
# they are modules importable from the pypy lib directories, so that we can
|
|
42
|
-
# find those directories.
|
|
43
42
|
modules_we_happen_to_have: list[ModuleType] = [
|
|
44
|
-
inspect,
|
|
43
|
+
inspect,
|
|
44
|
+
itertools,
|
|
45
|
+
os,
|
|
46
|
+
platform,
|
|
47
|
+
re,
|
|
48
|
+
sysconfig,
|
|
49
|
+
traceback,
|
|
45
50
|
]
|
|
46
51
|
|
|
47
52
|
if env.PYPY:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
+
# Pypy has some unusual stuff in the "stdlib". Consider those locations
|
|
54
|
+
# when deciding where the stdlib is. These modules are not used for anything,
|
|
55
|
+
# they are modules importable from the pypy lib directories, so that we can
|
|
56
|
+
# find those directories.
|
|
57
|
+
import _pypy_irc_topic # pylint: disable=import-error
|
|
58
|
+
import _structseq # pylint: disable=import-error
|
|
53
59
|
|
|
54
|
-
|
|
55
|
-
import _pypy_irc_topic
|
|
56
|
-
modules_we_happen_to_have.append(_pypy_irc_topic)
|
|
57
|
-
except ImportError:
|
|
58
|
-
pass
|
|
60
|
+
modules_we_happen_to_have.extend([_structseq, _pypy_irc_topic])
|
|
59
61
|
|
|
60
62
|
|
|
61
63
|
os = isolate_module(os)
|
|
62
64
|
|
|
65
|
+
|
|
63
66
|
def canonical_path(morf: TMorf, directory: bool = False) -> str:
|
|
64
67
|
"""Return the canonical path of the module or file `morf`.
|
|
65
68
|
|
|
@@ -74,7 +77,7 @@ def canonical_path(morf: TMorf, directory: bool = False) -> str:
|
|
|
74
77
|
return morf_path
|
|
75
78
|
|
|
76
79
|
|
|
77
|
-
def name_for_module(filename: str, frame: FrameType | None) -> str:
|
|
80
|
+
def name_for_module(filename: str, frame: FrameType | None) -> str | None:
|
|
78
81
|
"""Get the name of the module for a filename and frame.
|
|
79
82
|
|
|
80
83
|
For configurability's sake, we allow __main__ modules to be matched by
|
|
@@ -87,7 +90,7 @@ def name_for_module(filename: str, frame: FrameType | None) -> str:
|
|
|
87
90
|
|
|
88
91
|
"""
|
|
89
92
|
module_globals = frame.f_globals if frame is not None else {}
|
|
90
|
-
dunder_name: str = module_globals.get("__name__", None)
|
|
93
|
+
dunder_name: str | None = module_globals.get("__name__", None)
|
|
91
94
|
|
|
92
95
|
if isinstance(dunder_name, str) and dunder_name != "__main__":
|
|
93
96
|
# This is the usual case: an imported module.
|
|
@@ -191,14 +194,23 @@ class InOrOut:
|
|
|
191
194
|
self.debug = debug
|
|
192
195
|
self.include_namespace_packages = include_namespace_packages
|
|
193
196
|
|
|
194
|
-
self.source: list[str] = []
|
|
195
197
|
self.source_pkgs: list[str] = []
|
|
196
198
|
self.source_pkgs.extend(config.source_pkgs)
|
|
199
|
+
self.source_dirs: list[str] = []
|
|
200
|
+
self.source_dirs.extend(config.source_dirs)
|
|
197
201
|
for src in config.source or []:
|
|
198
202
|
if os.path.isdir(src):
|
|
199
|
-
self.
|
|
203
|
+
self.source_dirs.append(src)
|
|
200
204
|
else:
|
|
201
205
|
self.source_pkgs.append(src)
|
|
206
|
+
|
|
207
|
+
# Canonicalize everything in `source_dirs`.
|
|
208
|
+
# Also confirm that they actually are directories.
|
|
209
|
+
for i, src in enumerate(self.source_dirs):
|
|
210
|
+
if not os.path.isdir(src):
|
|
211
|
+
raise ConfigError(f"Source dir is not a directory: {src!r}")
|
|
212
|
+
self.source_dirs[i] = canonical_filename(src)
|
|
213
|
+
|
|
202
214
|
self.source_pkgs_unmatched = self.source_pkgs[:]
|
|
203
215
|
|
|
204
216
|
self.include = prep_patterns(config.run_include)
|
|
@@ -233,10 +245,10 @@ class InOrOut:
|
|
|
233
245
|
self.pylib_match = None
|
|
234
246
|
self.include_match = self.omit_match = None
|
|
235
247
|
|
|
236
|
-
if self.
|
|
248
|
+
if self.source_dirs or self.source_pkgs:
|
|
237
249
|
against = []
|
|
238
|
-
if self.
|
|
239
|
-
self.source_match = TreeMatcher(self.
|
|
250
|
+
if self.source_dirs:
|
|
251
|
+
self.source_match = TreeMatcher(self.source_dirs, "source")
|
|
240
252
|
against.append(f"trees {self.source_match!r}")
|
|
241
253
|
if self.source_pkgs:
|
|
242
254
|
self.source_pkgs_match = ModuleMatcher(self.source_pkgs, "source_pkgs")
|
|
@@ -285,7 +297,7 @@ class InOrOut:
|
|
|
285
297
|
)
|
|
286
298
|
self.source_in_third_paths.add(pathdir)
|
|
287
299
|
|
|
288
|
-
for src in self.
|
|
300
|
+
for src in self.source_dirs:
|
|
289
301
|
if self.third_match.match(src):
|
|
290
302
|
_debug(f"Source in third-party: source directory {src!r}")
|
|
291
303
|
self.source_in_third_paths.add(src)
|
|
@@ -410,7 +422,7 @@ class InOrOut:
|
|
|
410
422
|
extra = ""
|
|
411
423
|
ok = False
|
|
412
424
|
if self.source_pkgs_match:
|
|
413
|
-
if self.source_pkgs_match.match(modulename):
|
|
425
|
+
if isinstance(modulename, str) and self.source_pkgs_match.match(modulename):
|
|
414
426
|
ok = True
|
|
415
427
|
if modulename in self.source_pkgs_unmatched:
|
|
416
428
|
self.source_pkgs_unmatched.remove(modulename)
|
|
@@ -457,12 +469,12 @@ class InOrOut:
|
|
|
457
469
|
def warn_conflicting_settings(self) -> None:
|
|
458
470
|
"""Warn if there are settings that conflict."""
|
|
459
471
|
if self.include:
|
|
460
|
-
if self.
|
|
472
|
+
if self.source_dirs or self.source_pkgs:
|
|
461
473
|
self.warn("--include is ignored because --source is set", slug="include-ignored")
|
|
462
474
|
|
|
463
475
|
def warn_already_imported_files(self) -> None:
|
|
464
476
|
"""Warn if files have already been imported that we will be measuring."""
|
|
465
|
-
if self.include or self.
|
|
477
|
+
if self.include or self.source_dirs or self.source_pkgs:
|
|
466
478
|
warned = set()
|
|
467
479
|
for mod in list(sys.modules.values()):
|
|
468
480
|
filename = getattr(mod, "__file__", None)
|
|
@@ -488,7 +500,8 @@ class InOrOut:
|
|
|
488
500
|
elif self.debug and self.debug.should("trace"):
|
|
489
501
|
self.debug.write(
|
|
490
502
|
"Didn't trace already imported file {!r}: {}".format(
|
|
491
|
-
disp.original_filename,
|
|
503
|
+
disp.original_filename,
|
|
504
|
+
disp.reason,
|
|
492
505
|
),
|
|
493
506
|
)
|
|
494
507
|
|
|
@@ -529,13 +542,12 @@ class InOrOut:
|
|
|
529
542
|
Yields pairs: file path, and responsible plug-in name.
|
|
530
543
|
"""
|
|
531
544
|
for pkg in self.source_pkgs:
|
|
532
|
-
if
|
|
533
|
-
not module_has_file(sys.modules[pkg])):
|
|
545
|
+
if pkg not in sys.modules or not module_has_file(sys.modules[pkg]):
|
|
534
546
|
continue
|
|
535
547
|
pkg_file = source_for_file(cast(str, sys.modules[pkg].__file__))
|
|
536
548
|
yield from self._find_executable_files(canonical_path(pkg_file))
|
|
537
549
|
|
|
538
|
-
for src in self.
|
|
550
|
+
for src in self.source_dirs:
|
|
539
551
|
yield from self._find_executable_files(src)
|
|
540
552
|
|
|
541
553
|
def _find_plugin_files(self, src_dir: str) -> Iterable[tuple[str, str]]:
|
|
@@ -555,8 +567,8 @@ class InOrOut:
|
|
|
555
567
|
|
|
556
568
|
"""
|
|
557
569
|
py_files = (
|
|
558
|
-
(py_file, None)
|
|
559
|
-
find_python_files(src_dir, self.include_namespace_packages)
|
|
570
|
+
(py_file, None)
|
|
571
|
+
for py_file in find_python_files(src_dir, self.include_namespace_packages)
|
|
560
572
|
)
|
|
561
573
|
plugin_files = self._find_plugin_files(src_dir)
|
|
562
574
|
|
|
@@ -581,9 +593,14 @@ class InOrOut:
|
|
|
581
593
|
]
|
|
582
594
|
|
|
583
595
|
matcher_names = [
|
|
584
|
-
"source_match",
|
|
585
|
-
"
|
|
586
|
-
"
|
|
596
|
+
"source_match",
|
|
597
|
+
"source_pkgs_match",
|
|
598
|
+
"include_match",
|
|
599
|
+
"omit_match",
|
|
600
|
+
"cover_match",
|
|
601
|
+
"pylib_match",
|
|
602
|
+
"third_match",
|
|
603
|
+
"source_in_third_match",
|
|
587
604
|
]
|
|
588
605
|
|
|
589
606
|
for matcher_name in matcher_names:
|
coverage/jsonreport.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
|
|
2
|
-
# For details: https://github.com/
|
|
2
|
+
# For details: https://github.com/coveragepy/coveragepy/blob/main/NOTICE.txt
|
|
3
3
|
|
|
4
4
|
"""Json reporting for coverage.py"""
|
|
5
5
|
|
|
@@ -8,14 +8,13 @@ from __future__ import annotations
|
|
|
8
8
|
import datetime
|
|
9
9
|
import json
|
|
10
10
|
import sys
|
|
11
|
-
|
|
12
11
|
from collections.abc import Iterable
|
|
13
|
-
from typing import
|
|
12
|
+
from typing import IO, TYPE_CHECKING, Any
|
|
14
13
|
|
|
15
14
|
from coverage import __version__
|
|
16
15
|
from coverage.report_core import get_analysis_to_report
|
|
17
|
-
from coverage.results import Analysis, Numbers
|
|
18
|
-
from coverage.types import
|
|
16
|
+
from coverage.results import Analysis, AnalysisNarrower, Numbers
|
|
17
|
+
from coverage.types import TLineNo, TMorf
|
|
19
18
|
|
|
20
19
|
if TYPE_CHECKING:
|
|
21
20
|
from coverage import Coverage
|
|
@@ -31,6 +30,7 @@ JsonObj = dict[str, Any]
|
|
|
31
30
|
# 3: add region information (functions, classes)
|
|
32
31
|
FORMAT_VERSION = 3
|
|
33
32
|
|
|
33
|
+
|
|
34
34
|
class JsonReporter:
|
|
35
35
|
"""A reporter for writing JSON coverage results."""
|
|
36
36
|
|
|
@@ -51,6 +51,8 @@ class JsonReporter:
|
|
|
51
51
|
"percent_covered_display": nums.pc_covered_str,
|
|
52
52
|
"missing_lines": nums.n_missing,
|
|
53
53
|
"excluded_lines": nums.n_excluded,
|
|
54
|
+
"percent_statements_covered": nums.pc_statements,
|
|
55
|
+
"percent_statements_covered_display": nums.pc_statements_str,
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
def make_branch_summary(self, nums: Numbers) -> JsonObj:
|
|
@@ -60,6 +62,8 @@ class JsonReporter:
|
|
|
60
62
|
"num_partial_branches": nums.n_partial_branches,
|
|
61
63
|
"covered_branches": nums.n_executed_branches,
|
|
62
64
|
"missing_branches": nums.n_missing_branches,
|
|
65
|
+
"percent_branches_covered": nums.pc_branches,
|
|
66
|
+
"percent_branches_covered_display": nums.pc_branches_str,
|
|
63
67
|
}
|
|
64
68
|
|
|
65
69
|
def report(self, morfs: Iterable[TMorf] | None, outfile: IO[str]) -> float:
|
|
@@ -128,21 +132,30 @@ class JsonReporter:
|
|
|
128
132
|
)
|
|
129
133
|
|
|
130
134
|
num_lines = len(file_reporter.source().splitlines())
|
|
135
|
+
regions = file_reporter.code_regions()
|
|
131
136
|
for noun, plural in file_reporter.code_region_kinds():
|
|
132
|
-
reported_file[plural] = region_data = {}
|
|
133
137
|
outside_lines = set(range(1, num_lines + 1))
|
|
134
|
-
for region in
|
|
138
|
+
for region in regions:
|
|
135
139
|
if region.kind != noun:
|
|
136
140
|
continue
|
|
137
141
|
outside_lines -= region.lines
|
|
142
|
+
|
|
143
|
+
narrower = AnalysisNarrower(analysis)
|
|
144
|
+
narrower.add_regions(r.lines for r in regions if r.kind == noun)
|
|
145
|
+
narrower.add_regions([outside_lines])
|
|
146
|
+
|
|
147
|
+
reported_file[plural] = region_data = {}
|
|
148
|
+
for region in regions:
|
|
149
|
+
if region.kind != noun:
|
|
150
|
+
continue
|
|
138
151
|
region_data[region.name] = self.make_region_data(
|
|
139
152
|
coverage_data,
|
|
140
|
-
|
|
153
|
+
narrower.narrow(region.lines),
|
|
141
154
|
)
|
|
142
155
|
|
|
143
156
|
region_data[""] = self.make_region_data(
|
|
144
157
|
coverage_data,
|
|
145
|
-
|
|
158
|
+
narrower.narrow(outside_lines),
|
|
146
159
|
)
|
|
147
160
|
return reported_file
|
|
148
161
|
|
coverage/lcovreport.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
|
|
2
|
-
# For details: https://github.com/
|
|
2
|
+
# For details: https://github.com/coveragepy/coveragepy/blob/main/NOTICE.txt
|
|
3
3
|
|
|
4
4
|
"""LCOV reporting for coverage.py."""
|
|
5
5
|
|
|
@@ -8,13 +8,12 @@ from __future__ import annotations
|
|
|
8
8
|
import base64
|
|
9
9
|
import hashlib
|
|
10
10
|
import sys
|
|
11
|
-
|
|
12
|
-
from typing import IO, TYPE_CHECKING
|
|
13
11
|
from collections.abc import Iterable
|
|
12
|
+
from typing import IO, TYPE_CHECKING
|
|
14
13
|
|
|
15
14
|
from coverage.plugin import FileReporter
|
|
16
15
|
from coverage.report_core import get_analysis_to_report
|
|
17
|
-
from coverage.results import Analysis, Numbers
|
|
16
|
+
from coverage.results import Analysis, AnalysisNarrower, Numbers
|
|
18
17
|
from coverage.types import TMorf
|
|
19
18
|
|
|
20
19
|
if TYPE_CHECKING:
|
|
@@ -43,7 +42,7 @@ def lcov_lines(
|
|
|
43
42
|
hash_suffix = ""
|
|
44
43
|
for line in lines:
|
|
45
44
|
if source_lines:
|
|
46
|
-
hash_suffix = "," + line_hash(source_lines[line-1])
|
|
45
|
+
hash_suffix = "," + line_hash(source_lines[line - 1])
|
|
47
46
|
# Q: can we get info about the number of times a statement is
|
|
48
47
|
# executed? If so, that should be recorded here.
|
|
49
48
|
hit = int(line not in analysis.missing)
|
|
@@ -71,21 +70,26 @@ def lcov_functions(
|
|
|
71
70
|
|
|
72
71
|
# suppressions because of https://github.com/pylint-dev/pylint/issues/9923
|
|
73
72
|
functions = [
|
|
74
|
-
(
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
(
|
|
74
|
+
min(region.start, min(region.lines)), # pylint: disable=nested-min-max
|
|
75
|
+
max(region.start, max(region.lines)), # pylint: disable=nested-min-max
|
|
76
|
+
region,
|
|
77
|
+
)
|
|
77
78
|
for region in fr.code_regions()
|
|
78
79
|
if region.kind == "function" and region.lines
|
|
79
80
|
]
|
|
80
81
|
if not functions:
|
|
81
82
|
return
|
|
82
83
|
|
|
84
|
+
narrower = AnalysisNarrower(file_analysis)
|
|
85
|
+
narrower.add_regions(r.lines for _, _, r in functions)
|
|
86
|
+
|
|
83
87
|
functions.sort()
|
|
84
88
|
functions_hit = 0
|
|
85
89
|
for first_line, last_line, region in functions:
|
|
86
90
|
# A function counts as having been executed if any of it has been
|
|
87
91
|
# executed.
|
|
88
|
-
analysis =
|
|
92
|
+
analysis = narrower.narrow(region.lines)
|
|
89
93
|
hit = int(analysis.numbers.n_executed > 0)
|
|
90
94
|
functions_hit += hit
|
|
91
95
|
|
|
@@ -120,19 +124,13 @@ def lcov_arcs(
|
|
|
120
124
|
# When _none_ of the out arcs from 'line' were executed,
|
|
121
125
|
# it can mean the line always raised an exception.
|
|
122
126
|
assert len(executed_arcs[line]) == 0
|
|
123
|
-
destinations = [
|
|
124
|
-
(dst, "-") for dst in missing_arcs[line]
|
|
125
|
-
]
|
|
127
|
+
destinations = [(dst, "-") for dst in missing_arcs[line]]
|
|
126
128
|
else:
|
|
127
129
|
# Q: can we get counts of the number of times each arc was executed?
|
|
128
130
|
# branch_stats has "total" and "taken" counts for each branch,
|
|
129
131
|
# but it doesn't have "taken" broken down by destination.
|
|
130
|
-
destinations = [
|
|
131
|
-
|
|
132
|
-
]
|
|
133
|
-
destinations.extend(
|
|
134
|
-
(dst, "0") for dst in missing_arcs[line]
|
|
135
|
-
)
|
|
132
|
+
destinations = [(dst, "1") for dst in executed_arcs[line]]
|
|
133
|
+
destinations.extend((dst, "0") for dst in missing_arcs[line])
|
|
136
134
|
|
|
137
135
|
# Sort exit arcs after normal arcs. Exit arcs typically come from
|
|
138
136
|
# an if statement, at the end of a function, with no else clause.
|