eric7/DebugClients/Python/coverage/sqldata.py

branch
eric7
changeset 8991
2fc945191992
parent 8929
fcca2fa618bf
child 9099
0e511e0e94a3
--- a/eric7/DebugClients/Python/coverage/sqldata.py	Sun Mar 20 17:26:35 2022 +0100
+++ b/eric7/DebugClients/Python/coverage/sqldata.py	Sun Mar 20 17:49:44 2022 +0100
@@ -215,7 +215,7 @@
         self._dbs = {}
         self._pid = os.getpid()
         # Synchronize the operations used during collection.
-        self._lock = threading.Lock()
+        self._lock = threading.RLock()
 
         # Are we in sync with the data file?
         self._have_used = False
@@ -231,7 +231,11 @@
         """A decorator for methods that should hold self._lock."""
         @functools.wraps(method)
         def _wrapped(self, *args, **kwargs):
+            if self._debug.should("lock"):
+                self._debug.write(f"Locking {self._lock!r} for {method.__name__}")
             with self._lock:
+                if self._debug.should("lock"):
+                    self._debug.write(f"Locked  {self._lock!r} for {method.__name__}")
                 # pylint: disable=not-callable
                 return method(self, *args, **kwargs)
         return _wrapped
@@ -256,26 +260,6 @@
         self._have_used = False
         self._current_context_id = None
 
-    def _create_db(self):
-        """Create a db file that doesn't exist yet.
-
-        Initializes the schema and certain metadata.
-        """
-        if self._debug.should("dataio"):
-            self._debug.write(f"Creating data file {self._filename!r}")
-        self._dbs[threading.get_ident()] = db = SqliteDb(self._filename, self._debug)
-        with db:
-            db.executescript(SCHEMA)
-            db.execute("insert into coverage_schema (version) values (?)", (SCHEMA_VERSION,))
-            db.executemany(
-                "insert into meta (key, value) values (?, ?)",
-                [
-                    ("sys_argv", str(getattr(sys, "argv", None))),
-                    ("version", __version__),
-                    ("when", datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")),
-                ]
-            )
-
     def _open_db(self):
         """Open an existing db file, and read its metadata."""
         if self._debug.should("dataio"):
@@ -289,11 +273,14 @@
             try:
                 schema_version, = db.execute_one("select version from coverage_schema")
             except Exception as exc:
-                raise DataError(
-                    "Data file {!r} doesn't seem to be a coverage data file: {}".format(
-                        self._filename, exc
-                    )
-                ) from exc
+                if "no such table: coverage_schema" in str(exc):
+                    self._init_db(db)
+                else:
+                    raise DataError(
+                        "Data file {!r} doesn't seem to be a coverage data file: {}".format(
+                            self._filename, exc
+                        )
+                    ) from exc
             else:
                 if schema_version != SCHEMA_VERSION:
                     raise DataError(
@@ -309,13 +296,25 @@
             for path, file_id in db.execute("select path, id from file"):
                 self._file_map[path] = file_id
 
+    def _init_db(self, db):
+        """Write the initial contents of the database."""
+        if self._debug.should("dataio"):
+            self._debug.write(f"Initing data file {self._filename!r}")
+        db.executescript(SCHEMA)
+        db.execute("insert into coverage_schema (version) values (?)", (SCHEMA_VERSION,))
+        db.executemany(
+            "insert or ignore into meta (key, value) values (?, ?)",
+            [
+                ("sys_argv", str(getattr(sys, "argv", None))),
+                ("version", __version__),
+                ("when", datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")),
+            ]
+        )
+
     def _connect(self):
         """Get the SqliteDb object to use."""
         if threading.get_ident() not in self._dbs:
-            if os.path.exists(self._filename):
-                self._open_db()
-            else:
-                self._create_db()
+            self._open_db()
         return self._dbs[threading.get_ident()]
 
     def __bool__(self):
@@ -349,7 +348,8 @@
         if self._debug.should("dataio"):
             self._debug.write(f"Dumping data from data file {self._filename!r}")
         with self._connect() as con:
-            return b"z" + zlib.compress(con.dump().encode("utf-8"))
+            script = con.dump()
+            return b"z" + zlib.compress(script.encode("utf-8"))
 
     @contract(data="bytes")
     def loads(self, data):
@@ -501,6 +501,9 @@
             self._set_context_id()
             for filename, arcs in arc_data.items():
                 file_id = self._file_id(filename, add=True)
+                from coverage import env
+                if env.PYVERSION == (3, 11, 0, "alpha", 4, 0):
+                    arcs = [(a, b) for a, b in arcs if a is not None and b is not None]
                 data = [(file_id, self._current_context_id, fromno, tono) for fromno, tono in arcs]
                 con.executemany(
                     "insert or ignore into arc " +
@@ -513,15 +516,19 @@
         assert lines or arcs
         assert not (lines and arcs)
         if lines and self._has_arcs:
+            if self._debug.should("dataop"):
+                self._debug.write("Error: Can't add line measurements to existing branch data")
             raise DataError("Can't add line measurements to existing branch data")
         if arcs and self._has_lines:
+            if self._debug.should("dataop"):
+                self._debug.write("Error: Can't add branch measurements to existing line data")
             raise DataError("Can't add branch measurements to existing line data")
         if not self._has_arcs and not self._has_lines:
             self._has_lines = lines
             self._has_arcs = arcs
             with self._connect() as con:
                 con.execute(
-                    "insert into meta (key, value) values (?, ?)",
+                    "insert or ignore into meta (key, value) values (?, ?)",
                     ("has_arcs", str(int(arcs)))
                 )
 

eric ide

mercurial