DebugClients/Python/coverage/files.py

changeset 5051
3586ebd9fac8
parent 4490
3f58261e7bb1
--- a/DebugClients/Python/coverage/files.py	Sat Jul 23 13:33:54 2016 +0200
+++ b/DebugClients/Python/coverage/files.py	Sun Jul 24 12:01:01 2016 +0200
@@ -13,11 +13,10 @@
 
 from coverage import env
 from coverage.backward import unicode_class
-from coverage.misc import CoverageException, join_regex
+from coverage.misc import contract, CoverageException, join_regex, isolate_module
 
 
-RELATIVE_DIR = None
-CANONICAL_FILENAME_CACHE = {}
+os = isolate_module(os)
 
 
 def set_relative_directory():
@@ -31,10 +30,13 @@
     # avoid duplicating work.
     CANONICAL_FILENAME_CACHE = {}
 
+
 def relative_directory():
     """Return the directory that `relative_filename` is relative to."""
     return RELATIVE_DIR
 
+
+@contract(returns='unicode')
 def relative_filename(filename):
     """Return the relative form of `filename`.
 
@@ -45,8 +47,10 @@
     fnorm = os.path.normcase(filename)
     if fnorm.startswith(RELATIVE_DIR):
         filename = filename[len(RELATIVE_DIR):]
-    return filename
+    return unicode_filename(filename)
 
+
+@contract(returns='unicode')
 def canonical_filename(filename):
     """Return a canonical file name for `filename`.
 
@@ -58,7 +62,7 @@
             for path in [os.curdir] + sys.path:
                 if path is None:
                     continue
-                f = path + os.sep + filename
+                f = os.path.join(path, filename)
                 if os.path.exists(f):
                     filename = f
                     break
@@ -114,7 +118,7 @@
                 if os.path.normcase(f) == normtail:
                     tail = f
                     break
-            actpath = head.strip(os.sep) + os.sep + tail
+            actpath = os.path.join(head, tail)
         _ACTUAL_PATH_CACHE[path] = actpath
         return actpath
 
@@ -124,14 +128,36 @@
         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(filename):
     """Return the absolute normalized form of `filename`."""
     path = os.path.expandvars(os.path.expanduser(filename))
     path = os.path.abspath(os.path.realpath(path))
     path = actual_path(path)
+    path = unicode_filename(path)
     return path
 
 
+RELATIVE_DIR = None
+CANONICAL_FILENAME_CACHE = None
+set_relative_directory()
+
+
 def isabs_anywhere(filename):
     """Is `filename` an absolute path on any OS?"""
     return ntpath.isabs(filename) or posixpath.isabs(filename)
@@ -349,7 +375,7 @@
             # files: Must end with .py or .pyw, and must not have certain funny
             # characters that probably mean they are editor junk.
             if re.match(r"^[^.#~!$@%^&*()+=,]+\.pyw?$", filename):
-                yield dirpath + os.sep + filename
+                yield os.path.join(dirpath, filename)
 
 #
 # eflag: FileType = Python2

eric ide

mercurial