(root)/
Python-3.11.7/
Lib/
genericpath.py
       1  """
       2  Path operations common to more than one OS
       3  Do not use directly.  The OS specific modules import the appropriate
       4  functions from this module themselves.
       5  """
       6  import os
       7  import stat
       8  
       9  __all__ = ['commonprefix', 'exists', 'getatime', 'getctime', 'getmtime',
      10             'getsize', 'isdir', 'isfile', 'samefile', 'sameopenfile',
      11             'samestat']
      12  
      13  
      14  # Does a path exist?
      15  # This is false for dangling symbolic links on systems that support them.
      16  def exists(path):
      17      """Test whether a path exists.  Returns False for broken symbolic links"""
      18      try:
      19          os.stat(path)
      20      except (OSError, ValueError):
      21          return False
      22      return True
      23  
      24  
      25  # This follows symbolic links, so both islink() and isdir() can be true
      26  # for the same path on systems that support symlinks
      27  def isfile(path):
      28      """Test whether a path is a regular file"""
      29      try:
      30          st = os.stat(path)
      31      except (OSError, ValueError):
      32          return False
      33      return stat.S_ISREG(st.st_mode)
      34  
      35  
      36  # Is a path a directory?
      37  # This follows symbolic links, so both islink() and isdir()
      38  # can be true for the same path on systems that support symlinks
      39  def isdir(s):
      40      """Return true if the pathname refers to an existing directory."""
      41      try:
      42          st = os.stat(s)
      43      except (OSError, ValueError):
      44          return False
      45      return stat.S_ISDIR(st.st_mode)
      46  
      47  
      48  def getsize(filename):
      49      """Return the size of a file, reported by os.stat()."""
      50      return os.stat(filename).st_size
      51  
      52  
      53  def getmtime(filename):
      54      """Return the last modification time of a file, reported by os.stat()."""
      55      return os.stat(filename).st_mtime
      56  
      57  
      58  def getatime(filename):
      59      """Return the last access time of a file, reported by os.stat()."""
      60      return os.stat(filename).st_atime
      61  
      62  
      63  def getctime(filename):
      64      """Return the metadata change time of a file, reported by os.stat()."""
      65      return os.stat(filename).st_ctime
      66  
      67  
      68  # Return the longest prefix of all list elements.
      69  def commonprefix(m):
      70      "Given a list of pathnames, returns the longest common leading component"
      71      if not m: return ''
      72      # Some people pass in a list of pathname parts to operate in an OS-agnostic
      73      # fashion; don't try to translate in that case as that's an abuse of the
      74      # API and they are already doing what they need to be OS-agnostic and so
      75      # they most likely won't be using an os.PathLike object in the sublists.
      76      if not isinstance(m[0], (list, tuple)):
      77          m = tuple(map(os.fspath, m))
      78      s1 = min(m)
      79      s2 = max(m)
      80      for i, c in enumerate(s1):
      81          if c != s2[i]:
      82              return s1[:i]
      83      return s1
      84  
      85  # Are two stat buffers (obtained from stat, fstat or lstat)
      86  # describing the same file?
      87  def samestat(s1, s2):
      88      """Test whether two stat buffers reference the same file"""
      89      return (s1.st_ino == s2.st_ino and
      90              s1.st_dev == s2.st_dev)
      91  
      92  
      93  # Are two filenames really pointing to the same file?
      94  def samefile(f1, f2):
      95      """Test whether two pathnames reference the same actual file or directory
      96  
      97      This is determined by the device number and i-node number and
      98      raises an exception if an os.stat() call on either pathname fails.
      99      """
     100      s1 = os.stat(f1)
     101      s2 = os.stat(f2)
     102      return samestat(s1, s2)
     103  
     104  
     105  # Are two open files really referencing the same file?
     106  # (Not necessarily the same file descriptor!)
     107  def sameopenfile(fp1, fp2):
     108      """Test whether two open file objects reference the same file"""
     109      s1 = os.fstat(fp1)
     110      s2 = os.fstat(fp2)
     111      return samestat(s1, s2)
     112  
     113  
     114  # Split a path in root and extension.
     115  # The extension is everything starting at the last dot in the last
     116  # pathname component; the root is everything before that.
     117  # It is always true that root + ext == p.
     118  
     119  # Generic implementation of splitext, to be parametrized with
     120  # the separators
     121  def _splitext(p, sep, altsep, extsep):
     122      """Split the extension from a pathname.
     123  
     124      Extension is everything from the last dot to the end, ignoring
     125      leading dots.  Returns "(root, ext)"; ext may be empty."""
     126      # NOTE: This code must work for text and bytes strings.
     127  
     128      sepIndex = p.rfind(sep)
     129      if altsep:
     130          altsepIndex = p.rfind(altsep)
     131          sepIndex = max(sepIndex, altsepIndex)
     132  
     133      dotIndex = p.rfind(extsep)
     134      if dotIndex > sepIndex:
     135          # skip all leading dots
     136          filenameIndex = sepIndex + 1
     137          while filenameIndex < dotIndex:
     138              if p[filenameIndex:filenameIndex+1] != extsep:
     139                  return p[:dotIndex], p[dotIndex:]
     140              filenameIndex += 1
     141  
     142      return p, p[:0]
     143  
     144  def _check_arg_types(funcname, *args):
     145      hasstr = hasbytes = False
     146      for s in args:
     147          if isinstance(s, str):
     148              hasstr = True
     149          elif isinstance(s, bytes):
     150              hasbytes = True
     151          else:
     152              raise TypeError(f'{funcname}() argument must be str, bytes, or '
     153                              f'os.PathLike object, not {s.__class__.__name__!r}') from None
     154      if hasstr and hasbytes:
     155          raise TypeError("Can't mix strings and bytes in path components") from None