eric7/DebugClients/Python/coverage/sqldata.py

branch
eric7
changeset 8929
fcca2fa618bf
parent 8775
0802ae193343
child 8991
2fc945191992
diff -r d856023fbeb0 -r fcca2fa618bf eric7/DebugClients/Python/coverage/sqldata.py
--- a/eric7/DebugClients/Python/coverage/sqldata.py	Sun Jan 16 20:28:42 2022 +0100
+++ b/eric7/DebugClients/Python/coverage/sqldata.py	Sat Jan 22 14:44:56 2022 +0100
@@ -12,16 +12,18 @@
 import glob
 import itertools
 import os
+import random
 import re
+import socket
 import sqlite3
 import sys
 import threading
 import zlib
 
 from coverage.debug import NoDebugging, SimpleReprMixin, clipped_repr
-from coverage.exceptions import CoverageException
+from coverage.exceptions import CoverageException, DataError
 from coverage.files import PathAliases
-from coverage.misc import contract, file_be_gone, filename_suffix, isolate_module
+from coverage.misc import contract, file_be_gone, isolate_module
 from coverage.numbits import numbits_to_nums, numbits_union, nums_to_numbits
 from coverage.version import __version__
 
@@ -191,7 +193,7 @@
 
         Arguments:
             basename (str): the base name of the data file, defaulting to
-                ".coverage".
+                ".coverage". This can be a path to a file in another directory.
             suffix (str or bool): has the same meaning as the `data_suffix`
                 argument to :class:`coverage.Coverage`.
             no_disk (bool): if True, keep all data in memory, and don't
@@ -287,14 +289,14 @@
             try:
                 schema_version, = db.execute_one("select version from coverage_schema")
             except Exception as exc:
-                raise CoverageException(
+                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 CoverageException(
+                    raise DataError(
                         "Couldn't use data file {!r}: wrong schema: {} instead of {}".format(
                             self._filename, schema_version, SCHEMA_VERSION
                         )
@@ -316,7 +318,7 @@
                 self._create_db()
         return self._dbs[threading.get_ident()]
 
-    def __nonzero__(self):
+    def __bool__(self):
         if (threading.get_ident() not in self._dbs and not os.path.exists(self._filename)):
             return False
         try:
@@ -326,8 +328,6 @@
         except CoverageException:
             return False
 
-    __bool__ = __nonzero__
-
     @contract(returns="bytes")
     def dumps(self):
         """Serialize the current data to a byte string.
@@ -370,9 +370,9 @@
         if self._debug.should("dataio"):
             self._debug.write(f"Loading data into data file {self._filename!r}")
         if data[:1] != b"z":
-            raise CoverageException(
+            raise DataError(
                 f"Unrecognized serialization: {data[:40]!r} (head of {len(data)} bytes)"
-                )
+            )
         script = zlib.decompress(data[1:]).decode("utf-8")
         self._dbs[threading.get_ident()] = db = SqliteDb(self._filename, self._debug)
         with db:
@@ -513,9 +513,9 @@
         assert lines or arcs
         assert not (lines and arcs)
         if lines and self._has_arcs:
-            raise CoverageException("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:
-            raise CoverageException("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
@@ -541,14 +541,14 @@
             for filename, plugin_name in file_tracers.items():
                 file_id = self._file_id(filename)
                 if file_id is None:
-                    raise CoverageException(
+                    raise DataError(
                         f"Can't add file tracer data for unmeasured file '{filename}'"
                     )
 
                 existing_plugin = self.file_tracer(filename)
                 if existing_plugin:
                     if existing_plugin != plugin_name:
-                        raise CoverageException(
+                        raise DataError(
                             "Conflicting file tracer name for '{}': {!r} vs {!r}".format(
                                 filename, existing_plugin, plugin_name,
                             )
@@ -578,7 +578,7 @@
         self._start_using()
         with self._connect(): # Use this to get one transaction.
             if not self._has_arcs and not self._has_lines:
-                raise CoverageException("Can't touch files in an empty CoverageData")
+                raise DataError("Can't touch files in an empty CoverageData")
 
             for filename in filenames:
                 self._file_id(filename, add=True)
@@ -597,9 +597,9 @@
                 getattr(other_data, "_filename", "???"),
             ))
         if self._has_lines and other_data._has_arcs:
-            raise CoverageException("Can't combine arc data with line data")
+            raise DataError("Can't combine arc data with line data")
         if self._has_arcs and other_data._has_lines:
-            raise CoverageException("Can't combine line data with arc data")
+            raise DataError("Can't combine line data with arc data")
 
         aliases = aliases or PathAliases()
 
@@ -692,7 +692,7 @@
                 other_tracer = tracers.get(path, "")
                 # If there is no tracer, there is always the None tracer.
                 if this_tracer is not None and this_tracer != other_tracer:
-                    raise CoverageException(
+                    raise DataError(
                         "Conflicting file tracer name for '{}': {!r} vs {!r}".format(
                             path, this_tracer, other_tracer
                         )
@@ -1004,6 +1004,26 @@
         ]
 
 
+def filename_suffix(suffix):
+    """Compute a filename suffix for a data file.
+
+    If `suffix` is a string or None, simply return it. If `suffix` is True,
+    then build a suffix incorporating the hostname, process id, and a random
+    number.
+
+    Returns a string or None.
+
+    """
+    if suffix is True:
+        # If data_suffix was a simple true value, then make a suffix with
+        # plenty of distinguishing information.  We do this here in
+        # `save()` at the last minute so that the pid will be correct even
+        # if the process forks.
+        dice = random.Random(os.urandom(8)).randint(0, 999999)
+        suffix = "%s.%s.%06d" % (socket.gethostname(), os.getpid(), dice)
+    return suffix
+
+
 class SqliteDb(SimpleReprMixin):
     """A simple abstraction over a SQLite database.
 
@@ -1035,7 +1055,7 @@
         try:
             self.con = sqlite3.connect(self.filename, check_same_thread=False)
         except sqlite3.Error as exc:
-            raise CoverageException(f"Couldn't use data file {self.filename!r}: {exc}") from exc
+            raise DataError(f"Couldn't use data file {self.filename!r}: {exc}") from exc
 
         self.con.create_function("REGEXP", 2, _regexp)
 
@@ -1068,7 +1088,7 @@
             except Exception as exc:
                 if self.debug:
                     self.debug.write(f"EXCEPTION from __exit__: {exc}")
-                raise CoverageException(f"Couldn't end data file {self.filename!r}: {exc}") from exc
+                raise DataError(f"Couldn't end data file {self.filename!r}: {exc}") from exc
 
     def execute(self, sql, parameters=()):
         """Same as :meth:`python:sqlite3.Connection.execute`."""
@@ -1099,7 +1119,7 @@
                 pass
             if self.debug:
                 self.debug.write(f"EXCEPTION from execute: {msg}")
-            raise CoverageException(f"Couldn't use data file {self.filename!r}: {msg}") from exc
+            raise DataError(f"Couldn't use data file {self.filename!r}: {msg}") from exc
 
     def execute_one(self, sql, parameters=()):
         """Execute a statement and return the one row that results.

eric ide

mercurial