summaryrefslogtreecommitdiff
path: root/coverage/files.py
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2009-03-11 09:56:03 -0400
committerNed Batchelder <ned@nedbatchelder.com>2009-03-11 09:56:03 -0400
commit76adb3a5b0124b48bac56ad2fa9ed2eab7e67f75 (patch)
tree72f0e432136b45cbe575bb3b50ad1f0d1fe0b656 /coverage/files.py
parent151df1aa707218ae6a5e8d7d781aad408577dc76 (diff)
downloadpython-coveragepy-git-76adb3a5b0124b48bac56ad2fa9ed2eab7e67f75.tar.gz
Split out the filename operations; Morf -> CodeUnit.
--HG-- rename : coverage/morf.py => coverage/codeunit.py
Diffstat (limited to 'coverage/files.py')
-rw-r--r--coverage/files.py65
1 files changed, 65 insertions, 0 deletions
diff --git a/coverage/files.py b/coverage/files.py
new file mode 100644
index 00000000..625357c3
--- /dev/null
+++ b/coverage/files.py
@@ -0,0 +1,65 @@
+"""File wrangling."""
+
+import os, sys
+
+class FileWrangler:
+ """Understand how filenames work."""
+
+ def __init__(self):
+ self.relative_dir = self.abs_file(os.curdir) + os.sep
+
+ # Cache of results of calling the canonical_filename() method, to
+ # avoid duplicating work.
+ self.canonical_filename_cache = {}
+
+ def abs_file(self, filename):
+ """ Helper function to turn a filename into an absolute normalized
+ filename.
+ """
+ return os.path.normcase(os.path.abspath(os.path.realpath(filename)))
+
+ def relative_filename(self, filename):
+ """ Convert filename to relative filename from self.relative_dir.
+ """
+ return filename.replace(self.relative_dir, "")
+
+ def canonical_filename(self, filename):
+ """Return a canonical filename for `filename`.
+
+ An absolute path with no redundant components and normalized case.
+
+ """
+ if not self.canonical_filename_cache.has_key(filename):
+ f = filename
+ if os.path.isabs(f) and not os.path.exists(f):
+ if not self.get_zip_data(f):
+ f = os.path.basename(f)
+ if not os.path.isabs(f):
+ for path in [os.curdir] + sys.path:
+ g = os.path.join(path, f)
+ if os.path.exists(g):
+ f = g
+ break
+ cf = self.abs_file(f)
+ self.canonical_filename_cache[filename] = cf
+ return self.canonical_filename_cache[filename]
+
+ def get_zip_data(self, filename):
+ """ Get data from `filename` if it is a zip file path, or return None
+ if it is not.
+ """
+ import zipimport
+ markers = ['.zip'+os.sep, '.egg'+os.sep]
+ for marker in markers:
+ if marker in filename:
+ parts = filename.split(marker)
+ try:
+ zi = zipimport.zipimporter(parts[0]+marker[:-1])
+ except zipimport.ZipImportError:
+ continue
+ try:
+ data = zi.get_data(parts[1])
+ except IOError:
+ continue
+ return data
+ return None