eric7/DebugClients/Python/coverage/sqldata.py

Sat, 20 Nov 2021 16:47:38 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 20 Nov 2021 16:47:38 +0100
branch
eric7
changeset 8775
0802ae193343
parent 8527
2bd1325d727e
child 8929
fcca2fa618bf
permissions
-rw-r--r--

Upgraded coverage to 6.1.2.

7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
2 # For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
3
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
4 """Sqlite coverage data."""
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
5
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
6 # TODO: factor out dataop debugging to a wrapper class?
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
7 # TODO: make sure all dataop debugging is in place somehow
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
8
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
9 import collections
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
10 import datetime
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
11 import functools
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
12 import glob
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
13 import itertools
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
14 import os
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
15 import re
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
16 import sqlite3
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
17 import sys
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
18 import threading
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
19 import zlib
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
20
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
21 from coverage.debug import NoDebugging, SimpleReprMixin, clipped_repr
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
22 from coverage.exceptions import CoverageException
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
23 from coverage.files import PathAliases
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
24 from coverage.misc import contract, file_be_gone, filename_suffix, isolate_module
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
25 from coverage.numbits import numbits_to_nums, numbits_union, nums_to_numbits
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
26 from coverage.version import __version__
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
27
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
28 os = isolate_module(os)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
29
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
30 # If you change the schema, increment the SCHEMA_VERSION, and update the
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
31 # docs in docs/dbschema.rst also.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
32
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
33 SCHEMA_VERSION = 7
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
34
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
35 # Schema versions:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
36 # 1: Released in 5.0a2
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
37 # 2: Added contexts in 5.0a3.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
38 # 3: Replaced line table with line_map table.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
39 # 4: Changed line_map.bitmap to line_map.numbits.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
40 # 5: Added foreign key declarations.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
41 # 6: Key-value in meta.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
42 # 7: line_map -> line_bits
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
43
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
44 SCHEMA = """\
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
45 CREATE TABLE coverage_schema (
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
46 -- One row, to record the version of the schema in this db.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
47 version integer
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
48 );
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
49
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
50 CREATE TABLE meta (
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
51 -- Key-value pairs, to record metadata about the data
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
52 key text,
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
53 value text,
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
54 unique (key)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
55 -- Keys:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
56 -- 'has_arcs' boolean -- Is this data recording branches?
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
57 -- 'sys_argv' text -- The coverage command line that recorded the data.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
58 -- 'version' text -- The version of coverage.py that made the file.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
59 -- 'when' text -- Datetime when the file was created.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
60 );
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
61
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
62 CREATE TABLE file (
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
63 -- A row per file measured.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
64 id integer primary key,
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
65 path text,
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
66 unique (path)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
67 );
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
68
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
69 CREATE TABLE context (
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
70 -- A row per context measured.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
71 id integer primary key,
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
72 context text,
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
73 unique (context)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
74 );
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
75
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
76 CREATE TABLE line_bits (
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
77 -- If recording lines, a row per context per file executed.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
78 -- All of the line numbers for that file/context are in one numbits.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
79 file_id integer, -- foreign key to `file`.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
80 context_id integer, -- foreign key to `context`.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
81 numbits blob, -- see the numbits functions in coverage.numbits
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
82 foreign key (file_id) references file (id),
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
83 foreign key (context_id) references context (id),
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
84 unique (file_id, context_id)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
85 );
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
86
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
87 CREATE TABLE arc (
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
88 -- If recording branches, a row per context per from/to line transition executed.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
89 file_id integer, -- foreign key to `file`.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
90 context_id integer, -- foreign key to `context`.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
91 fromno integer, -- line number jumped from.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
92 tono integer, -- line number jumped to.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
93 foreign key (file_id) references file (id),
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
94 foreign key (context_id) references context (id),
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
95 unique (file_id, context_id, fromno, tono)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
96 );
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
97
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
98 CREATE TABLE tracer (
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
99 -- A row per file indicating the tracer used for that file.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
100 file_id integer primary key,
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
101 tracer text,
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
102 foreign key (file_id) references file (id)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
103 );
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
104 """
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
105
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
106 class CoverageData(SimpleReprMixin):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
107 """Manages collected coverage data, including file storage.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
108
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
109 This class is the public supported API to the data that coverage.py
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
110 collects during program execution. It includes information about what code
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
111 was executed. It does not include information from the analysis phase, to
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
112 determine what lines could have been executed, or what lines were not
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
113 executed.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
114
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
115 .. note::
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
116
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
117 The data file is currently a SQLite database file, with a
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
118 :ref:`documented schema <dbschema>`. The schema is subject to change
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
119 though, so be careful about querying it directly. Use this API if you
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
120 can to isolate yourself from changes.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
121
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
122 There are a number of kinds of data that can be collected:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
123
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
124 * **lines**: the line numbers of source lines that were executed.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
125 These are always available.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
126
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
127 * **arcs**: pairs of source and destination line numbers for transitions
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
128 between source lines. These are only available if branch coverage was
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
129 used.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
130
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
131 * **file tracer names**: the module names of the file tracer plugins that
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
132 handled each file in the data.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
133
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
134 Lines, arcs, and file tracer names are stored for each source file. File
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
135 names in this API are case-sensitive, even on platforms with
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
136 case-insensitive file systems.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
137
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
138 A data file either stores lines, or arcs, but not both.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
139
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
140 A data file is associated with the data when the :class:`CoverageData`
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
141 is created, using the parameters `basename`, `suffix`, and `no_disk`. The
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
142 base name can be queried with :meth:`base_filename`, and the actual file
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
143 name being used is available from :meth:`data_filename`.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
144
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
145 To read an existing coverage.py data file, use :meth:`read`. You can then
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
146 access the line, arc, or file tracer data with :meth:`lines`, :meth:`arcs`,
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
147 or :meth:`file_tracer`.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
148
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
149 The :meth:`has_arcs` method indicates whether arc data is available. You
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
150 can get a set of the files in the data with :meth:`measured_files`. As
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
151 with most Python containers, you can determine if there is any data at all
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
152 by using this object as a boolean value.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
153
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
154 The contexts for each line in a file can be read with
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
155 :meth:`contexts_by_lineno`.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
156
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
157 To limit querying to certain contexts, use :meth:`set_query_context` or
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
158 :meth:`set_query_contexts`. These will narrow the focus of subsequent
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
159 :meth:`lines`, :meth:`arcs`, and :meth:`contexts_by_lineno` calls. The set
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
160 of all measured context names can be retrieved with
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
161 :meth:`measured_contexts`.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
162
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
163 Most data files will be created by coverage.py itself, but you can use
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
164 methods here to create data files if you like. The :meth:`add_lines`,
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
165 :meth:`add_arcs`, and :meth:`add_file_tracers` methods add data, in ways
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
166 that are convenient for coverage.py.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
167
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
168 To record data for contexts, use :meth:`set_context` to set a context to
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
169 be used for subsequent :meth:`add_lines` and :meth:`add_arcs` calls.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
170
7975
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
171 To add a source file without any measured data, use :meth:`touch_file`,
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
172 or :meth:`touch_files` for a list of such files.
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
173
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
174 Write the data to its file with :meth:`write`.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
175
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
176 You can clear the data in memory with :meth:`erase`. Two data collections
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
177 can be combined by using :meth:`update` on one :class:`CoverageData`,
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
178 passing it the other.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
179
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
180 Data in a :class:`CoverageData` can be serialized and deserialized with
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
181 :meth:`dumps` and :meth:`loads`.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
182
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
183 The methods used during the coverage.py collection phase
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
184 (:meth:`add_lines`, :meth:`add_arcs`, :meth:`set_context`, and
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
185 :meth:`add_file_tracers`) are thread-safe. Other methods may not be.
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
186
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
187 """
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
188
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
189 def __init__(self, basename=None, suffix=None, no_disk=False, warn=None, debug=None):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
190 """Create a :class:`CoverageData` object to hold coverage-measured data.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
191
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
192 Arguments:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
193 basename (str): the base name of the data file, defaulting to
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
194 ".coverage".
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
195 suffix (str or bool): has the same meaning as the `data_suffix`
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
196 argument to :class:`coverage.Coverage`.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
197 no_disk (bool): if True, keep all data in memory, and don't
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
198 write any disk file.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
199 warn: a warning callback function, accepting a warning message
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
200 argument.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
201 debug: a `DebugControl` object (optional)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
202
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
203 """
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
204 self._no_disk = no_disk
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
205 self._basename = os.path.abspath(basename or ".coverage")
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
206 self._suffix = suffix
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
207 self._warn = warn
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
208 self._debug = debug or NoDebugging()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
209
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
210 self._choose_filename()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
211 self._file_map = {}
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
212 # Maps thread ids to SqliteDb objects.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
213 self._dbs = {}
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
214 self._pid = os.getpid()
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
215 # Synchronize the operations used during collection.
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
216 self._lock = threading.Lock()
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
217
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
218 # Are we in sync with the data file?
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
219 self._have_used = False
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
220
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
221 self._has_lines = False
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
222 self._has_arcs = False
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
223
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
224 self._current_context = None
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
225 self._current_context_id = None
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
226 self._query_context_ids = None
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
227
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
228 def _locked(method): # pylint: disable=no-self-argument
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
229 """A decorator for methods that should hold self._lock."""
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
230 @functools.wraps(method)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
231 def _wrapped(self, *args, **kwargs):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
232 with self._lock:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
233 # pylint: disable=not-callable
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
234 return method(self, *args, **kwargs)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
235 return _wrapped
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
236
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
237 def _choose_filename(self):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
238 """Set self._filename based on inited attributes."""
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
239 if self._no_disk:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
240 self._filename = ":memory:"
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
241 else:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
242 self._filename = self._basename
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
243 suffix = filename_suffix(self._suffix)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
244 if suffix:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
245 self._filename += "." + suffix
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
246
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
247 def _reset(self):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
248 """Reset our attributes."""
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
249 if self._dbs:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
250 for db in self._dbs.values():
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
251 db.close()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
252 self._dbs = {}
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
253 self._file_map = {}
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
254 self._have_used = False
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
255 self._current_context_id = None
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
256
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
257 def _create_db(self):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
258 """Create a db file that doesn't exist yet.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
259
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
260 Initializes the schema and certain metadata.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
261 """
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
262 if self._debug.should("dataio"):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
263 self._debug.write(f"Creating data file {self._filename!r}")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
264 self._dbs[threading.get_ident()] = db = SqliteDb(self._filename, self._debug)
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
265 with db:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
266 db.executescript(SCHEMA)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
267 db.execute("insert into coverage_schema (version) values (?)", (SCHEMA_VERSION,))
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
268 db.executemany(
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
269 "insert into meta (key, value) values (?, ?)",
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
270 [
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
271 ("sys_argv", str(getattr(sys, "argv", None))),
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
272 ("version", __version__),
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
273 ("when", datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")),
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
274 ]
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
275 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
276
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
277 def _open_db(self):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
278 """Open an existing db file, and read its metadata."""
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
279 if self._debug.should("dataio"):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
280 self._debug.write(f"Opening data file {self._filename!r}")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
281 self._dbs[threading.get_ident()] = SqliteDb(self._filename, self._debug)
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
282 self._read_db()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
283
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
284 def _read_db(self):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
285 """Read the metadata from a database so that we are ready to use it."""
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
286 with self._dbs[threading.get_ident()] as db:
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
287 try:
7702
f8b97639deb5 Third Party packages: updated coverage.py to 5.3.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7427
diff changeset
288 schema_version, = db.execute_one("select version from coverage_schema")
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
289 except Exception as exc:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
290 raise CoverageException(
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
291 "Data file {!r} doesn't seem to be a coverage data file: {}".format(
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
292 self._filename, exc
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
293 )
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
294 ) from exc
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
295 else:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
296 if schema_version != SCHEMA_VERSION:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
297 raise CoverageException(
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
298 "Couldn't use data file {!r}: wrong schema: {} instead of {}".format(
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
299 self._filename, schema_version, SCHEMA_VERSION
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
300 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
301 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
302
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
303 for row in db.execute("select value from meta where key = 'has_arcs'"):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
304 self._has_arcs = bool(int(row[0]))
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
305 self._has_lines = not self._has_arcs
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
306
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
307 for path, file_id in db.execute("select path, id from file"):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
308 self._file_map[path] = file_id
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
309
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
310 def _connect(self):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
311 """Get the SqliteDb object to use."""
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
312 if threading.get_ident() not in self._dbs:
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
313 if os.path.exists(self._filename):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
314 self._open_db()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
315 else:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
316 self._create_db()
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
317 return self._dbs[threading.get_ident()]
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
318
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
319 def __nonzero__(self):
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
320 if (threading.get_ident() not in self._dbs and not os.path.exists(self._filename)):
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
321 return False
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
322 try:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
323 with self._connect() as con:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
324 rows = con.execute("select * from file limit 1")
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
325 return bool(list(rows))
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
326 except CoverageException:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
327 return False
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
328
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
329 __bool__ = __nonzero__
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
330
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
331 @contract(returns="bytes")
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
332 def dumps(self):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
333 """Serialize the current data to a byte string.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
334
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
335 The format of the serialized data is not documented. It is only
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
336 suitable for use with :meth:`loads` in the same version of
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
337 coverage.py.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
338
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
339 Note that this serialization is not what gets stored in coverage data
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
340 files. This method is meant to produce bytes that can be transmitted
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
341 elsewhere and then deserialized with :meth:`loads`.
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
342
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
343 Returns:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
344 A byte string of serialized data.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
345
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
346 .. versionadded:: 5.0
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
347
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
348 """
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
349 if self._debug.should("dataio"):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
350 self._debug.write(f"Dumping data from data file {self._filename!r}")
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
351 with self._connect() as con:
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
352 return b"z" + zlib.compress(con.dump().encode("utf-8"))
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
353
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
354 @contract(data="bytes")
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
355 def loads(self, data):
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
356 """Deserialize data from :meth:`dumps`.
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
357
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
358 Use with a newly-created empty :class:`CoverageData` object. It's
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
359 undefined what happens if the object already has data in it.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
360
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
361 Note that this is not for reading data from a coverage data file. It
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
362 is only for use on data you produced with :meth:`dumps`.
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
363
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
364 Arguments:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
365 data: A byte string of serialized data produced by :meth:`dumps`.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
366
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
367 .. versionadded:: 5.0
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
368
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
369 """
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
370 if self._debug.should("dataio"):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
371 self._debug.write(f"Loading data into data file {self._filename!r}")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
372 if data[:1] != b"z":
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
373 raise CoverageException(
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
374 f"Unrecognized serialization: {data[:40]!r} (head of {len(data)} bytes)"
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
375 )
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
376 script = zlib.decompress(data[1:]).decode("utf-8")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
377 self._dbs[threading.get_ident()] = db = SqliteDb(self._filename, self._debug)
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
378 with db:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
379 db.executescript(script)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
380 self._read_db()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
381 self._have_used = True
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
382
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
383 def _file_id(self, filename, add=False):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
384 """Get the file id for `filename`.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
385
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
386 If filename is not in the database yet, add it if `add` is True.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
387 If `add` is not True, return None.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
388 """
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
389 if filename not in self._file_map:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
390 if add:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
391 with self._connect() as con:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
392 cur = con.execute("insert or replace into file (path) values (?)", (filename,))
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
393 self._file_map[filename] = cur.lastrowid
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
394 return self._file_map.get(filename)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
395
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
396 def _context_id(self, context):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
397 """Get the id for a context."""
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
398 assert context is not None
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
399 self._start_using()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
400 with self._connect() as con:
7702
f8b97639deb5 Third Party packages: updated coverage.py to 5.3.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7427
diff changeset
401 row = con.execute_one("select id from context where context = ?", (context,))
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
402 if row is not None:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
403 return row[0]
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
404 else:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
405 return None
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
406
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
407 @_locked
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
408 def set_context(self, context):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
409 """Set the current context for future :meth:`add_lines` etc.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
410
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
411 `context` is a str, the name of the context to use for the next data
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
412 additions. The context persists until the next :meth:`set_context`.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
413
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
414 .. versionadded:: 5.0
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
415
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
416 """
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
417 if self._debug.should("dataop"):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
418 self._debug.write(f"Setting context: {context!r}")
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
419 self._current_context = context
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
420 self._current_context_id = None
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
421
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
422 def _set_context_id(self):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
423 """Use the _current_context to set _current_context_id."""
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
424 context = self._current_context or ""
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
425 context_id = self._context_id(context)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
426 if context_id is not None:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
427 self._current_context_id = context_id
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
428 else:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
429 with self._connect() as con:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
430 cur = con.execute("insert into context (context) values (?)", (context,))
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
431 self._current_context_id = cur.lastrowid
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
432
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
433 def base_filename(self):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
434 """The base filename for storing data.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
435
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
436 .. versionadded:: 5.0
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
437
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
438 """
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
439 return self._basename
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
440
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
441 def data_filename(self):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
442 """Where is the data stored?
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
443
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
444 .. versionadded:: 5.0
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
445
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
446 """
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
447 return self._filename
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
448
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
449 @_locked
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
450 def add_lines(self, line_data):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
451 """Add measured line data.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
452
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
453 `line_data` is a dictionary mapping file names to iterables of ints::
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
454
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
455 { filename: { line1, line2, ... }, ...}
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
456
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
457 """
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
458 if self._debug.should("dataop"):
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
459 self._debug.write("Adding lines: %d files, %d lines total" % (
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
460 len(line_data), sum(len(lines) for lines in line_data.values())
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
461 ))
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
462 self._start_using()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
463 self._choose_lines_or_arcs(lines=True)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
464 if not line_data:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
465 return
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
466 with self._connect() as con:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
467 self._set_context_id()
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
468 for filename, linenos in line_data.items():
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
469 linemap = nums_to_numbits(linenos)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
470 file_id = self._file_id(filename, add=True)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
471 query = "select numbits from line_bits where file_id = ? and context_id = ?"
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
472 existing = list(con.execute(query, (file_id, self._current_context_id)))
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
473 if existing:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
474 linemap = numbits_union(linemap, existing[0][0])
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
475
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
476 con.execute(
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
477 "insert or replace into line_bits " +
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
478 " (file_id, context_id, numbits) values (?, ?, ?)",
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
479 (file_id, self._current_context_id, linemap),
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
480 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
481
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
482 @_locked
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
483 def add_arcs(self, arc_data):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
484 """Add measured arc data.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
485
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
486 `arc_data` is a dictionary mapping file names to iterables of pairs of
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
487 ints::
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
488
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
489 { filename: { (l1,l2), (l1,l2), ... }, ...}
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
490
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
491 """
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
492 if self._debug.should("dataop"):
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
493 self._debug.write("Adding arcs: %d files, %d arcs total" % (
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
494 len(arc_data), sum(len(arcs) for arcs in arc_data.values())
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
495 ))
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
496 self._start_using()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
497 self._choose_lines_or_arcs(arcs=True)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
498 if not arc_data:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
499 return
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
500 with self._connect() as con:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
501 self._set_context_id()
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
502 for filename, arcs in arc_data.items():
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
503 file_id = self._file_id(filename, add=True)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
504 data = [(file_id, self._current_context_id, fromno, tono) for fromno, tono in arcs]
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
505 con.executemany(
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
506 "insert or ignore into arc " +
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
507 "(file_id, context_id, fromno, tono) values (?, ?, ?, ?)",
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
508 data,
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
509 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
510
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
511 def _choose_lines_or_arcs(self, lines=False, arcs=False):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
512 """Force the data file to choose between lines and arcs."""
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
513 assert lines or arcs
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
514 assert not (lines and arcs)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
515 if lines and self._has_arcs:
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
516 raise CoverageException("Can't add line measurements to existing branch data")
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
517 if arcs and self._has_lines:
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
518 raise CoverageException("Can't add branch measurements to existing line data")
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
519 if not self._has_arcs and not self._has_lines:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
520 self._has_lines = lines
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
521 self._has_arcs = arcs
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
522 with self._connect() as con:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
523 con.execute(
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
524 "insert into meta (key, value) values (?, ?)",
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
525 ("has_arcs", str(int(arcs)))
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
526 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
527
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
528 @_locked
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
529 def add_file_tracers(self, file_tracers):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
530 """Add per-file plugin information.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
531
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
532 `file_tracers` is { filename: plugin_name, ... }
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
533
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
534 """
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
535 if self._debug.should("dataop"):
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
536 self._debug.write("Adding file tracers: %d files" % (len(file_tracers),))
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
537 if not file_tracers:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
538 return
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
539 self._start_using()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
540 with self._connect() as con:
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
541 for filename, plugin_name in file_tracers.items():
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
542 file_id = self._file_id(filename)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
543 if file_id is None:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
544 raise CoverageException(
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
545 f"Can't add file tracer data for unmeasured file '{filename}'"
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
546 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
547
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
548 existing_plugin = self.file_tracer(filename)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
549 if existing_plugin:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
550 if existing_plugin != plugin_name:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
551 raise CoverageException(
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
552 "Conflicting file tracer name for '{}': {!r} vs {!r}".format(
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
553 filename, existing_plugin, plugin_name,
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
554 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
555 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
556 elif plugin_name:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
557 con.execute(
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
558 "insert into tracer (file_id, tracer) values (?, ?)",
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
559 (file_id, plugin_name)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
560 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
561
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
562 def touch_file(self, filename, plugin_name=""):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
563 """Ensure that `filename` appears in the data, empty if needed.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
564
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
565 `plugin_name` is the name of the plugin responsible for this file. It is used
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
566 to associate the right filereporter, etc.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
567 """
7975
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
568 self.touch_files([filename], plugin_name)
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
569
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
570 def touch_files(self, filenames, plugin_name=""):
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
571 """Ensure that `filenames` appear in the data, empty if needed.
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
572
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
573 `plugin_name` is the name of the plugin responsible for these files. It is used
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
574 to associate the right filereporter, etc.
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
575 """
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
576 if self._debug.should("dataop"):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
577 self._debug.write(f"Touching {filenames!r}")
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
578 self._start_using()
7975
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
579 with self._connect(): # Use this to get one transaction.
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
580 if not self._has_arcs and not self._has_lines:
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
581 raise CoverageException("Can't touch files in an empty CoverageData")
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
582
7975
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
583 for filename in filenames:
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
584 self._file_id(filename, add=True)
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
585 if plugin_name:
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
586 # Set the tracer for this file
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
587 self.add_file_tracers({filename: plugin_name})
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
588
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
589 def update(self, other_data, aliases=None):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
590 """Update this data with data from several other :class:`CoverageData` instances.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
591
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
592 If `aliases` is provided, it's a `PathAliases` object that is used to
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
593 re-map paths to match the local machine's.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
594 """
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
595 if self._debug.should("dataop"):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
596 self._debug.write("Updating with data from {!r}".format(
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
597 getattr(other_data, "_filename", "???"),
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
598 ))
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
599 if self._has_lines and other_data._has_arcs:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
600 raise CoverageException("Can't combine arc data with line data")
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
601 if self._has_arcs and other_data._has_lines:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
602 raise CoverageException("Can't combine line data with arc data")
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
603
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
604 aliases = aliases or PathAliases()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
605
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
606 # Force the database we're writing to to exist before we start nesting
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
607 # contexts.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
608 self._start_using()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
609
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
610 # Collector for all arcs, lines and tracers
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
611 other_data.read()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
612 with other_data._connect() as conn:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
613 # Get files data.
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
614 cur = conn.execute("select path from file")
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
615 files = {path: aliases.map(path) for (path,) in cur}
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
616 cur.close()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
617
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
618 # Get contexts data.
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
619 cur = conn.execute("select context from context")
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
620 contexts = [context for (context,) in cur]
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
621 cur.close()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
622
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
623 # Get arc data.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
624 cur = conn.execute(
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
625 "select file.path, context.context, arc.fromno, arc.tono " +
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
626 "from arc " +
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
627 "inner join file on file.id = arc.file_id " +
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
628 "inner join context on context.id = arc.context_id"
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
629 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
630 arcs = [(files[path], context, fromno, tono) for (path, context, fromno, tono) in cur]
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
631 cur.close()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
632
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
633 # Get line data.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
634 cur = conn.execute(
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
635 "select file.path, context.context, line_bits.numbits " +
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
636 "from line_bits " +
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
637 "inner join file on file.id = line_bits.file_id " +
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
638 "inner join context on context.id = line_bits.context_id"
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
639 )
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
640 lines = {(files[path], context): numbits for (path, context, numbits) in cur}
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
641 cur.close()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
642
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
643 # Get tracer data.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
644 cur = conn.execute(
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
645 "select file.path, tracer " +
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
646 "from tracer " +
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
647 "inner join file on file.id = tracer.file_id"
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
648 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
649 tracers = {files[path]: tracer for (path, tracer) in cur}
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
650 cur.close()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
651
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
652 with self._connect() as conn:
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
653 conn.con.isolation_level = "IMMEDIATE"
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
654
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
655 # Get all tracers in the DB. Files not in the tracers are assumed
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
656 # to have an empty string tracer. Since Sqlite does not support
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
657 # full outer joins, we have to make two queries to fill the
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
658 # dictionary.
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
659 this_tracers = {path: "" for path, in conn.execute("select path from file")}
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
660 this_tracers.update({
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
661 aliases.map(path): tracer
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
662 for path, tracer in conn.execute(
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
663 "select file.path, tracer from tracer " +
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
664 "inner join file on file.id = tracer.file_id"
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
665 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
666 })
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
667
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
668 # Create all file and context rows in the DB.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
669 conn.executemany(
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
670 "insert or ignore into file (path) values (?)",
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
671 ((file,) for file in files.values())
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
672 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
673 file_ids = {
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
674 path: id
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
675 for id, path in conn.execute("select id, path from file")
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
676 }
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
677 conn.executemany(
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
678 "insert or ignore into context (context) values (?)",
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
679 ((context,) for context in contexts)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
680 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
681 context_ids = {
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
682 context: id
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
683 for id, context in conn.execute("select id, context from context")
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
684 }
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
685
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
686 # Prepare tracers and fail, if a conflict is found.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
687 # tracer_paths is used to ensure consistency over the tracer data
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
688 # and tracer_map tracks the tracers to be inserted.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
689 tracer_map = {}
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
690 for path in files.values():
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
691 this_tracer = this_tracers.get(path)
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
692 other_tracer = tracers.get(path, "")
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
693 # If there is no tracer, there is always the None tracer.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
694 if this_tracer is not None and this_tracer != other_tracer:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
695 raise CoverageException(
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
696 "Conflicting file tracer name for '{}': {!r} vs {!r}".format(
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
697 path, this_tracer, other_tracer
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
698 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
699 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
700 tracer_map[path] = other_tracer
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
701
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
702 # Prepare arc and line rows to be inserted by converting the file
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
703 # and context strings with integer ids. Then use the efficient
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
704 # `executemany()` to insert all rows at once.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
705 arc_rows = (
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
706 (file_ids[file], context_ids[context], fromno, tono)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
707 for file, context, fromno, tono in arcs
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
708 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
709
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
710 # Get line data.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
711 cur = conn.execute(
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
712 "select file.path, context.context, line_bits.numbits " +
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
713 "from line_bits " +
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
714 "inner join file on file.id = line_bits.file_id " +
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
715 "inner join context on context.id = line_bits.context_id"
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
716 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
717 for path, context, numbits in cur:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
718 key = (aliases.map(path), context)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
719 if key in lines:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
720 numbits = numbits_union(lines[key], numbits)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
721 lines[key] = numbits
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
722 cur.close()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
723
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
724 if arcs:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
725 self._choose_lines_or_arcs(arcs=True)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
726
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
727 # Write the combined data.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
728 conn.executemany(
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
729 "insert or ignore into arc " +
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
730 "(file_id, context_id, fromno, tono) values (?, ?, ?, ?)",
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
731 arc_rows
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
732 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
733
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
734 if lines:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
735 self._choose_lines_or_arcs(lines=True)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
736 conn.execute("delete from line_bits")
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
737 conn.executemany(
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
738 "insert into line_bits " +
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
739 "(file_id, context_id, numbits) values (?, ?, ?)",
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
740 [
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
741 (file_ids[file], context_ids[context], numbits)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
742 for (file, context), numbits in lines.items()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
743 ]
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
744 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
745 conn.executemany(
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
746 "insert or ignore into tracer (file_id, tracer) values (?, ?)",
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
747 ((file_ids[filename], tracer) for filename, tracer in tracer_map.items())
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
748 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
749
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
750 # Update all internal cache data.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
751 self._reset()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
752 self.read()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
753
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
754 def erase(self, parallel=False):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
755 """Erase the data in this object.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
756
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
757 If `parallel` is true, then also deletes data files created from the
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
758 basename by parallel-mode.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
759
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
760 """
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
761 self._reset()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
762 if self._no_disk:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
763 return
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
764 if self._debug.should("dataio"):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
765 self._debug.write(f"Erasing data file {self._filename!r}")
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
766 file_be_gone(self._filename)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
767 if parallel:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
768 data_dir, local = os.path.split(self._filename)
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
769 localdot = local + ".*"
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
770 pattern = os.path.join(os.path.abspath(data_dir), localdot)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
771 for filename in glob.glob(pattern):
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
772 if self._debug.should("dataio"):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
773 self._debug.write(f"Erasing parallel data file {filename!r}")
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
774 file_be_gone(filename)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
775
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
776 def read(self):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
777 """Start using an existing data file."""
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
778 with self._connect(): # TODO: doesn't look right
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
779 self._have_used = True
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
780
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
781 def write(self):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
782 """Ensure the data is written to the data file."""
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
783 pass
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
784
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
785 def _start_using(self):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
786 """Call this before using the database at all."""
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
787 if self._pid != os.getpid():
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
788 # Looks like we forked! Have to start a new data file.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
789 self._reset()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
790 self._choose_filename()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
791 self._pid = os.getpid()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
792 if not self._have_used:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
793 self.erase()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
794 self._have_used = True
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
795
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
796 def has_arcs(self):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
797 """Does the database have arcs (True) or lines (False)."""
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
798 return bool(self._has_arcs)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
799
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
800 def measured_files(self):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
801 """A set of all files that had been measured."""
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
802 return set(self._file_map)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
803
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
804 def measured_contexts(self):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
805 """A set of all contexts that have been measured.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
806
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
807 .. versionadded:: 5.0
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
808
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
809 """
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
810 self._start_using()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
811 with self._connect() as con:
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
812 contexts = {row[0] for row in con.execute("select distinct(context) from context")}
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
813 return contexts
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
814
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
815 def file_tracer(self, filename):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
816 """Get the plugin name of the file tracer for a file.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
817
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
818 Returns the name of the plugin that handles this file. If the file was
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
819 measured, but didn't use a plugin, then "" is returned. If the file
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
820 was not measured, then None is returned.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
821
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
822 """
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
823 self._start_using()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
824 with self._connect() as con:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
825 file_id = self._file_id(filename)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
826 if file_id is None:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
827 return None
7702
f8b97639deb5 Third Party packages: updated coverage.py to 5.3.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7427
diff changeset
828 row = con.execute_one("select tracer from tracer where file_id = ?", (file_id,))
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
829 if row is not None:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
830 return row[0] or ""
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
831 return "" # File was measured, but no tracer associated.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
832
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
833 def set_query_context(self, context):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
834 """Set a context for subsequent querying.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
835
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
836 The next :meth:`lines`, :meth:`arcs`, or :meth:`contexts_by_lineno`
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
837 calls will be limited to only one context. `context` is a string which
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
838 must match a context exactly. If it does not, no exception is raised,
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
839 but queries will return no data.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
840
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
841 .. versionadded:: 5.0
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
842
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
843 """
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
844 self._start_using()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
845 with self._connect() as con:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
846 cur = con.execute("select id from context where context = ?", (context,))
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
847 self._query_context_ids = [row[0] for row in cur.fetchall()]
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
848
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
849 def set_query_contexts(self, contexts):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
850 """Set a number of contexts for subsequent querying.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
851
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
852 The next :meth:`lines`, :meth:`arcs`, or :meth:`contexts_by_lineno`
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
853 calls will be limited to the specified contexts. `contexts` is a list
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
854 of Python regular expressions. Contexts will be matched using
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
855 :func:`re.search <python:re.search>`. Data will be included in query
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
856 results if they are part of any of the contexts matched.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
857
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
858 .. versionadded:: 5.0
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
859
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
860 """
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
861 self._start_using()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
862 if contexts:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
863 with self._connect() as con:
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
864 context_clause = " or ".join(["context regexp ?"] * len(contexts))
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
865 cur = con.execute("select id from context where " + context_clause, contexts)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
866 self._query_context_ids = [row[0] for row in cur.fetchall()]
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
867 else:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
868 self._query_context_ids = None
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
869
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
870 def lines(self, filename):
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
871 """Get the list of lines executed for a source file.
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
872
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
873 If the file was not measured, returns None. A file might be measured,
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
874 and have no lines executed, in which case an empty list is returned.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
875
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
876 If the file was executed, returns a list of integers, the line numbers
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
877 executed in the file. The list is in no particular order.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
878
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
879 """
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
880 self._start_using()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
881 if self.has_arcs():
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
882 arcs = self.arcs(filename)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
883 if arcs is not None:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
884 all_lines = itertools.chain.from_iterable(arcs)
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
885 return list({l for l in all_lines if l > 0})
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
886
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
887 with self._connect() as con:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
888 file_id = self._file_id(filename)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
889 if file_id is None:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
890 return None
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
891 else:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
892 query = "select numbits from line_bits where file_id = ?"
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
893 data = [file_id]
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
894 if self._query_context_ids is not None:
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
895 ids_array = ", ".join("?" * len(self._query_context_ids))
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
896 query += " and context_id in (" + ids_array + ")"
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
897 data += self._query_context_ids
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
898 bitmaps = list(con.execute(query, data))
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
899 nums = set()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
900 for row in bitmaps:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
901 nums.update(numbits_to_nums(row[0]))
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
902 return list(nums)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
903
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
904 def arcs(self, filename):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
905 """Get the list of arcs executed for a file.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
906
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
907 If the file was not measured, returns None. A file might be measured,
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
908 and have no arcs executed, in which case an empty list is returned.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
909
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
910 If the file was executed, returns a list of 2-tuples of integers. Each
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
911 pair is a starting line number and an ending line number for a
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
912 transition from one line to another. The list is in no particular
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
913 order.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
914
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
915 Negative numbers have special meaning. If the starting line number is
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
916 -N, it represents an entry to the code object that starts at line N.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
917 If the ending ling number is -N, it's an exit from the code object that
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
918 starts at line N.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
919
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
920 """
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
921 self._start_using()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
922 with self._connect() as con:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
923 file_id = self._file_id(filename)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
924 if file_id is None:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
925 return None
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
926 else:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
927 query = "select distinct fromno, tono from arc where file_id = ?"
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
928 data = [file_id]
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
929 if self._query_context_ids is not None:
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
930 ids_array = ", ".join("?" * len(self._query_context_ids))
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
931 query += " and context_id in (" + ids_array + ")"
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
932 data += self._query_context_ids
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
933 arcs = con.execute(query, data)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
934 return list(arcs)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
935
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
936 def contexts_by_lineno(self, filename):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
937 """Get the contexts for each line in a file.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
938
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
939 Returns:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
940 A dict mapping line numbers to a list of context names.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
941
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
942 .. versionadded:: 5.0
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
943
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
944 """
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
945 self._start_using()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
946 with self._connect() as con:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
947 file_id = self._file_id(filename)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
948 if file_id is None:
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
949 return {}
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
950
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
951 lineno_contexts_map = collections.defaultdict(set)
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
952 if self.has_arcs():
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
953 query = (
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
954 "select arc.fromno, arc.tono, context.context " +
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
955 "from arc, context " +
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
956 "where arc.file_id = ? and arc.context_id = context.id"
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
957 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
958 data = [file_id]
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
959 if self._query_context_ids is not None:
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
960 ids_array = ", ".join("?" * len(self._query_context_ids))
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
961 query += " and arc.context_id in (" + ids_array + ")"
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
962 data += self._query_context_ids
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
963 for fromno, tono, context in con.execute(query, data):
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
964 if fromno > 0:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
965 lineno_contexts_map[fromno].add(context)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
966 if tono > 0:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
967 lineno_contexts_map[tono].add(context)
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
968 else:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
969 query = (
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
970 "select l.numbits, c.context from line_bits l, context c " +
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
971 "where l.context_id = c.id " +
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
972 "and file_id = ?"
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
973 )
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
974 data = [file_id]
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
975 if self._query_context_ids is not None:
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
976 ids_array = ", ".join("?" * len(self._query_context_ids))
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
977 query += " and l.context_id in (" + ids_array + ")"
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
978 data += self._query_context_ids
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
979 for numbits, context in con.execute(query, data):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
980 for lineno in numbits_to_nums(numbits):
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
981 lineno_contexts_map[lineno].add(context)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
982
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
983 return {lineno: list(contexts) for lineno, contexts in lineno_contexts_map.items()}
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
984
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
985 @classmethod
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
986 def sys_info(cls):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
987 """Our information for `Coverage.sys_info`.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
988
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
989 Returns a list of (key, value) pairs.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
990
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
991 """
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
992 with SqliteDb(":memory:", debug=NoDebugging()) as db:
7702
f8b97639deb5 Third Party packages: updated coverage.py to 5.3.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7427
diff changeset
993 temp_store = [row[0] for row in db.execute("pragma temp_store")]
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
994 copts = [row[0] for row in db.execute("pragma compile_options")]
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
995 # Yes, this is overkill. I don't like the long list of options
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
996 # at the end of "debug sys", but I don't want to omit information.
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
997 copts = ["; ".join(copts[i:i + 3]) for i in range(0, len(copts), 3)]
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
998
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
999 return [
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1000 ("sqlite3_version", sqlite3.version),
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1001 ("sqlite3_sqlite_version", sqlite3.sqlite_version),
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1002 ("sqlite3_temp_store", temp_store),
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1003 ("sqlite3_compile_options", copts),
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1004 ]
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1005
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1006
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1007 class SqliteDb(SimpleReprMixin):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1008 """A simple abstraction over a SQLite database.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1009
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1010 Use as a context manager, then you can use it like a
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1011 :class:`python:sqlite3.Connection` object::
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1012
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1013 with SqliteDb(filename, debug_control) as db:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1014 db.execute("insert into schema (version) values (?)", (SCHEMA_VERSION,))
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1015
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1016 """
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1017 def __init__(self, filename, debug):
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1018 self.debug = debug if debug.should("sql") else None
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1019 self.filename = filename
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1020 self.nest = 0
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1021 self.con = None
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1022
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1023 def _connect(self):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1024 """Connect to the db and do universal initialization."""
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1025 if self.con is not None:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1026 return
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1027
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1028 # It can happen that Python switches threads while the tracer writes
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1029 # data. The second thread will also try to write to the data,
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1030 # effectively causing a nested context. However, given the idempotent
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1031 # nature of the tracer operations, sharing a connection among threads
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1032 # is not a problem.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1033 if self.debug:
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1034 self.debug.write(f"Connecting to {self.filename!r}")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1035 try:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1036 self.con = sqlite3.connect(self.filename, check_same_thread=False)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1037 except sqlite3.Error as exc:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1038 raise CoverageException(f"Couldn't use data file {self.filename!r}: {exc}") from exc
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1039
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1040 self.con.create_function("REGEXP", 2, _regexp)
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1041
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1042 # This pragma makes writing faster. It disables rollbacks, but we never need them.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1043 # PyPy needs the .close() calls here, or sqlite gets twisted up:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1044 # https://bitbucket.org/pypy/pypy/issues/2872/default-isolation-mode-is-different-on
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1045 self.execute("pragma journal_mode=off").close()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1046 # This pragma makes writing faster.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1047 self.execute("pragma synchronous=off").close()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1048
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1049 def close(self):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1050 """If needed, close the connection."""
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1051 if self.con is not None and self.filename != ":memory:":
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1052 self.con.close()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1053 self.con = None
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1054
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1055 def __enter__(self):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1056 if self.nest == 0:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1057 self._connect()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1058 self.con.__enter__()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1059 self.nest += 1
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1060 return self
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1061
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1062 def __exit__(self, exc_type, exc_value, traceback):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1063 self.nest -= 1
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1064 if self.nest == 0:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1065 try:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1066 self.con.__exit__(exc_type, exc_value, traceback)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1067 self.close()
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1068 except Exception as exc:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1069 if self.debug:
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1070 self.debug.write(f"EXCEPTION from __exit__: {exc}")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1071 raise CoverageException(f"Couldn't end data file {self.filename!r}: {exc}") from exc
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1072
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1073 def execute(self, sql, parameters=()):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1074 """Same as :meth:`python:sqlite3.Connection.execute`."""
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1075 if self.debug:
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1076 tail = f" with {parameters!r}" if parameters else ""
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1077 self.debug.write(f"Executing {sql!r}{tail}")
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1078 try:
7975
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
1079 try:
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
1080 return self.con.execute(sql, parameters)
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
1081 except Exception:
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
1082 # In some cases, an error might happen that isn't really an
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
1083 # error. Try again immediately.
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
1084 # https://github.com/nedbat/coveragepy/issues/1010
7d493839a8fc Third Party Packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7702
diff changeset
1085 return self.con.execute(sql, parameters)
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1086 except sqlite3.Error as exc:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1087 msg = str(exc)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1088 try:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1089 # `execute` is the first thing we do with the database, so try
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1090 # hard to provide useful hints if something goes wrong now.
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1091 with open(self.filename, "rb") as bad_file:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1092 cov4_sig = b"!coverage.py: This is a private format"
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1093 if bad_file.read(len(cov4_sig)) == cov4_sig:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1094 msg = (
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1095 "Looks like a coverage 4.x data file. " +
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1096 "Are you mixing versions of coverage?"
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1097 )
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1098 except Exception: # pragma: cant happen
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1099 pass
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1100 if self.debug:
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1101 self.debug.write(f"EXCEPTION from execute: {msg}")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1102 raise CoverageException(f"Couldn't use data file {self.filename!r}: {msg}") from exc
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1103
7702
f8b97639deb5 Third Party packages: updated coverage.py to 5.3.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7427
diff changeset
1104 def execute_one(self, sql, parameters=()):
f8b97639deb5 Third Party packages: updated coverage.py to 5.3.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7427
diff changeset
1105 """Execute a statement and return the one row that results.
f8b97639deb5 Third Party packages: updated coverage.py to 5.3.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7427
diff changeset
1106
f8b97639deb5 Third Party packages: updated coverage.py to 5.3.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7427
diff changeset
1107 This is like execute(sql, parameters).fetchone(), except it is
f8b97639deb5 Third Party packages: updated coverage.py to 5.3.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7427
diff changeset
1108 correct in reading the entire result set. This will raise an
f8b97639deb5 Third Party packages: updated coverage.py to 5.3.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7427
diff changeset
1109 exception if more than one row results.
f8b97639deb5 Third Party packages: updated coverage.py to 5.3.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7427
diff changeset
1110
f8b97639deb5 Third Party packages: updated coverage.py to 5.3.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7427
diff changeset
1111 Returns a row, or None if there were no rows.
f8b97639deb5 Third Party packages: updated coverage.py to 5.3.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7427
diff changeset
1112 """
f8b97639deb5 Third Party packages: updated coverage.py to 5.3.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7427
diff changeset
1113 rows = list(self.execute(sql, parameters))
f8b97639deb5 Third Party packages: updated coverage.py to 5.3.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7427
diff changeset
1114 if len(rows) == 0:
f8b97639deb5 Third Party packages: updated coverage.py to 5.3.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7427
diff changeset
1115 return None
f8b97639deb5 Third Party packages: updated coverage.py to 5.3.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7427
diff changeset
1116 elif len(rows) == 1:
f8b97639deb5 Third Party packages: updated coverage.py to 5.3.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7427
diff changeset
1117 return rows[0]
f8b97639deb5 Third Party packages: updated coverage.py to 5.3.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7427
diff changeset
1118 else:
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1119 raise AssertionError(f"SQL {sql!r} shouldn't return {len(rows)} rows")
7702
f8b97639deb5 Third Party packages: updated coverage.py to 5.3.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7427
diff changeset
1120
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1121 def executemany(self, sql, data):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1122 """Same as :meth:`python:sqlite3.Connection.executemany`."""
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1123 if self.debug:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1124 data = list(data)
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1125 self.debug.write(f"Executing many {sql!r} with {len(data)} rows")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1126 try:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1127 return self.con.executemany(sql, data)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1128 except Exception: # pragma: cant happen
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1129 # In some cases, an error might happen that isn't really an
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1130 # error. Try again immediately.
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1131 # https://github.com/nedbat/coveragepy/issues/1010
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1132 return self.con.executemany(sql, data)
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1133
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1134 def executescript(self, script):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1135 """Same as :meth:`python:sqlite3.Connection.executescript`."""
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1136 if self.debug:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1137 self.debug.write("Executing script with {} chars: {}".format(
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1138 len(script), clipped_repr(script, 100),
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1139 ))
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1140 self.con.executescript(script)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1141
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1142 def dump(self):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1143 """Return a multi-line string, the SQL dump of the database."""
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1144 return "\n".join(self.con.iterdump())
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1145
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1146
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1147 def _regexp(text, pattern):
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1148 """A regexp function for SQLite."""
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1149 return re.search(text, pattern) is not None

eric ide

mercurial