mirror of
https://github.com/python/cpython.git
synced 2025-08-31 05:58:33 +00:00
gh-102511: Speed up os.path.splitroot() with native helpers (GH-118089)
This commit is contained in:
parent
e38b43c213
commit
10bb90ed49
8 changed files with 337 additions and 108 deletions
|
@ -134,33 +134,53 @@ def splitdrive(p):
|
|||
return p[:0], p
|
||||
|
||||
|
||||
def splitroot(p):
|
||||
"""Split a pathname into drive, root and tail. On Posix, drive is always
|
||||
empty; the root may be empty, a single slash, or two slashes. The tail
|
||||
contains anything after the root. For example:
|
||||
try:
|
||||
from posix import _path_splitroot_ex
|
||||
except ImportError:
|
||||
def splitroot(p):
|
||||
"""Split a pathname into drive, root and tail. On Posix, drive is always
|
||||
empty; the root may be empty, a single slash, or two slashes. The tail
|
||||
contains anything after the root. For example:
|
||||
|
||||
splitroot('foo/bar') == ('', '', 'foo/bar')
|
||||
splitroot('/foo/bar') == ('', '/', 'foo/bar')
|
||||
splitroot('//foo/bar') == ('', '//', 'foo/bar')
|
||||
splitroot('///foo/bar') == ('', '/', '//foo/bar')
|
||||
"""
|
||||
p = os.fspath(p)
|
||||
if isinstance(p, bytes):
|
||||
sep = b'/'
|
||||
empty = b''
|
||||
else:
|
||||
sep = '/'
|
||||
empty = ''
|
||||
if p[:1] != sep:
|
||||
# Relative path, e.g.: 'foo'
|
||||
return empty, empty, p
|
||||
elif p[1:2] != sep or p[2:3] == sep:
|
||||
# Absolute path, e.g.: '/foo', '///foo', '////foo', etc.
|
||||
return empty, sep, p[1:]
|
||||
else:
|
||||
# Precisely two leading slashes, e.g.: '//foo'. Implementation defined per POSIX, see
|
||||
# https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
|
||||
return empty, p[:2], p[2:]
|
||||
splitroot('foo/bar') == ('', '', 'foo/bar')
|
||||
splitroot('/foo/bar') == ('', '/', 'foo/bar')
|
||||
splitroot('//foo/bar') == ('', '//', 'foo/bar')
|
||||
splitroot('///foo/bar') == ('', '/', '//foo/bar')
|
||||
"""
|
||||
p = os.fspath(p)
|
||||
if isinstance(p, bytes):
|
||||
sep = b'/'
|
||||
empty = b''
|
||||
else:
|
||||
sep = '/'
|
||||
empty = ''
|
||||
if p[:1] != sep:
|
||||
# Relative path, e.g.: 'foo'
|
||||
return empty, empty, p
|
||||
elif p[1:2] != sep or p[2:3] == sep:
|
||||
# Absolute path, e.g.: '/foo', '///foo', '////foo', etc.
|
||||
return empty, sep, p[1:]
|
||||
else:
|
||||
# Precisely two leading slashes, e.g.: '//foo'. Implementation defined per POSIX, see
|
||||
# https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
|
||||
return empty, p[:2], p[2:]
|
||||
else:
|
||||
def splitroot(p):
|
||||
"""Split a pathname into drive, root and tail. On Posix, drive is always
|
||||
empty; the root may be empty, a single slash, or two slashes. The tail
|
||||
contains anything after the root. For example:
|
||||
|
||||
splitroot('foo/bar') == ('', '', 'foo/bar')
|
||||
splitroot('/foo/bar') == ('', '/', 'foo/bar')
|
||||
splitroot('//foo/bar') == ('', '//', 'foo/bar')
|
||||
splitroot('///foo/bar') == ('', '/', '//foo/bar')
|
||||
"""
|
||||
p = os.fspath(p)
|
||||
if isinstance(p, bytes):
|
||||
# Optimisation: the drive is always empty
|
||||
_, root, tail = _path_splitroot_ex(os.fsdecode(p))
|
||||
return b'', os.fsencode(root), os.fsencode(tail)
|
||||
return _path_splitroot_ex(p)
|
||||
|
||||
|
||||
# Return the tail (basename) part of a path, same as split(path)[1].
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue