##// END OF EJS Templates
interfaces: make the `peer` mixin not a Protocol to fix Python 3.10 failures...
interfaces: make the `peer` mixin not a Protocol to fix Python 3.10 failures I can't find any documentation on this, but it appears that Protocol class attributes don't get inherited in subclasses that explicitly subclass a Protocol until Python 3.11, which caused a ton of failures in CI on macOS and Windows (which both test using Python 3.9). The problem started with 1df97507c6b8, and typically manifested as most tests failing to access `ui` on various `peer` classes. Here's a short proof of concept: from __future__ import annotations from typing import ( Protocol, ) class peer(Protocol): limitedarguments: bool = False def __init__(self, arg1, arg2, remotehidden: bool = False) -> None: self.arg1 = arg1 self.arg2 = arg2 class subclass(peer): def __init__(self, arg1, arg2): super(subclass, self).__init__(arg1, arg2, False) sub = subclass(1, 2) print("sub.arg1 is %r" % sub.arg1) When run with Python 3.8.10, 3.9.13, and 3.10.11, the result is: $ py -3.8 prot-test.py Traceback (most recent call last): File "prot-test.py", line 20, in <module> print("sub.arg1 is %r" % sub.arg1) AttributeError: 'subclass' object has no attribute 'arg1' On Python 3.11.9, 3.12.7, and 3.13.0, the result is: $ py -3.11 ../prot-test.py sub.arg1 is 1 Explicitly adding annotations to `peer` like `limitedarguments` didn't help.

File last commit:

r53261:7ac7d5f2 default
r53403:199b0e62 default
Show More
posix.py
810 lines | 23.9 KiB | text/x-python | PythonLexer
Martin Geisler
put license and copyright info into comment blocks
r8226 # posix.py - Posix utility function implementations for Mercurial
#
Raphaël Gomès
contributor: change mentions of mpm to olivia...
r47575 # Copyright 2005-2009 Olivia Mackall <olivia@selenic.com> and others
Martin Geisler
put license and copyright info into comment blocks
r8226 #
# This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Matt Mackall
util: split out posix, windows, and win32 modules
r7890
Matt Harbison
typing: add `from __future__ import annotations` to most files...
r52756 from __future__ import annotations
Gregory Szorc
posix: use absolute_import
r25967
import errno
import fcntl
import getpass
import grp
import os
import pwd
import re
Pierre-Yves David
util: add a simple poll utility...
r25420 import select
Gregory Szorc
posix: use absolute_import
r25967 import stat
import sys
import tempfile
Matt Harbison
typing: attempt to remove @overloads in the platform module for stdlib methods...
r50713 import typing
Gregory Szorc
posix: use absolute_import
r25967 import unicodedata
Matt Harbison
typing: add type hints to the posix platform module matching win32.py
r50706 from typing import (
Matt Harbison
typing: add type hints to the platform `cachestat` classes
r50710 Any,
Matt Harbison
typing: attempt to remove @overloads in the platform module for stdlib methods...
r50713 AnyStr,
Manuel Jacob
typing: fix type annotation
r52686 Callable,
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 Iterable,
Iterator,
Matt Harbison
typing: add type hints to the posix platform module matching win32.py
r50706 List,
Matt Harbison
typing: add type hints to the rest of the posix module...
r50711 Match,
Matt Harbison
typing: add type hints to the posix platform module matching win32.py
r50706 NoReturn,
Optional,
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 Sequence,
Matt Harbison
typing: add type hints to the rest of the posix module...
r50711 Tuple,
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 Union,
Matt Harbison
typing: add type hints to the posix platform module matching win32.py
r50706 )
Gregory Szorc
posix: use absolute_import
r25967 from .i18n import _
from . import (
encoding,
Augie Fackler
ssh: ban any username@host or host that starts with - (SEC)...
r33724 error,
Matt Harbison
util: move getfstype() to the platform modules...
r35527 policy,
Pulkit Goyal
py3: replace os.pathsep with pycompat.ospathsep...
r30612 pycompat,
Gregory Szorc
posix: use absolute_import
r25967 )
Matt Mackall
util: split out posix, windows, and win32 modules
r7890
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 osutil = policy.importmod('osutil')
Matt Harbison
util: move getfstype() to the platform modules...
r35527
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 normpath = os.path.normpath
samestat = os.path.samestat
windows: introduce a `util.abspath` to replace os.path.abspath...
r48422 abspath = os.path.abspath # re-exports
Augie Fackler
posix: work around "posix" systems without os.link available (issue4974)...
r27236 try:
oslink = os.link
except AttributeError:
# Some platforms build Python without os.link on systems that are
# vaguely unix-like but don't have hardlink support. For those
# poor souls, just say we tried and that it failed so we fall back
# to copies.
Matt Harbison
typing: add type hints to the posix platform module matching win32.py
r50706 def oslink(src: bytes, dst: bytes) -> NoReturn:
Augie Fackler
formatting: blacken the codebase...
r43346 raise OSError(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 errno.EINVAL, b'hardlinks not supported: %s to %s' % (src, dst)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Matt Harbison
py3: convert os.readlink() path to native strings on Windows...
r39940 readlink = os.readlink
Adrian Buehlmann
reintroduces util.unlink, for POSIX and Windows....
r13280 unlink = os.unlink
Adrian Buehlmann
util: move rename into posix.py and windows.py
r9549 rename = os.rename
FUJIWARA Katsunori
util: add removedirs as platform depending function...
r24692 removedirs = os.removedirs
Matt Harbison
typing: attempt to remove @overloads in the platform module for stdlib methods...
r50713
if typing.TYPE_CHECKING:
def normpath(path: bytes) -> bytes:
raise NotImplementedError
def abspath(path: AnyStr) -> AnyStr:
raise NotImplementedError
def oslink(src: bytes, dst: bytes) -> None:
raise NotImplementedError
def readlink(path: bytes) -> bytes:
raise NotImplementedError
def unlink(path: bytes) -> None:
raise NotImplementedError
def rename(src: bytes, dst: bytes) -> None:
raise NotImplementedError
def removedirs(name: bytes) -> None:
raise NotImplementedError
Matt Harbison
typing: add type hints to the rest of the posix module...
r50711 expandglobs: bool = False
Matt Mackall
util: split out posix, windows, and win32 modules
r7890
Matt Harbison
typing: add type hints to the rest of the posix module...
r50711 umask: int = os.umask(0)
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 os.umask(umask)
Matt Harbison
posix: (mostly) stop using the `pycompat.open()` shim...
r53261 posixfile = pycompat.open
Augie Fackler
posix: always seek to EOF when opening a file in append mode...
r42778
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the rest of the posix module...
r50711 def split(p: bytes) -> Tuple[bytes, bytes]:
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """Same as posixpath.split, but faster
Remy Blank
posix: fix split() for the case where the path is at the root of the filesystem...
r18288
>>> import posixpath
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> for f in [b'/absolute/path/to/file',
... b'relative/path/to/file',
... b'file_alone',
... b'path/to/directory/',
... b'/multiple/path//separators',
... b'/file_at_root',
... b'///multiple_leading_separators_at_root',
... b'']:
Remy Blank
posix: fix split() for the case where the path is at the root of the filesystem...
r18288 ... assert split(f) == posixpath.split(f), f
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ht = p.rsplit(b'/', 1)
Bryan O'Sullivan
util: implement a faster os.path.split for posix systems...
r17560 if len(ht) == 1:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return b'', p
nh = ht[0].rstrip(b'/')
Bryan O'Sullivan
util: implement a faster os.path.split for posix systems...
r17560 if nh:
return nh, ht[1]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return ht[0] + b'/', ht[1]
Bryan O'Sullivan
util: implement a faster os.path.split for posix systems...
r17560
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def openhardlinks() -> bool:
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 '''return true if it is safe to hold open file handles to hardlinks'''
return True
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the posix platform module matching win32.py
r50706 def nlinks(name: bytes) -> int:
Adrian Buehlmann
port win32.py to using the Python ctypes library...
r13375 '''return number of hardlinks for the given file'''
return os.lstat(name).st_nlink
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def parsepatchoutput(output_line: bytes) -> bytes:
timeless
Generally replace "file name" with "filename" in help and comments.
r8761 """parses the output produced by patch and returns the filename"""
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 pf = output_line[14:]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if pycompat.sysplatform == b'OpenVMS':
if pf[0] == b'`':
Augie Fackler
formatting: blacken the codebase...
r43346 pf = pf[1:-1] # Remove the quotes
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if pf.startswith(b"'") and pf.endswith(b"'") and b" " in pf:
Augie Fackler
formatting: blacken the codebase...
r43346 pf = pf[1:-1] # Remove the quotes
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 return pf
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def sshargs(
sshcmd: bytes, host: bytes, user: Optional[bytes], port: Optional[bytes]
) -> bytes:
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 '''Build argument list for ssh'''
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 args = user and (b"%s@%s" % (user, host)) or host
if b'-' in args[:1]:
Augie Fackler
ssh: ban any username@host or host that starts with - (SEC)...
r33724 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'illegal ssh hostname or username starting with -: %s') % args
Augie Fackler
formatting: blacken the codebase...
r43346 )
Jun Wu
ssh: quote parameters using shellquote (SEC)...
r33732 args = shellquote(args)
if port:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 args = b'-p %s %s' % (shellquote(port), args)
Jun Wu
ssh: quote parameters using shellquote (SEC)...
r33732 return args
Matt Mackall
util: split out posix, windows, and win32 modules
r7890
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def isexec(f: bytes) -> bool:
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 """check whether a file is executable"""
Augie Fackler
formatting: blacken the codebase...
r43346 return os.lstat(f).st_mode & 0o100 != 0
Matt Mackall
util: split out posix, windows, and win32 modules
r7890
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def setflags(f: bytes, l: bool, x: bool) -> None:
Koen Van Hoof
chmod: create a new file when flags are set on a hardlinked file...
r32721 st = os.lstat(f)
s = st.st_mode
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 if l:
if not stat.S_ISLNK(s):
# switch file to link
Matt Harbison
posix: (mostly) stop using the `pycompat.open()` shim...
r53261 with open(f, 'rb') as fp:
Matt Harbison
posix: use context managers in a couple of places...
r46309 data = fp.read()
Ryan McElroy
posix: use local reference to unlink...
r31537 unlink(f)
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 try:
os.symlink(data, f)
Idan Kamara
eliminate various naked except clauses
r14004 except OSError:
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 # failed to make a link, rewrite file
Matt Harbison
posix: (mostly) stop using the `pycompat.open()` shim...
r53261 with open(f, "wb") as fp:
Matt Harbison
posix: use context managers in a couple of places...
r46309 fp.write(data)
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 # no chmod needed at this point
return
if stat.S_ISLNK(s):
# switch link to file
data = os.readlink(f)
Ryan McElroy
posix: use local reference to unlink...
r31537 unlink(f)
Matt Harbison
posix: (mostly) stop using the `pycompat.open()` shim...
r53261 with open(f, "wb") as fp:
Matt Harbison
posix: use context managers in a couple of places...
r46309 fp.write(data)
Augie Fackler
formatting: blacken the codebase...
r43346 s = 0o666 & ~umask # avoid restatting for chmod
Matt Mackall
util: split out posix, windows, and win32 modules
r7890
Gregory Szorc
global: mass rewrite to use modern octal syntax...
r25658 sx = s & 0o100
Koen Van Hoof
chmod: create a new file when flags are set on a hardlinked file...
r32721 if st.st_nlink > 1 and bool(x) != bool(sx):
# the file is a hardlink, break it
Matt Harbison
posix: (mostly) stop using the `pycompat.open()` shim...
r53261 with open(f, "rb") as fp:
Koen Van Hoof
chmod: create a new file when flags are set on a hardlinked file...
r32721 data = fp.read()
unlink(f)
Matt Harbison
posix: (mostly) stop using the `pycompat.open()` shim...
r53261 with open(f, "wb") as fp:
Koen Van Hoof
chmod: create a new file when flags are set on a hardlinked file...
r32721 fp.write(data)
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 if x and not sx:
# Turn on +x for every +r bit when making a file executable
# and obey umask.
Gregory Szorc
global: mass rewrite to use modern octal syntax...
r25658 os.chmod(f, s | (s & 0o444) >> 2 & ~umask)
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 elif not x and sx:
# Turn off all +x bits
Gregory Szorc
global: mass rewrite to use modern octal syntax...
r25658 os.chmod(f, s & 0o666)
Matt Mackall
util: split out posix, windows, and win32 modules
r7890
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def copymode(
src: bytes,
dst: bytes,
Matt Harbison
typing: fix the hint for the `mode` argument of `platform.copymode()`...
r52692 mode: Optional[int] = None,
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 enforcewritable: bool = False,
) -> None:
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """Copy the file mode from the file at path src to dst.
Adrian Buehlmann
util: move copymode into posix.py and windows.py...
r15011 If src doesn't exist, we're using mode instead. If mode is None, we're
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 using umask."""
Adrian Buehlmann
util: move copymode into posix.py and windows.py...
r15011 try:
Gregory Szorc
global: mass rewrite to use modern octal syntax...
r25658 st_mode = os.lstat(src).st_mode & 0o777
Manuel Jacob
py3: catch FileNotFoundError instead of checking errno == ENOENT
r50201 except FileNotFoundError:
Adrian Buehlmann
util: move copymode into posix.py and windows.py...
r15011 st_mode = mode
if st_mode is None:
st_mode = ~umask
Gregory Szorc
global: mass rewrite to use modern octal syntax...
r25658 st_mode &= 0o666
Boris Feld
update: fix edge-case with update.atomic-file and read-only files...
r41325
new_mode = st_mode
if enforcewritable:
new_mode |= stat.S_IWUSR
os.chmod(dst, new_mode)
Adrian Buehlmann
util: move copymode into posix.py and windows.py...
r15011
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def checkexec(path: bytes) -> bool:
Adrian Buehlmann
util: move checkexec() to posix.py and return False on Windows
r13879 """
Check whether the given path is on a filesystem with UNIX-like exec flags
Requires a directory (like /foo/.hg)
"""
# VFAT on some Linux versions can flip mode but it doesn't persist
# a FS remount. Frequently we can detect it if files are created
# with exec bit on.
try:
EXECFLAGS = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 basedir = os.path.join(path, b'.hg')
cachedir = os.path.join(basedir, b'wcache')
storedir = os.path.join(basedir, b'store')
Boris Feld
checkexec: create destination directory if necessary...
r40703 if not os.path.exists(cachedir):
try:
# we want to create the 'cache' directory, not the '.hg' one.
# Automatically creating '.hg' directory could silently spawn
# invalid Mercurial repositories. That seems like a bad idea.
os.mkdir(cachedir)
if os.path.exists(storedir):
copymode(storedir, cachedir)
else:
copymode(basedir, cachedir)
except (IOError, OSError):
# we other fallback logic triggers
pass
Mads Kiilerich
posix: give checkexec a fast path; keep the check files and test read only...
r30446 if os.path.isdir(cachedir):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 checkisexec = os.path.join(cachedir, b'checkisexec')
checknoexec = os.path.join(cachedir, b'checknoexec')
Mads Kiilerich
posix: give checkexec a fast path; keep the check files and test read only...
r30446
try:
m = os.stat(checkisexec).st_mode
Manuel Jacob
py3: catch FileNotFoundError instead of checking errno == ENOENT
r50201 except FileNotFoundError:
Mads Kiilerich
posix: give checkexec a fast path; keep the check files and test read only...
r30446 # checkisexec does not exist - fall through ...
Manuel Jacob
py3: catch FileNotFoundError instead of checking errno == ENOENT
r50201 pass
Mads Kiilerich
posix: give checkexec a fast path; keep the check files and test read only...
r30446 else:
# checkisexec exists, check if it actually is exec
if m & EXECFLAGS != 0:
Arseniy Alekseyev
doc: add a few comments
r50790 # ensure checknoexec exists, check it isn't exec
Mads Kiilerich
posix: give checkexec a fast path; keep the check files and test read only...
r30446 try:
m = os.stat(checknoexec).st_mode
Manuel Jacob
py3: catch FileNotFoundError instead of checking errno == ENOENT
r50201 except FileNotFoundError:
Matt Harbison
posix: (mostly) stop using the `pycompat.open()` shim...
r53261 open(checknoexec, 'w').close() # might fail
Mads Kiilerich
posix: give checkexec a fast path; keep the check files and test read only...
r30446 m = os.stat(checknoexec).st_mode
if m & EXECFLAGS == 0:
# check-exec is exec and check-no-exec is not exec
return True
# checknoexec exists but is exec - delete it
Ryan McElroy
posix: use local reference to unlink...
r31537 unlink(checknoexec)
Mads Kiilerich
posix: give checkexec a fast path; keep the check files and test read only...
r30446 # checkisexec exists but is not exec - delete it
Ryan McElroy
posix: use local reference to unlink...
r31537 unlink(checkisexec)
Mads Kiilerich
posix: give checkexec a fast path; keep the check files and test read only...
r30446
# check using one file, leave it as checkisexec
checkdir = cachedir
else:
# check directly in path and don't leave checkisexec behind
checkdir = path
checkisexec = None
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fh, fn = pycompat.mkstemp(dir=checkdir, prefix=b'hg-checkexec-')
Adrian Buehlmann
util: move checkexec() to posix.py and return False on Windows
r13879 try:
os.close(fh)
Mads Kiilerich
posix: simplify checkexec check...
r30445 m = os.stat(fn).st_mode
Mads Kiilerich
posix: give checkexec a fast path; keep the check files and test read only...
r30446 if m & EXECFLAGS == 0:
os.chmod(fn, m & 0o777 | EXECFLAGS)
if os.stat(fn).st_mode & EXECFLAGS != 0:
if checkisexec is not None:
os.rename(fn, checkisexec)
fn = None
return True
Adrian Buehlmann
util: move checkexec() to posix.py and return False on Windows
r13879 finally:
Mads Kiilerich
posix: give checkexec a fast path; keep the check files and test read only...
r30446 if fn is not None:
Ryan McElroy
posix: use local reference to unlink...
r31537 unlink(fn)
Adrian Buehlmann
util: move checkexec() to posix.py and return False on Windows
r13879 except (IOError, OSError):
# we don't care, the user probably won't be able to commit anyway
return False
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def checklink(path: bytes) -> bool:
Adrian Buehlmann
util: move checklink() to posix.py and return False on Windows...
r13890 """check whether the given path is on a symlink-capable filesystem"""
# mktemp is not racy because symlink creation will fail if the
# file already exists
Matt Mackall
posix: retry on symlink race in checklink...
r26883 while True:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cachedir = os.path.join(path, b'.hg', b'wcache')
checklink = os.path.join(cachedir, b'checklink')
Mads Kiilerich
posix: give checklink a fast path that cache the check file and is read only...
r30448 # try fast path, read only
if os.path.islink(checklink):
return True
Mads Kiilerich
posix: move checklink test file to .hg/cache...
r30447 if os.path.isdir(cachedir):
checkdir = cachedir
else:
checkdir = path
cachedir = None
Augie Fackler
formatting: blacken the codebase...
r43346 name = tempfile.mktemp(
dir=pycompat.fsdecode(checkdir), prefix=r'checklink-'
)
Augie Fackler
posix: tiptoe around tempfile module more delicately...
r31506 name = pycompat.fsencode(name)
Augie Fackler
checklink: always close the NamedTemporaryFile...
r22946 try:
Martijn Pieters
posix: give the cached symlink a real target...
r30555 fd = None
if cachedir is None:
Augie Fackler
formatting: blacken the codebase...
r43346 fd = pycompat.namedtempfile(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 dir=checkdir, prefix=b'hg-checklink-'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Yuya Nishihara
py3: wrap tempfile.NamedTemporaryFile() to return bytes fp.name...
r38184 target = os.path.basename(fd.name)
Martijn Pieters
posix: give the cached symlink a real target...
r30555 else:
# create a fixed file to link to; doesn't matter if it
# already exists.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 target = b'checklink-target'
Augie Fackler
checklink: degrade gracefully on posix when fs is readonly (issue5511)...
r32393 try:
Augie Fackler
cleanup: fix some latent open(path).read() et al calls we previously missed...
r36966 fullpath = os.path.join(cachedir, target)
Matt Harbison
posix: (mostly) stop using the `pycompat.open()` shim...
r53261 open(fullpath, 'w').close()
Manuel Jacob
py3: catch PermissionError instead of checking errno == EACCES
r50202 except PermissionError:
# If we can't write to cachedir, just pretend
# that the fs is readonly and by association
# that the fs won't support symlinks. This
# seems like the least dangerous way to avoid
# data loss.
return False
Matt Mackall
posix: retry on symlink race in checklink...
r26883 try:
Martijn Pieters
posix: give the cached symlink a real target...
r30555 os.symlink(target, name)
Mads Kiilerich
posix: give checklink a fast path that cache the check file and is read only...
r30448 if cachedir is None:
Ryan McElroy
posix: use local reference to unlink...
r31537 unlink(name)
Mads Kiilerich
posix: give checklink a fast path that cache the check file and is read only...
r30448 else:
try:
os.rename(name, checklink)
except OSError:
Ryan McElroy
posix: use local reference to unlink...
r31537 unlink(name)
Matt Mackall
posix: retry on symlink race in checklink...
r26883 return True
Manuel Jacob
py3: catch FileExistsError instead of checking errno == EEXIST
r50200 except FileExistsError:
Matt Mackall
posix: retry on symlink race in checklink...
r26883 # link creation might race, try again
Manuel Jacob
py3: catch FileExistsError instead of checking errno == EEXIST
r50200 continue
Matt Mackall
posix: retry on symlink race in checklink...
r26883 finally:
Martijn Pieters
posix: give the cached symlink a real target...
r30555 if fd is not None:
fd.close()
Matt Mackall
posix: retry on symlink race in checklink...
r26883 except AttributeError:
return False
Matt Mackall
posix: fix test-permissions regression
r26889 except OSError as inst:
# sshfs might report failure while successfully creating the link
Augie Fackler
posix: use inst.errno instead of inst[0] on OSError instances...
r37953 if inst.errno == errno.EIO and os.path.exists(name):
Ryan McElroy
posix: use local reference to unlink...
r31537 unlink(name)
Matt Mackall
posix: fix test-permissions regression
r26889 return False
Adrian Buehlmann
util: move checklink() to posix.py and return False on Windows...
r13890
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the rest of the posix module...
r50711 def checkosfilename(path: bytes) -> Optional[bytes]:
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """Check that the base-relative path is a valid filename on this platform.
Returns None if the path is ok, or a UI string describing the problem."""
Augie Fackler
formatting: blacken the codebase...
r43346 return None # on posix platforms, every path is ok
Adrian Buehlmann
path_auditor: check filenames for basic platform validity (issue2755)...
r13916
Matt Harbison
typing: avoid some useless @overload definitions in `mercurial.util`...
r52613 def getfsmountpoint(path: bytes) -> Optional[bytes]:
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """Get the filesystem mount point from a directory (best-effort)
Matt Harbison
util: add a function to show the mount point of the filesystem...
r35531
Returns None if we are unsure. Raises OSError on ENOENT, EPERM, etc.
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """
Matt Harbison
typing: avoid some useless @overload definitions in `mercurial.util`...
r52613 return getattr(osutil, 'getfsmountpoint', lambda x: None)(path)
Matt Harbison
util: add a function to show the mount point of the filesystem...
r35531
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: avoid some useless @overload definitions in `mercurial.util`...
r52613 def getfstype(path: bytes) -> Optional[bytes]:
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """Get the filesystem type name from a directory (best-effort)
Matt Harbison
util: move getfstype() to the platform modules...
r35527
Returns None if we are unsure. Raises OSError on ENOENT, EPERM, etc.
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """
Matt Harbison
typing: avoid some useless @overload definitions in `mercurial.util`...
r52613 return getattr(osutil, 'getfstype', lambda x: None)(path)
Matt Harbison
util: move getfstype() to the platform modules...
r35527
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def get_password() -> bytes:
Matt Harbison
util: avoid echoing the password to the console on Windows py3 (issue6446)...
r47949 return encoding.strtolocal(getpass.getpass(''))
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def setbinary(fd) -> None:
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 pass
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def pconvert(path: bytes) -> bytes:
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 return path
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def localpath(path: bytes) -> bytes:
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 return path
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the posix platform module matching win32.py
r50706 def samefile(fpath1: bytes, fpath2: bytes) -> bool:
Siddharth Agarwal
Add support for relinking on Windows....
r10218 """Returns whether path1 and path2 refer to the same file. This is only
guaranteed to work for files, not directories."""
return os.path.samefile(fpath1, fpath2)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the posix platform module matching win32.py
r50706 def samedevice(fpath1: bytes, fpath2: bytes) -> bool:
Siddharth Agarwal
Add support for relinking on Windows....
r10218 """Returns whether fpath1 and fpath2 are on the same device. This is only
guaranteed to work for files, not directories."""
st1 = os.lstat(fpath1)
st2 = os.lstat(fpath2)
return st1.st_dev == st2.st_dev
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
dirstate: fix case-folding identity for traditional Unix...
r15488 # os.path.normcase is a no-op, which doesn't help us on non-native filesystems
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def normcase(path: bytes) -> bytes:
Matt Mackall
dirstate: fix case-folding identity for traditional Unix...
r15488 return path.lower()
Augie Fackler
formatting: blacken the codebase...
r43346
Siddharth Agarwal
posix: define normcase spec and fallback...
r24594 # what normcase does to ASCII strings
Matt Harbison
typing: add type hints to the rest of the posix module...
r50711 normcasespec: int = encoding.normcasespecs.lower
Siddharth Agarwal
posix: define normcase spec and fallback...
r24594 # fallback normcase function for non-ASCII strings
normcasefallback = normcase
Jun Wu
codemod: use pycompat.isdarwin...
r34648 if pycompat.isdarwin:
Matt Mackall
posix: add extended support for OS X path folding...
r15551
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def normcase(path: bytes) -> bytes:
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """
Matt Mackall
hfs+: rewrite percent-escaper (issue3918)...
r19131 Normalize a filename for OS X-compatible comparison:
- escape-encode invalid characters
- decompose to NFD
- lowercase
Augie Fackler
darwin: omit ignorable codepoints when normcase()ing a file path...
r23597 - omit ignored characters [200c-200f, 202a-202e, 206a-206f,feff]
Matt Mackall
hfs+: rewrite percent-escaper (issue3918)...
r19131
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> normcase(b'UPPER')
Matt Mackall
hfs+: rewrite percent-escaper (issue3918)...
r19131 'upper'
Augie Fackler
posix: fix HFS+ normcase doctest to produce valid bytes literals in Python 3...
r34196 >>> normcase(b'Caf\\xc3\\xa9')
Matt Mackall
hfs+: rewrite percent-escaper (issue3918)...
r19131 'cafe\\xcc\\x81'
Augie Fackler
posix: fix HFS+ normcase doctest to produce valid bytes literals in Python 3...
r34196 >>> normcase(b'\\xc3\\x89')
Matt Mackall
hfs+: rewrite percent-escaper (issue3918)...
r19131 'e\\xcc\\x81'
Augie Fackler
posix: fix HFS+ normcase doctest to produce valid bytes literals in Python 3...
r34196 >>> normcase(b'\\xb8\\xca\\xc3\\xca\\xbe\\xc8.JPG') # issue3918
Matt Mackall
hfs+: rewrite percent-escaper (issue3918)...
r19131 '%b8%ca%c3\\xca\\xbe%c8.jpg'
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """
Matt Mackall
hfs+: rewrite percent-escaper (issue3918)...
r19131
Matt Mackall
posix: add extended support for OS X path folding...
r15551 try:
Siddharth Agarwal
normcase: for darwin, use fast ASCII lower...
r22781 return encoding.asciilower(path) # exception for non-ASCII
Mads Kiilerich
OS X: try cheap ascii .lower() in normcase before making full unicode dance...
r18501 except UnicodeDecodeError:
Siddharth Agarwal
darwin: define normcase spec and fallback...
r24595 return normcasefallback(path)
normcasespec = encoding.normcasespecs.lower
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def normcasefallback(path: bytes) -> bytes:
Mads Kiilerich
OS X: try cheap ascii .lower() in normcase before making full unicode dance...
r18501 try:
Matt Mackall
posix: add extended support for OS X path folding...
r15551 u = path.decode('utf-8')
except UnicodeDecodeError:
Matt Mackall
hfs+: rewrite percent-escaper (issue3918)...
r19131 # OS X percent-encodes any bytes that aren't valid utf-8
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 s = b''
Matt Mackall
posix: use getutf8char to handle OS X filename percent-escaping...
r26876 pos = 0
Matt Mackall
mac: fix percent-encoding of non-utf-8 characters (issue4999)
r27380 l = len(path)
Matt Mackall
posix: use getutf8char to handle OS X filename percent-escaping...
r26876 while pos < l:
try:
c = encoding.getutf8char(path, pos)
pos += len(c)
except ValueError:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 c = b'%%%02X' % ord(path[pos : pos + 1])
Matt Mackall
posix: use getutf8char to handle OS X filename percent-escaping...
r26876 pos += 1
s += c
Matt Mackall
hfs+: rewrite percent-escaper (issue3918)...
r19131
Matt Mackall
posix: add extended support for OS X path folding...
r15551 u = s.decode('utf-8')
# Decompose then lowercase (HFS+ technote specifies lower)
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 enc = unicodedata.normalize('NFD', u).lower().encode('utf-8')
Augie Fackler
darwin: omit ignorable codepoints when normcase()ing a file path...
r23597 # drop HFS+ ignored characters
return encoding.hfsignoreclean(enc)
Matt Mackall
posix: add extended support for OS X path folding...
r15551
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if pycompat.sysplatform == b'cygwin':
FUJIWARA Katsunori
cygwin: add cygwin specific normcase logic...
r15711 # workaround for cygwin, in which mount point part of path is
# treated as case sensitive, even though underlying NTFS is case
# insensitive.
# default mount points
Augie Fackler
formatting: blacken the codebase...
r43346 cygwinmountpoints = sorted(
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 [
b"/usr/bin",
b"/usr/lib",
b"/cygdrive",
],
reverse=True,
Augie Fackler
formatting: blacken the codebase...
r43346 )
FUJIWARA Katsunori
cygwin: add cygwin specific normcase logic...
r15711
# use upper-ing as normcase as same as NTFS workaround
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def normcase(path: bytes) -> bytes:
FUJIWARA Katsunori
cygwin: add cygwin specific normcase logic...
r15711 pathlen = len(path)
Pulkit Goyal
py3: replace os.sep with pycompat.ossep (part 2 of 4)...
r30614 if (pathlen == 0) or (path[0] != pycompat.ossep):
FUJIWARA Katsunori
cygwin: add cygwin specific normcase logic...
r15711 # treat as relative
Adrian Buehlmann
util, posix: eliminate encodinglower and encodingupper...
r17203 return encoding.upper(path)
FUJIWARA Katsunori
cygwin: add cygwin specific normcase logic...
r15711
# to preserve case of mountpoint part
for mp in cygwinmountpoints:
if not path.startswith(mp):
continue
mplen = len(mp)
Augie Fackler
formatting: blacken the codebase...
r43346 if mplen == pathlen: # mount point itself
FUJIWARA Katsunori
cygwin: add cygwin specific normcase logic...
r15711 return mp
Pulkit Goyal
py3: replace os.sep with pycompat.ossep (part 2 of 4)...
r30614 if path[mplen] == pycompat.ossep:
Adrian Buehlmann
util, posix: eliminate encodinglower and encodingupper...
r17203 return mp + encoding.upper(path[mplen:])
FUJIWARA Katsunori
cygwin: add cygwin specific normcase logic...
r15711
Adrian Buehlmann
util, posix: eliminate encodinglower and encodingupper...
r17203 return encoding.upper(path)
FUJIWARA Katsunori
cygwin: add cygwin specific normcase logic...
r15711
Siddharth Agarwal
cygwin: define normcase spec and fallback...
r24596 normcasespec = encoding.normcasespecs.other
normcasefallback = normcase
A. S. Budden
posix: ignore execution bit in cygwin (issue3301)
r16240 # Cygwin translates native ACLs to POSIX permissions,
# but these translations are not supported by native
# tools, so the exec bit tends to be set erroneously.
# Therefore, disable executable bit access on Cygwin.
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def checkexec(path: bytes) -> bool:
A. S. Budden
posix: ignore execution bit in cygwin (issue3301)
r16240 return False
Matt Mackall
posix: disable cygwin's symlink emulation
r16241 # Similarly, Cygwin's symlink emulation is likely to create
# problems when Mercurial is used from both Cygwin and native
# Windows, with other native tools, or on shared volumes
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def checklink(path: bytes) -> bool:
Matt Mackall
posix: disable cygwin's symlink emulation
r16241 return False
Augie Fackler
formatting: blacken the codebase...
r43346
Jean-Francois Pieronne
openvms: mark symlink as unsupported on OpenVMS...
r51889 if pycompat.sysplatform == b'OpenVMS':
# OpenVMS's symlink emulation is broken on some OpenVMS versions.
Matt Harbison
typing: add a trivial type hint to `mercurial/posix.py` to avoid an @overload...
r52569 def checklink(path: bytes) -> bool:
Jean-Francois Pieronne
openvms: mark symlink as unsupported on OpenVMS...
r51889 return False
Manuel Jacob
typing: fix type annotation
r52686 _needsshellquote: Optional[Callable[[bytes], Optional[Match[bytes]]]] = None
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def shellquote(s: bytes) -> bytes:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if pycompat.sysplatform == b'OpenVMS':
return b'"%s"' % s
FUJIWARA Katsunori
posix: quote the specified string only when it may have to be quoted...
r23683 global _needsshellquote
if _needsshellquote is None:
Pulkit Goyal
py3: make the regular expression bytes to prevent TypeError
r31491 _needsshellquote = re.compile(br'[^a-zA-Z0-9._/+-]').search
Yuya Nishihara
shellquote: fix missing quotes for empty string...
r24108 if s and not _needsshellquote(s):
FUJIWARA Katsunori
posix: quote the specified string only when it may have to be quoted...
r23683 # "s" shouldn't have to be quoted
return s
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return b"'%s'" % s.replace(b"'", b"'\\''")
Matt Mackall
util: split out posix, windows, and win32 modules
r7890
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def shellsplit(s: bytes) -> List[bytes]:
Yuya Nishihara
util: factor out shellsplit() function...
r36433 """Parse a command string in POSIX shell way (best-effort)"""
return pycompat.shlexsplit(s, posix=True)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the posix platform module matching win32.py
r50706 def testpid(pid: int) -> bool:
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 '''return False if pid dead, True if running or not sure'''
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if pycompat.sysplatform == b'OpenVMS':
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 return True
try:
os.kill(pid, 0)
return True
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except OSError as inst:
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 return inst.errno != errno.ESRCH
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def isowner(st: os.stat_result) -> bool:
Martin Geisler
posix: do not use fstat in isowner...
r8657 """Return True if the stat object st is from the current user."""
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 return st.st_uid == os.getuid()
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def findexe(command: bytes) -> Optional[bytes]:
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """Find executable for command searching like which does.
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 If command is a basename then PATH is searched for command.
PATH isn't searched if command is an absolute or relative path.
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 If command isn't found None is returned."""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if pycompat.sysplatform == b'OpenVMS':
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 return command
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def findexisting(executable: bytes) -> Optional[bytes]:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'Will return executable if existing file'
Marc-Antoine Ruel
posix: fix findexe() to check for file type and access
r15499 if os.path.isfile(executable) and os.access(executable, os.X_OK):
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 return executable
return None
Pulkit Goyal
py3: replace os.sep with pycompat.ossep (part 2 of 4)...
r30614 if pycompat.ossep in command:
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 return findexisting(command)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if pycompat.sysplatform == b'plan9':
return findexisting(os.path.join(b'/bin', command))
Steven Stallion
plan9: initial support for plan 9 from bell labs...
r16383
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for path in encoding.environ.get(b'PATH', b'').split(pycompat.ospathsep):
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 executable = findexisting(os.path.join(path, command))
if executable is not None:
Marc-Antoine Ruel
posix: fix findexe() to check for file type and access
r15499 return executable
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 return None
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the posix platform module matching win32.py
r50706 def setsignalhandler() -> None:
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 pass
Augie Fackler
formatting: blacken the codebase...
r43346
Martin von Zweigbergk
cleanup: use set literals...
r32291 _wantedkinds = {stat.S_IFREG, stat.S_IFLNK}
Bryan O'Sullivan
dirstate: move file type filtering to its source...
r18017
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def statfiles(files: Sequence[bytes]) -> Iterator[Optional[os.stat_result]]:
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """Stat each file in files. Yield each stat, or None if a file does not
exist or has a type we don't care about."""
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 lstat = os.lstat
Bryan O'Sullivan
dirstate: move file type filtering to its source...
r18017 getkind = stat.S_IFMT
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 for nf in files:
try:
st = lstat(nf)
Bryan O'Sullivan
dirstate: move file type filtering to its source...
r18017 if getkind(st.st_mode) not in _wantedkinds:
st = None
Manuel Jacob
py3: catch specific OSError subclasses instead of checking errno...
r50205 except (FileNotFoundError, NotADirectoryError):
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 st = None
yield st
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the posix platform module matching win32.py
r50706 def getuser() -> bytes:
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 '''return name of current user'''
Pulkit Goyal
py3: make posix.getuser return a bytes
r32129 return pycompat.fsencode(getpass.getuser())
Matt Mackall
util: split out posix, windows, and win32 modules
r7890
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def username(uid: Optional[int] = None) -> Optional[bytes]:
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 """Return the name of the user with the given uid.
If uid is None, return the name of the current user."""
if uid is None:
uid = os.getuid()
try:
Pulkit Goyal
py3: make sure util.username() always returns bytes...
r38271 return pycompat.fsencode(pwd.getpwuid(uid)[0])
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 except KeyError:
Pulkit Goyal
py3: make sure util.username() always returns bytes...
r38271 return b'%d' % uid
Matt Mackall
util: split out posix, windows, and win32 modules
r7890
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def groupname(gid: Optional[int] = None) -> Optional[bytes]:
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 """Return the name of the group with the given gid.
If gid is None, return the name of the current group."""
if gid is None:
gid = os.getgid()
try:
Pulkit Goyal
py3: make sure return value of posix.groupname() is bytes...
r41993 return pycompat.fsencode(grp.getgrgid(gid)[0])
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 except KeyError:
Pulkit Goyal
py3: make sure return value of posix.groupname() is bytes...
r41993 return pycompat.bytestr(gid)
Patrick Mezard
serve: add and use portable spawnvp replacement...
r10237
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def groupmembers(name: bytes) -> List[bytes]:
Patrick Mezard
acl: grp module is not available on windows
r11138 """Return the list of members of the group with the given
name, KeyError if the group does not exist.
"""
Pulkit Goyal
py3: do a fsdecode(), fsencode() dance in posix.py...
r41664 name = pycompat.fsdecode(name)
return pycompat.rapply(pycompat.fsencode, list(grp.getgrnam(name).gr_mem))
Patrick Mezard
acl: grp module is not available on windows
r11138
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the posix platform module matching win32.py
r50706 def spawndetached(args: List[bytes]) -> int:
Augie Fackler
formatting: blacken the codebase...
r43346 return os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0), args[0], args)
Patrick Mezard
serve: add and use portable spawnvp replacement...
r10237
Matt Harbison
typing: add type hints to the rest of the posix module...
r50711 def gethgcmd(): # TODO: convert to bytes, like on Windows?
Patrick Mezard
Find right hg command for detached process...
r10239 return sys.argv[:1]
Patrick Mezard
util: fix default termwidth() under Windows...
r11010
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the posix platform module matching win32.py
r50706 def makedir(path: bytes, notindexed: bool) -> None:
Adrian Buehlmann
util: move "default" makedir to posix.py...
r14908 os.mkdir(path)
Adrian Buehlmann
util: move "default" unlinkpath to posix.py...
r14909
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def lookupreg(
key: bytes,
Matt Harbison
typing: avoid some useless @overload definitions in `mercurial.util`...
r52613 valname: Optional[bytes] = None,
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 scope: Optional[Union[int, Iterable[int]]] = None,
) -> Optional[bytes]:
Adrian Buehlmann
util: move "default" lookupreg to posix.py...
r14910 return None
Adrian Buehlmann
util: move "default" hidewindow to posix.py...
r14911
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the posix platform module matching win32.py
r50706 def hidewindow() -> None:
Adrian Buehlmann
util: move "default" hidewindow to posix.py...
r14911 """Hide current shell window.
Used to hide the window opened when starting asynchronous
child process under Windows, unneeded on other systems.
"""
pass
Adrian Buehlmann
util: eliminate wildcard imports
r14926
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
py3: use class X: instead of class X(object):...
r49801 class cachestat:
Matt Harbison
typing: add type hints to `mercurial.dirstatemap`...
r52609 stat: os.stat_result
Matt Harbison
typing: add type hints to the platform `cachestat` classes
r50710 def __init__(self, path: bytes) -> None:
Idan Kamara
posix, windows: introduce cachestat...
r14927 self.stat = os.stat(path)
Matt Harbison
typing: add type hints to the platform `cachestat` classes
r50710 def cacheable(self) -> bool:
Idan Kamara
posix, windows: introduce cachestat...
r14927 return bool(self.stat.st_ino)
Martin Geisler
Use explicit integer division...
r15791 __hash__ = object.__hash__
Matt Harbison
typing: add type hints to the platform `cachestat` classes
r50710 def __eq__(self, other: Any) -> bool:
Idan Kamara
posix, windows: introduce cachestat...
r14927 try:
Siddharth Agarwal
posix: don't compare atime when determining if a file has changed...
r18442 # Only dev, ino, size, mtime and atime are likely to change. Out
# of these, we shouldn't compare atime but should compare the
# rest. However, one of the other fields changing indicates
# something fishy going on, so return False if anything but atime
# changes.
Augie Fackler
formatting: blacken the codebase...
r43346 return (
self.stat.st_mode == other.stat.st_mode
and self.stat.st_ino == other.stat.st_ino
and self.stat.st_dev == other.stat.st_dev
and self.stat.st_nlink == other.stat.st_nlink
and self.stat.st_uid == other.stat.st_uid
and self.stat.st_gid == other.stat.st_gid
and self.stat.st_size == other.stat.st_size
and self.stat[stat.ST_MTIME] == other.stat[stat.ST_MTIME]
and self.stat[stat.ST_CTIME] == other.stat[stat.ST_CTIME]
)
Idan Kamara
posix, windows: introduce cachestat...
r14927 except AttributeError:
return False
Matt Harbison
typing: add type hints to the platform `cachestat` classes
r50710 def __ne__(self, other: Any) -> bool:
Idan Kamara
posix, windows: introduce cachestat...
r14927 return not self == other
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def statislink(st: Optional[os.stat_result]) -> bool:
Bryan O'Sullivan
util: add functions to check symlink/exec bits...
r18868 '''check whether a stat result is a symlink'''
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 return stat.S_ISLNK(st.st_mode) if st else False
Bryan O'Sullivan
util: add functions to check symlink/exec bits...
r18868
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def statisexec(st: Optional[os.stat_result]) -> bool:
Bryan O'Sullivan
util: add functions to check symlink/exec bits...
r18868 '''check whether a stat result is an executable file'''
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 return (st.st_mode & 0o100 != 0) if st else False
Gregory Szorc
platform: implement readpipe()...
r22245
Augie Fackler
formatting: blacken the codebase...
r43346
Pierre-Yves David
util: add a simple poll utility...
r25420 def poll(fds):
"""block until something happens on any file descriptor
This is a generic helper that will check for any activity
(read, write. exception) and return the list of touched files.
In unsupported cases, it will raise a NotImplementedError"""
try:
Manuel Jacob
py3: remove retry on EINTR errno...
r50197 res = select.select(fds, fds, fds)
Augie Fackler
formatting: blacken the codebase...
r43346 except ValueError: # out of range file descriptor
Pierre-Yves David
util: add a simple poll utility...
r25420 raise NotImplementedError()
return sorted(list(set(sum(res, []))))
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def readpipe(pipe) -> bytes:
Gregory Szorc
platform: implement readpipe()...
r22245 """Read all available data from a pipe."""
Gregory Szorc
posix: implement readpipe using non-blocking I/O (issue4336)...
r22246 # We can't fstat() a pipe because Linux will always report 0.
# So, we set the pipe to non-blocking mode and read everything
# that's available.
flags = fcntl.fcntl(pipe, fcntl.F_GETFL)
flags |= os.O_NONBLOCK
oldflags = fcntl.fcntl(pipe, fcntl.F_SETFL, flags)
Gregory Szorc
platform: implement readpipe()...
r22245
Gregory Szorc
posix: implement readpipe using non-blocking I/O (issue4336)...
r22246 try:
chunks = []
while True:
try:
s = pipe.read()
if not s:
break
chunks.append(s)
except IOError:
break
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return b''.join(chunks)
Gregory Szorc
posix: implement readpipe using non-blocking I/O (issue4336)...
r22246 finally:
fcntl.fcntl(pipe, fcntl.F_SETFL, oldflags)
Yuya Nishihara
chgserver: extract utility to bind unix domain socket to long path...
r29530
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to the common posix/windows platform functions...
r50707 def bindunixsocket(sock, path: bytes) -> None:
Yuya Nishihara
chgserver: extract utility to bind unix domain socket to long path...
r29530 """Bind the UNIX domain socket to the specified path"""
# use relative path instead of full path at bind() if possible, since
# AF_UNIX path has very small length limit (107 chars) on common
# platforms (see sys/un.h)
dirname, basename = os.path.split(path)
bakwdfd = None
Matt Harbison
posix: avoid a leaked file descriptor in a unix domain socket exception case...
r46310
try:
if dirname:
bakwdfd = os.open(b'.', os.O_DIRECTORY)
os.chdir(dirname)
sock.bind(basename)
if bakwdfd:
os.fchdir(bakwdfd)
finally:
if bakwdfd:
os.close(bakwdfd)