OXIESEC PANEL
- Current Dir:
/
/
usr
/
lib
/
python3.7
Server IP: 139.59.38.164
Upload:
Create Dir:
Name
Size
Modified
Perms
📁
..
-
10/28/2024 06:50:42 AM
rwxr-xr-x
📄
LICENSE.txt
12.47 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
__future__.py
4.98 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
__phello__.foo.py
64 bytes
12/09/2021 05:04:37 PM
rw-r--r--
📁
__pycache__
-
05/09/2024 06:49:08 AM
rwxr-xr-x
📄
_bootlocale.py
1.76 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
_collections_abc.py
25.8 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
_compat_pickle.py
8.54 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
_compression.py
5.21 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
_dummy_thread.py
5.89 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
_markupbase.py
14.26 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
_osx_support.py
18.67 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
_py_abc.py
6.04 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
_pydecimal.py
223.18 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
_pyio.py
89.33 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
_sitebuiltins.py
3.04 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
_strptime.py
24.91 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
_sysconfigdata_m_linux_x86_64-linux-gnu.py
24.06 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
_threading_local.py
7.04 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
_weakrefset.py
5.55 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
abc.py
5.45 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
aifc.py
32.04 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
antigravity.py
477 bytes
12/09/2021 05:04:37 PM
rw-r--r--
📄
argparse.py
93.31 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
ast.py
12.56 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
asynchat.py
11.06 KB
12/09/2021 05:04:37 PM
rw-r--r--
📁
asyncio
-
05/09/2024 06:49:07 AM
rwxr-xr-x
📄
asyncore.py
19.65 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
base64.py
19.9 KB
12/09/2021 05:04:37 PM
rwxr-xr-x
📄
bdb.py
31.18 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
binhex.py
13.63 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
bisect.py
2.5 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
bz2.py
12.12 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
cProfile.py
6.09 KB
12/09/2021 05:04:37 PM
rwxr-xr-x
📄
calendar.py
24.24 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
cgi.py
33.84 KB
12/09/2021 05:04:37 PM
rwxr-xr-x
📄
cgitb.py
11.74 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
chunk.py
5.31 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
cmd.py
14.51 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
code.py
10.37 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
codecs.py
35.68 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
codeop.py
5.85 KB
12/09/2021 05:04:37 PM
rw-r--r--
📁
collections
-
05/09/2024 06:49:07 AM
rwxr-xr-x
📄
colorsys.py
3.97 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
compileall.py
13.33 KB
12/09/2021 05:04:37 PM
rw-r--r--
📁
concurrent
-
05/09/2024 06:49:08 AM
rwxr-xr-x
📄
configparser.py
53.01 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
contextlib.py
24.18 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
contextvars.py
129 bytes
12/09/2021 05:04:37 PM
rw-r--r--
📄
copy.py
8.61 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
copyreg.py
6.85 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
crypt.py
3.27 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
csv.py
15.8 KB
12/09/2021 05:04:37 PM
rw-r--r--
📁
ctypes
-
05/09/2024 06:49:08 AM
rwxr-xr-x
📁
curses
-
05/09/2024 06:49:08 AM
rwxr-xr-x
📄
dataclasses.py
47.7 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
datetime.py
84.52 KB
12/09/2021 05:04:37 PM
rw-r--r--
📁
dbm
-
05/09/2024 06:49:08 AM
rwxr-xr-x
📄
decimal.py
320 bytes
12/09/2021 05:04:37 PM
rw-r--r--
📄
difflib.py
82.41 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
dis.py
19.42 KB
12/09/2021 05:04:37 PM
rw-r--r--
📁
distutils
-
05/09/2024 06:57:52 AM
rwxr-xr-x
📄
doctest.py
101.84 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
dummy_threading.py
2.75 KB
12/09/2021 05:04:37 PM
rw-r--r--
📁
email
-
05/09/2024 06:49:08 AM
rwxr-xr-x
📁
encodings
-
05/09/2024 06:49:07 AM
rwxr-xr-x
📁
ensurepip
-
05/09/2024 07:26:24 AM
rwxr-xr-x
📄
enum.py
33.96 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
filecmp.py
9.6 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
fileinput.py
14.28 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
fnmatch.py
3.96 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
formatter.py
14.79 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
fractions.py
23.08 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
ftplib.py
34.43 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
functools.py
32.16 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
genericpath.py
4.8 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
getopt.py
7.31 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
getpass.py
5.85 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
gettext.py
21.87 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
glob.py
5.51 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
gzip.py
19.86 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
hashlib.py
9.31 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
heapq.py
22.48 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
hmac.py
6.36 KB
12/09/2021 05:04:37 PM
rw-r--r--
📁
html
-
05/09/2024 06:49:08 AM
rwxr-xr-x
📁
http
-
05/09/2024 06:49:08 AM
rwxr-xr-x
📄
imaplib.py
52.04 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
imghdr.py
3.71 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
imp.py
10.29 KB
12/09/2021 05:04:37 PM
rw-r--r--
📁
importlib
-
05/09/2024 06:49:07 AM
rwxr-xr-x
📄
inspect.py
114.88 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
io.py
3.43 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
ipaddress.py
71.84 KB
12/09/2021 05:04:37 PM
rw-r--r--
📁
json
-
05/09/2024 06:49:08 AM
rwxr-xr-x
📄
keyword.py
2.19 KB
12/09/2021 05:04:37 PM
rwxr-xr-x
📁
lib-dynload
-
05/09/2024 07:13:53 AM
rwxr-xr-x
📁
lib2to3
-
05/09/2024 06:58:00 AM
rwxr-xr-x
📄
linecache.py
5.19 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
locale.py
76.36 KB
12/09/2021 05:04:37 PM
rw-r--r--
📁
logging
-
05/09/2024 06:49:07 AM
rwxr-xr-x
📄
lzma.py
12.68 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
macpath.py
5.98 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
mailbox.py
76.81 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
mailcap.py
7.91 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
mimetypes.py
20.99 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
modulefinder.py
22.5 KB
12/09/2021 05:04:37 PM
rw-r--r--
📁
multiprocessing
-
05/09/2024 06:49:08 AM
rwxr-xr-x
📄
netrc.py
5.44 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
nntplib.py
42.08 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
ntpath.py
21.82 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
nturl2path.py
2.52 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
numbers.py
10 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
opcode.py
5.69 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
operator.py
10.61 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
optparse.py
58.96 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
os.py
36.9 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
pathlib.py
48.54 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
pdb.py
61.03 KB
12/09/2021 05:04:37 PM
rwxr-xr-x
📄
pickle.py
56.63 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
pickletools.py
89.08 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
pipes.py
8.71 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
pkgutil.py
20.96 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
platform.py
46.84 KB
12/09/2021 05:04:37 PM
rwxr-xr-x
📄
plistlib.py
29.2 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
poplib.py
14.61 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
posixpath.py
15.4 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
pprint.py
20.39 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
profile.py
21.95 KB
12/09/2021 05:04:37 PM
rwxr-xr-x
📄
pstats.py
26.67 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
pty.py
4.65 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
py_compile.py
7.81 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
pyclbr.py
14.78 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
pydoc.py
104.52 KB
12/09/2021 05:04:37 PM
rwxr-xr-x
📁
pydoc_data
-
05/09/2024 06:49:08 AM
rwxr-xr-x
📄
queue.py
11.09 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
quopri.py
7.08 KB
12/09/2021 05:04:37 PM
rwxr-xr-x
📄
random.py
26.91 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
re.py
14.84 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
reprlib.py
5.14 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
rlcompleter.py
6.93 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
runpy.py
11.68 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
sched.py
6.29 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
secrets.py
1.99 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
selectors.py
18.13 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
shelve.py
8.33 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
shlex.py
12.74 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
shutil.py
40.97 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
signal.py
2.07 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
site.py
21.79 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
sitecustomize.py
155 bytes
12/09/2021 05:04:37 PM
rw-r--r--
📄
smtpd.py
33.9 KB
12/09/2021 05:04:37 PM
rwxr-xr-x
📄
smtplib.py
43.17 KB
12/09/2021 05:04:37 PM
rwxr-xr-x
📄
sndhdr.py
6.92 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
socket.py
26.72 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
socketserver.py
26.29 KB
12/09/2021 05:04:37 PM
rw-r--r--
📁
sqlite3
-
05/09/2024 06:49:08 AM
rwxr-xr-x
📄
sre_compile.py
26.24 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
sre_constants.py
7.01 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
sre_parse.py
38.24 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
ssl.py
44.43 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
stat.py
4.92 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
statistics.py
20.17 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
string.py
11.29 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
stringprep.py
12.61 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
struct.py
257 bytes
12/09/2021 05:04:37 PM
rw-r--r--
📄
subprocess.py
70 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
sunau.py
17.94 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
symbol.py
2.08 KB
12/09/2021 05:04:37 PM
rwxr-xr-x
📄
symtable.py
7.1 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
sysconfig.py
23.94 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
tabnanny.py
11.14 KB
12/09/2021 05:04:37 PM
rwxr-xr-x
📄
tarfile.py
90.45 KB
12/09/2021 05:04:37 PM
rwxr-xr-x
📄
telnetlib.py
22.59 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
tempfile.py
31.06 KB
12/09/2021 05:04:37 PM
rw-r--r--
📁
test
-
05/09/2024 06:49:08 AM
rwxr-xr-x
📄
textwrap.py
18.95 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
this.py
1003 bytes
12/09/2021 05:04:37 PM
rw-r--r--
📄
threading.py
47.9 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
timeit.py
13.13 KB
12/09/2021 05:04:37 PM
rwxr-xr-x
📄
token.py
3.67 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
tokenize.py
26.4 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
trace.py
28.3 KB
12/09/2021 05:04:37 PM
rwxr-xr-x
📄
traceback.py
22.89 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
tracemalloc.py
16.68 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
tty.py
879 bytes
12/09/2021 05:04:37 PM
rw-r--r--
📄
turtle.py
140.24 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
types.py
9.67 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
typing.py
54.37 KB
12/09/2021 05:04:37 PM
rw-r--r--
📁
unittest
-
05/09/2024 06:49:08 AM
rwxr-xr-x
📁
urllib
-
05/09/2024 06:49:08 AM
rwxr-xr-x
📄
uu.py
6.65 KB
12/09/2021 05:04:37 PM
rwxr-xr-x
📄
uuid.py
28.83 KB
12/09/2021 05:04:37 PM
rw-r--r--
📁
venv
-
05/09/2024 06:49:08 AM
rwxr-xr-x
📄
warnings.py
19.77 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
wave.py
17.8 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
weakref.py
21 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
webbrowser.py
22.55 KB
12/09/2021 05:04:37 PM
rwxr-xr-x
📁
wsgiref
-
05/09/2024 06:49:08 AM
rwxr-xr-x
📄
xdrlib.py
5.77 KB
12/09/2021 05:04:37 PM
rw-r--r--
📁
xml
-
05/09/2024 06:49:08 AM
rwxr-xr-x
📁
xmlrpc
-
05/09/2024 06:49:08 AM
rwxr-xr-x
📄
zipapp.py
7.36 KB
12/09/2021 05:04:37 PM
rw-r--r--
📄
zipfile.py
78.63 KB
12/09/2021 05:04:37 PM
rw-r--r--
Editing: ntpath.py
Close
# Module 'ntpath' -- common operations on WinNT/Win95 pathnames """Common pathname manipulations, WindowsNT/95 version. Instead of importing this module directly, import os and refer to this module as os.path. """ # strings representing various path-related bits and pieces # These are primarily for export; internally, they are hardcoded. # Should be set before imports for resolving cyclic dependency. curdir = '.' pardir = '..' extsep = '.' sep = '\\' pathsep = ';' altsep = '/' defpath = '.;C:\\bin' devnull = 'nul' import os import sys import stat import genericpath from genericpath import * __all__ = ["normcase","isabs","join","splitdrive","split","splitext", "basename","dirname","commonprefix","getsize","getmtime", "getatime","getctime", "islink","exists","lexists","isdir","isfile", "ismount", "expanduser","expandvars","normpath","abspath", "curdir","pardir","sep","pathsep","defpath","altsep", "extsep","devnull","realpath","supports_unicode_filenames","relpath", "samefile", "sameopenfile", "samestat", "commonpath"] def _get_bothseps(path): if isinstance(path, bytes): return b'\\/' else: return '\\/' # Normalize the case of a pathname and map slashes to backslashes. # Other normalizations (such as optimizing '../' away) are not done # (this is done by normpath). def normcase(s): """Normalize case of pathname. Makes all characters lowercase and all slashes into backslashes.""" s = os.fspath(s) try: if isinstance(s, bytes): return s.replace(b'/', b'\\').lower() else: return s.replace('/', '\\').lower() except (TypeError, AttributeError): if not isinstance(s, (bytes, str)): raise TypeError("normcase() argument must be str or bytes, " "not %r" % s.__class__.__name__) from None raise # Return whether a path is absolute. # Trivial in Posix, harder on Windows. # For Windows it is absolute if it starts with a slash or backslash (current # volume), or if a pathname after the volume-letter-and-colon or UNC-resource # starts with a slash or backslash. def isabs(s): """Test whether a path is absolute""" s = os.fspath(s) s = splitdrive(s)[1] return len(s) > 0 and s[0] in _get_bothseps(s) # Join two (or more) paths. def join(path, *paths): path = os.fspath(path) if isinstance(path, bytes): sep = b'\\' seps = b'\\/' colon = b':' else: sep = '\\' seps = '\\/' colon = ':' try: if not paths: path[:0] + sep #23780: Ensure compatible data type even if p is null. result_drive, result_path = splitdrive(path) for p in map(os.fspath, paths): p_drive, p_path = splitdrive(p) if p_path and p_path[0] in seps: # Second path is absolute if p_drive or not result_drive: result_drive = p_drive result_path = p_path continue elif p_drive and p_drive != result_drive: if p_drive.lower() != result_drive.lower(): # Different drives => ignore the first path entirely result_drive = p_drive result_path = p_path continue # Same drive in different case result_drive = p_drive # Second path is relative to the first if result_path and result_path[-1] not in seps: result_path = result_path + sep result_path = result_path + p_path ## add separator between UNC and non-absolute path if (result_path and result_path[0] not in seps and result_drive and result_drive[-1:] != colon): return result_drive + sep + result_path return result_drive + result_path except (TypeError, AttributeError, BytesWarning): genericpath._check_arg_types('join', path, *paths) raise # Split a path in a drive specification (a drive letter followed by a # colon) and the path specification. # It is always true that drivespec + pathspec == p def splitdrive(p): """Split a pathname into drive/UNC sharepoint and relative path specifiers. Returns a 2-tuple (drive_or_unc, path); either part may be empty. If you assign result = splitdrive(p) It is always true that: result[0] + result[1] == p If the path contained a drive letter, drive_or_unc will contain everything up to and including the colon. e.g. splitdrive("c:/dir") returns ("c:", "/dir") If the path contained a UNC path, the drive_or_unc will contain the host name and share up to but not including the fourth directory separator character. e.g. splitdrive("//host/computer/dir") returns ("//host/computer", "/dir") Paths cannot contain both a drive letter and a UNC path. """ p = os.fspath(p) if len(p) >= 2: if isinstance(p, bytes): sep = b'\\' altsep = b'/' colon = b':' else: sep = '\\' altsep = '/' colon = ':' normp = p.replace(altsep, sep) if (normp[0:2] == sep*2) and (normp[2:3] != sep): # is a UNC path: # vvvvvvvvvvvvvvvvvvvv drive letter or UNC path # \\machine\mountpoint\directory\etc\... # directory ^^^^^^^^^^^^^^^ index = normp.find(sep, 2) if index == -1: return p[:0], p index2 = normp.find(sep, index + 1) # a UNC path can't have two slashes in a row # (after the initial two) if index2 == index + 1: return p[:0], p if index2 == -1: index2 = len(p) return p[:index2], p[index2:] if normp[1:2] == colon: return p[:2], p[2:] return p[:0], p # Split a path in head (everything up to the last '/') and tail (the # rest). After the trailing '/' is stripped, the invariant # join(head, tail) == p holds. # The resulting head won't end in '/' unless it is the root. def split(p): """Split a pathname. Return tuple (head, tail) where tail is everything after the final slash. Either part may be empty.""" p = os.fspath(p) seps = _get_bothseps(p) d, p = splitdrive(p) # set i to index beyond p's last slash i = len(p) while i and p[i-1] not in seps: i -= 1 head, tail = p[:i], p[i:] # now tail has no slashes # remove trailing slashes from head, unless it's all slashes head = head.rstrip(seps) or head return d + head, tail # Split a path in root and extension. # The extension is everything starting at the last dot in the last # pathname component; the root is everything before that. # It is always true that root + ext == p. def splitext(p): p = os.fspath(p) if isinstance(p, bytes): return genericpath._splitext(p, b'\\', b'/', b'.') else: return genericpath._splitext(p, '\\', '/', '.') splitext.__doc__ = genericpath._splitext.__doc__ # Return the tail (basename) part of a path. def basename(p): """Returns the final component of a pathname""" return split(p)[1] # Return the head (dirname) part of a path. def dirname(p): """Returns the directory component of a pathname""" return split(p)[0] # Is a path a symbolic link? # This will always return false on systems where os.lstat doesn't exist. def islink(path): """Test whether a path is a symbolic link. This will always return false for Windows prior to 6.0. """ try: st = os.lstat(path) except (OSError, AttributeError): return False return stat.S_ISLNK(st.st_mode) # Being true for dangling symbolic links is also useful. def lexists(path): """Test whether a path exists. Returns True for broken symbolic links""" try: st = os.lstat(path) except OSError: return False return True # Is a path a mount point? # Any drive letter root (eg c:\) # Any share UNC (eg \\server\share) # Any volume mounted on a filesystem folder # # No one method detects all three situations. Historically we've lexically # detected drive letter roots and share UNCs. The canonical approach to # detecting mounted volumes (querying the reparse tag) fails for the most # common case: drive letter roots. The alternative which uses GetVolumePathName # fails if the drive letter is the result of a SUBST. try: from nt import _getvolumepathname except ImportError: _getvolumepathname = None def ismount(path): """Test whether a path is a mount point (a drive root, the root of a share, or a mounted volume)""" path = os.fspath(path) seps = _get_bothseps(path) path = abspath(path) root, rest = splitdrive(path) if root and root[0] in seps: return (not rest) or (rest in seps) if rest in seps: return True if _getvolumepathname: return path.rstrip(seps) == _getvolumepathname(path).rstrip(seps) else: return False # Expand paths beginning with '~' or '~user'. # '~' means $HOME; '~user' means that user's home directory. # If the path doesn't begin with '~', or if the user or $HOME is unknown, # the path is returned unchanged (leaving error reporting to whatever # function is called with the expanded path as argument). # See also module 'glob' for expansion of *, ? and [...] in pathnames. # (A function should also be defined to do full *sh-style environment # variable expansion.) def expanduser(path): """Expand ~ and ~user constructs. If user or $HOME is unknown, do nothing.""" path = os.fspath(path) if isinstance(path, bytes): tilde = b'~' else: tilde = '~' if not path.startswith(tilde): return path i, n = 1, len(path) while i < n and path[i] not in _get_bothseps(path): i += 1 if 'HOME' in os.environ: userhome = os.environ['HOME'] elif 'USERPROFILE' in os.environ: userhome = os.environ['USERPROFILE'] elif not 'HOMEPATH' in os.environ: return path else: try: drive = os.environ['HOMEDRIVE'] except KeyError: drive = '' userhome = join(drive, os.environ['HOMEPATH']) if isinstance(path, bytes): userhome = os.fsencode(userhome) if i != 1: #~user userhome = join(dirname(userhome), path[1:i]) return userhome + path[i:] # Expand paths containing shell variable substitutions. # The following rules apply: # - no expansion within single quotes # - '$$' is translated into '$' # - '%%' is translated into '%' if '%%' are not seen in %var1%%var2% # - ${varname} is accepted. # - $varname is accepted. # - %varname% is accepted. # - varnames can be made out of letters, digits and the characters '_-' # (though is not verified in the ${varname} and %varname% cases) # XXX With COMMAND.COM you can use any characters in a variable name, # XXX except '^|<>='. def expandvars(path): """Expand shell variables of the forms $var, ${var} and %var%. Unknown variables are left unchanged.""" path = os.fspath(path) if isinstance(path, bytes): if b'$' not in path and b'%' not in path: return path import string varchars = bytes(string.ascii_letters + string.digits + '_-', 'ascii') quote = b'\'' percent = b'%' brace = b'{' rbrace = b'}' dollar = b'$' environ = getattr(os, 'environb', None) else: if '$' not in path and '%' not in path: return path import string varchars = string.ascii_letters + string.digits + '_-' quote = '\'' percent = '%' brace = '{' rbrace = '}' dollar = '$' environ = os.environ res = path[:0] index = 0 pathlen = len(path) while index < pathlen: c = path[index:index+1] if c == quote: # no expansion within single quotes path = path[index + 1:] pathlen = len(path) try: index = path.index(c) res += c + path[:index + 1] except ValueError: res += c + path index = pathlen - 1 elif c == percent: # variable or '%' if path[index + 1:index + 2] == percent: res += c index += 1 else: path = path[index+1:] pathlen = len(path) try: index = path.index(percent) except ValueError: res += percent + path index = pathlen - 1 else: var = path[:index] try: if environ is None: value = os.fsencode(os.environ[os.fsdecode(var)]) else: value = environ[var] except KeyError: value = percent + var + percent res += value elif c == dollar: # variable or '$$' if path[index + 1:index + 2] == dollar: res += c index += 1 elif path[index + 1:index + 2] == brace: path = path[index+2:] pathlen = len(path) try: index = path.index(rbrace) except ValueError: res += dollar + brace + path index = pathlen - 1 else: var = path[:index] try: if environ is None: value = os.fsencode(os.environ[os.fsdecode(var)]) else: value = environ[var] except KeyError: value = dollar + brace + var + rbrace res += value else: var = path[:0] index += 1 c = path[index:index + 1] while c and c in varchars: var += c index += 1 c = path[index:index + 1] try: if environ is None: value = os.fsencode(os.environ[os.fsdecode(var)]) else: value = environ[var] except KeyError: value = dollar + var res += value if c: index -= 1 else: res += c index += 1 return res # Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A\B. # Previously, this function also truncated pathnames to 8+3 format, # but as this module is called "ntpath", that's obviously wrong! def normpath(path): """Normalize path, eliminating double slashes, etc.""" path = os.fspath(path) if isinstance(path, bytes): sep = b'\\' altsep = b'/' curdir = b'.' pardir = b'..' special_prefixes = (b'\\\\.\\', b'\\\\?\\') else: sep = '\\' altsep = '/' curdir = '.' pardir = '..' special_prefixes = ('\\\\.\\', '\\\\?\\') if path.startswith(special_prefixes): # in the case of paths with these prefixes: # \\.\ -> device names # \\?\ -> literal paths # do not do any normalization, but return the path unchanged return path path = path.replace(altsep, sep) prefix, path = splitdrive(path) # collapse initial backslashes if path.startswith(sep): prefix += sep path = path.lstrip(sep) comps = path.split(sep) i = 0 while i < len(comps): if not comps[i] or comps[i] == curdir: del comps[i] elif comps[i] == pardir: if i > 0 and comps[i-1] != pardir: del comps[i-1:i+1] i -= 1 elif i == 0 and prefix.endswith(sep): del comps[i] else: i += 1 else: i += 1 # If the path is now empty, substitute '.' if not prefix and not comps: comps.append(curdir) return prefix + sep.join(comps) def _abspath_fallback(path): """Return the absolute version of a path as a fallback function in case `nt._getfullpathname` is not available or raises OSError. See bpo-31047 for more. """ path = os.fspath(path) if not isabs(path): if isinstance(path, bytes): cwd = os.getcwdb() else: cwd = os.getcwd() path = join(cwd, path) return normpath(path) # Return an absolute path. try: from nt import _getfullpathname except ImportError: # not running on Windows - mock up something sensible abspath = _abspath_fallback else: # use native Windows method on Windows def abspath(path): """Return the absolute version of a path.""" try: return normpath(_getfullpathname(path)) except (OSError, ValueError): return _abspath_fallback(path) # realpath is a no-op on systems without islink support realpath = abspath # Win9x family and earlier have no Unicode filename support. supports_unicode_filenames = (hasattr(sys, "getwindowsversion") and sys.getwindowsversion()[3] >= 2) def relpath(path, start=None): """Return a relative version of a path""" path = os.fspath(path) if isinstance(path, bytes): sep = b'\\' curdir = b'.' pardir = b'..' else: sep = '\\' curdir = '.' pardir = '..' if start is None: start = curdir if not path: raise ValueError("no path specified") start = os.fspath(start) try: start_abs = abspath(normpath(start)) path_abs = abspath(normpath(path)) start_drive, start_rest = splitdrive(start_abs) path_drive, path_rest = splitdrive(path_abs) if normcase(start_drive) != normcase(path_drive): raise ValueError("path is on mount %r, start on mount %r" % ( path_drive, start_drive)) start_list = [x for x in start_rest.split(sep) if x] path_list = [x for x in path_rest.split(sep) if x] # Work out how much of the filepath is shared by start and path. i = 0 for e1, e2 in zip(start_list, path_list): if normcase(e1) != normcase(e2): break i += 1 rel_list = [pardir] * (len(start_list)-i) + path_list[i:] if not rel_list: return curdir return join(*rel_list) except (TypeError, ValueError, AttributeError, BytesWarning, DeprecationWarning): genericpath._check_arg_types('relpath', path, start) raise # Return the longest common sub-path of the sequence of paths given as input. # The function is case-insensitive and 'separator-insensitive', i.e. if the # only difference between two paths is the use of '\' versus '/' as separator, # they are deemed to be equal. # # However, the returned path will have the standard '\' separator (even if the # given paths had the alternative '/' separator) and will have the case of the # first path given in the sequence. Additionally, any trailing separator is # stripped from the returned path. def commonpath(paths): """Given a sequence of path names, returns the longest common sub-path.""" if not paths: raise ValueError('commonpath() arg is an empty sequence') paths = tuple(map(os.fspath, paths)) if isinstance(paths[0], bytes): sep = b'\\' altsep = b'/' curdir = b'.' else: sep = '\\' altsep = '/' curdir = '.' try: drivesplits = [splitdrive(p.replace(altsep, sep).lower()) for p in paths] split_paths = [p.split(sep) for d, p in drivesplits] try: isabs, = set(p[:1] == sep for d, p in drivesplits) except ValueError: raise ValueError("Can't mix absolute and relative paths") from None # Check that all drive letters or UNC paths match. The check is made only # now otherwise type errors for mixing strings and bytes would not be # caught. if len(set(d for d, p in drivesplits)) != 1: raise ValueError("Paths don't have the same drive") drive, path = splitdrive(paths[0].replace(altsep, sep)) common = path.split(sep) common = [c for c in common if c and c != curdir] 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) for i, c in enumerate(s1): if c != s2[i]: common = common[:i] break else: common = common[:len(s1)] prefix = drive + sep if isabs else drive return prefix + sep.join(common) except (TypeError, AttributeError): genericpath._check_arg_types('commonpath', *paths) raise # determine if two files are in fact the same file try: # GetFinalPathNameByHandle is available starting with Windows 6.0. # Windows XP and non-Windows OS'es will mock _getfinalpathname. if sys.getwindowsversion()[:2] >= (6, 0): from nt import _getfinalpathname else: raise ImportError except (AttributeError, ImportError): # On Windows XP and earlier, two files are the same if their absolute # pathnames are the same. # Non-Windows operating systems fake this method with an XP # approximation. def _getfinalpathname(f): return normcase(abspath(f)) try: # The genericpath.isdir implementation uses os.stat and checks the mode # attribute to tell whether or not the path is a directory. # This is overkill on Windows - just pass the path to GetFileAttributes # and check the attribute from there. from nt import _isdir as isdir except ImportError: # Use genericpath.isdir as imported above. pass