DebugClients/Python/coverage/files.py

Sat, 05 Sep 2015 15:13:13 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 05 Sep 2015 15:13:13 +0200
changeset 4435
9f6555d3c3c0
parent 4385
599681bf149a
child 4489
d0d6e4ad31bd
permissions
-rw-r--r--

Fixed some code style issues and removed code no longer needed.

0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1 """File wrangling."""
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
2
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
3 from .backward import to_string
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
4 from .misc import CoverageException
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
5 import fnmatch, os, os.path, re, sys
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
6 import ntpath, posixpath
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
7
31
744cd0b4b8cd Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
8 class FileLocator(object):
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
9 """Understand how filenames work."""
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
10
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
11 def __init__(self):
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
12 # The absolute path to our current directory.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
13 self.relative_dir = os.path.normcase(abs_file(os.curdir) + os.sep)
4385
599681bf149a Source files now executable even with unicodes in path or filename.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3499
diff changeset
14 if isinstance(self.relative_dir, str):
599681bf149a Source files now executable even with unicodes in path or filename.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3499
diff changeset
15 self.relative_dir = self.relative_dir.decode(sys.getfilesystemencoding())
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
16
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
17 # Cache of results of calling the canonical_filename() method, to
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
18 # avoid duplicating work.
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
19 self.canonical_filename_cache = {}
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
20
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
21 def relative_filename(self, filename):
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
22 """Return the relative form of `filename`.
31
744cd0b4b8cd Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
23
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
24 The filename will be relative to the current directory when the
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
25 `FileLocator` was constructed.
31
744cd0b4b8cd Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
26
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
27 """
4385
599681bf149a Source files now executable even with unicodes in path or filename.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3499
diff changeset
28 if isinstance(filename, str):
599681bf149a Source files now executable even with unicodes in path or filename.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3499
diff changeset
29 filename = filename.decode(sys.getfilesystemencoding())
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
30 fnorm = os.path.normcase(filename)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
31 if fnorm.startswith(self.relative_dir):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
32 filename = filename[len(self.relative_dir):]
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
33 return filename
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
34
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
35 def canonical_filename(self, filename):
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
36 """Return a canonical filename for `filename`.
31
744cd0b4b8cd Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
37
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
38 An absolute path with no redundant components and normalized case.
31
744cd0b4b8cd Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
39
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
40 """
31
744cd0b4b8cd Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
41 if filename not in self.canonical_filename_cache:
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
42 if not os.path.isabs(filename):
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
43 for path in [os.curdir] + sys.path:
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
44 if path is None:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
45 continue
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
46 f = os.path.join(path, filename)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
47 if os.path.exists(f):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
48 filename = f
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
49 break
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
50 cf = abs_file(filename)
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
51 self.canonical_filename_cache[filename] = cf
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
52 return self.canonical_filename_cache[filename]
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
53
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
54 def get_zip_data(self, filename):
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
55 """Get data from `filename` if it is a zip file path.
31
744cd0b4b8cd Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
56
744cd0b4b8cd Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
57 Returns the string data read from the zip file, or None if no zip file
744cd0b4b8cd Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
58 could be found or `filename` isn't in it. The data returned will be
744cd0b4b8cd Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
59 an empty string if the file is empty.
744cd0b4b8cd Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
60
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
61 """
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
62 import zipimport
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
63 markers = ['.zip'+os.sep, '.egg'+os.sep]
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
64 for marker in markers:
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
65 if marker in filename:
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
66 parts = filename.split(marker)
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
67 try:
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
68 zi = zipimport.zipimporter(parts[0]+marker[:-1])
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
69 except zipimport.ZipImportError:
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
70 continue
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
71 try:
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
72 data = zi.get_data(parts[1])
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
73 except IOError:
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
74 continue
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
75 return to_string(data)
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
76 return None
790
2c0ea0163ef4 Marked the Python2 debugger client files with the new eflag: marker.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 31
diff changeset
77
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
78
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
79 if sys.platform == 'win32':
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
80
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
81 def actual_path(path):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
82 """Get the actual path of `path`, including the correct case."""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
83 if path in actual_path.cache:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
84 return actual_path.cache[path]
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
85
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
86 head, tail = os.path.split(path)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
87 if not tail:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
88 actpath = head
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
89 elif not head:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
90 actpath = tail
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
91 else:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
92 head = actual_path(head)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
93 if head in actual_path.list_cache:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
94 files = actual_path.list_cache[head]
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
95 else:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
96 try:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
97 files = os.listdir(head)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
98 except OSError:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
99 files = []
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
100 actual_path.list_cache[head] = files
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
101 normtail = os.path.normcase(tail)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
102 for f in files:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
103 if os.path.normcase(f) == normtail:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
104 tail = f
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
105 break
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
106 actpath = os.path.join(head, tail)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
107 actual_path.cache[path] = actpath
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
108 return actpath
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
109
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
110 actual_path.cache = {}
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
111 actual_path.list_cache = {}
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
112
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
113 else:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
114 def actual_path(filename):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
115 """The actual path for non-Windows platforms."""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
116 return filename
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
117
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
118
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
119 def abs_file(filename):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
120 """Return the absolute normalized form of `filename`."""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
121 path = os.path.expandvars(os.path.expanduser(filename))
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
122 path = os.path.abspath(os.path.realpath(path))
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
123 path = actual_path(path)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
124 return path
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
125
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
126
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
127 def isabs_anywhere(filename):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
128 """Is `filename` an absolute path on any OS?"""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
129 return ntpath.isabs(filename) or posixpath.isabs(filename)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
130
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
131
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
132 def prep_patterns(patterns):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
133 """Prepare the file patterns for use in a `FnmatchMatcher`.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
134
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
135 If a pattern starts with a wildcard, it is used as a pattern
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
136 as-is. If it does not start with a wildcard, then it is made
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
137 absolute with the current directory.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
138
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
139 If `patterns` is None, an empty list is returned.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
140
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
141 """
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
142 prepped = []
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
143 for p in patterns or []:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
144 if p.startswith("*") or p.startswith("?"):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
145 prepped.append(p)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
146 else:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
147 prepped.append(abs_file(p))
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
148 return prepped
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
149
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
150
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
151 class TreeMatcher(object):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
152 """A matcher for files in a tree."""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
153 def __init__(self, directories):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
154 self.dirs = directories[:]
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
155
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
156 def __repr__(self):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
157 return "<TreeMatcher %r>" % self.dirs
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
158
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
159 def info(self):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
160 """A list of strings for displaying when dumping state."""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
161 return self.dirs
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
162
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
163 def add(self, directory):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
164 """Add another directory to the list we match for."""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
165 self.dirs.append(directory)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
166
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
167 def match(self, fpath):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
168 """Does `fpath` indicate a file in one of our trees?"""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
169 for d in self.dirs:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
170 if fpath.startswith(d):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
171 if fpath == d:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
172 # This is the same file!
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
173 return True
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
174 if fpath[len(d)] == os.sep:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
175 # This is a file in the directory
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
176 return True
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
177 return False
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
178
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
179
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
180 class FnmatchMatcher(object):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
181 """A matcher for files by filename pattern."""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
182 def __init__(self, pats):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
183 self.pats = pats[:]
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
184
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
185 def __repr__(self):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
186 return "<FnmatchMatcher %r>" % self.pats
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
187
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
188 def info(self):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
189 """A list of strings for displaying when dumping state."""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
190 return self.pats
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
191
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
192 def match(self, fpath):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
193 """Does `fpath` match one of our filename patterns?"""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
194 for pat in self.pats:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
195 if fnmatch.fnmatch(fpath, pat):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
196 return True
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
197 return False
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
198
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
199
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
200 def sep(s):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
201 """Find the path separator used in this string, or os.sep if none."""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
202 sep_match = re.search(r"[\\/]", s)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
203 if sep_match:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
204 the_sep = sep_match.group(0)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
205 else:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
206 the_sep = os.sep
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
207 return the_sep
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
208
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
209
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
210 class PathAliases(object):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
211 """A collection of aliases for paths.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
212
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
213 When combining data files from remote machines, often the paths to source
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
214 code are different, for example, due to OS differences, or because of
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
215 serialized checkouts on continuous integration machines.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
216
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
217 A `PathAliases` object tracks a list of pattern/result pairs, and can
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
218 map a path through those aliases to produce a unified path.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
219
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
220 `locator` is a FileLocator that is used to canonicalize the results.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
221
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
222 """
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
223 def __init__(self, locator=None):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
224 self.aliases = []
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
225 self.locator = locator
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
226
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
227 def add(self, pattern, result):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
228 """Add the `pattern`/`result` pair to the list of aliases.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
229
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
230 `pattern` is an `fnmatch`-style pattern. `result` is a simple
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
231 string. When mapping paths, if a path starts with a match against
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
232 `pattern`, then that match is replaced with `result`. This models
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
233 isomorphic source trees being rooted at different places on two
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
234 different machines.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
235
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
236 `pattern` can't end with a wildcard component, since that would
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
237 match an entire tree, and not just its root.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
238
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
239 """
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
240 # The pattern can't end with a wildcard component.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
241 pattern = pattern.rstrip(r"\/")
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
242 if pattern.endswith("*"):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
243 raise CoverageException("Pattern must not end with wildcards.")
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
244 pattern_sep = sep(pattern)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
245
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
246 # The pattern is meant to match a filepath. Let's make it absolute
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
247 # unless it already is, or is meant to match any prefix.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
248 if not pattern.startswith('*') and not isabs_anywhere(pattern):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
249 pattern = abs_file(pattern)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
250 pattern += pattern_sep
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
251
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
252 # Make a regex from the pattern. fnmatch always adds a \Z or $ to
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
253 # match the whole string, which we don't want.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
254 regex_pat = fnmatch.translate(pattern).replace(r'\Z(', '(')
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
255 if regex_pat.endswith("$"):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
256 regex_pat = regex_pat[:-1]
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
257 # We want */a/b.py to match on Windows too, so change slash to match
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
258 # either separator.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
259 regex_pat = regex_pat.replace(r"\/", r"[\\/]")
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
260 # We want case-insensitive matching, so add that flag.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
261 regex = re.compile(r"(?i)" + regex_pat)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
262
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
263 # Normalize the result: it must end with a path separator.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
264 result_sep = sep(result)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
265 result = result.rstrip(r"\/") + result_sep
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
266 self.aliases.append((regex, result, pattern_sep, result_sep))
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
267
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
268 def map(self, path):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
269 """Map `path` through the aliases.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
270
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
271 `path` is checked against all of the patterns. The first pattern to
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
272 match is used to replace the root of the path with the result root.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
273 Only one pattern is ever used. If no patterns match, `path` is
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
274 returned unchanged.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
275
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
276 The separator style in the result is made to match that of the result
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
277 in the alias.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
278
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
279 """
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
280 for regex, result, pattern_sep, result_sep in self.aliases:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
281 m = regex.match(path)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
282 if m:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
283 new = path.replace(m.group(0), result)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
284 if pattern_sep != result_sep:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
285 new = new.replace(pattern_sep, result_sep)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
286 if self.locator:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
287 new = self.locator.canonical_filename(new)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
288 return new
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
289 return path
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
290
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
291
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
292 def find_python_files(dirname):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
293 """Yield all of the importable Python files in `dirname`, recursively.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
294
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
295 To be importable, the files have to be in a directory with a __init__.py,
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
296 except for `dirname` itself, which isn't required to have one. The
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
297 assumption is that `dirname` was specified directly, so the user knows
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
298 best, but subdirectories are checked for a __init__.py to be sure we only
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
299 find the importable files.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
300
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
301 """
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
302 for i, (dirpath, dirnames, filenames) in enumerate(os.walk(dirname)):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
303 if i > 0 and '__init__.py' not in filenames:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
304 # If a directory doesn't have __init__.py, then it isn't
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
305 # importable and neither are its files
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
306 del dirnames[:]
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
307 continue
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
308 for filename in filenames:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
309 # We're only interested in files that look like reasonable Python
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
310 # files: Must end with .py or .pyw, and must not have certain funny
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
311 # characters that probably mean they are editor junk.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
312 if re.match(r"^[^.#~!$@%^&*()+=,]+\.pyw?$", filename):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 790
diff changeset
313 yield os.path.join(dirpath, filename)
3499
f2d4b02c7e88 Modified the Python2 coverage files to include the Python2 eflags line and fixed an issue in both variants.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 3495
diff changeset
314
f2d4b02c7e88 Modified the Python2 coverage files to include the Python2 eflags line and fixed an issue in both variants.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 3495
diff changeset
315 #
f2d4b02c7e88 Modified the Python2 coverage files to include the Python2 eflags line and fixed an issue in both variants.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 3495
diff changeset
316 # eflag: FileType = Python2

eric ide

mercurial