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

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: 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 []
129
130 def filter_all(fs, dirpath, basename): # pylint: disable=unused-argumen t
132 return True 131 return True
jeffcarp 2016/11/15 19:10:01 Would turning this into a lambda get rid of the li
133 132
134 file_filter = file_filter or filter_all 133 file_filter = file_filter or filter_all
135 files = [] 134 files = []
136 if self.isfile(path): 135 if self.isfile(path):
137 if file_filter(self, self.dirname(path), self.basename(path)) and se lf.files[path] is not None: 136 if file_filter(self, self.dirname(path), self.basename(path)) and se lf.files[path] is not None:
138 files.append(path) 137 files.append(path)
139 return files 138 return files
140 139
141 if self.basename(path) in dirs_to_skip: 140 if self.basename(path) in dirs_to_skip:
142 return [] 141 return []
(...skipping 19 matching lines...) Expand all
162 def getcwd(self): 161 def getcwd(self):
163 return self.cwd 162 return self.cwd
164 163
165 def glob(self, glob_string): 164 def glob(self, glob_string):
166 # FIXME: This handles '*', but not '?', '[', or ']'. 165 # FIXME: This handles '*', but not '?', '[', or ']'.
167 glob_string = re.escape(glob_string) 166 glob_string = re.escape(glob_string)
168 glob_string = glob_string.replace('\\*', '[^\\/]*') + '$' 167 glob_string = glob_string.replace('\\*', '[^\\/]*') + '$'
169 glob_string = glob_string.replace('\\/', '/') 168 glob_string = glob_string.replace('\\/', '/')
170 path_filter = lambda path: re.match(glob_string, path) 169 path_filter = lambda path: re.match(glob_string, path)
171 170
172 # We could use fnmatch.fnmatch, but that might not do the right thing on windows. 171 # 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] 172 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) 173 return filter(path_filter, existing_files) + filter(path_filter, self.di rs)
175 174
176 def isabs(self, path): 175 def isabs(self, path):
177 return path.startswith(self.sep) 176 return path.startswith(self.sep)
178 177
179 def isfile(self, path): 178 def isfile(self, path):
180 return path in self.files and self.files[path] is not None 179 return path in self.files and self.files[path] is not None
181 180
182 def isdir(self, path): 181 def isdir(self, path):
183 return self.normpath(path) in self.dirs 182 return self.normpath(path) in self.dirs
184 183
185 def _slow_but_correct_join(self, *comps): 184 def _slow_but_correct_join(self, *comps):
186 return re.sub(re.escape(os.path.sep), self.sep, os.path.join(*comps)) 185 return re.sub(re.escape(os.path.sep), self.sep, os.path.join(*comps))
187 186
188 def join(self, *comps): 187 def join(self, *comps):
189 # This function is called a lot, so we optimize it; there are 188 # This function is called a lot, so we optimize it; there are
190 # unittests to check that we match _slow_but_correct_join(), above. 189 # unit tests to check that we match _slow_but_correct_join(), above.
191 path = '' 190 path = ''
192 sep = self.sep 191 sep = self.sep
193 for comp in comps: 192 for comp in comps:
194 if not comp: 193 if not comp:
195 continue 194 continue
196 if comp[0] == sep: 195 if comp[0] == sep:
197 path = comp 196 path = comp
198 continue 197 continue
199 if path: 198 if path:
200 path += sep 199 path += sep
201 path += comp 200 path += comp
202 if comps[-1] == '' and path: 201 if comps[-1] == '' and path:
203 path += '/' 202 path += '/'
204 path = path.replace(sep + sep, sep) 203 path = path.replace(sep + sep, sep)
205 return path 204 return path
206 205
207 def listdir(self, path): 206 def listdir(self, path):
208 _, dirs, files = list(self.walk(path))[0] 207 _, directories, files = list(self.walk(path))[0]
209 return dirs + files 208 return directories + files
210 209
211 def walk(self, top): 210 def walk(self, top):
212 sep = self.sep 211 sep = self.sep
213 if not self.isdir(top): 212 if not self.isdir(top):
214 raise OSError("%s is not a directory" % top) 213 raise OSError("%s is not a directory" % top)
215 214
216 if not top.endswith(sep): 215 if not top.endswith(sep):
217 top += sep 216 top += sep
218 217
219 dirs = [] 218 directories = []
220 files = [] 219 files = []
221 for f in self.files: 220 for file_path in self.files:
222 if self.exists(f) and f.startswith(top): 221 if self.exists(file_path) and file_path.startswith(top):
223 remaining = f[len(top):] 222 remaining = file_path[len(top):]
224 if sep in remaining: 223 if sep in remaining:
225 dir = remaining[:remaining.index(sep)] 224 directory = remaining[:remaining.index(sep)]
226 if not dir in dirs: 225 if directory not in directories:
227 dirs.append(dir) 226 directories.append(directory)
228 else: 227 else:
229 files.append(remaining) 228 files.append(remaining)
230 file_system_tuples = [(top[:-1], dirs, files)] 229 file_system_tuples = [(top[:-1], directories, files)]
231 for dir in dirs: 230 for directory in directories:
232 dir = top + dir 231 directory = top + directory
233 tuples_from_subdirs = self.walk(dir) 232 tuples_from_subdirs = self.walk(directory)
234 file_system_tuples += tuples_from_subdirs 233 file_system_tuples += tuples_from_subdirs
235 return file_system_tuples 234 return file_system_tuples
236 235
237 def mtime(self, path): 236 def mtime(self, path):
238 if self.exists(path): 237 if self.exists(path):
239 return 0 238 return 0
240 self._raise_not_found(path) 239 self._raise_not_found(path)
241 240
242 def _mktemp(self, suffix='', prefix='tmp', dir=None, **kwargs): 241 def _mktemp(self, suffix='', prefix='tmp', dir=None, **_): # pylint: disabl e=redefined-builtin
243 if dir is None: 242 if dir is None:
244 dir = self.sep + '__im_tmp' 243 dir = self.sep + '__im_tmp'
245 curno = self.current_tmpno 244 curno = self.current_tmpno
246 self.current_tmpno += 1 245 self.current_tmpno += 1
247 self.last_tmpdir = self.join(dir, '%s_%u_%s' % (prefix, curno, suffix)) 246 self.last_tmpdir = self.join(dir, '%s_%u_%s' % (prefix, curno, suffix))
248 return self.last_tmpdir 247 return self.last_tmpdir
249 248
250 def mkdtemp(self, **kwargs): 249 def mkdtemp(self, **kwargs):
251 class TemporaryDirectory(object): 250 class TemporaryDirectory(object):
252 251
253 def __init__(self, fs, **kwargs): 252 def __init__(self, fs, **kwargs):
254 self._kwargs = kwargs 253 self._kwargs = kwargs
255 self._filesystem = fs 254 self._filesystem = fs
256 self._directory_path = fs._mktemp(**kwargs) 255 self._directory_path = fs._mktemp(**kwargs) # pylint: disable=p rotected-access
257 fs.maybe_make_directory(self._directory_path) 256 fs.maybe_make_directory(self._directory_path)
258 257
259 def __str__(self): 258 def __str__(self):
260 return self._directory_path 259 return self._directory_path
261 260
262 def __enter__(self): 261 def __enter__(self):
263 return self._directory_path 262 return self._directory_path
264 263
265 def __exit__(self, type, value, traceback): 264 def __exit__(self, exception_type, exception_value, traceback):
266 # Only self-delete if necessary. 265 # Only self-delete if necessary.
267 266
268 # FIXME: Should we delete non-empty directories? 267 # FIXME: Should we delete non-empty directories?
269 if self._filesystem.exists(self._directory_path): 268 if self._filesystem.exists(self._directory_path):
270 self._filesystem.rmtree(self._directory_path) 269 self._filesystem.rmtree(self._directory_path)
271 270
272 return TemporaryDirectory(fs=self, **kwargs) 271 return TemporaryDirectory(fs=self, **kwargs)
273 272
274 def maybe_make_directory(self, *path): 273 def maybe_make_directory(self, *path):
275 norm_path = self.normpath(self.join(*path)) 274 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:] 382 rel_path = path[len(common_root) + 1:]
384 383
385 return dot_dot + rel_path 384 return dot_dot + rel_path
386 385
387 def remove(self, path): 386 def remove(self, path):
388 if self.files[path] is None: 387 if self.files[path] is None:
389 self._raise_not_found(path) 388 self._raise_not_found(path)
390 self.files[path] = None 389 self.files[path] = None
391 self.written_files[path] = None 390 self.written_files[path] = None
392 391
393 def rmtree(self, path): 392 def rmtree(self, path_to_remove):
394 path = self.normpath(path) 393 path_to_remove = self.normpath(path_to_remove)
395 394
396 for f in self.files: 395 for file_path in self.files:
397 # We need to add a trailing separator to path to avoid matching 396 # 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'. 397 # cases like path_to_remove='/foo/b' and file_path='/foo/bar/baz'.
399 if f == path or f.startswith(path + self.sep): 398 if file_path == path_to_remove or file_path.startswith(path_to_remov e + self.sep):
400 self.files[f] = None 399 self.files[file_path] = None
401 400
402 self.dirs = set(filter(lambda d: not (d == path or d.startswith(path + s elf.sep)), self.dirs)) 401 def should_remove(directory):
402 return directory == path_to_remove or directory.startswith(path_to_r emove + self.sep)
403
404 self.dirs = {d for d in self.dirs if not should_remove(d)}
403 405
404 def copytree(self, source, destination): 406 def copytree(self, source, destination):
405 source = self.normpath(source) 407 source = self.normpath(source)
406 destination = self.normpath(destination) 408 destination = self.normpath(destination)
407 409
408 for source_file in list(self.files): 410 for source_file in list(self.files):
409 if source_file.startswith(source): 411 if source_file.startswith(source):
410 destination_path = self.join(destination, self.relpath(source_fi le, source)) 412 destination_path = self.join(destination, self.relpath(source_fi le, source))
411 self.maybe_make_directory(self.dirname(destination_path)) 413 self.maybe_make_directory(self.dirname(destination_path))
412 self.files[destination_path] = self.files[source_file] 414 self.files[destination_path] = self.files[source_file]
(...skipping 15 matching lines...) Expand all
428 430
429 def __init__(self, fs, path): 431 def __init__(self, fs, path):
430 self.fs = fs 432 self.fs = fs
431 self.path = path 433 self.path = path
432 self.closed = False 434 self.closed = False
433 self.fs.files[path] = "" 435 self.fs.files[path] = ""
434 436
435 def __enter__(self): 437 def __enter__(self):
436 return self 438 return self
437 439
438 def __exit__(self, type, value, traceback): 440 def __exit__(self, exception_type, exception_value, traceback):
439 self.close() 441 self.close()
440 442
441 def close(self): 443 def close(self):
442 self.closed = True 444 self.closed = True
443 445
444 def write(self, str): 446 def write(self, string):
445 self.fs.files[self.path] += str 447 self.fs.files[self.path] += string
446 self.fs.written_files[self.path] = self.fs.files[self.path] 448 self.fs.written_files[self.path] = self.fs.files[self.path]
447 449
448 450
449 class WritableTextFileObject(WritableBinaryFileObject): 451 class WritableTextFileObject(WritableBinaryFileObject):
450 452
451 def write(self, str): 453 def write(self, string):
452 WritableBinaryFileObject.write(self, str.encode('utf-8')) 454 WritableBinaryFileObject.write(self, string.encode('utf-8'))
453 455
454 456
455 class ReadableBinaryFileObject(object): 457 class ReadableBinaryFileObject(object):
456 458
457 def __init__(self, fs, path, data): 459 def __init__(self, fs, path, data):
458 self.fs = fs 460 self.fs = fs
459 self.path = path 461 self.path = path
460 self.closed = False 462 self.closed = False
461 self.data = data 463 self.data = data
462 self.offset = 0 464 self.offset = 0
463 465
464 def __enter__(self): 466 def __enter__(self):
465 return self 467 return self
466 468
467 def __exit__(self, type, value, traceback): 469 def __exit__(self, exception_type, exception_value, traceback):
468 self.close() 470 self.close()
469 471
470 def close(self): 472 def close(self):
471 self.closed = True 473 self.closed = True
472 474
473 def read(self, bytes=None): 475 def read(self, num_bytes=None):
474 if not bytes: 476 if not num_bytes:
475 return self.data[self.offset:] 477 return self.data[self.offset:]
476 start = self.offset 478 start = self.offset
477 self.offset += bytes 479 self.offset += num_bytes
478 return self.data[start:self.offset] 480 return self.data[start:self.offset]
479 481
480 482
481 class ReadableTextFileObject(ReadableBinaryFileObject): 483 class ReadableTextFileObject(ReadableBinaryFileObject):
482 484
483 def __init__(self, fs, path, data): 485 def __init__(self, fs, path, data):
484 super(ReadableTextFileObject, self).__init__(fs, path, StringIO.StringIO (data.decode("utf-8"))) 486 super(ReadableTextFileObject, self).__init__(fs, path, StringIO.StringIO (data.decode("utf-8")))
485 487
486 def close(self): 488 def close(self):
487 self.data.close() 489 self.data.close()
488 super(ReadableTextFileObject, self).close() 490 super(ReadableTextFileObject, self).close()
489 491
490 def read(self, bytes=-1): 492 def read(self, num_bytes=-1):
491 return self.data.read(bytes) 493 return self.data.read(num_bytes)
492 494
493 def readline(self, length=None): 495 def readline(self, length=None):
494 return self.data.readline(length) 496 return self.data.readline(length)
495 497
496 def __iter__(self): 498 def __iter__(self):
497 return self.data.__iter__() 499 return self.data.__iter__()
498 500
499 def next(self): 501 def next(self):
500 return self.data.next() 502 return self.data.next()
501 503
502 def seek(self, offset, whence=os.SEEK_SET): 504 def seek(self, offset, whence=os.SEEK_SET):
503 self.data.seek(offset, whence) 505 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