comparison mercurial/vfs.py @ 43077:687b865b95ad

formatting: byteify all mercurial/ and hgext/ string literals Done with python3.7 contrib/byteify-strings.py -i $(hg files 'set:mercurial/**.py - mercurial/thirdparty/** + hgext/**.py - hgext/fsmonitor/pywatchman/** - mercurial/__init__.py') black -l 80 -t py33 -S $(hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**" - hgext/fsmonitor/pywatchman/**') # skip-blame mass-reformatting only Differential Revision: https://phab.mercurial-scm.org/D6972
author Augie Fackler <augie@google.com>
date Sun, 06 Oct 2019 09:48:39 -0400
parents 2372284d9457
children 66f2cc210a29
comparison
equal deleted inserted replaced
43076:2372284d9457 43077:687b865b95ad
45 class abstractvfs(object): 45 class abstractvfs(object):
46 """Abstract base class; cannot be instantiated""" 46 """Abstract base class; cannot be instantiated"""
47 47
48 def __init__(self, *args, **kwargs): 48 def __init__(self, *args, **kwargs):
49 '''Prevent instantiation; don't call this from subclasses.''' 49 '''Prevent instantiation; don't call this from subclasses.'''
50 raise NotImplementedError('attempted instantiating ' + str(type(self))) 50 raise NotImplementedError(b'attempted instantiating ' + str(type(self)))
51 51
52 def _auditpath(self, path, mode): 52 def _auditpath(self, path, mode):
53 raise NotImplementedError 53 raise NotImplementedError
54 54
55 def tryread(self, path): 55 def tryread(self, path):
57 try: 57 try:
58 return self.read(path) 58 return self.read(path)
59 except IOError as inst: 59 except IOError as inst:
60 if inst.errno != errno.ENOENT: 60 if inst.errno != errno.ENOENT:
61 raise 61 raise
62 return "" 62 return b""
63 63
64 def tryreadlines(self, path, mode='rb'): 64 def tryreadlines(self, path, mode=b'rb'):
65 '''gracefully return an empty array for missing files''' 65 '''gracefully return an empty array for missing files'''
66 try: 66 try:
67 return self.readlines(path, mode=mode) 67 return self.readlines(path, mode=mode)
68 except IOError as inst: 68 except IOError as inst:
69 if inst.errno != errno.ENOENT: 69 if inst.errno != errno.ENOENT:
79 for "write" mode access. 79 for "write" mode access.
80 ''' 80 '''
81 return self.__call__ 81 return self.__call__
82 82
83 def read(self, path): 83 def read(self, path):
84 with self(path, 'rb') as fp: 84 with self(path, b'rb') as fp:
85 return fp.read() 85 return fp.read()
86 86
87 def readlines(self, path, mode='rb'): 87 def readlines(self, path, mode=b'rb'):
88 with self(path, mode=mode) as fp: 88 with self(path, mode=mode) as fp:
89 return fp.readlines() 89 return fp.readlines()
90 90
91 def write(self, path, data, backgroundclose=False, **kwargs): 91 def write(self, path, data, backgroundclose=False, **kwargs):
92 with self(path, 'wb', backgroundclose=backgroundclose, **kwargs) as fp: 92 with self(path, b'wb', backgroundclose=backgroundclose, **kwargs) as fp:
93 return fp.write(data) 93 return fp.write(data)
94 94
95 def writelines(self, path, data, mode='wb', notindexed=False): 95 def writelines(self, path, data, mode=b'wb', notindexed=False):
96 with self(path, mode=mode, notindexed=notindexed) as fp: 96 with self(path, mode=mode, notindexed=notindexed) as fp:
97 return fp.writelines(data) 97 return fp.writelines(data)
98 98
99 def append(self, path, data): 99 def append(self, path, data):
100 with self(path, 'ab') as fp: 100 with self(path, b'ab') as fp:
101 return fp.write(data) 101 return fp.write(data)
102 102
103 def basename(self, path): 103 def basename(self, path):
104 """return base element of a path (as os.path.basename would do) 104 """return base element of a path (as os.path.basename would do)
105 105
173 return util.makelock(info, self.join(path)) 173 return util.makelock(info, self.join(path))
174 174
175 def mkdir(self, path=None): 175 def mkdir(self, path=None):
176 return os.mkdir(self.join(path)) 176 return os.mkdir(self.join(path))
177 177
178 def mkstemp(self, suffix='', prefix='tmp', dir=None): 178 def mkstemp(self, suffix=b'', prefix=b'tmp', dir=None):
179 fd, name = pycompat.mkstemp( 179 fd, name = pycompat.mkstemp(
180 suffix=suffix, prefix=prefix, dir=self.join(dir) 180 suffix=suffix, prefix=prefix, dir=self.join(dir)
181 ) 181 )
182 dname, fname = util.split(name) 182 dname, fname = util.split(name)
183 if dir: 183 if dir:
201 To avoid file stat ambiguity forcibly, checkambig=True involves 201 To avoid file stat ambiguity forcibly, checkambig=True involves
202 copying ``src`` file, if it is owned by another. Therefore, use 202 copying ``src`` file, if it is owned by another. Therefore, use
203 checkambig=True only in limited cases (see also issue5418 and 203 checkambig=True only in limited cases (see also issue5418 and
204 issue5584 for detail). 204 issue5584 for detail).
205 """ 205 """
206 self._auditpath(dst, 'w') 206 self._auditpath(dst, b'w')
207 srcpath = self.join(src) 207 srcpath = self.join(src)
208 dstpath = self.join(dst) 208 dstpath = self.join(dst)
209 oldstat = checkambig and util.filestat.frompath(dstpath) 209 oldstat = checkambig and util.filestat.frompath(dstpath)
210 if oldstat and oldstat.stat: 210 if oldstat and oldstat.stat:
211 ret = util.rename(srcpath, dstpath) 211 ret = util.rename(srcpath, dstpath)
300 yield 300 yield
301 return 301 return
302 vfs = getattr(self, 'vfs', self) 302 vfs = getattr(self, 'vfs', self)
303 if getattr(vfs, '_backgroundfilecloser', None): 303 if getattr(vfs, '_backgroundfilecloser', None):
304 raise error.Abort( 304 raise error.Abort(
305 _('can only have 1 active background file closer') 305 _(b'can only have 1 active background file closer')
306 ) 306 )
307 307
308 with backgroundfilecloser(ui, expectedcount=expectedcount) as bfc: 308 with backgroundfilecloser(ui, expectedcount=expectedcount) as bfc:
309 try: 309 try:
310 vfs._backgroundfilecloser = bfc 310 vfs._backgroundfilecloser = bfc
363 if self._audit: 363 if self._audit:
364 if os.path.isabs(path) and path.startswith(self.base): 364 if os.path.isabs(path) and path.startswith(self.base):
365 path = os.path.relpath(path, self.base) 365 path = os.path.relpath(path, self.base)
366 r = util.checkosfilename(path) 366 r = util.checkosfilename(path)
367 if r: 367 if r:
368 raise error.Abort("%s: %r" % (r, path)) 368 raise error.Abort(b"%s: %r" % (r, path))
369 self.audit(path, mode=mode) 369 self.audit(path, mode=mode)
370 370
371 def __call__( 371 def __call__(
372 self, 372 self,
373 path, 373 path,
374 mode="r", 374 mode=b"r",
375 atomictemp=False, 375 atomictemp=False,
376 notindexed=False, 376 notindexed=False,
377 backgroundclose=False, 377 backgroundclose=False,
378 checkambig=False, 378 checkambig=False,
379 auditpath=True, 379 auditpath=True,
411 ''' 411 '''
412 if auditpath: 412 if auditpath:
413 self._auditpath(path, mode) 413 self._auditpath(path, mode)
414 f = self.join(path) 414 f = self.join(path)
415 415
416 if "b" not in mode: 416 if b"b" not in mode:
417 mode += "b" # for that other OS 417 mode += b"b" # for that other OS
418 418
419 nlink = -1 419 nlink = -1
420 if mode not in ('r', 'rb'): 420 if mode not in (b'r', b'rb'):
421 dirname, basename = util.split(f) 421 dirname, basename = util.split(f)
422 # If basename is empty, then the path is malformed because it points 422 # If basename is empty, then the path is malformed because it points
423 # to a directory. Let the posixfile() call below raise IOError. 423 # to a directory. Let the posixfile() call below raise IOError.
424 if basename: 424 if basename:
425 if atomictemp: 425 if atomictemp:
427 util.makedirs(dirname, self.createmode, notindexed) 427 util.makedirs(dirname, self.createmode, notindexed)
428 return util.atomictempfile( 428 return util.atomictempfile(
429 f, mode, self.createmode, checkambig=checkambig 429 f, mode, self.createmode, checkambig=checkambig
430 ) 430 )
431 try: 431 try:
432 if 'w' in mode: 432 if b'w' in mode:
433 util.unlink(f) 433 util.unlink(f)
434 nlink = 0 434 nlink = 0
435 else: 435 else:
436 # nlinks() may behave differently for files on Windows 436 # nlinks() may behave differently for files on Windows
437 # shares if the file is open. 437 # shares if the file is open.
453 fp = util.posixfile(f, mode) 453 fp = util.posixfile(f, mode)
454 if nlink == 0: 454 if nlink == 0:
455 self._fixfilemode(f) 455 self._fixfilemode(f)
456 456
457 if checkambig: 457 if checkambig:
458 if mode in ('r', 'rb'): 458 if mode in (b'r', b'rb'):
459 raise error.Abort( 459 raise error.Abort(
460 _( 460 _(
461 'implementation error: mode %s is not' 461 b'implementation error: mode %s is not'
462 ' valid for checkambig=True' 462 b' valid for checkambig=True'
463 ) 463 )
464 % mode 464 % mode
465 ) 465 )
466 fp = checkambigatclosing(fp) 466 fp = checkambigatclosing(fp)
467 467
469 threading.currentThread(), threading._MainThread 469 threading.currentThread(), threading._MainThread
470 ): 470 ):
471 if not self._backgroundfilecloser: 471 if not self._backgroundfilecloser:
472 raise error.Abort( 472 raise error.Abort(
473 _( 473 _(
474 'backgroundclose can only be used when a ' 474 b'backgroundclose can only be used when a '
475 'backgroundclosing context manager is active' 475 b'backgroundclosing context manager is active'
476 ) 476 )
477 ) 477 )
478 478
479 fp = delayclosedfile(fp, self._backgroundfilecloser) 479 fp = delayclosedfile(fp, self._backgroundfilecloser)
480 480
491 try: 491 try:
492 os.symlink(src, linkname) 492 os.symlink(src, linkname)
493 except OSError as err: 493 except OSError as err:
494 raise OSError( 494 raise OSError(
495 err.errno, 495 err.errno,
496 _('could not symlink to %r: %s') 496 _(b'could not symlink to %r: %s')
497 % (src, encoding.strtolocal(err.strerror)), 497 % (src, encoding.strtolocal(err.strerror)),
498 linkname, 498 linkname,
499 ) 499 )
500 else: 500 else:
501 self.write(dst, src) 501 self.write(dst, src)
550 '''Wrapper vfs preventing any writing.''' 550 '''Wrapper vfs preventing any writing.'''
551 551
552 def __init__(self, vfs): 552 def __init__(self, vfs):
553 proxyvfs.__init__(self, vfs) 553 proxyvfs.__init__(self, vfs)
554 554
555 def __call__(self, path, mode='r', *args, **kw): 555 def __call__(self, path, mode=b'r', *args, **kw):
556 if mode not in ('r', 'rb'): 556 if mode not in (b'r', b'rb'):
557 raise error.Abort(_('this vfs is read only')) 557 raise error.Abort(_(b'this vfs is read only'))
558 return self.vfs(path, mode, *args, **kw) 558 return self.vfs(path, mode, *args, **kw)
559 559
560 def join(self, path, *insidef): 560 def join(self, path, *insidef):
561 return self.vfs.join(path, *insidef) 561 return self.vfs.join(path, *insidef)
562 562
582 def __enter__(self): 582 def __enter__(self):
583 self._origfh.__enter__() 583 self._origfh.__enter__()
584 return self 584 return self
585 585
586 def __exit__(self, exc_type, exc_value, exc_tb): 586 def __exit__(self, exc_type, exc_value, exc_tb):
587 raise NotImplementedError('attempted instantiating ' + str(type(self))) 587 raise NotImplementedError(b'attempted instantiating ' + str(type(self)))
588 588
589 def close(self): 589 def close(self):
590 raise NotImplementedError('attempted instantiating ' + str(type(self))) 590 raise NotImplementedError(b'attempted instantiating ' + str(type(self)))
591 591
592 592
593 class delayclosedfile(closewrapbase): 593 class delayclosedfile(closewrapbase):
594 """Proxy for a file object whose close is delayed. 594 """Proxy for a file object whose close is delayed.
595 595
617 self._threadexception = None 617 self._threadexception = None
618 618
619 # Only Windows/NTFS has slow file closing. So only enable by default 619 # Only Windows/NTFS has slow file closing. So only enable by default
620 # on that platform. But allow to be enabled elsewhere for testing. 620 # on that platform. But allow to be enabled elsewhere for testing.
621 defaultenabled = pycompat.iswindows 621 defaultenabled = pycompat.iswindows
622 enabled = ui.configbool('worker', 'backgroundclose', defaultenabled) 622 enabled = ui.configbool(b'worker', b'backgroundclose', defaultenabled)
623 623
624 if not enabled: 624 if not enabled:
625 return 625 return
626 626
627 # There is overhead to starting and stopping the background threads. 627 # There is overhead to starting and stopping the background threads.
628 # Don't do background processing unless the file count is large enough 628 # Don't do background processing unless the file count is large enough
629 # to justify it. 629 # to justify it.
630 minfilecount = ui.configint('worker', 'backgroundcloseminfilecount') 630 minfilecount = ui.configint(b'worker', b'backgroundcloseminfilecount')
631 # FUTURE dynamically start background threads after minfilecount closes. 631 # FUTURE dynamically start background threads after minfilecount closes.
632 # (We don't currently have any callers that don't know their file count) 632 # (We don't currently have any callers that don't know their file count)
633 if expectedcount > 0 and expectedcount < minfilecount: 633 if expectedcount > 0 and expectedcount < minfilecount:
634 return 634 return
635 635
636 maxqueue = ui.configint('worker', 'backgroundclosemaxqueue') 636 maxqueue = ui.configint(b'worker', b'backgroundclosemaxqueue')
637 threadcount = ui.configint('worker', 'backgroundclosethreadcount') 637 threadcount = ui.configint(b'worker', b'backgroundclosethreadcount')
638 638
639 ui.debug( 639 ui.debug(
640 'starting %d threads for background file closing\n' % threadcount 640 b'starting %d threads for background file closing\n' % threadcount
641 ) 641 )
642 642
643 self._queue = pycompat.queue.Queue(maxsize=maxqueue) 643 self._queue = pycompat.queue.Queue(maxsize=maxqueue)
644 self._running = True 644 self._running = True
645 645
646 for i in range(threadcount): 646 for i in range(threadcount):
647 t = threading.Thread(target=self._worker, name='backgroundcloser') 647 t = threading.Thread(target=self._worker, name=b'backgroundcloser')
648 self._threads.append(t) 648 self._threads.append(t)
649 t.start() 649 t.start()
650 650
651 def __enter__(self): 651 def __enter__(self):
652 self._entered = True 652 self._entered = True
678 678
679 def close(self, fh): 679 def close(self, fh):
680 """Schedule a file for closing.""" 680 """Schedule a file for closing."""
681 if not self._entered: 681 if not self._entered:
682 raise error.Abort( 682 raise error.Abort(
683 _('can only call close() when context manager ' 'active') 683 _(b'can only call close() when context manager ' b'active')
684 ) 684 )
685 685
686 # If a background thread encountered an exception, raise now so we fail 686 # If a background thread encountered an exception, raise now so we fail
687 # fast. Otherwise we may potentially go on for minutes until the error 687 # fast. Otherwise we may potentially go on for minutes until the error
688 # is acted on. 688 # is acted on.