curdir = '.'
pardir = '..'
extsep = '.'
sep = '/'
pathsep = ':'
defpath = '/bin:/usr/bin'
altsep = None
devnull = '/dev/null'
import errno
import os
import sys
import stat
import genericpath
from genericpath import *
__all__ = ["normcase","isabs","join","splitdrive","splitroot","split","splitext",
"basename","dirname","commonprefix","getsize","getmtime",
"getatime","getctime","islink","exists","lexists","isdir","isfile",
"ismount", "expanduser","expandvars","normpath","abspath",
"samefile","sameopenfile","samestat",
"curdir","pardir","sep","pathsep","defpath","altsep","extsep",
"devnull","realpath","supports_unicode_filenames","relpath",
"commonpath", "isjunction","isdevdrive","ALLOW_MISSING"]
def _get_sep(path):
if isinstance(path, bytes):
return b'/'
else:
return '/'
def normcase(s):
return os.fspath(s)
def isabs(s):
s = os.fspath(s)
sep = _get_sep(s)
return s.startswith(sep)
def join(a, *p):
a = os.fspath(a)
sep = _get_sep(a)
path = a
try:
for b in p:
b = os.fspath(b)
if b.startswith(sep) or not path:
path = b
elif path.endswith(sep):
path += b
else:
path += sep + b
except (TypeError, AttributeError, BytesWarning):
genericpath._check_arg_types('join', a, *p)
raise
return path
def split(p):
p = os.fspath(p)
sep = _get_sep(p)
i = p.rfind(sep) + 1
head, tail = p[:i], p[i:]
if head and head != sep*len(head):
head = head.rstrip(sep)
return head, tail
def splitext(p):
p = os.fspath(p)
if isinstance(p, bytes):
sep = b'/'
extsep = b'.'
else:
sep = '/'
extsep = '.'
return genericpath._splitext(p, sep, None, extsep)
splitext.__doc__ = genericpath._splitext.__doc__
def splitdrive(p):
p = os.fspath(p)
return p[:0], p
try:
from posix import _path_splitroot_ex as splitroot
except ImportError:
def splitroot(p):
p = os.fspath(p)
if isinstance(p, bytes):
sep = b'/'
empty = b''
else:
sep = '/'
empty = ''
if p[:1] != sep:
return empty, empty, p
elif p[1:2] != sep or p[2:3] == sep:
return empty, sep, p[1:]
else:
return empty, p[:2], p[2:]
def basename(p):
p = os.fspath(p)
sep = _get_sep(p)
i = p.rfind(sep) + 1
return p[i:]
def dirname(p):
p = os.fspath(p)
sep = _get_sep(p)
i = p.rfind(sep) + 1
head = p[:i]
if head and head != sep*len(head):
head = head.rstrip(sep)
return head
def ismount(path):
try:
s1 = os.lstat(path)
except (OSError, ValueError):
return False
else:
if stat.S_ISLNK(s1.st_mode):
return False
path = os.fspath(path)
if isinstance(path, bytes):
parent = join(path, b'..')
else:
parent = join(path, '..')
try:
s2 = os.lstat(parent)
except OSError:
parent = realpath(parent)
try:
s2 = os.lstat(parent)
except OSError:
return False
return s1.st_dev != s2.st_dev or s1.st_ino == s2.st_ino
def expanduser(path):
path = os.fspath(path)
if isinstance(path, bytes):
tilde = b'~'
else:
tilde = '~'
if not path.startswith(tilde):
return path
sep = _get_sep(path)
i = path.find(sep, 1)
if i < 0:
i = len(path)
if i == 1:
if 'HOME' not in os.environ:
try:
import pwd
except ImportError:
return path
try:
userhome = pwd.getpwuid(os.getuid()).pw_dir
except KeyError:
return path
else:
userhome = os.environ['HOME']
else:
try:
import pwd
except ImportError:
return path
name = path[1:i]
if isinstance(name, bytes):
name = os.fsdecode(name)
try:
pwent = pwd.getpwnam(name)
except KeyError:
return path
userhome = pwent.pw_dir
if userhome is None and sys.platform == "vxworks":
return path
if isinstance(path, bytes):
userhome = os.fsencode(userhome)
userhome = userhome.rstrip(sep)
return (userhome + path[i:]) or sep
_varpattern = r'\$(\w+|\{[^}]*\}?)'
_varsub = None
_varsubb = None
def expandvars(path):
path = os.fspath(path)
global _varsub, _varsubb
if isinstance(path, bytes):
if b'$' not in path:
return path
if not _varsubb:
import re
_varsubb = re.compile(_varpattern.encode(), re.ASCII).sub
sub = _varsubb
start = b'{'
end = b'}'
environ = getattr(os, 'environb', None)
else:
if '$' not in path:
return path
if not _varsub:
import re
_varsub = re.compile(_varpattern, re.ASCII).sub
sub = _varsub
start = '{'
end = '}'
environ = os.environ
def repl(m):
name = m[1]
if name.startswith(start):
if not name.endswith(end):
return m[0]
name = name[1:-1]
try:
if environ is None:
value = os.fsencode(os.environ[os.fsdecode(name)])
else:
value = environ[name]
except KeyError:
return m[0]
else:
return value
return sub(repl, path)
try:
from posix import _path_normpath as normpath
except ImportError:
def normpath(path):
path = os.fspath(path)
if isinstance(path, bytes):
sep = b'/'
dot = b'.'
dotdot = b'..'
else:
sep = '/'
dot = '.'
dotdot = '..'
if not path:
return dot
_, initial_slashes, path = splitroot(path)
comps = path.split(sep)
new_comps = []
for comp in comps:
if not comp or comp == dot:
continue
if (comp != dotdot or (not initial_slashes and not new_comps) or
(new_comps and new_comps[-1] == dotdot)):
new_comps.append(comp)
elif new_comps:
new_comps.pop()
comps = new_comps
path = initial_slashes + sep.join(comps)
return path or dot
def abspath(path):
path = os.fspath(path)
if isinstance(path, bytes):
if not path.startswith(b'/'):
path = join(os.getcwdb(), path)
else:
if not path.startswith('/'):
path = join(os.getcwd(), path)
return normpath(path)
def realpath(filename, *, strict=False):
filename = os.fspath(filename)
if isinstance(filename, bytes):
sep = b'/'
curdir = b'.'
pardir = b'..'
getcwd = os.getcwdb
else:
sep = '/'
curdir = '.'
pardir = '..'
getcwd = os.getcwd
if strict is ALLOW_MISSING:
ignored_error = FileNotFoundError
strict = True
elif strict:
ignored_error = ()
else:
ignored_error = OSError
lstat = os.lstat
readlink = os.readlink
maxlinks = None
rest = filename.split(sep)[::-1]
part_count = len(rest)
path = sep if filename.startswith(sep) else getcwd()
seen = {}
link_count = 0
while part_count:
name = rest.pop()
if name is None:
seen[rest.pop()] = path
continue
part_count -= 1
if not name or name == curdir:
continue
if name == pardir:
path = path[:path.rindex(sep)] or sep
continue
if path == sep:
newpath = path + name
else:
newpath = path + sep + name
try:
st_mode = lstat(newpath).st_mode
if not stat.S_ISLNK(st_mode):
if strict and part_count and not stat.S_ISDIR(st_mode):
raise OSError(errno.ENOTDIR, os.strerror(errno.ENOTDIR),
newpath)
path = newpath
continue
elif maxlinks is not None:
link_count += 1
if link_count > maxlinks:
if strict:
raise OSError(errno.ELOOP, os.strerror(errno.ELOOP),
newpath)
path = newpath
continue
elif newpath in seen:
path = seen[newpath]
if path is not None:
continue
if strict:
raise OSError(errno.ELOOP, os.strerror(errno.ELOOP),
newpath)
path = newpath
continue
target = readlink(newpath)
except ignored_error:
pass
else:
if target.startswith(sep):
path = sep
if maxlinks is None:
seen[newpath] = None
rest.append(newpath)
rest.append(None)
target_parts = target.split(sep)[::-1]
rest.extend(target_parts)
part_count += len(target_parts)
continue
path = newpath
return path
supports_unicode_filenames = (sys.platform == 'darwin')
def relpath(path, start=None):
path = os.fspath(path)
if not path:
raise ValueError("no path specified")
if isinstance(path, bytes):
curdir = b'.'
sep = b'/'
pardir = b'..'
else:
curdir = '.'
sep = '/'
pardir = '..'
if start is None:
start = curdir
else:
start = os.fspath(start)
try:
start_tail = abspath(start).lstrip(sep)
path_tail = abspath(path).lstrip(sep)
start_list = start_tail.split(sep) if start_tail else []
path_list = path_tail.split(sep) if path_tail else []
i = len(commonprefix([start_list, path_list]))
rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
if not rel_list:
return curdir
return sep.join(rel_list)
except (TypeError, AttributeError, BytesWarning, DeprecationWarning):
genericpath._check_arg_types('relpath', path, start)
raise
def commonpath(paths):
paths = tuple(map(os.fspath, paths))
if not paths:
raise ValueError('commonpath() arg is an empty sequence')
if isinstance(paths[0], bytes):
sep = b'/'
curdir = b'.'
else:
sep = '/'
curdir = '.'
try:
split_paths = [path.split(sep) for path in paths]
try:
isabs, = {p.startswith(sep) for p in paths}
except ValueError:
raise ValueError("Can't mix absolute and relative paths") from None
split_paths = [[c for c in s if c and c != curdir] for s in split_paths]
s1 = min(split_paths)
s2 = max(split_paths)
common = s1
for i, c in enumerate(s1):
if c != s2[i]:
common = s1[:i]
break
prefix = sep if isabs else sep[:0]
return prefix + sep.join(common)
except (TypeError, AttributeError):
genericpath._check_arg_types('commonpath', *paths)
raise