summaryrefslogtreecommitdiffstats
path: root/Lib/posixpath.py
diff options
context:
space:
mode:
authorSteve Dower <steve.dower@python.org>2021-12-03 00:08:42 (GMT)
committerGitHub <noreply@github.com>2021-12-03 00:08:42 (GMT)
commit99fcf1505218464c489d419d4500f126b6d6dc28 (patch)
treea9d607d854e943b3651248eadbe2f31f8c410021 /Lib/posixpath.py
parent9f2f7e42269db74a89fc8cd74d82a875787f01d7 (diff)
downloadcpython-99fcf1505218464c489d419d4500f126b6d6dc28.zip
cpython-99fcf1505218464c489d419d4500f126b6d6dc28.tar.gz
cpython-99fcf1505218464c489d419d4500f126b6d6dc28.tar.bz2
bpo-45582: Port getpath[p].c to Python (GH-29041)
The getpath.py file is frozen at build time and executed as code over a namespace. It is never imported, nor is it meant to be importable or reusable. However, it should be easier to read, modify, and patch than the previous code. This commit attempts to preserve every previously tested quirk, but these may be changed in the future to better align platforms.
Diffstat (limited to 'Lib/posixpath.py')
-rw-r--r--Lib/posixpath.py86
1 files changed, 49 insertions, 37 deletions
diff --git a/Lib/posixpath.py b/Lib/posixpath.py
index 1953746..a46c667 100644
--- a/Lib/posixpath.py
+++ b/Lib/posixpath.py
@@ -334,43 +334,55 @@ def expandvars(path):
# It should be understood that this may change the meaning of the path
# if it contains symbolic links!
-def normpath(path):
- """Normalize path, eliminating double slashes, etc."""
- path = os.fspath(path)
- if isinstance(path, bytes):
- sep = b'/'
- empty = b''
- dot = b'.'
- dotdot = b'..'
- else:
- sep = '/'
- empty = ''
- dot = '.'
- dotdot = '..'
- if path == empty:
- return dot
- initial_slashes = path.startswith(sep)
- # POSIX allows one or two initial slashes, but treats three or more
- # as single slash.
- # (see http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13)
- if (initial_slashes and
- path.startswith(sep*2) and not path.startswith(sep*3)):
- initial_slashes = 2
- comps = path.split(sep)
- new_comps = []
- for comp in comps:
- if comp in (empty, 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 = sep.join(comps)
- if initial_slashes:
- path = sep*initial_slashes + path
- return path or dot
+try:
+ from posix import _path_normpath
+
+except ImportError:
+ def normpath(path):
+ """Normalize path, eliminating double slashes, etc."""
+ path = os.fspath(path)
+ if isinstance(path, bytes):
+ sep = b'/'
+ empty = b''
+ dot = b'.'
+ dotdot = b'..'
+ else:
+ sep = '/'
+ empty = ''
+ dot = '.'
+ dotdot = '..'
+ if path == empty:
+ return dot
+ initial_slashes = path.startswith(sep)
+ # POSIX allows one or two initial slashes, but treats three or more
+ # as single slash.
+ # (see http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13)
+ if (initial_slashes and
+ path.startswith(sep*2) and not path.startswith(sep*3)):
+ initial_slashes = 2
+ comps = path.split(sep)
+ new_comps = []
+ for comp in comps:
+ if comp in (empty, 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 = sep.join(comps)
+ if initial_slashes:
+ path = sep*initial_slashes + path
+ return path or dot
+
+else:
+ def normpath(path):
+ """Normalize path, eliminating double slashes, etc."""
+ path = os.fspath(path)
+ if isinstance(path, bytes):
+ return os.fsencode(_path_normpath(os.fsdecode(path))) or b"."
+ return _path_normpath(path) or "."
def abspath(path):