eric7/DebugClients/Python/coverage/files.py

branch
eric7
changeset 8775
0802ae193343
parent 8527
2bd1325d727e
child 8929
fcca2fa618bf
--- a/eric7/DebugClients/Python/coverage/files.py	Fri Nov 19 19:28:47 2021 +0100
+++ b/eric7/DebugClients/Python/coverage/files.py	Sat Nov 20 16:47:38 2021 +0100
@@ -13,8 +13,8 @@
 import sys
 
 from coverage import env
-from coverage.backward import unicode_class
-from coverage.misc import contract, CoverageException, join_regex, isolate_module
+from coverage.exceptions import CoverageException
+from coverage.misc import contract, human_sorted, isolate_module, join_regex
 
 
 os = isolate_module(os)
@@ -48,7 +48,7 @@
     fnorm = os.path.normcase(filename)
     if fnorm.startswith(RELATIVE_DIR):
         filename = filename[len(RELATIVE_DIR):]
-    return unicode_filename(filename)
+    return filename
 
 
 @contract(returns='unicode')
@@ -77,7 +77,7 @@
     return CANONICAL_FILENAME_CACHE[filename]
 
 
-MAX_FLAT = 200
+MAX_FLAT = 100
 
 @contract(filename='unicode', returns='unicode')
 def flat_rootname(filename):
@@ -87,15 +87,16 @@
     the same directory, but need to differentiate same-named files from
     different directories.
 
-    For example, the file a/b/c.py will return 'a_b_c_py'
+    For example, the file a/b/c.py will return 'd_86bbcbe134d28fd2_c_py'
 
     """
-    name = ntpath.splitdrive(filename)[1]
-    name = re.sub(r"[\\/.:]", "_", name)
-    if len(name) > MAX_FLAT:
-        h = hashlib.sha1(name.encode('UTF-8')).hexdigest()
-        name = name[-(MAX_FLAT-len(h)-1):] + '_' + h
-    return name
+    dirname, basename = ntpath.split(filename)
+    if dirname:
+        fp = hashlib.new("sha3_256", dirname.encode("UTF-8")).hexdigest()[:16]
+        prefix = f"d_{fp}_"
+    else:
+        prefix = ""
+    return prefix + basename.replace(".", "_")
 
 
 if env.WINDOWS:
@@ -105,8 +106,6 @@
 
     def actual_path(path):
         """Get the actual path of `path`, including the correct case."""
-        if env.PY2 and isinstance(path, unicode_class):
-            path = path.encode(sys.getfilesystemencoding())
         if path in _ACTUAL_PATH_CACHE:
             return _ACTUAL_PATH_CACHE[path]
 
@@ -143,21 +142,6 @@
         return filename
 
 
-if env.PY2:
-    @contract(returns='unicode')
-    def unicode_filename(filename):
-        """Return a Unicode version of `filename`."""
-        if isinstance(filename, str):
-            encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
-            filename = filename.decode(encoding, "replace")
-        return filename
-else:
-    @contract(filename='unicode', returns='unicode')
-    def unicode_filename(filename):
-        """Return a Unicode version of `filename`."""
-        return filename
-
-
 @contract(returns='unicode')
 def abs_file(path):
     """Return the absolute normalized form of `path`."""
@@ -167,7 +151,6 @@
         pass
     path = os.path.abspath(path)
     path = actual_path(path)
-    path = unicode_filename(path)
     return path
 
 
@@ -207,7 +190,7 @@
     return prepped
 
 
-class TreeMatcher(object):
+class TreeMatcher:
     """A matcher for files in a tree.
 
     Construct with a list of paths, either files or directories. Paths match
@@ -215,18 +198,21 @@
     somewhere in a subtree rooted at one of the directories.
 
     """
-    def __init__(self, paths):
-        self.paths = list(paths)
+    def __init__(self, paths, name="unknown"):
+        self.original_paths = human_sorted(paths)
+        self.paths = list(map(os.path.normcase, paths))
+        self.name = name
 
     def __repr__(self):
-        return "<TreeMatcher %r>" % self.paths
+        return f"<TreeMatcher {self.name} {self.original_paths!r}>"
 
     def info(self):
         """A list of strings for displaying when dumping state."""
-        return self.paths
+        return self.original_paths
 
     def match(self, fpath):
         """Does `fpath` indicate a file in one of our trees?"""
+        fpath = os.path.normcase(fpath)
         for p in self.paths:
             if fpath.startswith(p):
                 if fpath == p:
@@ -238,13 +224,14 @@
         return False
 
 
-class ModuleMatcher(object):
+class ModuleMatcher:
     """A matcher for modules in a tree."""
-    def __init__(self, module_names):
+    def __init__(self, module_names, name="unknown"):
         self.modules = list(module_names)
+        self.name = name
 
     def __repr__(self):
-        return "<ModuleMatcher %r>" % (self.modules)
+        return f"<ModuleMatcher {self.name} {self.modules!r}>"
 
     def info(self):
         """A list of strings for displaying when dumping state."""
@@ -266,14 +253,15 @@
         return False
 
 
-class FnmatchMatcher(object):
+class FnmatchMatcher:
     """A matcher for files by file name pattern."""
-    def __init__(self, pats):
+    def __init__(self, pats, name="unknown"):
         self.pats = list(pats)
         self.re = fnmatches_to_regex(self.pats, case_insensitive=env.WINDOWS)
+        self.name = name
 
     def __repr__(self):
-        return "<FnmatchMatcher %r>" % self.pats
+        return f"<FnmatchMatcher {self.name} {self.pats!r}>"
 
     def info(self):
         """A list of strings for displaying when dumping state."""
@@ -327,7 +315,7 @@
     return compiled
 
 
-class PathAliases(object):
+class PathAliases:
     """A collection of aliases for paths.
 
     When combining data files from remote machines, often the paths to source
@@ -338,13 +326,15 @@
     map a path through those aliases to produce a unified path.
 
     """
-    def __init__(self):
+    def __init__(self, relative=False):
         self.aliases = []
+        self.relative = relative
 
     def pprint(self):       # pragma: debugging
         """Dump the important parts of the PathAliases, for debugging."""
+        print(f"Aliases (relative={self.relative}):")
         for regex, result in self.aliases:
-            print("{!r} --> {!r}".format(regex.pattern, result))
+            print(f"{regex.pattern!r} --> {result!r}")
 
     def add(self, pattern, result):
         """Add the `pattern`/`result` pair to the list of aliases.
@@ -405,7 +395,8 @@
             if m:
                 new = path.replace(m.group(0), result)
                 new = new.replace(sep(path), sep(result))
-                new = canonical_filename(new)
+                if not self.relative:
+                    new = canonical_filename(new)
                 return new
         return path
 

eric ide

mercurial