Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(216)

Side by Side Diff: third_party/coverage-3.7.1/coverage/files.py

Issue 225633007: Upgrade to coverage 3.7.1 and have it auto-build itself on first use. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: sigh our imports are a mess Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 """File wrangling.""" 1 """File wrangling."""
2 2
3 from coverage.backward import to_string 3 from coverage.backward import to_string
4 from coverage.misc import CoverageException 4 from coverage.misc import CoverageException
5 import fnmatch, os, os.path, re, sys 5 import fnmatch, os, os.path, re, sys
6 import ntpath, posixpath
6 7
7 class FileLocator(object): 8 class FileLocator(object):
8 """Understand how filenames work.""" 9 """Understand how filenames work."""
9 10
10 def __init__(self): 11 def __init__(self):
11 # The absolute path to our current directory. 12 # The absolute path to our current directory.
12 self.relative_dir = os.path.normcase(abs_file(os.curdir) + os.sep) 13 self.relative_dir = os.path.normcase(abs_file(os.curdir) + os.sep)
13 14
14 # Cache of results of calling the canonical_filename() method, to 15 # Cache of results of calling the canonical_filename() method, to
15 # avoid duplicating work. 16 # avoid duplicating work.
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 return actpath 104 return actpath
104 105
105 actual_path.cache = {} 106 actual_path.cache = {}
106 actual_path.list_cache = {} 107 actual_path.list_cache = {}
107 108
108 else: 109 else:
109 def actual_path(filename): 110 def actual_path(filename):
110 """The actual path for non-Windows platforms.""" 111 """The actual path for non-Windows platforms."""
111 return filename 112 return filename
112 113
114
113 def abs_file(filename): 115 def abs_file(filename):
114 """Return the absolute normalized form of `filename`.""" 116 """Return the absolute normalized form of `filename`."""
115 path = os.path.abspath(os.path.realpath(filename)) 117 path = os.path.expandvars(os.path.expanduser(filename))
118 path = os.path.abspath(os.path.realpath(path))
116 path = actual_path(path) 119 path = actual_path(path)
117 return path 120 return path
118 121
119 122
123 def isabs_anywhere(filename):
124 """Is `filename` an absolute path on any OS?"""
125 return ntpath.isabs(filename) or posixpath.isabs(filename)
126
127
120 def prep_patterns(patterns): 128 def prep_patterns(patterns):
121 """Prepare the file patterns for use in a `FnmatchMatcher`. 129 """Prepare the file patterns for use in a `FnmatchMatcher`.
122 130
123 If a pattern starts with a wildcard, it is used as a pattern 131 If a pattern starts with a wildcard, it is used as a pattern
124 as-is. If it does not start with a wildcard, then it is made 132 as-is. If it does not start with a wildcard, then it is made
125 absolute with the current directory. 133 absolute with the current directory.
126 134
127 If `patterns` is None, an empty list is returned. 135 If `patterns` is None, an empty list is returned.
128 136
129 """ 137 """
130 patterns = patterns or []
131 prepped = [] 138 prepped = []
132 for p in patterns or []: 139 for p in patterns or []:
133 if p.startswith("*") or p.startswith("?"): 140 if p.startswith("*") or p.startswith("?"):
134 prepped.append(p) 141 prepped.append(p)
135 else: 142 else:
136 prepped.append(abs_file(p)) 143 prepped.append(abs_file(p))
137 return prepped 144 return prepped
138 145
139 146
140 class TreeMatcher(object): 147 class TreeMatcher(object):
141 """A matcher for files in a tree.""" 148 """A matcher for files in a tree."""
142 def __init__(self, directories): 149 def __init__(self, directories):
143 self.dirs = directories[:] 150 self.dirs = directories[:]
144 151
145 def __repr__(self): 152 def __repr__(self):
146 return "<TreeMatcher %r>" % self.dirs 153 return "<TreeMatcher %r>" % self.dirs
147 154
155 def info(self):
156 """A list of strings for displaying when dumping state."""
157 return self.dirs
158
148 def add(self, directory): 159 def add(self, directory):
149 """Add another directory to the list we match for.""" 160 """Add another directory to the list we match for."""
150 self.dirs.append(directory) 161 self.dirs.append(directory)
151 162
152 def match(self, fpath): 163 def match(self, fpath):
153 """Does `fpath` indicate a file in one of our trees?""" 164 """Does `fpath` indicate a file in one of our trees?"""
154 for d in self.dirs: 165 for d in self.dirs:
155 if fpath.startswith(d): 166 if fpath.startswith(d):
156 if fpath == d: 167 if fpath == d:
157 # This is the same file! 168 # This is the same file!
158 return True 169 return True
159 if fpath[len(d)] == os.sep: 170 if fpath[len(d)] == os.sep:
160 # This is a file in the directory 171 # This is a file in the directory
161 return True 172 return True
162 return False 173 return False
163 174
164 175
165 class FnmatchMatcher(object): 176 class FnmatchMatcher(object):
166 """A matcher for files by filename pattern.""" 177 """A matcher for files by filename pattern."""
167 def __init__(self, pats): 178 def __init__(self, pats):
168 self.pats = pats[:] 179 self.pats = pats[:]
169 180
170 def __repr__(self): 181 def __repr__(self):
171 return "<FnmatchMatcher %r>" % self.pats 182 return "<FnmatchMatcher %r>" % self.pats
172 183
184 def info(self):
185 """A list of strings for displaying when dumping state."""
186 return self.pats
187
173 def match(self, fpath): 188 def match(self, fpath):
174 """Does `fpath` match one of our filename patterns?""" 189 """Does `fpath` match one of our filename patterns?"""
175 for pat in self.pats: 190 for pat in self.pats:
176 if fnmatch.fnmatch(fpath, pat): 191 if fnmatch.fnmatch(fpath, pat):
177 return True 192 return True
178 return False 193 return False
179 194
180 195
181 def sep(s): 196 def sep(s):
182 """Find the path separator used in this string, or os.sep if none.""" 197 """Find the path separator used in this string, or os.sep if none."""
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 231
217 `pattern` can't end with a wildcard component, since that would 232 `pattern` can't end with a wildcard component, since that would
218 match an entire tree, and not just its root. 233 match an entire tree, and not just its root.
219 234
220 """ 235 """
221 # The pattern can't end with a wildcard component. 236 # The pattern can't end with a wildcard component.
222 pattern = pattern.rstrip(r"\/") 237 pattern = pattern.rstrip(r"\/")
223 if pattern.endswith("*"): 238 if pattern.endswith("*"):
224 raise CoverageException("Pattern must not end with wildcards.") 239 raise CoverageException("Pattern must not end with wildcards.")
225 pattern_sep = sep(pattern) 240 pattern_sep = sep(pattern)
241
242 # The pattern is meant to match a filepath. Let's make it absolute
243 # unless it already is, or is meant to match any prefix.
244 if not pattern.startswith('*') and not isabs_anywhere(pattern):
245 pattern = abs_file(pattern)
226 pattern += pattern_sep 246 pattern += pattern_sep
227 247
228 # Make a regex from the pattern. fnmatch always adds a \Z or $ to 248 # Make a regex from the pattern. fnmatch always adds a \Z or $ to
229 # match the whole string, which we don't want. 249 # match the whole string, which we don't want.
230 regex_pat = fnmatch.translate(pattern).replace(r'\Z(', '(') 250 regex_pat = fnmatch.translate(pattern).replace(r'\Z(', '(')
231 if regex_pat.endswith("$"): 251 if regex_pat.endswith("$"):
232 regex_pat = regex_pat[:-1] 252 regex_pat = regex_pat[:-1]
233 # We want */a/b.py to match on Windows to, so change slash to match 253 # We want */a/b.py to match on Windows too, so change slash to match
234 # either separator. 254 # either separator.
235 regex_pat = regex_pat.replace(r"\/", r"[\\/]") 255 regex_pat = regex_pat.replace(r"\/", r"[\\/]")
236 # We want case-insensitive matching, so add that flag. 256 # We want case-insensitive matching, so add that flag.
237 regex = re.compile(r"(?i)" + regex_pat) 257 regex = re.compile(r"(?i)" + regex_pat)
238 258
239 # Normalize the result: it must end with a path separator. 259 # Normalize the result: it must end with a path separator.
240 result_sep = sep(result) 260 result_sep = sep(result)
241 result = result.rstrip(r"\/") + result_sep 261 result = result.rstrip(r"\/") + result_sep
242 self.aliases.append((regex, result, pattern_sep, result_sep)) 262 self.aliases.append((regex, result, pattern_sep, result_sep))
243 263
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 296
277 """ 297 """
278 for i, (dirpath, dirnames, filenames) in enumerate(os.walk(dirname)): 298 for i, (dirpath, dirnames, filenames) in enumerate(os.walk(dirname)):
279 if i > 0 and '__init__.py' not in filenames: 299 if i > 0 and '__init__.py' not in filenames:
280 # If a directory doesn't have __init__.py, then it isn't 300 # If a directory doesn't have __init__.py, then it isn't
281 # importable and neither are its files 301 # importable and neither are its files
282 del dirnames[:] 302 del dirnames[:]
283 continue 303 continue
284 for filename in filenames: 304 for filename in filenames:
285 # We're only interested in files that look like reasonable Python 305 # We're only interested in files that look like reasonable Python
286 # files: Must end with .py, and must not have certain funny 306 # files: Must end with .py or .pyw, and must not have certain funny
287 # characters that probably mean they are editor junk. 307 # characters that probably mean they are editor junk.
288 if re.match(r"^[^.#~!$@%^&*()+=,]+\.py$", filename): 308 if re.match(r"^[^.#~!$@%^&*()+=,]+\.pyw?$", filename):
289 yield os.path.join(dirpath, filename) 309 yield os.path.join(dirpath, filename)
OLDNEW
« no previous file with comments | « third_party/coverage-3.7.1/coverage/execfile.py ('k') | third_party/coverage-3.7.1/coverage/fullcoverage/encodings.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698