diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2009-03-11 09:56:03 -0400 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2009-03-11 09:56:03 -0400 |
commit | 76adb3a5b0124b48bac56ad2fa9ed2eab7e67f75 (patch) | |
tree | 72f0e432136b45cbe575bb3b50ad1f0d1fe0b656 /coverage/files.py | |
parent | 151df1aa707218ae6a5e8d7d781aad408577dc76 (diff) | |
download | python-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.py | 65 |
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 |