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

Side by Side Diff: third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem_mock.py

Issue 2497153002: Clean up pylint warnings in filesystem_mock.py. (Closed)
Patch Set: Use lambda Created 4 years, 1 month 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (C) 2009 Google Inc. All rights reserved. 1 # Copyright (C) 2009 Google Inc. All rights reserved.
2 # 2 #
3 # Redistribution and use in source and binary forms, with or without 3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are 4 # modification, are permitted provided that the following conditions are
5 # met: 5 # met:
6 # 6 #
7 # * Redistributions of source code must retain the above copyright 7 # * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer. 8 # notice, this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above 9 # * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following disclaimer 10 # copyright notice, this list of conditions and the following disclaimer
(...skipping 14 matching lines...) Expand all
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 28
29 import StringIO 29 import StringIO
30 import errno 30 import errno
31 import hashlib 31 import hashlib
32 import os 32 import os
33 import re 33 import re
34 34
35 from webkitpy.common.system import path
36
37 35
38 class MockFileSystem(object): 36 class MockFileSystem(object):
39 sep = '/' 37 sep = '/'
40 pardir = '..' 38 pardir = '..'
41 39
42 def __init__(self, files=None, dirs=None, cwd='/'): 40 def __init__(self, files=None, dirs=None, cwd='/'):
43 """Initializes a "mock" filesystem that can be used to completely 41 """Initializes a "mock" filesystem that can be used to replace the
44 stub out a filesystem. 42 FileSystem class in tests.
45 43
46 Args: 44 Args:
47 files: a dict of filenames -> file contents. A file contents 45 files: A dictionary of filenames to file contents. A file contents
48 value of None is used to indicate that the file should 46 value of None indicates that the file does not exist.
49 not exist.
50 """ 47 """
51 self.files = files or {} 48 self.files = files or {}
52 self.executable_files = set() 49 self.executable_files = set()
53 self.written_files = {} 50 self.written_files = {}
54 self.last_tmpdir = None 51 self.last_tmpdir = None
55 self.current_tmpno = 0 52 self.current_tmpno = 0
56 self.cwd = cwd 53 self.cwd = cwd
57 self.dirs = set(dirs or []) 54 self.dirs = set(dirs or [])
58 self.dirs.add(cwd) 55 self.dirs.add(cwd)
59 for f in self.files: 56 for file_path in self.files:
60 d = self.dirname(f) 57 directory = self.dirname(file_path)
61 while not d in self.dirs: 58 while directory not in self.dirs:
62 self.dirs.add(d) 59 self.dirs.add(directory)
63 d = self.dirname(d) 60 directory = self.dirname(directory)
64 61
65 def clear_written_files(self): 62 def clear_written_files(self):
66 # This function can be used to track what is written between steps in a test. 63 # This function can be used to track what is written between steps in a test.
67 self.written_files = {} 64 self.written_files = {}
68 65
69 def _raise_not_found(self, path): 66 def _raise_not_found(self, path):
70 raise IOError(errno.ENOENT, path, os.strerror(errno.ENOENT)) 67 raise IOError(errno.ENOENT, path, os.strerror(errno.ENOENT))
71 68
72 def _split(self, path): 69 def _split(self, path):
73 # This is not quite a full implementation of os.path.split 70 # This is not quite a full implementation of os.path.split; see:
74 # http://docs.python.org/library/os.path.html#os.path.split 71 # http://docs.python.org/library/os.path.html#os.path.split
75 if self.sep in path: 72 if self.sep in path:
76 return path.rsplit(self.sep, 1) 73 return path.rsplit(self.sep, 1)
77 return ('', path) 74 return ('', path)
78 75
79 def make_executable(self, file_path): 76 def make_executable(self, file_path):
80 self.executable_files.add(file_path) 77 self.executable_files.add(file_path)
81 78
82 def abspath(self, path): 79 def abspath(self, path):
83 if os.path.isabs(path): 80 if os.path.isabs(path):
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 117
121 self.files[destination] = self.files[source] 118 self.files[destination] = self.files[source]
122 self.written_files[destination] = self.files[source] 119 self.written_files[destination] = self.files[source]
123 120
124 def dirname(self, path): 121 def dirname(self, path):
125 return self._split(path)[0] 122 return self._split(path)[0]
126 123
127 def exists(self, path): 124 def exists(self, path):
128 return self.isfile(path) or self.isdir(path) 125 return self.isfile(path) or self.isdir(path)
129 126
130 def files_under(self, path, dirs_to_skip=[], file_filter=None): 127 def files_under(self, path, dirs_to_skip=None, file_filter=None):
131 def filter_all(fs, dirpath, basename): 128 dirs_to_skip = dirs_to_skip or []
132 return True 129
130 filter_all = lambda fs, dirpath, basename: True
133 131
134 file_filter = file_filter or filter_all 132 file_filter = file_filter or filter_all
135 files = [] 133 files = []
136 if self.isfile(path): 134 if self.isfile(path):
137 if file_filter(self, self.dirname(path), self.basename(path)) and se lf.files[path] is not None: 135 if file_filter(self, self.dirname(path), self.basename(path)) and se lf.files[path] is not None:
138 files.append(path) 136 files.append(path)
139 return files 137 return files
140 138
141 if self.basename(path) in dirs_to_skip: 139 if self.basename(path) in dirs_to_skip:
142 return [] 140 return []
(...skipping 19 matching lines...) Expand all
162 def getcwd(self): 160 def getcwd(self):
163 return self.cwd 161 return self.cwd
164 162
165 def glob(self, glob_string): 163 def glob(self, glob_string):
166 # FIXME: This handles '*', but not '?', '[', or ']'. 164 # FIXME: This handles '*', but not '?', '[', or ']'.
167 glob_string = re.escape(glob_string) 165 glob_string = re.escape(glob_string)
168 glob_string = glob_string.replace('\\*', '[^\\/]*') + '$' 166 glob_string = glob_string.replace('\\*', '[^\\/]*') + '$'
169 glob_string = glob_string.replace('\\/', '/') 167 glob_string = glob_string.replace('\\/', '/')
170 path_filter = lambda path: re.match(glob_string, path) 168 path_filter = lambda path: re.match(glob_string, path)
171 169
172 # We could use fnmatch.fnmatch, but that might not do the right thing on windows. 170 # We could use fnmatch.fnmatch, but that might not do the right thing on Windows.
173 existing_files = [path for path, contents in self.files.items() if conte nts is not None] 171 existing_files = [path for path, contents in self.files.items() if conte nts is not None]
174 return filter(path_filter, existing_files) + filter(path_filter, self.di rs) 172 return filter(path_filter, existing_files) + filter(path_filter, self.di rs)
175 173
176 def isabs(self, path): 174 def isabs(self, path):
177 return path.startswith(self.sep) 175 return path.startswith(self.sep)
178 176
179 def isfile(self, path): 177 def isfile(self, path):
180 return path in self.files and self.files[path] is not None 178 return path in self.files and self.files[path] is not None
181 179
182 def isdir(self, path): 180 def isdir(self, path):
183 return self.normpath(path) in self.dirs 181 return self.normpath(path) in self.dirs
184 182
185 def _slow_but_correct_join(self, *comps): 183 def _slow_but_correct_join(self, *comps):
186 return re.sub(re.escape(os.path.sep), self.sep, os.path.join(*comps)) 184 return re.sub(re.escape(os.path.sep), self.sep, os.path.join(*comps))
187 185
188 def join(self, *comps): 186 def join(self, *comps):
189 # This function is called a lot, so we optimize it; there are 187 # This function is called a lot, so we optimize it; there are
190 # unittests to check that we match _slow_but_correct_join(), above. 188 # unit tests to check that we match _slow_but_correct_join(), above.
191 path = '' 189 path = ''
192 sep = self.sep 190 sep = self.sep
193 for comp in comps: 191 for comp in comps:
194 if not comp: 192 if not comp:
195 continue 193 continue
196 if comp[0] == sep: 194 if comp[0] == sep:
197 path = comp 195 path = comp
198 continue 196 continue
199 if path: 197 if path:
200 path += sep 198 path += sep
201 path += comp 199 path += comp
202 if comps[-1] == '' and path: 200 if comps[-1] == '' and path:
203 path += '/' 201 path += '/'
204 path = path.replace(sep + sep, sep) 202 path = path.replace(sep + sep, sep)
205 return path 203 return path
206 204
207 def listdir(self, path): 205 def listdir(self, path):
208 _, dirs, files = list(self.walk(path))[0] 206 _, directories, files = list(self.walk(path))[0]
209 return dirs + files 207 return directories + files
210 208
211 def walk(self, top): 209 def walk(self, top):
212 sep = self.sep 210 sep = self.sep
213 if not self.isdir(top): 211 if not self.isdir(top):
214 raise OSError("%s is not a directory" % top) 212 raise OSError("%s is not a directory" % top)
215 213
216 if not top.endswith(sep): 214 if not top.endswith(sep):
217 top += sep 215 top += sep
218 216
219 dirs = [] 217 directories = []
220 files = [] 218 files = []
221 for f in self.files: 219 for file_path in self.files:
222 if self.exists(f) and f.startswith(top): 220 if self.exists(file_path) and file_path.startswith(top):
223 remaining = f[len(top):] 221 remaining = file_path[len(top):]
224 if sep in remaining: 222 if sep in remaining:
225 dir = remaining[:remaining.index(sep)] 223 directory = remaining[:remaining.index(sep)]
226 if not dir in dirs: 224 if directory not in directories:
227 dirs.append(dir) 225 directories.append(directory)
228 else: 226 else:
229 files.append(remaining) 227 files.append(remaining)
230 file_system_tuples = [(top[:-1], dirs, files)] 228 file_system_tuples = [(top[:-1], directories, files)]
231 for dir in dirs: 229 for directory in directories:
232 dir = top + dir 230 directory = top + directory
233 tuples_from_subdirs = self.walk(dir) 231 tuples_from_subdirs = self.walk(directory)
234 file_system_tuples += tuples_from_subdirs 232 file_system_tuples += tuples_from_subdirs
235 return file_system_tuples 233 return file_system_tuples
236 234
237 def mtime(self, path): 235 def mtime(self, path):
238 if self.exists(path): 236 if self.exists(path):
239 return 0 237 return 0
240 self._raise_not_found(path) 238 self._raise_not_found(path)
241 239
242 def _mktemp(self, suffix='', prefix='tmp', dir=None, **kwargs): 240 def _mktemp(self, suffix='', prefix='tmp', dir=None, **_): # pylint: disabl e=redefined-builtin
243 if dir is None: 241 if dir is None:
244 dir = self.sep + '__im_tmp' 242 dir = self.sep + '__im_tmp'
245 curno = self.current_tmpno 243 curno = self.current_tmpno
246 self.current_tmpno += 1 244 self.current_tmpno += 1
247 self.last_tmpdir = self.join(dir, '%s_%u_%s' % (prefix, curno, suffix)) 245 self.last_tmpdir = self.join(dir, '%s_%u_%s' % (prefix, curno, suffix))
248 return self.last_tmpdir 246 return self.last_tmpdir
249 247
250 def mkdtemp(self, **kwargs): 248 def mkdtemp(self, **kwargs):
251 class TemporaryDirectory(object): 249 class TemporaryDirectory(object):
252 250
253 def __init__(self, fs, **kwargs): 251 def __init__(self, fs, **kwargs):
254 self._kwargs = kwargs 252 self._kwargs = kwargs
255 self._filesystem = fs 253 self._filesystem = fs
256 self._directory_path = fs._mktemp(**kwargs) 254 self._directory_path = fs._mktemp(**kwargs) # pylint: disable=p rotected-access
257 fs.maybe_make_directory(self._directory_path) 255 fs.maybe_make_directory(self._directory_path)
258 256
259 def __str__(self): 257 def __str__(self):
260 return self._directory_path 258 return self._directory_path
261 259
262 def __enter__(self): 260 def __enter__(self):
263 return self._directory_path 261 return self._directory_path
264 262
265 def __exit__(self, type, value, traceback): 263 def __exit__(self, exception_type, exception_value, traceback):
266 # Only self-delete if necessary. 264 # Only self-delete if necessary.
267 265
268 # FIXME: Should we delete non-empty directories? 266 # FIXME: Should we delete non-empty directories?
269 if self._filesystem.exists(self._directory_path): 267 if self._filesystem.exists(self._directory_path):
270 self._filesystem.rmtree(self._directory_path) 268 self._filesystem.rmtree(self._directory_path)
271 269
272 return TemporaryDirectory(fs=self, **kwargs) 270 return TemporaryDirectory(fs=self, **kwargs)
273 271
274 def maybe_make_directory(self, *path): 272 def maybe_make_directory(self, *path):
275 norm_path = self.normpath(self.join(*path)) 273 norm_path = self.normpath(self.join(*path))
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 rel_path = path[len(common_root) + 1:] 381 rel_path = path[len(common_root) + 1:]
384 382
385 return dot_dot + rel_path 383 return dot_dot + rel_path
386 384
387 def remove(self, path): 385 def remove(self, path):
388 if self.files[path] is None: 386 if self.files[path] is None:
389 self._raise_not_found(path) 387 self._raise_not_found(path)
390 self.files[path] = None 388 self.files[path] = None
391 self.written_files[path] = None 389 self.written_files[path] = None
392 390
393 def rmtree(self, path): 391 def rmtree(self, path_to_remove):
394 path = self.normpath(path) 392 path_to_remove = self.normpath(path_to_remove)
395 393
396 for f in self.files: 394 for file_path in self.files:
397 # We need to add a trailing separator to path to avoid matching 395 # We need to add a trailing separator to path_to_remove to avoid mat ching
398 # cases like path='/foo/b' and f='/foo/bar/baz'. 396 # cases like path_to_remove='/foo/b' and file_path='/foo/bar/baz'.
399 if f == path or f.startswith(path + self.sep): 397 if file_path == path_to_remove or file_path.startswith(path_to_remov e + self.sep):
400 self.files[f] = None 398 self.files[file_path] = None
401 399
402 self.dirs = set(filter(lambda d: not (d == path or d.startswith(path + s elf.sep)), self.dirs)) 400 def should_remove(directory):
401 return directory == path_to_remove or directory.startswith(path_to_r emove + self.sep)
402
403 self.dirs = {d for d in self.dirs if not should_remove(d)}
403 404
404 def copytree(self, source, destination): 405 def copytree(self, source, destination):
405 source = self.normpath(source) 406 source = self.normpath(source)
406 destination = self.normpath(destination) 407 destination = self.normpath(destination)
407 408
408 for source_file in list(self.files): 409 for source_file in list(self.files):
409 if source_file.startswith(source): 410 if source_file.startswith(source):
410 destination_path = self.join(destination, self.relpath(source_fi le, source)) 411 destination_path = self.join(destination, self.relpath(source_fi le, source))
411 self.maybe_make_directory(self.dirname(destination_path)) 412 self.maybe_make_directory(self.dirname(destination_path))
412 self.files[destination_path] = self.files[source_file] 413 self.files[destination_path] = self.files[source_file]
(...skipping 15 matching lines...) Expand all
428 429
429 def __init__(self, fs, path): 430 def __init__(self, fs, path):
430 self.fs = fs 431 self.fs = fs
431 self.path = path 432 self.path = path
432 self.closed = False 433 self.closed = False
433 self.fs.files[path] = "" 434 self.fs.files[path] = ""
434 435
435 def __enter__(self): 436 def __enter__(self):
436 return self 437 return self
437 438
438 def __exit__(self, type, value, traceback): 439 def __exit__(self, exception_type, exception_value, traceback):
439 self.close() 440 self.close()
440 441
441 def close(self): 442 def close(self):
442 self.closed = True 443 self.closed = True
443 444
444 def write(self, str): 445 def write(self, string):
445 self.fs.files[self.path] += str 446 self.fs.files[self.path] += string
446 self.fs.written_files[self.path] = self.fs.files[self.path] 447 self.fs.written_files[self.path] = self.fs.files[self.path]
447 448
448 449
449 class WritableTextFileObject(WritableBinaryFileObject): 450 class WritableTextFileObject(WritableBinaryFileObject):
450 451
451 def write(self, str): 452 def write(self, string):
452 WritableBinaryFileObject.write(self, str.encode('utf-8')) 453 WritableBinaryFileObject.write(self, string.encode('utf-8'))
453 454
454 455
455 class ReadableBinaryFileObject(object): 456 class ReadableBinaryFileObject(object):
456 457
457 def __init__(self, fs, path, data): 458 def __init__(self, fs, path, data):
458 self.fs = fs 459 self.fs = fs
459 self.path = path 460 self.path = path
460 self.closed = False 461 self.closed = False
461 self.data = data 462 self.data = data
462 self.offset = 0 463 self.offset = 0
463 464
464 def __enter__(self): 465 def __enter__(self):
465 return self 466 return self
466 467
467 def __exit__(self, type, value, traceback): 468 def __exit__(self, exception_type, exception_value, traceback):
468 self.close() 469 self.close()
469 470
470 def close(self): 471 def close(self):
471 self.closed = True 472 self.closed = True
472 473
473 def read(self, bytes=None): 474 def read(self, num_bytes=None):
474 if not bytes: 475 if not num_bytes:
475 return self.data[self.offset:] 476 return self.data[self.offset:]
476 start = self.offset 477 start = self.offset
477 self.offset += bytes 478 self.offset += num_bytes
478 return self.data[start:self.offset] 479 return self.data[start:self.offset]
479 480
480 481
481 class ReadableTextFileObject(ReadableBinaryFileObject): 482 class ReadableTextFileObject(ReadableBinaryFileObject):
482 483
483 def __init__(self, fs, path, data): 484 def __init__(self, fs, path, data):
484 super(ReadableTextFileObject, self).__init__(fs, path, StringIO.StringIO (data.decode("utf-8"))) 485 super(ReadableTextFileObject, self).__init__(fs, path, StringIO.StringIO (data.decode("utf-8")))
485 486
486 def close(self): 487 def close(self):
487 self.data.close() 488 self.data.close()
488 super(ReadableTextFileObject, self).close() 489 super(ReadableTextFileObject, self).close()
489 490
490 def read(self, bytes=-1): 491 def read(self, num_bytes=-1):
491 return self.data.read(bytes) 492 return self.data.read(num_bytes)
492 493
493 def readline(self, length=None): 494 def readline(self, length=None):
494 return self.data.readline(length) 495 return self.data.readline(length)
495 496
496 def __iter__(self): 497 def __iter__(self):
497 return self.data.__iter__() 498 return self.data.__iter__()
498 499
499 def next(self): 500 def next(self):
500 return self.data.next() 501 return self.data.next()
501 502
502 def seek(self, offset, whence=os.SEEK_SET): 503 def seek(self, offset, whence=os.SEEK_SET):
503 self.data.seek(offset, whence) 504 self.data.seek(offset, whence)
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698