mercurial/vfs.py
changeset 43076 2372284d9457
parent 43025 3518da504303
child 43077 687b865b95ad
--- a/mercurial/vfs.py	Sat Oct 05 10:29:34 2019 -0400
+++ b/mercurial/vfs.py	Sun Oct 06 09:45:02 2019 -0400
@@ -22,23 +22,26 @@
     util,
 )
 
+
 def _avoidambig(path, oldstat):
     """Avoid file stat ambiguity forcibly
 
     This function causes copying ``path`` file, if it is owned by
     another (see issue5418 and issue5584 for detail).
     """
+
     def checkandavoid():
         newstat = util.filestat.frompath(path)
         # return whether file stat ambiguity is (already) avoided
-        return (not newstat.isambig(oldstat) or
-                newstat.avoidambig(path, oldstat))
+        return not newstat.isambig(oldstat) or newstat.avoidambig(path, oldstat)
+
     if not checkandavoid():
         # simply copy to change owner of path to get privilege to
         # advance mtime (see issue5418)
         util.rename(util.mktempcopy(path), path)
         checkandavoid()
 
+
 class abstractvfs(object):
     """Abstract base class; cannot be instantiated"""
 
@@ -173,8 +176,9 @@
         return os.mkdir(self.join(path))
 
     def mkstemp(self, suffix='', prefix='tmp', dir=None):
-        fd, name = pycompat.mkstemp(suffix=suffix, prefix=prefix,
-                                    dir=self.join(dir))
+        fd, name = pycompat.mkstemp(
+            suffix=suffix, prefix=prefix, dir=self.join(dir)
+        )
         dname, fname = util.split(name)
         if dir:
             return fd, os.path.join(dir, fname)
@@ -227,6 +231,7 @@
         If ``forcibly``, this tries to remove READ-ONLY files, too.
         """
         if forcibly:
+
             def onerror(function, path, excinfo):
                 if function is not os.remove:
                     raise
@@ -236,10 +241,12 @@
                     raise
                 os.chmod(path, stat.S_IMODE(s.st_mode) | stat.S_IWRITE)
                 os.remove(path)
+
         else:
             onerror = None
-        return shutil.rmtree(self.join(path),
-                             ignore_errors=ignore_errors, onerror=onerror)
+        return shutil.rmtree(
+            self.join(path), ignore_errors=ignore_errors, onerror=onerror
+        )
 
     def setflags(self, path, l, x):
         return util.setflags(self.join(path), l, x)
@@ -255,8 +262,9 @@
         util.tryunlink(self.join(path))
 
     def unlinkpath(self, path=None, ignoremissing=False, rmdir=True):
-        return util.unlinkpath(self.join(path), ignoremissing=ignoremissing,
-                               rmdir=rmdir)
+        return util.unlinkpath(
+            self.join(path), ignoremissing=ignoremissing, rmdir=rmdir
+        )
 
     def utime(self, path=None, t=None):
         return os.utime(self.join(path), t)
@@ -294,7 +302,8 @@
         vfs = getattr(self, 'vfs', self)
         if getattr(vfs, '_backgroundfilecloser', None):
             raise error.Abort(
-                _('can only have 1 active background file closer'))
+                _('can only have 1 active background file closer')
+            )
 
         with backgroundfilecloser(ui, expectedcount=expectedcount) as bfc:
             try:
@@ -303,6 +312,7 @@
             finally:
                 vfs._backgroundfilecloser = None
 
+
 class vfs(abstractvfs):
     '''Operate files relative to a base directory
 
@@ -313,8 +323,15 @@
     (b) the base directory is managed by hg and considered sort-of append-only.
     See pathutil.pathauditor() for details.
     '''
-    def __init__(self, base, audit=True, cacheaudited=False, expandpath=False,
-                 realpath=False):
+
+    def __init__(
+        self,
+        base,
+        audit=True,
+        cacheaudited=False,
+        expandpath=False,
+        realpath=False,
+    ):
         if expandpath:
             base = util.expandpath(base)
         if realpath:
@@ -324,7 +341,7 @@
         if audit:
             self.audit = pathutil.pathauditor(self.base, cached=cacheaudited)
         else:
-            self.audit = (lambda path, mode=None: True)
+            self.audit = lambda path, mode=None: True
         self.createmode = None
         self._trustnlink = None
         self.options = {}
@@ -351,9 +368,17 @@
                 raise error.Abort("%s: %r" % (r, path))
             self.audit(path, mode=mode)
 
-    def __call__(self, path, mode="r", atomictemp=False, notindexed=False,
-                 backgroundclose=False, checkambig=False, auditpath=True,
-                 makeparentdirs=True):
+    def __call__(
+        self,
+        path,
+        mode="r",
+        atomictemp=False,
+        notindexed=False,
+        backgroundclose=False,
+        checkambig=False,
+        auditpath=True,
+        makeparentdirs=True,
+    ):
         '''Open ``path`` file, which is relative to vfs root.
 
         By default, parent directories are created as needed. Newly created
@@ -389,7 +414,7 @@
         f = self.join(path)
 
         if "b" not in mode:
-            mode += "b" # for that other OS
+            mode += "b"  # for that other OS
 
         nlink = -1
         if mode not in ('r', 'rb'):
@@ -400,8 +425,9 @@
                 if atomictemp:
                     if makeparentdirs:
                         util.makedirs(dirname, self.createmode, notindexed)
-                    return util.atomictempfile(f, mode, self.createmode,
-                                               checkambig=checkambig)
+                    return util.atomictempfile(
+                        f, mode, self.createmode, checkambig=checkambig
+                    )
                 try:
                     if 'w' in mode:
                         util.unlink(f)
@@ -412,7 +438,7 @@
                         with util.posixfile(f):
                             nlink = util.nlinks(f)
                             if nlink < 1:
-                                nlink = 2 # force mktempcopy (issue1922)
+                                nlink = 2  # force mktempcopy (issue1922)
                 except (OSError, IOError) as e:
                     if e.errno != errno.ENOENT:
                         raise
@@ -430,16 +456,25 @@
 
         if checkambig:
             if mode in ('r', 'rb'):
-                raise error.Abort(_('implementation error: mode %s is not'
-                                    ' valid for checkambig=True') % mode)
+                raise error.Abort(
+                    _(
+                        'implementation error: mode %s is not'
+                        ' valid for checkambig=True'
+                    )
+                    % mode
+                )
             fp = checkambigatclosing(fp)
 
-        if (backgroundclose and
-                isinstance(threading.currentThread(), threading._MainThread)):
+        if backgroundclose and isinstance(
+            threading.currentThread(), threading._MainThread
+        ):
             if not self._backgroundfilecloser:
-                raise error.Abort(_('backgroundclose can only be used when a '
-                                  'backgroundclosing context manager is active')
-                                  )
+                raise error.Abort(
+                    _(
+                        'backgroundclose can only be used when a '
+                        'backgroundclosing context manager is active'
+                    )
+                )
 
             fp = delayclosedfile(fp, self._backgroundfilecloser)
 
@@ -456,9 +491,12 @@
             try:
                 os.symlink(src, linkname)
             except OSError as err:
-                raise OSError(err.errno, _('could not symlink to %r: %s') %
-                              (src, encoding.strtolocal(err.strerror)),
-                              linkname)
+                raise OSError(
+                    err.errno,
+                    _('could not symlink to %r: %s')
+                    % (src, encoding.strtolocal(err.strerror)),
+                    linkname,
+                )
         else:
             self.write(dst, src)
 
@@ -468,8 +506,10 @@
         else:
             return self.base
 
+
 opener = vfs
 
+
 class proxyvfs(abstractvfs):
     def __init__(self, vfs):
         self.vfs = vfs
@@ -485,6 +525,7 @@
     def options(self, value):
         self.vfs.options = value
 
+
 class filtervfs(proxyvfs, abstractvfs):
     '''Wrapper vfs for filtering filenames with a function.'''
 
@@ -501,8 +542,10 @@
         else:
             return self.vfs.join(path)
 
+
 filteropener = filtervfs
 
+
 class readonlyvfs(proxyvfs):
     '''Wrapper vfs preventing any writing.'''
 
@@ -517,11 +560,13 @@
     def join(self, path, *insidef):
         return self.vfs.join(path, *insidef)
 
+
 class closewrapbase(object):
     """Base class of wrapper, which hooks closing
 
     Do not instantiate outside of the vfs layer.
     """
+
     def __init__(self, fh):
         object.__setattr__(self, r'_origfh', fh)
 
@@ -544,11 +589,13 @@
     def close(self):
         raise NotImplementedError('attempted instantiating ' + str(type(self)))
 
+
 class delayclosedfile(closewrapbase):
     """Proxy for a file object whose close is delayed.
 
     Do not instantiate outside of the vfs layer.
     """
+
     def __init__(self, fh, closer):
         super(delayclosedfile, self).__init__(fh)
         object.__setattr__(self, r'_closer', closer)
@@ -559,8 +606,10 @@
     def close(self):
         self._closer.close(self._origfh)
 
+
 class backgroundfilecloser(object):
     """Coordinates background closing of file handles on multiple threads."""
+
     def __init__(self, ui, expectedcount=-1):
         self._running = False
         self._entered = False
@@ -587,8 +636,9 @@
         maxqueue = ui.configint('worker', 'backgroundclosemaxqueue')
         threadcount = ui.configint('worker', 'backgroundclosethreadcount')
 
-        ui.debug('starting %d threads for background file closing\n' %
-                 threadcount)
+        ui.debug(
+            'starting %d threads for background file closing\n' % threadcount
+        )
 
         self._queue = pycompat.queue.Queue(maxsize=maxqueue)
         self._running = True
@@ -629,8 +679,9 @@
     def close(self, fh):
         """Schedule a file for closing."""
         if not self._entered:
-            raise error.Abort(_('can only call close() when context manager '
-                              'active'))
+            raise error.Abort(
+                _('can only call close() when context manager ' 'active')
+            )
 
         # If a background thread encountered an exception, raise now so we fail
         # fast. Otherwise we may potentially go on for minutes until the error
@@ -647,6 +698,7 @@
 
         self._queue.put(fh, block=True, timeout=None)
 
+
 class checkambigatclosing(closewrapbase):
     """Proxy for a file object, to avoid ambiguity of file stat
 
@@ -657,6 +709,7 @@
 
     Do not instantiate outside of the vfs layer.
     """
+
     def __init__(self, fh):
         super(checkambigatclosing, self).__init__(fh)
         object.__setattr__(self, r'_oldstat', util.filestat.frompath(fh.name))