mercurial/posix.py
changeset 49906 0a91aba258e0
parent 49905 a9faacdc5943
child 49907 58dff81ffba1
equal deleted inserted replaced
49905:a9faacdc5943 49906:0a91aba258e0
    17 import stat
    17 import stat
    18 import sys
    18 import sys
    19 import tempfile
    19 import tempfile
    20 import unicodedata
    20 import unicodedata
    21 
    21 
       
    22 from typing import (
       
    23     List,
       
    24     NoReturn,
       
    25     Optional,
       
    26 )
       
    27 
    22 from .i18n import _
    28 from .i18n import _
    23 from .pycompat import (
    29 from .pycompat import (
    24     getattr,
    30     getattr,
    25     open,
    31     open,
    26 )
    32 )
    42 except AttributeError:
    48 except AttributeError:
    43     # Some platforms build Python without os.link on systems that are
    49     # Some platforms build Python without os.link on systems that are
    44     # vaguely unix-like but don't have hardlink support. For those
    50     # vaguely unix-like but don't have hardlink support. For those
    45     # poor souls, just say we tried and that it failed so we fall back
    51     # poor souls, just say we tried and that it failed so we fall back
    46     # to copies.
    52     # to copies.
    47     def oslink(src, dst):
    53     def oslink(src: bytes, dst: bytes) -> NoReturn:
    48         raise OSError(
    54         raise OSError(
    49             errno.EINVAL, b'hardlinks not supported: %s to %s' % (src, dst)
    55             errno.EINVAL, b'hardlinks not supported: %s to %s' % (src, dst)
    50         )
    56         )
    51 
    57 
    52 
    58 
    88 def openhardlinks():
    94 def openhardlinks():
    89     '''return true if it is safe to hold open file handles to hardlinks'''
    95     '''return true if it is safe to hold open file handles to hardlinks'''
    90     return True
    96     return True
    91 
    97 
    92 
    98 
    93 def nlinks(name):
    99 def nlinks(name: bytes) -> int:
    94     '''return number of hardlinks for the given file'''
   100     '''return number of hardlinks for the given file'''
    95     return os.lstat(name).st_nlink
   101     return os.lstat(name).st_nlink
    96 
   102 
    97 
   103 
    98 def parsepatchoutput(output_line):
   104 def parsepatchoutput(output_line):
   346     Returns None if we are unsure. Raises OSError on ENOENT, EPERM, etc.
   352     Returns None if we are unsure. Raises OSError on ENOENT, EPERM, etc.
   347     """
   353     """
   348     return getattr(osutil, 'getfsmountpoint', lambda x: None)(dirpath)
   354     return getattr(osutil, 'getfsmountpoint', lambda x: None)(dirpath)
   349 
   355 
   350 
   356 
   351 def getfstype(dirpath):
   357 def getfstype(dirpath: bytes) -> Optional[bytes]:
   352     """Get the filesystem type name from a directory (best-effort)
   358     """Get the filesystem type name from a directory (best-effort)
   353 
   359 
   354     Returns None if we are unsure. Raises OSError on ENOENT, EPERM, etc.
   360     Returns None if we are unsure. Raises OSError on ENOENT, EPERM, etc.
   355     """
   361     """
   356     return getattr(osutil, 'getfstype', lambda x: None)(dirpath)
   362     return getattr(osutil, 'getfstype', lambda x: None)(dirpath)
   370 
   376 
   371 def localpath(path):
   377 def localpath(path):
   372     return path
   378     return path
   373 
   379 
   374 
   380 
   375 def samefile(fpath1, fpath2):
   381 def samefile(fpath1: bytes, fpath2: bytes) -> bool:
   376     """Returns whether path1 and path2 refer to the same file. This is only
   382     """Returns whether path1 and path2 refer to the same file. This is only
   377     guaranteed to work for files, not directories."""
   383     guaranteed to work for files, not directories."""
   378     return os.path.samefile(fpath1, fpath2)
   384     return os.path.samefile(fpath1, fpath2)
   379 
   385 
   380 
   386 
   381 def samedevice(fpath1, fpath2):
   387 def samedevice(fpath1: bytes, fpath2: bytes) -> bool:
   382     """Returns whether fpath1 and fpath2 are on the same device. This is only
   388     """Returns whether fpath1 and fpath2 are on the same device. This is only
   383     guaranteed to work for files, not directories."""
   389     guaranteed to work for files, not directories."""
   384     st1 = os.lstat(fpath1)
   390     st1 = os.lstat(fpath1)
   385     st2 = os.lstat(fpath2)
   391     st2 = os.lstat(fpath2)
   386     return st1.st_dev == st2.st_dev
   392     return st1.st_dev == st2.st_dev
   519 def shellsplit(s):
   525 def shellsplit(s):
   520     """Parse a command string in POSIX shell way (best-effort)"""
   526     """Parse a command string in POSIX shell way (best-effort)"""
   521     return pycompat.shlexsplit(s, posix=True)
   527     return pycompat.shlexsplit(s, posix=True)
   522 
   528 
   523 
   529 
   524 def testpid(pid):
   530 def testpid(pid: int) -> bool:
   525     '''return False if pid dead, True if running or not sure'''
   531     '''return False if pid dead, True if running or not sure'''
   526     if pycompat.sysplatform == b'OpenVMS':
   532     if pycompat.sysplatform == b'OpenVMS':
   527         return True
   533         return True
   528     try:
   534     try:
   529         os.kill(pid, 0)
   535         os.kill(pid, 0)
   562         if executable is not None:
   568         if executable is not None:
   563             return executable
   569             return executable
   564     return None
   570     return None
   565 
   571 
   566 
   572 
   567 def setsignalhandler():
   573 def setsignalhandler() -> None:
   568     pass
   574     pass
   569 
   575 
   570 
   576 
   571 _wantedkinds = {stat.S_IFREG, stat.S_IFLNK}
   577 _wantedkinds = {stat.S_IFREG, stat.S_IFLNK}
   572 
   578 
   584         except (FileNotFoundError, NotADirectoryError):
   590         except (FileNotFoundError, NotADirectoryError):
   585             st = None
   591             st = None
   586         yield st
   592         yield st
   587 
   593 
   588 
   594 
   589 def getuser():
   595 def getuser() -> bytes:
   590     '''return name of current user'''
   596     '''return name of current user'''
   591     return pycompat.fsencode(getpass.getuser())
   597     return pycompat.fsencode(getpass.getuser())
   592 
   598 
   593 
   599 
   594 def username(uid=None):
   600 def username(uid=None):
   623     """
   629     """
   624     name = pycompat.fsdecode(name)
   630     name = pycompat.fsdecode(name)
   625     return pycompat.rapply(pycompat.fsencode, list(grp.getgrnam(name).gr_mem))
   631     return pycompat.rapply(pycompat.fsencode, list(grp.getgrnam(name).gr_mem))
   626 
   632 
   627 
   633 
   628 def spawndetached(args) -> int:
   634 def spawndetached(args: List[bytes]) -> int:
   629     return os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0), args[0], args)
   635     return os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0), args[0], args)
   630 
   636 
   631 
   637 
   632 def gethgcmd():
   638 def gethgcmd():
   633     return sys.argv[:1]
   639     return sys.argv[:1]
   634 
   640 
   635 
   641 
   636 def makedir(path, notindexed):
   642 def makedir(path: bytes, notindexed: bool) -> None:
   637     os.mkdir(path)
   643     os.mkdir(path)
   638 
   644 
   639 
   645 
   640 def lookupreg(key, name=None, scope=None):
   646 def lookupreg(key, name=None, scope=None):
   641     return None
   647     return None
   642 
   648 
   643 
   649 
   644 def hidewindow():
   650 def hidewindow() -> None:
   645     """Hide current shell window.
   651     """Hide current shell window.
   646 
   652 
   647     Used to hide the window opened when starting asynchronous
   653     Used to hide the window opened when starting asynchronous
   648     child process under Windows, unneeded on other systems.
   654     child process under Windows, unneeded on other systems.
   649     """
   655     """