mercurial/vfs.py
author Rapha?l Gom?s <rgomes@octobus.net>
Wed, 19 Jun 2024 19:10:49 +0200
changeset 52163 7346f93be7a4
parent 51890 992fcf6b2473
child 52643 5cc8deb96b48
permissions -rw-r--r--
revlog: add the glue to use the Rust `InnerRevlog` from Python The performance of this has been looked at for quite some time, and some workflows are actually quite a bit faster than with the Python + C code. However, we are still (up to 20%) slower in some crucial places like cloning certain repos, log, cat, which makes this an incomplete rewrite. This is mostly due to the high amount of overhead in Python <-> Rust FFI, especially around the VFS code. A future patch series will rewrite the VFS code in pure Rust, which should hopefully get us up to par with current perfomance, if not better in all important cases. This is a "save state" of sorts, as this is a ton of code, and I don't want to pile up even more things in a single review. Continuing to try to match the current performance will take an extremely long time, if it's not impossible, without the aforementioned VFS work.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
31217
0f31830fbfc4 vfs: extract 'vfs' class and related code to a new 'vfs' module (API)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31025
diff changeset
     1
# vfs.py - Mercurial 'vfs' classes
13962
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     2
#
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Rapha?l Gom?s <rgomes@octobus.net>
parents: 45942
diff changeset
     3
#  Copyright Olivia Mackall <olivia@selenic.com>
13962
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     4
#
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
27482
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
     7
51859
f4733654f144 typing: add `from __future__ import annotations` to most files
Matt Harbison <matt_harbison@yahoo.com>
parents: 51675
diff changeset
     8
from __future__ import annotations
f4733654f144 typing: add `from __future__ import annotations` to most files
Matt Harbison <matt_harbison@yahoo.com>
parents: 51675
diff changeset
     9
51880
f79f98733a5b vfs: use @abstractmethod instead of homebrewing abstract methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 51879
diff changeset
    10
import abc
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
    11
import contextlib
27482
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
    12
import os
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
    13
import shutil
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
    14
import stat
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
    15
import threading
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
    16
import typing
27482
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
    17
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
    18
from typing import (
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
    19
    Any,
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
    20
    BinaryIO,
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
    21
    Callable,
51890
992fcf6b2473 typing: add a handful more annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51889
diff changeset
    22
    Dict,
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
    23
    Iterable,
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
    24
    Iterator,
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
    25
    List,
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
    26
    MutableMapping,
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
    27
    Optional,
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
    28
    Tuple,
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
    29
    Type,
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
    30
    TypeVar,
51890
992fcf6b2473 typing: add a handful more annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51889
diff changeset
    31
    Union,
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
    32
)
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
    33
27482
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
    34
from .i18n import _
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
    35
from . import (
34022
d5b2beca16c0 python3: wrap all uses of <exception>.strerror with strtolocal
Augie Fackler <raf@durin42.com>
parents: 33649
diff changeset
    36
    encoding,
27482
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
    37
    error,
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
    38
    pathutil,
30305
af7c60988f6e py3: make scmutil.rcpath() return bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30109
diff changeset
    39
    pycompat,
27482
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
    40
    util,
dde3da2246f1 scmutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27093
diff changeset
    41
)
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents: 18678
diff changeset
    42
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
    43
if typing.TYPE_CHECKING:
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
    44
    from . import (
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
    45
        ui as uimod,
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
    46
    )
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
    47
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
    48
    _Tbackgroundfilecloser = TypeVar(
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
    49
        '_Tbackgroundfilecloser', bound='backgroundfilecloser'
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
    50
    )
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
    51
    _Tclosewrapbase = TypeVar('_Tclosewrapbase', bound='closewrapbase')
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
    52
    _OnErrorFn = Callable[[Exception], Optional[object]]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
    53
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
    54
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
    55
def _avoidambig(path: bytes, oldstat: util.filestat) -> None:
33280
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    56
    """Avoid file stat ambiguity forcibly
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    57
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    58
    This function causes copying ``path`` file, if it is owned by
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    59
    another (see issue5418 and issue5584 for detail).
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    60
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
    61
33280
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    62
    def checkandavoid():
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    63
        newstat = util.filestat.frompath(path)
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    64
        # return whether file stat ambiguity is (already) avoided
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
    65
        return not newstat.isambig(oldstat) or newstat.avoidambig(path, oldstat)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
    66
33280
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    67
    if not checkandavoid():
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    68
        # simply copy to change owner of path to get privilege to
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    69
        # advance mtime (see issue5418)
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    70
        util.rename(util.mktempcopy(path), path)
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    71
        checkandavoid()
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
    72
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
    73
51880
f79f98733a5b vfs: use @abstractmethod instead of homebrewing abstract methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 51879
diff changeset
    74
class abstractvfs(abc.ABC):
14089
d3f7e110c3c0 opener: introduce an abstact superclass of it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14068
diff changeset
    75
    """Abstract base class; cannot be instantiated"""
d3f7e110c3c0 opener: introduce an abstact superclass of it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14068
diff changeset
    76
47809
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
    77
    # default directory separator for vfs
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
    78
    #
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
    79
    # Other vfs code always use `/` and this works fine because python file API
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
    80
    # abstract the use of `/` and make it work transparently. For consistency
51882
e59e1d8d29d2 vfs: do minor copyediting on comments and doc strings
Matt Harbison <matt_harbison@yahoo.com>
parents: 51881
diff changeset
    81
    # vfs will always use `/` when joining. This avoids some confusion in
47809
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
    82
    # encoded vfs (see issue6546)
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
    83
    _dir_sep: bytes = b'/'
47809
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
    84
52163
7346f93be7a4 revlog: add the glue to use the Rust `InnerRevlog` from Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51890
diff changeset
    85
    # Used to disable the Rust `InnerRevlog` in case the VFS is not supported
7346f93be7a4 revlog: add the glue to use the Rust `InnerRevlog` from Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51890
diff changeset
    86
    # by the Rust code
7346f93be7a4 revlog: add the glue to use the Rust `InnerRevlog` from Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51890
diff changeset
    87
    rust_compatible = True
7346f93be7a4 revlog: add the glue to use the Rust `InnerRevlog` from Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51890
diff changeset
    88
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
    89
    # TODO: type return, which is util.posixfile wrapped by a proxy
51880
f79f98733a5b vfs: use @abstractmethod instead of homebrewing abstract methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 51879
diff changeset
    90
    @abc.abstractmethod
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
    91
    def __call__(self, path: bytes, mode: bytes = b'rb', **kwargs) -> Any:
51880
f79f98733a5b vfs: use @abstractmethod instead of homebrewing abstract methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 51879
diff changeset
    92
        ...
43467
b16912f8c07c vfs: add a NotImplementedError implementation of __call__
Augie Fackler <augie@google.com>
parents: 43466
diff changeset
    93
51880
f79f98733a5b vfs: use @abstractmethod instead of homebrewing abstract methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 51879
diff changeset
    94
    @abc.abstractmethod
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
    95
    def _auditpath(self, path: bytes, mode: bytes) -> None:
51880
f79f98733a5b vfs: use @abstractmethod instead of homebrewing abstract methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 51879
diff changeset
    96
        ...
41091
d9b6b9ed96d8 vfs: add a `_auditpath` to abstract vfs
Boris Feld <boris.feld@octobus.net>
parents: 41090
diff changeset
    97
51880
f79f98733a5b vfs: use @abstractmethod instead of homebrewing abstract methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 51879
diff changeset
    98
    @abc.abstractmethod
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
    99
    def join(self, path: Optional[bytes], *insidef: bytes) -> bytes:
51880
f79f98733a5b vfs: use @abstractmethod instead of homebrewing abstract methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 51879
diff changeset
   100
        ...
43468
8b0fa4de0064 vfs: add NotImplementedError version of join
Augie Fackler <augie@google.com>
parents: 43467
diff changeset
   101
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   102
    def tryread(self, path: bytes) -> bytes:
16479
fc04698fa778 opener: coding style, use triple quotes for doc string
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16455
diff changeset
   103
        '''gracefully return an empty string for missing files'''
16455
154219f3a6a4 opener: introduce tryread helper
Matt Mackall <mpm@selenic.com>
parents: 16436
diff changeset
   104
        try:
154219f3a6a4 opener: introduce tryread helper
Matt Mackall <mpm@selenic.com>
parents: 16436
diff changeset
   105
            return self.read(path)
49306
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 48946
diff changeset
   106
        except FileNotFoundError:
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 48946
diff changeset
   107
            pass
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   108
        return b""
16455
154219f3a6a4 opener: introduce tryread helper
Matt Mackall <mpm@selenic.com>
parents: 16436
diff changeset
   109
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   110
    def tryreadlines(self, path: bytes, mode: bytes = b'rb') -> List[bytes]:
23368
bf8c3172255c vfs: add "readlines" and "tryreadlines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23259
diff changeset
   111
        '''gracefully return an empty array for missing files'''
bf8c3172255c vfs: add "readlines" and "tryreadlines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23259
diff changeset
   112
        try:
bf8c3172255c vfs: add "readlines" and "tryreadlines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23259
diff changeset
   113
            return self.readlines(path, mode=mode)
49306
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 48946
diff changeset
   114
        except FileNotFoundError:
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 48946
diff changeset
   115
            pass
23368
bf8c3172255c vfs: add "readlines" and "tryreadlines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23259
diff changeset
   116
        return []
bf8c3172255c vfs: add "readlines" and "tryreadlines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23259
diff changeset
   117
29718
2dd8c225e94c vfs: use propertycache for open
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29714
diff changeset
   118
    @util.propertycache
2dd8c225e94c vfs: use propertycache for open
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29714
diff changeset
   119
    def open(self):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44566
diff changeset
   120
        """Open ``path`` file, which is relative to vfs root.
23370
46265d0f0c7b vfs: add "notindexed" argument to invoke "ensuredir" with it in write mode
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23368
diff changeset
   121
46265d0f0c7b vfs: add "notindexed" argument to invoke "ensuredir" with it in write mode
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23368
diff changeset
   122
        Newly created directories are marked as "not to be indexed by
46265d0f0c7b vfs: add "notindexed" argument to invoke "ensuredir" with it in write mode
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23368
diff changeset
   123
        the content indexing service", if ``notindexed`` is specified
46265d0f0c7b vfs: add "notindexed" argument to invoke "ensuredir" with it in write mode
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23368
diff changeset
   124
        for "write" mode access.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44566
diff changeset
   125
        """
29718
2dd8c225e94c vfs: use propertycache for open
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29714
diff changeset
   126
        return self.__call__
19897
896a4568def7 vfs: add "open()" for newly added code paths which open files via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19896
diff changeset
   127
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   128
    def read(self, path: bytes) -> bytes:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   129
        with self(path, b'rb') as fp:
14097
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
   130
            return fp.read()
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
   131
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   132
    def readlines(self, path: bytes, mode: bytes = b'rb') -> List[bytes]:
27706
22e362da27cf scmutil: use context managers for file handles
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27651
diff changeset
   133
        with self(path, mode=mode) as fp:
23368
bf8c3172255c vfs: add "readlines" and "tryreadlines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23259
diff changeset
   134
            return fp.readlines()
bf8c3172255c vfs: add "readlines" and "tryreadlines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23259
diff changeset
   135
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   136
    def write(
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   137
        self, path: bytes, data: bytes, backgroundclose: bool = False, **kwargs
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   138
    ) -> int:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   139
        with self(path, b'wb', backgroundclose=backgroundclose, **kwargs) as fp:
14167
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
   140
            return fp.write(data)
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
   141
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   142
    def writelines(
51887
ad83e4f9b40e typing: correct pytype mistakes in `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51886
diff changeset
   143
        self,
ad83e4f9b40e typing: correct pytype mistakes in `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51886
diff changeset
   144
        path: bytes,
ad83e4f9b40e typing: correct pytype mistakes in `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51886
diff changeset
   145
        data: Iterable[bytes],
ad83e4f9b40e typing: correct pytype mistakes in `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51886
diff changeset
   146
        mode: bytes = b'wb',
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   147
        notindexed: bool = False,
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   148
    ) -> None:
27706
22e362da27cf scmutil: use context managers for file handles
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27651
diff changeset
   149
        with self(path, mode=mode, notindexed=notindexed) as fp:
23371
1df6519eb3ab vfs: add "writelines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23370
diff changeset
   150
            return fp.writelines(data)
1df6519eb3ab vfs: add "writelines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23370
diff changeset
   151
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   152
    def append(self, path: bytes, data: bytes) -> int:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   153
        with self(path, b'ab') as fp:
14097
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
   154
            return fp.write(data)
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
   155
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   156
    def basename(self, path: bytes) -> bytes:
25770
39de2e9cc6f4 vfs: add basename
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25739
diff changeset
   157
        """return base element of a path (as os.path.basename would do)
39de2e9cc6f4 vfs: add basename
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25739
diff changeset
   158
39de2e9cc6f4 vfs: add basename
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25739
diff changeset
   159
        This exists to allow handling of strange encoding if needed."""
39de2e9cc6f4 vfs: add basename
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25739
diff changeset
   160
        return os.path.basename(path)
39de2e9cc6f4 vfs: add basename
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25739
diff changeset
   161
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   162
    def chmod(self, path: bytes, mode: int) -> None:
20086
f3df2612f3c3 vfs: add "chmod()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20085
diff changeset
   163
        return os.chmod(self.join(path), mode)
f3df2612f3c3 vfs: add "chmod()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20085
diff changeset
   164
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   165
    def dirname(self, path: bytes) -> bytes:
25772
5471965af5cb vfs: add dirname
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25770
diff changeset
   166
        """return dirname element of a path (as os.path.dirname would do)
5471965af5cb vfs: add dirname
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25770
diff changeset
   167
5471965af5cb vfs: add dirname
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25770
diff changeset
   168
        This exists to allow handling of strange encoding if needed."""
5471965af5cb vfs: add dirname
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25770
diff changeset
   169
        return os.path.dirname(path)
5471965af5cb vfs: add dirname
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25770
diff changeset
   170
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   171
    def exists(self, path: Optional[bytes] = None) -> bool:
17161
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   172
        return os.path.exists(self.join(path))
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   173
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   174
    def fstat(self, fp: BinaryIO) -> os.stat_result:
19899
8c3dcbbfb5de changelog: use "vfs.fstat()" instead of "util.fstat()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19897
diff changeset
   175
        return util.fstat(fp)
8c3dcbbfb5de changelog: use "vfs.fstat()" instead of "util.fstat()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19897
diff changeset
   176
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   177
    def isdir(self, path: Optional[bytes] = None) -> bool:
17161
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   178
        return os.path.isdir(self.join(path))
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   179
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   180
    def isfile(self, path: Optional[bytes] = None) -> bool:
20085
589d6bb5b18d vfs: add "isfile()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20045
diff changeset
   181
        return os.path.isfile(self.join(path))
589d6bb5b18d vfs: add "isfile()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20045
diff changeset
   182
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   183
    def islink(self, path: Optional[bytes] = None) -> bool:
18949
138978f20180 localrepo: use "vfs.islink()" instead of "os.path.islink()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18948
diff changeset
   184
        return os.path.islink(self.join(path))
138978f20180 localrepo: use "vfs.islink()" instead of "os.path.islink()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18948
diff changeset
   185
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   186
    def isfileorlink(self, path: Optional[bytes] = None) -> bool:
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44566
diff changeset
   187
        """return whether path is a regular file or a symlink
27571
6a6e78f84cc6 merge: while checking for unknown files don't follow symlinks (issue5027)
Siddharth Agarwal <sid0@fb.com>
parents: 26836
diff changeset
   188
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44566
diff changeset
   189
        Unlike isfile, this doesn't follow symlinks."""
27571
6a6e78f84cc6 merge: while checking for unknown files don't follow symlinks (issue5027)
Siddharth Agarwal <sid0@fb.com>
parents: 26836
diff changeset
   190
        try:
6a6e78f84cc6 merge: while checking for unknown files don't follow symlinks (issue5027)
Siddharth Agarwal <sid0@fb.com>
parents: 26836
diff changeset
   191
            st = self.lstat(path)
6a6e78f84cc6 merge: while checking for unknown files don't follow symlinks (issue5027)
Siddharth Agarwal <sid0@fb.com>
parents: 26836
diff changeset
   192
        except OSError:
6a6e78f84cc6 merge: while checking for unknown files don't follow symlinks (issue5027)
Siddharth Agarwal <sid0@fb.com>
parents: 26836
diff changeset
   193
            return False
6a6e78f84cc6 merge: while checking for unknown files don't follow symlinks (issue5027)
Siddharth Agarwal <sid0@fb.com>
parents: 26836
diff changeset
   194
        mode = st.st_mode
6a6e78f84cc6 merge: while checking for unknown files don't follow symlinks (issue5027)
Siddharth Agarwal <sid0@fb.com>
parents: 26836
diff changeset
   195
        return stat.S_ISREG(mode) or stat.S_ISLNK(mode)
6a6e78f84cc6 merge: while checking for unknown files don't follow symlinks (issue5027)
Siddharth Agarwal <sid0@fb.com>
parents: 26836
diff changeset
   196
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   197
    def _join(self, *paths: bytes) -> bytes:
47809
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   198
        root_idx = 0
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   199
        for idx, p in enumerate(paths):
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   200
            if os.path.isabs(p) or p.startswith(self._dir_sep):
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   201
                root_idx = idx
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   202
        if root_idx != 0:
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   203
            paths = paths[root_idx:]
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   204
        paths = [p for p in paths if p]
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   205
        return self._dir_sep.join(paths)
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   206
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   207
    def reljoin(self, *paths: bytes) -> bytes:
23581
aed981c7bebf vfs: add a 'reljoin' function for joining relative paths
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23539
diff changeset
   208
        """join various elements of a path together (as os.path.join would do)
aed981c7bebf vfs: add a 'reljoin' function for joining relative paths
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23539
diff changeset
   209
aed981c7bebf vfs: add a 'reljoin' function for joining relative paths
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23539
diff changeset
   210
        The vfs base is not injected so that path stay relative. This exists
aed981c7bebf vfs: add a 'reljoin' function for joining relative paths
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23539
diff changeset
   211
        to allow handling of strange encoding if needed."""
47809
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   212
        return self._join(*paths)
23581
aed981c7bebf vfs: add a 'reljoin' function for joining relative paths
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23539
diff changeset
   213
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   214
    def split(self, path: bytes) -> Tuple[bytes, bytes]:
23582
7559dc8c4238 vfs: add a 'split' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23581
diff changeset
   215
        """split top-most element of a path (as os.path.split would do)
7559dc8c4238 vfs: add a 'split' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23581
diff changeset
   216
7559dc8c4238 vfs: add a 'split' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23581
diff changeset
   217
        This exists to allow handling of strange encoding if needed."""
7559dc8c4238 vfs: add a 'split' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23581
diff changeset
   218
        return os.path.split(path)
7559dc8c4238 vfs: add a 'split' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23581
diff changeset
   219
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   220
    def lexists(self, path: Optional[bytes] = None) -> bool:
21563
764b691b8bda vfs: add lexists() in current api
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21111
diff changeset
   221
        return os.path.lexists(self.join(path))
764b691b8bda vfs: add lexists() in current api
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21111
diff changeset
   222
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   223
    def lstat(self, path: Optional[bytes] = None) -> os.stat_result:
19900
7c21e3398931 context: use "vfs.lstat()" instead of "os.lstat()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19899
diff changeset
   224
        return os.lstat(self.join(path))
7c21e3398931 context: use "vfs.lstat()" instead of "os.lstat()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19899
diff changeset
   225
51649
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   226
    def is_mmap_safe(self, path: Optional[bytes] = None) -> bool:
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   227
        """return True if it is safe to read a file content as mmap
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   228
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   229
        This focus on the file system aspect of such safety, the application
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   230
        logic around that file is not taken into account, so caller need to
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   231
        make sure the file won't be truncated in a way that will create SIGBUS
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   232
        on access.
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   233
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   234
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   235
        The initial motivation for this logic is that if mmap is used on NFS
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   236
        and somebody deletes the mapped file (e.g. by renaming on top of it),
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   237
        then you get SIGBUS, which can be pretty disruptive: we get core dump
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   238
        reports, and the process terminates without writing to the blackbox.
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   239
51882
e59e1d8d29d2 vfs: do minor copyediting on comments and doc strings
Matt Harbison <matt_harbison@yahoo.com>
parents: 51881
diff changeset
   240
        Instead, in this situation we prefer to read the file normally.
51649
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   241
        The risk of ESTALE in the middle of the read remains, but it's
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   242
        smaller because we read sooner and the error should be reported
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   243
        just as any other error.
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   244
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   245
        Note that python standard library does not offer the necessary function
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   246
        to detect the file stem bits. So this detection rely on compiled bits
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   247
        and is not available in pure python.
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   248
        """
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   249
        # XXX Since we already assume a vfs to address a consistent file system
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   250
        # in other location, we could determine the fstype once for the root
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   251
        # and cache that value.
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   252
        fstype = util.getfstype(self.join(path))
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   253
        return fstype is not None and fstype != b'nfs'
ba205f944cb4 mmap: add a `is_mmap_safe` method to vfs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51590
diff changeset
   254
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   255
    def listdir(self, path: Optional[bytes] = None) -> List[bytes]:
21799
dfacdd6a111e vfs: add listdir for os.listdir in vfs
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21716
diff changeset
   256
        return os.listdir(self.join(path))
dfacdd6a111e vfs: add listdir for os.listdir in vfs
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21716
diff changeset
   257
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   258
    def makedir(self, path: Optional[bytes] = None, notindexed=True) -> None:
17161
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   259
        return util.makedir(self.join(path), notindexed)
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   260
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   261
    def makedirs(
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   262
        self, path: Optional[bytes] = None, mode: Optional[int] = None
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   263
    ) -> None:
17161
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   264
        return util.makedirs(self.join(path), mode)
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   265
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   266
    def makelock(self, info: bytes, path: bytes) -> None:
20090
88d8e568add1 vfs: add "makelock()" and "readlock()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20086
diff changeset
   267
        return util.makelock(info, self.join(path))
88d8e568add1 vfs: add "makelock()" and "readlock()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20086
diff changeset
   268
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   269
    def mkdir(self, path: Optional[bytes] = None) -> None:
17723
ab23768746fd scmutil: reorder newly added functions for vfs support in dictionary order
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17681
diff changeset
   270
        return os.mkdir(self.join(path))
ab23768746fd scmutil: reorder newly added functions for vfs support in dictionary order
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17681
diff changeset
   271
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   272
    def mkstemp(
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   273
        self,
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   274
        suffix: bytes = b'',
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   275
        prefix: bytes = b'tmp',
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   276
        dir: Optional[bytes] = None,
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   277
    ) -> Tuple[int, bytes]:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   278
        fd, name = pycompat.mkstemp(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   279
            suffix=suffix, prefix=prefix, dir=self.join(dir)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   280
        )
20980
6fb4c94ae300 vfs: add "mkstemp()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20862
diff changeset
   281
        dname, fname = util.split(name)
6fb4c94ae300 vfs: add "mkstemp()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20862
diff changeset
   282
        if dir:
6fb4c94ae300 vfs: add "mkstemp()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20862
diff changeset
   283
            return fd, os.path.join(dir, fname)
6fb4c94ae300 vfs: add "mkstemp()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20862
diff changeset
   284
        else:
6fb4c94ae300 vfs: add "mkstemp()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20862
diff changeset
   285
            return fd, fname
6fb4c94ae300 vfs: add "mkstemp()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20862
diff changeset
   286
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   287
    # TODO: This doesn't match osutil.listdir().  stat=False in pure;
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   288
    #  non-optional bool in cext.  'skip' is bool if we trust cext, or bytes
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   289
    #  going by how pure uses it.  Also, cext returns a custom stat structure.
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   290
    #  from cext.osutil.pyi:
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   291
    #
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   292
    #     path: bytes, st: bool, skip: Optional[bool]
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   293
    def readdir(
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   294
        self, path: Optional[bytes] = None, stat=None, skip=None
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   295
    ) -> Any:
32208
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 31644
diff changeset
   296
        return util.listdir(self.join(path), stat, skip)
17747
aad3bce98f76 store: invoke "osutil.listdir()" via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17726
diff changeset
   297
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   298
    def readlock(self, path: bytes) -> bytes:
20090
88d8e568add1 vfs: add "makelock()" and "readlock()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20086
diff changeset
   299
        return util.readlock(self.join(path))
88d8e568add1 vfs: add "makelock()" and "readlock()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20086
diff changeset
   300
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   301
    def rename(self, src: bytes, dst: bytes, checkambig: bool = False) -> None:
29367
4e6e280e238f doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29341
diff changeset
   302
        """Rename from src to dst
4e6e280e238f doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29341
diff changeset
   303
4e6e280e238f doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29341
diff changeset
   304
        checkambig argument is used with util.filestat, and is useful
4e6e280e238f doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29341
diff changeset
   305
        only if destination file is guarded by any lock
4e6e280e238f doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29341
diff changeset
   306
        (e.g. repo.lock or repo.wlock).
33282
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   307
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   308
        To avoid file stat ambiguity forcibly, checkambig=True involves
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   309
        copying ``src`` file, if it is owned by another. Therefore, use
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   310
        checkambig=True only in limited cases (see also issue5418 and
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   311
        issue5584 for detail).
29367
4e6e280e238f doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29341
diff changeset
   312
        """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   313
        self._auditpath(dst, b'w')
32748
ed66ec39933f vfs: create copy at renaming to avoid file stat ambiguity if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 32747
diff changeset
   314
        srcpath = self.join(src)
29203
731ced087a4b vfs: make rename avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29202
diff changeset
   315
        dstpath = self.join(dst)
51881
adbb183c2f27 vfs: simplify the `abstractvfs.rename()` implementation
Matt Harbison <matt_harbison@yahoo.com>
parents: 51880
diff changeset
   316
        oldstat = util.filestat.frompath(dstpath) if checkambig else None
adbb183c2f27 vfs: simplify the `abstractvfs.rename()` implementation
Matt Harbison <matt_harbison@yahoo.com>
parents: 51880
diff changeset
   317
adbb183c2f27 vfs: simplify the `abstractvfs.rename()` implementation
Matt Harbison <matt_harbison@yahoo.com>
parents: 51880
diff changeset
   318
        util.rename(srcpath, dstpath)
adbb183c2f27 vfs: simplify the `abstractvfs.rename()` implementation
Matt Harbison <matt_harbison@yahoo.com>
parents: 51880
diff changeset
   319
29203
731ced087a4b vfs: make rename avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29202
diff changeset
   320
        if oldstat and oldstat.stat:
33281
6af0f023d014 vfs: replace avoiding ambiguity in abstractvfs.rename with _avoidambig
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33280
diff changeset
   321
            _avoidambig(dstpath, oldstat)
18948
2f05fa162316 localrepo: use "vfs.rename()" instead of "util.rename()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18945
diff changeset
   322
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   323
    def readlink(self, path: bytes) -> bytes:
39904
5fe0b880200e py3: convert os.readlink() path to native strings on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39464
diff changeset
   324
        return util.readlink(self.join(path))
18950
647e3b0c8751 localrepo: use "vfs.readlink()" instead of "os.readlink()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18949
diff changeset
   325
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   326
    def removedirs(self, path: Optional[bytes] = None) -> None:
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44566
diff changeset
   327
        """Remove a leaf directory and all empty intermediate ones"""
24693
0d28b0df77ea vfs: add removedirs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24689
diff changeset
   328
        return util.removedirs(self.join(path))
0d28b0df77ea vfs: add removedirs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24689
diff changeset
   329
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   330
    def rmdir(self, path: Optional[bytes] = None) -> None:
39464
3dd34b401bc2 merge: use vfs methods for I/O
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38493
diff changeset
   331
        """Remove an empty directory."""
3dd34b401bc2 merge: use vfs methods for I/O
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38493
diff changeset
   332
        return os.rmdir(self.join(path))
3dd34b401bc2 merge: use vfs methods for I/O
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38493
diff changeset
   333
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   334
    def rmtree(
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   335
        self,
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   336
        path: Optional[bytes] = None,
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   337
        ignore_errors: bool = False,
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   338
        forcibly: bool = False,
51675
be6d8ea6d3d2 typing: add a trivial type hint to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51649
diff changeset
   339
    ) -> None:
24689
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   340
        """Remove a directory tree recursively
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   341
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   342
        If ``forcibly``, this tries to remove READ-ONLY files, too.
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   343
        """
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   344
        if forcibly:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   345
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   346
            def onexc(function, path: bytes, excinfo):
24689
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   347
                if function is not os.remove:
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   348
                    raise
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   349
                # read-only files cannot be unlinked under Windows
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   350
                s = os.stat(path)
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   351
                if (s.st_mode & stat.S_IWRITE) != 0:
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   352
                    raise
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   353
                os.chmod(path, stat.S_IMODE(s.st_mode) | stat.S_IWRITE)
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   354
                os.remove(path)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   355
24689
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   356
        else:
50751
f173c2c23289 vfs: handle shutil.rmtree deprecation of onerror in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 50365
diff changeset
   357
            onexc = None
f173c2c23289 vfs: handle shutil.rmtree deprecation of onerror in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 50365
diff changeset
   358
        try:
f173c2c23289 vfs: handle shutil.rmtree deprecation of onerror in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 50365
diff changeset
   359
            # pytype: disable=wrong-keyword-args
f173c2c23289 vfs: handle shutil.rmtree deprecation of onerror in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 50365
diff changeset
   360
            return shutil.rmtree(
f173c2c23289 vfs: handle shutil.rmtree deprecation of onerror in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 50365
diff changeset
   361
                self.join(path), ignore_errors=ignore_errors, onexc=onexc
f173c2c23289 vfs: handle shutil.rmtree deprecation of onerror in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 50365
diff changeset
   362
            )
f173c2c23289 vfs: handle shutil.rmtree deprecation of onerror in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 50365
diff changeset
   363
            # pytype: enable=wrong-keyword-args
f173c2c23289 vfs: handle shutil.rmtree deprecation of onerror in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 50365
diff changeset
   364
        except TypeError:  # onexc was introduced in Python 3.12
f173c2c23289 vfs: handle shutil.rmtree deprecation of onerror in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 50365
diff changeset
   365
            return shutil.rmtree(
f173c2c23289 vfs: handle shutil.rmtree deprecation of onerror in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 50365
diff changeset
   366
                self.join(path), ignore_errors=ignore_errors, onerror=onexc
f173c2c23289 vfs: handle shutil.rmtree deprecation of onerror in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 50365
diff changeset
   367
            )
24689
ca3a90096c95 vfs: add rmtree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24635
diff changeset
   368
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   369
    def setflags(self, path: bytes, l: bool, x: bool) -> None:
18951
d13916a00b7e localrepo: use "vfs.setflags()" instead of "util.setflags()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18950
diff changeset
   370
        return util.setflags(self.join(path), l, x)
d13916a00b7e localrepo: use "vfs.setflags()" instead of "util.setflags()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18950
diff changeset
   371
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   372
    def stat(self, path: Optional[bytes] = None) -> os.stat_result:
17726
7cb7e17c23b2 store: invoke "os.stat()" for "createmode" initialization via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17725
diff changeset
   373
        return os.stat(self.join(path))
7cb7e17c23b2 store: invoke "os.stat()" for "createmode" initialization via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17725
diff changeset
   374
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   375
    def unlink(self, path: Optional[bytes] = None) -> None:
19895
37c0d93fb166 bookmarks: use "vfs.unlink()" instead of "util.unlink()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19655
diff changeset
   376
        return util.unlink(self.join(path))
37c0d93fb166 bookmarks: use "vfs.unlink()" instead of "util.unlink()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19655
diff changeset
   377
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   378
    def tryunlink(self, path: Optional[bytes] = None) -> bool:
31542
fad440db3565 vfs: add tryunlink method
Ryan McElroy <rmcelroy@fb.com>
parents: 31309
diff changeset
   379
        """Attempt to remove a file, ignoring missing file errors."""
51427
187c5769a629 vfs: have tryunlink tell what it did
Georges Racinet <georges.racinet@octobus.net>
parents: 50926
diff changeset
   380
        return util.tryunlink(self.join(path))
31542
fad440db3565 vfs: add tryunlink method
Ryan McElroy <rmcelroy@fb.com>
parents: 31309
diff changeset
   381
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   382
    def unlinkpath(
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   383
        self,
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   384
        path: Optional[bytes] = None,
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   385
        ignoremissing: bool = False,
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   386
        rmdir: bool = True,
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   387
    ) -> None:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   388
        return util.unlinkpath(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   389
            self.join(path), ignoremissing=ignoremissing, rmdir=rmdir
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   390
        )
21716
90f9be5adade vfs: add unlinkpath to vfs
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21563
diff changeset
   391
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   392
    # TODO: could be Tuple[float, float] too.
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   393
    def utime(
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   394
        self, path: Optional[bytes] = None, t: Optional[Tuple[int, int]] = None
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   395
    ) -> None:
19896
af03279c766a bookmarks: use "vfs.utime()" instead of "os.utime()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19895
diff changeset
   396
        return os.utime(self.join(path), t)
af03279c766a bookmarks: use "vfs.utime()" instead of "os.utime()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19895
diff changeset
   397
51887
ad83e4f9b40e typing: correct pytype mistakes in `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51886
diff changeset
   398
    def walk(
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   399
        self, path: Optional[bytes] = None, onerror: Optional[_OnErrorFn] = None
51887
ad83e4f9b40e typing: correct pytype mistakes in `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51886
diff changeset
   400
    ) -> Iterator[Tuple[bytes, List[bytes], List[bytes]]]:
51882
e59e1d8d29d2 vfs: do minor copyediting on comments and doc strings
Matt Harbison <matt_harbison@yahoo.com>
parents: 51881
diff changeset
   401
        """Yield (dirpath, dirs, files) tuple for each directory under path
24725
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   402
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   403
        ``dirpath`` is relative one from the root of this vfs. This
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   404
        uses ``os.sep`` as path separator, even you specify POSIX
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   405
        style ``path``.
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   406
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   407
        "The root of this vfs" is represented as empty ``dirpath``.
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   408
        """
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   409
        root = os.path.normpath(self.join(None))
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   410
        # when dirpath == root, dirpath[prefixlen:] becomes empty
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   411
        # because len(dirpath) < prefixlen.
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   412
        prefixlen = len(pathutil.normasprefix(root))
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   413
        for dirpath, dirs, files in os.walk(self.join(path), onerror=onerror):
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   414
            yield (dirpath[prefixlen:], dirs, files)
ee751d47cf2c vfs: add walk
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24723
diff changeset
   415
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   416
    @contextlib.contextmanager
51887
ad83e4f9b40e typing: correct pytype mistakes in `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51886
diff changeset
   417
    def backgroundclosing(
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   418
        self, ui: uimod.ui, expectedcount: int = -1
51887
ad83e4f9b40e typing: correct pytype mistakes in `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51886
diff changeset
   419
    ) -> Iterator[Optional[backgroundfilecloser]]:
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   420
        """Allow files to be closed asynchronously.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   421
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   422
        When this context manager is active, ``backgroundclose`` can be passed
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   423
        to ``__call__``/``open`` to result in the file possibly being closed
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   424
        asynchronously, on a background thread.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   425
        """
35426
60f2a215faa7 workers: don't use backgroundfilecloser in threads
Wojciech Lis <wlis@fb.com>
parents: 34645
diff changeset
   426
        # Sharing backgroundfilecloser between threads is complex and using
60f2a215faa7 workers: don't use backgroundfilecloser in threads
Wojciech Lis <wlis@fb.com>
parents: 34645
diff changeset
   427
        # multiple instances puts us at risk of running out of file descriptors
60f2a215faa7 workers: don't use backgroundfilecloser in threads
Wojciech Lis <wlis@fb.com>
parents: 34645
diff changeset
   428
        # only allow to use backgroundfilecloser when in main thread.
51879
1edac12af730 vfs: modernize the detection of the main thread
Matt Harbison <matt_harbison@yahoo.com>
parents: 51859
diff changeset
   429
        if threading.current_thread() is not threading.main_thread():
35426
60f2a215faa7 workers: don't use backgroundfilecloser in threads
Wojciech Lis <wlis@fb.com>
parents: 34645
diff changeset
   430
            yield
60f2a215faa7 workers: don't use backgroundfilecloser in threads
Wojciech Lis <wlis@fb.com>
parents: 34645
diff changeset
   431
            return
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   432
        vfs = getattr(self, 'vfs', self)
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   433
        if getattr(vfs, '_backgroundfilecloser', None):
29389
98e8313dcd9e i18n: translate abort messages
liscju <piotr.listkiewicz@gmail.com>
parents: 29373
diff changeset
   434
            raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   435
                _(b'can only have 1 active background file closer')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   436
            )
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   437
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   438
        with backgroundfilecloser(ui, expectedcount=expectedcount) as bfc:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   439
            try:
43482
fc19f8ab8199 vfs: suppress some pytype errors around us using a private attribute
Augie Fackler <augie@google.com>
parents: 43468
diff changeset
   440
                vfs._backgroundfilecloser = (
fc19f8ab8199 vfs: suppress some pytype errors around us using a private attribute
Augie Fackler <augie@google.com>
parents: 43468
diff changeset
   441
                    bfc  # pytype: disable=attribute-error
fc19f8ab8199 vfs: suppress some pytype errors around us using a private attribute
Augie Fackler <augie@google.com>
parents: 43468
diff changeset
   442
                )
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   443
                yield bfc
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   444
            finally:
43482
fc19f8ab8199 vfs: suppress some pytype errors around us using a private attribute
Augie Fackler <augie@google.com>
parents: 43468
diff changeset
   445
                vfs._backgroundfilecloser = (
fc19f8ab8199 vfs: suppress some pytype errors around us using a private attribute
Augie Fackler <augie@google.com>
parents: 43468
diff changeset
   446
                    None  # pytype: disable=attribute-error
fc19f8ab8199 vfs: suppress some pytype errors around us using a private attribute
Augie Fackler <augie@google.com>
parents: 43468
diff changeset
   447
                )
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   448
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   449
    def register_file(self, path: bytes) -> None:
47443
9ab54aa56982 vfs: add a `register_file` method on the vfs class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47178
diff changeset
   450
        """generic hook point to lets fncache steer its stew"""
9ab54aa56982 vfs: add a `register_file` method on the vfs class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47178
diff changeset
   451
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   452
17649
f65c6a5f256c scmutil: rename classes from "opener" to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17561
diff changeset
   453
class vfs(abstractvfs):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44566
diff changeset
   454
    """Operate files relative to a base directory
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   455
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   456
    This class is used to hide the details of COW semantics and
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   457
    remote file access from higher level code.
33649
377e8ddaebef pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents: 33435
diff changeset
   458
377e8ddaebef pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents: 33435
diff changeset
   459
    'cacheaudited' should be enabled only if (a) vfs object is short-lived, or
377e8ddaebef pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents: 33435
diff changeset
   460
    (b) the base directory is managed by hg and considered sort-of append-only.
377e8ddaebef pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents: 33435
diff changeset
   461
    See pathutil.pathauditor() for details.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44566
diff changeset
   462
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   463
51890
992fcf6b2473 typing: add a handful more annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51889
diff changeset
   464
    audit: Union[pathutil.pathauditor, Callable[[bytes, Optional[bytes]], Any]]
992fcf6b2473 typing: add a handful more annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51889
diff changeset
   465
    base: bytes
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   466
    createmode: Optional[int]
51890
992fcf6b2473 typing: add a handful more annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51889
diff changeset
   467
    options: Dict[bytes, Any]
992fcf6b2473 typing: add a handful more annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51889
diff changeset
   468
    _audit: bool
992fcf6b2473 typing: add a handful more annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51889
diff changeset
   469
    _trustnlink: Optional[bool]
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   470
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   471
    def __init__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   472
        self,
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   473
        base: bytes,
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   474
        audit: bool = True,
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   475
        cacheaudited: bool = False,
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   476
        expandpath: bool = False,
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   477
        realpath: bool = False,
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   478
    ) -> None:
18945
e75b72fffdfe vfs: split "expand" into "realpath"/"expandpath" to apply each separately
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18900
diff changeset
   479
        if expandpath:
e75b72fffdfe vfs: split "expand" into "realpath"/"expandpath" to apply each separately
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18900
diff changeset
   480
            base = util.expandpath(base)
e75b72fffdfe vfs: split "expand" into "realpath"/"expandpath" to apply each separately
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18900
diff changeset
   481
        if realpath:
e75b72fffdfe vfs: split "expand" into "realpath"/"expandpath" to apply each separately
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18900
diff changeset
   482
            base = os.path.realpath(base)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   483
        self.base = base
33259
6fb5c5096887 vfs: drop the 'mustaudit' API
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33257
diff changeset
   484
        self._audit = audit
6fb5c5096887 vfs: drop the 'mustaudit' API
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33257
diff changeset
   485
        if audit:
33649
377e8ddaebef pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents: 33435
diff changeset
   486
            self.audit = pathutil.pathauditor(self.base, cached=cacheaudited)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   487
        else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   488
            self.audit = lambda path, mode=None: True
33259
6fb5c5096887 vfs: drop the 'mustaudit' API
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33257
diff changeset
   489
        self.createmode = None
6fb5c5096887 vfs: drop the 'mustaudit' API
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33257
diff changeset
   490
        self._trustnlink = None
43025
3518da504303 vfs: give all vfs an options attribute by default
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 41095
diff changeset
   491
        self.options = {}
17554
5450c8ad9d98 scmutil: turn opener._audit into a property, mustaudit
Bryan O'Sullivan <bryano@fb.com>
parents: 17248
diff changeset
   492
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   493
    @util.propertycache
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   494
    def _cansymlink(self) -> bool:
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   495
        return util.checklink(self.base)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   496
18192
f9a89bdd64a6 scmutil: don't try to match modes on filesystems without modes (issue3740)
Matt Mackall <mpm@selenic.com>
parents: 17850
diff changeset
   497
    @util.propertycache
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   498
    def _chmod(self) -> bool:
18192
f9a89bdd64a6 scmutil: don't try to match modes on filesystems without modes (issue3740)
Matt Mackall <mpm@selenic.com>
parents: 17850
diff changeset
   499
        return util.checkexec(self.base)
f9a89bdd64a6 scmutil: don't try to match modes on filesystems without modes (issue3740)
Matt Mackall <mpm@selenic.com>
parents: 17850
diff changeset
   500
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   501
    def _fixfilemode(self, name: bytes) -> None:
18192
f9a89bdd64a6 scmutil: don't try to match modes on filesystems without modes (issue3740)
Matt Mackall <mpm@selenic.com>
parents: 17850
diff changeset
   502
        if self.createmode is None or not self._chmod:
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   503
            return
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25629
diff changeset
   504
        os.chmod(name, self.createmode & 0o666)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   505
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   506
    def _auditpath(self, path: bytes, mode: bytes) -> None:
40754
34f15db81cf0 vfs: extract the audit path logic into a submethod
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   507
        if self._audit:
41090
c8006a25b845 vfs: makes all audited path relative
Boris Feld <boris.feld@octobus.net>
parents: 40989
diff changeset
   508
            if os.path.isabs(path) and path.startswith(self.base):
c8006a25b845 vfs: makes all audited path relative
Boris Feld <boris.feld@octobus.net>
parents: 40989
diff changeset
   509
                path = os.path.relpath(path, self.base)
40754
34f15db81cf0 vfs: extract the audit path logic into a submethod
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   510
            r = util.checkosfilename(path)
34f15db81cf0 vfs: extract the audit path logic into a submethod
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   511
            if r:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   512
                raise error.Abort(b"%s: %r" % (r, path))
40754
34f15db81cf0 vfs: extract the audit path logic into a submethod
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   513
            self.audit(path, mode=mode)
34f15db81cf0 vfs: extract the audit path logic into a submethod
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   514
49909
b7cf91ef03ba merge: skip syntactic path checks in [_checkunknownfile]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49574
diff changeset
   515
    def isfileorlink_checkdir(
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   516
        self,
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   517
        dircache: MutableMapping[bytes, bool],
51889
22e1924e9402 typing: make `vfs.isfileorlink_checkdir()` path arg required
Matt Harbison <matt_harbison@yahoo.com>
parents: 51888
diff changeset
   518
        path: bytes,
49909
b7cf91ef03ba merge: skip syntactic path checks in [_checkunknownfile]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49574
diff changeset
   519
    ) -> bool:
b7cf91ef03ba merge: skip syntactic path checks in [_checkunknownfile]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49574
diff changeset
   520
        """return True if the path is a regular file or a symlink and
b7cf91ef03ba merge: skip syntactic path checks in [_checkunknownfile]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49574
diff changeset
   521
        the directories along the path are "normal", that is
49912
bc83ebe07bf0 pathauditor: make _checkfs_exists a static method
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49909
diff changeset
   522
        not symlinks or nested hg repositories.
bc83ebe07bf0 pathauditor: make _checkfs_exists a static method
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49909
diff changeset
   523
bc83ebe07bf0 pathauditor: make _checkfs_exists a static method
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49909
diff changeset
   524
        Ignores the `_audit` setting, and checks the directories regardless.
bc83ebe07bf0 pathauditor: make _checkfs_exists a static method
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49909
diff changeset
   525
        `dircache` is used to cache the directory checks.
bc83ebe07bf0 pathauditor: make _checkfs_exists a static method
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49909
diff changeset
   526
        """
49909
b7cf91ef03ba merge: skip syntactic path checks in [_checkunknownfile]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49574
diff changeset
   527
        try:
b7cf91ef03ba merge: skip syntactic path checks in [_checkunknownfile]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49574
diff changeset
   528
            for prefix in pathutil.finddirs_rev_noroot(util.localpath(path)):
b7cf91ef03ba merge: skip syntactic path checks in [_checkunknownfile]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49574
diff changeset
   529
                if prefix in dircache:
b7cf91ef03ba merge: skip syntactic path checks in [_checkunknownfile]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49574
diff changeset
   530
                    res = dircache[prefix]
b7cf91ef03ba merge: skip syntactic path checks in [_checkunknownfile]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49574
diff changeset
   531
                else:
49912
bc83ebe07bf0 pathauditor: make _checkfs_exists a static method
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49909
diff changeset
   532
                    res = pathutil.pathauditor._checkfs_exists(
bc83ebe07bf0 pathauditor: make _checkfs_exists a static method
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49909
diff changeset
   533
                        self.base, prefix, path
bc83ebe07bf0 pathauditor: make _checkfs_exists a static method
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49909
diff changeset
   534
                    )
49909
b7cf91ef03ba merge: skip syntactic path checks in [_checkunknownfile]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49574
diff changeset
   535
                    dircache[prefix] = res
b7cf91ef03ba merge: skip syntactic path checks in [_checkunknownfile]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49574
diff changeset
   536
                if not res:
b7cf91ef03ba merge: skip syntactic path checks in [_checkunknownfile]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49574
diff changeset
   537
                    return False
b7cf91ef03ba merge: skip syntactic path checks in [_checkunknownfile]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49574
diff changeset
   538
        except (OSError, error.Abort):
b7cf91ef03ba merge: skip syntactic path checks in [_checkunknownfile]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49574
diff changeset
   539
            return False
b7cf91ef03ba merge: skip syntactic path checks in [_checkunknownfile]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49574
diff changeset
   540
        return self.isfileorlink(path)
b7cf91ef03ba merge: skip syntactic path checks in [_checkunknownfile]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49574
diff changeset
   541
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   542
    def __call__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   543
        self,
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   544
        path: bytes,
49574
2506c3ac73f4 vfs: make the default opener mode binary
Matt Harbison <matt_harbison@yahoo.com>
parents: 49573
diff changeset
   545
        mode: bytes = b"rb",
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   546
        atomictemp: bool = False,
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   547
        notindexed: bool = False,
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   548
        backgroundclose: bool = False,
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   549
        checkambig: bool = False,
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   550
        auditpath: bool = True,
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   551
        makeparentdirs: bool = True,
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   552
    ) -> Any:  # TODO: should be BinaryIO if util.atomictempfile can be coersed
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44566
diff changeset
   553
        """Open ``path`` file, which is relative to vfs root.
23370
46265d0f0c7b vfs: add "notindexed" argument to invoke "ensuredir" with it in write mode
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23368
diff changeset
   554
40796
03bca908d9fb vfs: add option to not create parent directories implicitly
Yuya Nishihara <yuya@tcha.org>
parents: 40754
diff changeset
   555
        By default, parent directories are created as needed. Newly created
03bca908d9fb vfs: add option to not create parent directories implicitly
Yuya Nishihara <yuya@tcha.org>
parents: 40754
diff changeset
   556
        directories are marked as "not to be indexed by the content indexing
03bca908d9fb vfs: add option to not create parent directories implicitly
Yuya Nishihara <yuya@tcha.org>
parents: 40754
diff changeset
   557
        service", if ``notindexed`` is specified for "write" mode access.
03bca908d9fb vfs: add option to not create parent directories implicitly
Yuya Nishihara <yuya@tcha.org>
parents: 40754
diff changeset
   558
        Set ``makeparentdirs=False`` to not create directories implicitly.
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   559
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   560
        If ``backgroundclose`` is passed, the file may be closed asynchronously.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   561
        It can only be used if the ``self.backgroundclosing()`` context manager
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   562
        is active. This should only be specified if the following criteria hold:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   563
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   564
        1. There is a potential for writing thousands of files. Unless you
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   565
           are writing thousands of files, the performance benefits of
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   566
           asynchronously closing files is not realized.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   567
        2. Files are opened exactly once for the ``backgroundclosing``
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   568
           active duration and are therefore free of race conditions between
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   569
           closing a file on a background thread and reopening it. (If the
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   570
           file were opened multiple times, there could be unflushed data
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   571
           because the original file handle hasn't been flushed/closed yet.)
29202
76f1ea360c7e vfs: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29119
diff changeset
   572
44566
77d48738b8e0 vfs: fix typo in comment (remove extra "l")
Kyle Lippincott <spectral@google.com>
parents: 43506
diff changeset
   573
        ``checkambig`` argument is passed to atomictempfile (valid
29367
4e6e280e238f doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29341
diff changeset
   574
        only for writing), and is useful only if target file is
4e6e280e238f doc: describe detail about checkambig optional argument
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29341
diff changeset
   575
        guarded by any lock (e.g. repo.lock or repo.wlock).
33282
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   576
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   577
        To avoid file stat ambiguity forcibly, checkambig=True involves
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   578
        copying ``path`` file opened in "append" mode (e.g. for
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   579
        truncation), if it is owned by another. Therefore, use
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   580
        combination of append mode and checkambig=True only in limited
d1db7af81548 vfs: add explanation about cost of checkambig=True in corner case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33281
diff changeset
   581
        cases (see also issue5418 and issue5584 for detail).
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44566
diff changeset
   582
        """
33257
15e9cbe6ae49 vfs: simplify path audit disabling in stream clone
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33234
diff changeset
   583
        if auditpath:
40754
34f15db81cf0 vfs: extract the audit path logic into a submethod
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   584
            self._auditpath(path, mode)
16199
8181bd808dc5 scmutil: add join method to opener to construct path relative to base
Idan Kamara <idankk86@gmail.com>
parents: 16198
diff changeset
   585
        f = self.join(path)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   586
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   587
        if b"b" not in mode:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   588
            mode += b"b"  # for that other OS
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   589
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   590
        nlink = -1
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   591
        if mode not in (b'r', b'rb'):
17937
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   592
            dirname, basename = util.split(f)
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   593
            # If basename is empty, then the path is malformed because it points
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   594
            # to a directory. Let the posixfile() call below raise IOError.
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   595
            if basename:
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   596
                if atomictemp:
40796
03bca908d9fb vfs: add option to not create parent directories implicitly
Yuya Nishihara <yuya@tcha.org>
parents: 40754
diff changeset
   597
                    if makeparentdirs:
03bca908d9fb vfs: add option to not create parent directories implicitly
Yuya Nishihara <yuya@tcha.org>
parents: 40754
diff changeset
   598
                        util.makedirs(dirname, self.createmode, notindexed)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   599
                    return util.atomictempfile(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   600
                        f, mode, self.createmode, checkambig=checkambig
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   601
                    )
17937
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   602
                try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   603
                    if b'w' in mode:
17937
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   604
                        util.unlink(f)
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   605
                        nlink = 0
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   606
                    else:
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   607
                        # nlinks() may behave differently for files on Windows
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   608
                        # shares if the file is open.
27706
22e362da27cf scmutil: use context managers for file handles
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27651
diff changeset
   609
                        with util.posixfile(f):
22e362da27cf scmutil: use context managers for file handles
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27651
diff changeset
   610
                            nlink = util.nlinks(f)
22e362da27cf scmutil: use context managers for file handles
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27651
diff changeset
   611
                            if nlink < 1:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   612
                                nlink = 2  # force mktempcopy (issue1922)
49306
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 48946
diff changeset
   613
                except FileNotFoundError:
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   614
                    nlink = 0
40796
03bca908d9fb vfs: add option to not create parent directories implicitly
Yuya Nishihara <yuya@tcha.org>
parents: 40754
diff changeset
   615
                    if makeparentdirs:
03bca908d9fb vfs: add option to not create parent directories implicitly
Yuya Nishihara <yuya@tcha.org>
parents: 40754
diff changeset
   616
                        util.makedirs(dirname, self.createmode, notindexed)
17937
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   617
                if nlink > 0:
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   618
                    if self._trustnlink is None:
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   619
                        self._trustnlink = nlink > 1 or util.checknlink(f)
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   620
                    if nlink > 1 or not self._trustnlink:
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   621
                        util.rename(util.mktempcopy(f), f)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   622
        fp = util.posixfile(f, mode)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   623
        if nlink == 0:
17763
13070de77c86 vfs: backout fchmod change from 76b73ce0ffac
Matt Mackall <mpm@selenic.com>
parents: 17752
diff changeset
   624
            self._fixfilemode(f)
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   625
29996
9766d88c2465 vfs: use checkambigatclosing in checkambig=True but atomictemp=False case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29995
diff changeset
   626
        if checkambig:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   627
            if mode in (b'r', b'rb'):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   628
                raise error.Abort(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   629
                    _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   630
                        b'implementation error: mode %s is not'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   631
                        b' valid for checkambig=True'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   632
                    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   633
                    % mode
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   634
                )
29996
9766d88c2465 vfs: use checkambigatclosing in checkambig=True but atomictemp=False case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29995
diff changeset
   635
            fp = checkambigatclosing(fp)
9766d88c2465 vfs: use checkambigatclosing in checkambig=True but atomictemp=False case
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29995
diff changeset
   636
51879
1edac12af730 vfs: modernize the detection of the main thread
Matt Harbison <matt_harbison@yahoo.com>
parents: 51859
diff changeset
   637
        if (
1edac12af730 vfs: modernize the detection of the main thread
Matt Harbison <matt_harbison@yahoo.com>
parents: 51859
diff changeset
   638
            backgroundclose
1edac12af730 vfs: modernize the detection of the main thread
Matt Harbison <matt_harbison@yahoo.com>
parents: 51859
diff changeset
   639
            and threading.current_thread() is threading.main_thread()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   640
        ):
43484
da9ecbb10368 vfs: more attribute suppressions
Augie Fackler <augie@google.com>
parents: 43482
diff changeset
   641
            if (
da9ecbb10368 vfs: more attribute suppressions
Augie Fackler <augie@google.com>
parents: 43482
diff changeset
   642
                not self._backgroundfilecloser  # pytype: disable=attribute-error
da9ecbb10368 vfs: more attribute suppressions
Augie Fackler <augie@google.com>
parents: 43482
diff changeset
   643
            ):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   644
                raise error.Abort(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   645
                    _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   646
                        b'backgroundclose can only be used when a '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   647
                        b'backgroundclosing context manager is active'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   648
                    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   649
                )
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   650
43484
da9ecbb10368 vfs: more attribute suppressions
Augie Fackler <augie@google.com>
parents: 43482
diff changeset
   651
            fp = delayclosedfile(
da9ecbb10368 vfs: more attribute suppressions
Augie Fackler <augie@google.com>
parents: 43482
diff changeset
   652
                fp,
da9ecbb10368 vfs: more attribute suppressions
Augie Fackler <augie@google.com>
parents: 43482
diff changeset
   653
                self._backgroundfilecloser,  # pytype: disable=attribute-error
da9ecbb10368 vfs: more attribute suppressions
Augie Fackler <augie@google.com>
parents: 43482
diff changeset
   654
            )
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   655
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   656
        return fp
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   657
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   658
    def symlink(self, src: bytes, dst: bytes) -> None:
18327
4aecdb91443c scmutil: simplify vfs.audit - drop wrapped vfs.auditor
Mads Kiilerich <mads@kiilerich.com>
parents: 18316
diff changeset
   659
        self.audit(dst)
16199
8181bd808dc5 scmutil: add join method to opener to construct path relative to base
Idan Kamara <idankk86@gmail.com>
parents: 16198
diff changeset
   660
        linkname = self.join(dst)
31549
18b9d9b95719 vfs: use tryunlink
Ryan McElroy <rmcelroy@fb.com>
parents: 31542
diff changeset
   661
        util.tryunlink(linkname)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   662
29017
07be86828e79 util: fix race in makedirs()
Adam Simpkins <simpkins@fb.com>
parents: 28819
diff changeset
   663
        util.makedirs(os.path.dirname(linkname), self.createmode)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   664
14261
e3649bcca3f6 opener: rename _can_symlink to _cansymlink
Adrian Buehlmann <adrian@cadifra.com>
parents: 14236
diff changeset
   665
        if self._cansymlink:
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   666
            try:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   667
                os.symlink(src, linkname)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25658
diff changeset
   668
            except OSError as err:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   669
                raise OSError(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   670
                    err.errno,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   671
                    _(b'could not symlink to %r: %s')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   672
                    % (src, encoding.strtolocal(err.strerror)),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   673
                    linkname,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   674
                )
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   675
        else:
17768
9837cafc25b1 vfs: use self.write to write symlink placeholders
Matt Mackall <mpm@selenic.com>
parents: 17763
diff changeset
   676
            self.write(dst, src)
13971
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   677
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   678
    def join(self, path: Optional[bytes], *insidef: bytes) -> bytes:
17161
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   679
        if path:
47809
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   680
            parts = [self.base, path]
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   681
            parts.extend(insidef)
98c3fa6a3ac2 vfs: always use / as file separator (issue6546)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   682
            return self._join(*parts)
17681
a41fd730f230 scmutil: backout 83785bb56062 (issue3643)
Matt Mackall <mpm@selenic.com>
parents: 17675
diff changeset
   683
        else:
a41fd730f230 scmutil: backout 83785bb56062 (issue3643)
Matt Mackall <mpm@selenic.com>
parents: 17675
diff changeset
   684
            return self.base
16199
8181bd808dc5 scmutil: add join method to opener to construct path relative to base
Idan Kamara <idankk86@gmail.com>
parents: 16198
diff changeset
   685
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   686
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   687
opener: Type[vfs] = vfs
17649
f65c6a5f256c scmutil: rename classes from "opener" to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17561
diff changeset
   688
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   689
51880
f79f98733a5b vfs: use @abstractmethod instead of homebrewing abstract methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 51879
diff changeset
   690
class proxyvfs(abstractvfs, abc.ABC):
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   691
    def __init__(self, vfs: vfs) -> None:
17845
408ded42c5ec scmutil: abstract out mustaudit delegation
Bryan O'Sullivan <bryano@fb.com>
parents: 17821
diff changeset
   692
        self.vfs = vfs
408ded42c5ec scmutil: abstract out mustaudit delegation
Bryan O'Sullivan <bryano@fb.com>
parents: 17821
diff changeset
   693
50365
d1d458fb96a5 vfsproxy: inherit the `createmode` attribute too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49912
diff changeset
   694
    @property
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   695
    def createmode(self) -> Optional[int]:
50365
d1d458fb96a5 vfsproxy: inherit the `createmode` attribute too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49912
diff changeset
   696
        return self.vfs.createmode
d1d458fb96a5 vfsproxy: inherit the `createmode` attribute too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49912
diff changeset
   697
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   698
    def _auditpath(self, path: bytes, mode: bytes) -> None:
41094
adee334d94cd vfs: handle _auditpath in proxyvfs
Boris Feld <boris.feld@octobus.net>
parents: 41093
diff changeset
   699
        return self.vfs._auditpath(path, mode)
adee334d94cd vfs: handle _auditpath in proxyvfs
Boris Feld <boris.feld@octobus.net>
parents: 41093
diff changeset
   700
27879
52a4ad62b006 cleanup: use modern @property/@foo.setter property specification
Augie Fackler <augie@google.com>
parents: 27851
diff changeset
   701
    @property
51890
992fcf6b2473 typing: add a handful more annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51889
diff changeset
   702
    def options(self) -> Dict[bytes, Any]:
29714
69109052d9ac auditvfs: forward options property from nested vfs
Augie Fackler <augie@google.com>
parents: 29417
diff changeset
   703
        return self.vfs.options
69109052d9ac auditvfs: forward options property from nested vfs
Augie Fackler <augie@google.com>
parents: 29417
diff changeset
   704
69109052d9ac auditvfs: forward options property from nested vfs
Augie Fackler <augie@google.com>
parents: 29417
diff changeset
   705
    @options.setter
51890
992fcf6b2473 typing: add a handful more annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51889
diff changeset
   706
    def options(self, value: Dict[bytes, Any]) -> None:
29714
69109052d9ac auditvfs: forward options property from nested vfs
Augie Fackler <augie@google.com>
parents: 29417
diff changeset
   707
        self.vfs.options = value
69109052d9ac auditvfs: forward options property from nested vfs
Augie Fackler <augie@google.com>
parents: 29417
diff changeset
   708
51590
b5500857e173 proxy-vfs: also proxy the `audit` attribute
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51427
diff changeset
   709
    @property
b5500857e173 proxy-vfs: also proxy the `audit` attribute
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51427
diff changeset
   710
    def audit(self):
b5500857e173 proxy-vfs: also proxy the `audit` attribute
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51427
diff changeset
   711
        return self.vfs.audit
b5500857e173 proxy-vfs: also proxy the `audit` attribute
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51427
diff changeset
   712
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   713
41093
6498f0e03526 vfs: fix proxyvfs inheritance
Boris Feld <boris.feld@octobus.net>
parents: 41092
diff changeset
   714
class filtervfs(proxyvfs, abstractvfs):
17649
f65c6a5f256c scmutil: rename classes from "opener" to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17561
diff changeset
   715
    '''Wrapper vfs for filtering filenames with a function.'''
14090
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
   716
51890
992fcf6b2473 typing: add a handful more annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51889
diff changeset
   717
    def __init__(self, vfs: vfs, filter: Callable[[bytes], bytes]) -> None:
33412
a42369e04aee vfs: rename auditvfs to proxyvfs
Yuya Nishihara <yuya@tcha.org>
parents: 33282
diff changeset
   718
        proxyvfs.__init__(self, vfs)
14090
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
   719
        self._filter = filter
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
   720
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   721
    # TODO: The return type should be BinaryIO
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   722
    def __call__(self, path: bytes, *args, **kwargs) -> Any:
17846
f42cf30873dc scmutil: add mustaudit delegation to filtervfs (issue3673)
Bryan O'Sullivan <bryano@fb.com>
parents: 17845
diff changeset
   723
        return self.vfs(self._filter(path), *args, **kwargs)
14090
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
   724
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   725
    def join(self, path: Optional[bytes], *insidef: bytes) -> bytes:
17725
ffd589d4b785 vfs: define "join()" in each classes derived from "abstractvfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17723
diff changeset
   726
        if path:
24628
a0b47885a1c5 vfs: make it possible to pass multiple path elements to join
Matt Harbison <matt_harbison@yahoo.com>
parents: 24582
diff changeset
   727
            return self.vfs.join(self._filter(self.vfs.reljoin(path, *insidef)))
17725
ffd589d4b785 vfs: define "join()" in each classes derived from "abstractvfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17723
diff changeset
   728
        else:
17846
f42cf30873dc scmutil: add mustaudit delegation to filtervfs (issue3673)
Bryan O'Sullivan <bryano@fb.com>
parents: 17845
diff changeset
   729
            return self.vfs.join(path)
17725
ffd589d4b785 vfs: define "join()" in each classes derived from "abstractvfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17723
diff changeset
   730
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   731
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   732
filteropener: Type[filtervfs] = filtervfs
17649
f65c6a5f256c scmutil: rename classes from "opener" to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17561
diff changeset
   733
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   734
41093
6498f0e03526 vfs: fix proxyvfs inheritance
Boris Feld <boris.feld@octobus.net>
parents: 41092
diff changeset
   735
class readonlyvfs(proxyvfs):
18213
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   736
    '''Wrapper vfs preventing any writing.'''
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   737
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   738
    def __init__(self, vfs: vfs) -> None:
33412
a42369e04aee vfs: rename auditvfs to proxyvfs
Yuya Nishihara <yuya@tcha.org>
parents: 33282
diff changeset
   739
        proxyvfs.__init__(self, vfs)
18213
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   740
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   741
    # TODO: The return type should be BinaryIO
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   742
    def __call__(self, path: bytes, mode: bytes = b'rb', *args, **kw) -> Any:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   743
        if mode not in (b'r', b'rb'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   744
            raise error.Abort(_(b'this vfs is read only'))
18213
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   745
        return self.vfs(path, mode, *args, **kw)
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   746
49573
cc9a60050a07 typing: add basic type hints to vfs.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49306
diff changeset
   747
    def join(self, path: Optional[bytes], *insidef: bytes) -> bytes:
26156
a112fffdb632 scmutil.readonlyvfs: implement join
Siddharth Agarwal <sid0@fb.com>
parents: 26098
diff changeset
   748
        return self.vfs.join(path, *insidef)
18213
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   749
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   750
51880
f79f98733a5b vfs: use @abstractmethod instead of homebrewing abstract methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 51879
diff changeset
   751
class closewrapbase(abc.ABC):
29994
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   752
    """Base class of wrapper, which hooks closing
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   753
51882
e59e1d8d29d2 vfs: do minor copyediting on comments and doc strings
Matt Harbison <matt_harbison@yahoo.com>
parents: 51881
diff changeset
   754
    Do not instantiate outside the vfs layer.
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   755
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   756
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   757
    def __init__(self, fh) -> None:
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43484
diff changeset
   758
        object.__setattr__(self, '_origfh', fh)
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   759
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   760
    def __getattr__(self, attr: str) -> Any:
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   761
        return getattr(self._origfh, attr)
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   762
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   763
    def __setattr__(self, attr: str, value: Any) -> None:
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   764
        return setattr(self._origfh, attr, value)
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   765
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   766
    def __delattr__(self, attr: str) -> None:
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   767
        return delattr(self._origfh, attr)
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   768
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   769
    def __enter__(self: _Tclosewrapbase) -> _Tclosewrapbase:
40939
8d9f366b7f19 vfs: ensure closewrapbase fh doesn't escape by entering context manager
Matt Harbison <matt_harbison@yahoo.com>
parents: 39904
diff changeset
   770
        self._origfh.__enter__()
8d9f366b7f19 vfs: ensure closewrapbase fh doesn't escape by entering context manager
Matt Harbison <matt_harbison@yahoo.com>
parents: 39904
diff changeset
   771
        return self
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   772
51880
f79f98733a5b vfs: use @abstractmethod instead of homebrewing abstract methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 51879
diff changeset
   773
    @abc.abstractmethod
51887
ad83e4f9b40e typing: correct pytype mistakes in `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51886
diff changeset
   774
    def __exit__(self, exc_type, exc_value, exc_tb) -> None:
51880
f79f98733a5b vfs: use @abstractmethod instead of homebrewing abstract methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 51879
diff changeset
   775
        ...
29994
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   776
51880
f79f98733a5b vfs: use @abstractmethod instead of homebrewing abstract methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 51879
diff changeset
   777
    @abc.abstractmethod
51887
ad83e4f9b40e typing: correct pytype mistakes in `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51886
diff changeset
   778
    def close(self) -> None:
51880
f79f98733a5b vfs: use @abstractmethod instead of homebrewing abstract methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 51879
diff changeset
   779
        ...
29994
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   780
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   781
29994
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   782
class delayclosedfile(closewrapbase):
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   783
    """Proxy for a file object whose close is delayed.
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   784
51882
e59e1d8d29d2 vfs: do minor copyediting on comments and doc strings
Matt Harbison <matt_harbison@yahoo.com>
parents: 51881
diff changeset
   785
    Do not instantiate outside the vfs layer.
29994
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   786
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   787
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   788
    def __init__(self, fh, closer) -> None:
29994
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   789
        super(delayclosedfile, self).__init__(fh)
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43484
diff changeset
   790
        object.__setattr__(self, '_closer', closer)
29994
0c40e64d6154 scmutil: factor out common logic of delayclosedfile to reuse it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29802
diff changeset
   791
51887
ad83e4f9b40e typing: correct pytype mistakes in `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51886
diff changeset
   792
    def __exit__(self, exc_type, exc_value, exc_tb) -> None:
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   793
        self._closer.close(self._origfh)
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   794
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   795
    def close(self) -> None:
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   796
        self._closer.close(self._origfh)
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   797
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   798
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   799
class backgroundfilecloser:
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   800
    """Coordinates background closing of file handles on multiple threads."""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   801
51888
fa9e8a6521c1 typing: manually add type annotations to `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51887
diff changeset
   802
    def __init__(self, ui: uimod.ui, expectedcount: int = -1) -> None:
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   803
        self._running = False
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   804
        self._entered = False
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   805
        self._threads = []
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   806
        self._threadexception = None
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   807
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   808
        # Only Windows/NTFS has slow file closing. So only enable by default
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   809
        # on that platform. But allow to be enabled elsewhere for testing.
34645
75979c8d4572 codemod: use pycompat.iswindows
Jun Wu <quark@fb.com>
parents: 34022
diff changeset
   810
        defaultenabled = pycompat.iswindows
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   811
        enabled = ui.configbool(b'worker', b'backgroundclose', defaultenabled)
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   812
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   813
        if not enabled:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   814
            return
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   815
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   816
        # There is overhead to starting and stopping the background threads.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   817
        # Don't do background processing unless the file count is large enough
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   818
        # to justify it.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   819
        minfilecount = ui.configint(b'worker', b'backgroundcloseminfilecount')
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   820
        # FUTURE dynamically start background threads after minfilecount closes.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   821
        # (We don't currently have any callers that don't know their file count)
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   822
        if expectedcount > 0 and expectedcount < minfilecount:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   823
            return
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   824
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   825
        maxqueue = ui.configint(b'worker', b'backgroundclosemaxqueue')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   826
        threadcount = ui.configint(b'worker', b'backgroundclosethreadcount')
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   827
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   828
        ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   829
            b'starting %d threads for background file closing\n' % threadcount
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   830
        )
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   831
37844
8fb9985382be pycompat: export queue module instead of symbols in module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35725
diff changeset
   832
        self._queue = pycompat.queue.Queue(maxsize=maxqueue)
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   833
        self._running = True
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   834
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   835
        for i in range(threadcount):
43462
ffd632c224c3 vfs: another bytes-str confusion on thread name
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   836
            t = threading.Thread(target=self._worker, name='backgroundcloser')
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   837
            self._threads.append(t)
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   838
            t.start()
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   839
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   840
    def __enter__(self: _Tbackgroundfilecloser) -> _Tbackgroundfilecloser:
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   841
        self._entered = True
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   842
        return self
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   843
51887
ad83e4f9b40e typing: correct pytype mistakes in `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51886
diff changeset
   844
    def __exit__(self, exc_type, exc_value, exc_tb) -> None:
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   845
        self._running = False
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   846
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   847
        # Wait for threads to finish closing so open files don't linger for
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   848
        # longer than lifetime of context manager.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   849
        for t in self._threads:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   850
            t.join()
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   851
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   852
    def _worker(self) -> None:
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   853
        """Main routine for worker thread."""
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   854
        while True:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   855
            try:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   856
                fh = self._queue.get(block=True, timeout=0.100)
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   857
                # Need to catch or the thread will terminate and
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   858
                # we could orphan file descriptors.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   859
                try:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   860
                    fh.close()
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   861
                except Exception as e:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   862
                    # Stash so can re-raise from main thread later.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   863
                    self._threadexception = e
37844
8fb9985382be pycompat: export queue module instead of symbols in module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35725
diff changeset
   864
            except pycompat.queue.Empty:
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   865
                if not self._running:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   866
                    break
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   867
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   868
    def close(self, fh) -> None:
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   869
        """Schedule a file for closing."""
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   870
        if not self._entered:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   871
            raise error.Abort(
43117
8ff1ecfadcd1 cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents: 43090
diff changeset
   872
                _(b'can only call close() when context manager active')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   873
            )
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   874
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   875
        # If a background thread encountered an exception, raise now so we fail
51882
e59e1d8d29d2 vfs: do minor copyediting on comments and doc strings
Matt Harbison <matt_harbison@yahoo.com>
parents: 51881
diff changeset
   876
        # fast. Otherwise, we may potentially go on for minutes until the error
27895
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   877
        # is acted on.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   878
        if self._threadexception:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   879
            e = self._threadexception
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   880
            self._threadexception = None
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   881
            raise e
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   882
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   883
        # If we're not actively running, close synchronously.
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   884
        if not self._running:
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   885
            fh.close()
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   886
            return
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   887
2d6a89e79b48 scmutil: support background file closing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27879
diff changeset
   888
        self._queue.put(fh, block=True, timeout=None)
29995
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   889
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   890
29995
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   891
class checkambigatclosing(closewrapbase):
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   892
    """Proxy for a file object, to avoid ambiguity of file stat
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   893
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   894
    See also util.filestat for detail about "ambiguity of file stat".
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   895
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   896
    This proxy is useful only if the target file is guarded by any
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   897
    lock (e.g. repo.lock or repo.wlock)
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   898
51882
e59e1d8d29d2 vfs: do minor copyediting on comments and doc strings
Matt Harbison <matt_harbison@yahoo.com>
parents: 51881
diff changeset
   899
    Do not instantiate outside the vfs layer.
29995
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   900
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43025
diff changeset
   901
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   902
    def __init__(self, fh) -> None:
29995
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   903
        super(checkambigatclosing, self).__init__(fh)
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43484
diff changeset
   904
        object.__setattr__(self, '_oldstat', util.filestat.frompath(fh.name))
29995
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   905
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   906
    def _checkambig(self) -> None:
29995
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   907
        oldstat = self._oldstat
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   908
        if oldstat.stat:
33280
646352291f5b vfs: copy if EPERM to avoid file stat ambiguity forcibly at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33259
diff changeset
   909
            _avoidambig(self._origfh.name, oldstat)
29995
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   910
51887
ad83e4f9b40e typing: correct pytype mistakes in `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51886
diff changeset
   911
    def __exit__(self, exc_type, exc_value, exc_tb) -> None:
29995
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   912
        self._origfh.__exit__(exc_type, exc_value, exc_tb)
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   913
        self._checkambig()
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   914
51886
38720073aa34 typing: run `merge-pyi` on `mercurial/vfs.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51882
diff changeset
   915
    def close(self) -> None:
29995
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   916
        self._origfh.close()
57830bd0e787 scmutil: add file object wrapper class to check ambiguity at closing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29994
diff changeset
   917
        self._checkambig()