DebugClients/Python/coverage/files.py

changeset 0
de9c2efb9d02
child 31
744cd0b4b8cd
equal deleted inserted replaced
-1:000000000000 0:de9c2efb9d02
1 """File wrangling."""
2
3 import os, sys
4
5 class FileLocator:
6 """Understand how filenames work."""
7
8 def __init__(self):
9 self.relative_dir = self.abs_file(os.curdir) + os.sep
10
11 # Cache of results of calling the canonical_filename() method, to
12 # avoid duplicating work.
13 self.canonical_filename_cache = {}
14
15 def abs_file(self, filename):
16 """Return the absolute normalized form of `filename`."""
17 return os.path.normcase(os.path.abspath(os.path.realpath(filename)))
18
19 def relative_filename(self, filename):
20 """Return the relative form of `filename`.
21
22 The filename will be relative to the current directory when the
23 FileLocator was constructed.
24
25 """
26 return filename.replace(self.relative_dir, "")
27
28 def canonical_filename(self, filename):
29 """Return a canonical filename for `filename`.
30
31 An absolute path with no redundant components and normalized case.
32
33 """
34 if not self.canonical_filename_cache.has_key(filename):
35 f = filename
36 if os.path.isabs(f) and not os.path.exists(f):
37 if not self.get_zip_data(f):
38 f = os.path.basename(f)
39 if not os.path.isabs(f):
40 for path in [os.curdir] + sys.path:
41 g = os.path.join(path, f)
42 if os.path.exists(g):
43 f = g
44 break
45 cf = self.abs_file(f)
46 self.canonical_filename_cache[filename] = cf
47 return self.canonical_filename_cache[filename]
48
49 def get_zip_data(self, filename):
50 """Get data from `filename` if it is a zip file path.
51
52 Returns the data read from the zip file, or None if no zip file could
53 be found or `filename` isn't in it.
54
55 """
56 import zipimport
57 markers = ['.zip'+os.sep, '.egg'+os.sep]
58 for marker in markers:
59 if marker in filename:
60 parts = filename.split(marker)
61 try:
62 zi = zipimport.zipimporter(parts[0]+marker[:-1])
63 except zipimport.ZipImportError:
64 continue
65 try:
66 data = zi.get_data(parts[1])
67 except IOError:
68 continue
69 return data
70 return None

eric ide

mercurial