summaryrefslogtreecommitdiffstats
path: root/Lib/ntpath.py
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2014-01-27 21:14:51 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2014-01-27 21:14:51 (GMT)
commit31f5121275908b8d3f428d7e5499ddfe005f82ee (patch)
tree96b876435d22c81cf58da22805163ddb8eab57fa /Lib/ntpath.py
parent027ab390143d9f95c16db19bc66c00bebbb04a96 (diff)
downloadcpython-31f5121275908b8d3f428d7e5499ddfe005f82ee.zip
cpython-31f5121275908b8d3f428d7e5499ddfe005f82ee.tar.gz
cpython-31f5121275908b8d3f428d7e5499ddfe005f82ee.tar.bz2
Issue #19456: ntpath.join() now joins relative paths correctly when a drive
is present.
Diffstat (limited to 'Lib/ntpath.py')
-rw-r--r--Lib/ntpath.py79
1 files changed, 24 insertions, 55 deletions
diff --git a/Lib/ntpath.py b/Lib/ntpath.py
index f3b3111..fc9463c 100644
--- a/Lib/ntpath.py
+++ b/Lib/ntpath.py
@@ -59,61 +59,30 @@ def isabs(s):
# Join two (or more) paths.
-
-def join(a, *p):
- """Join two or more pathname components, inserting "\\" as needed.
- If any component is an absolute path, all previous path components
- will be discarded."""
- path = a
- for b in p:
- b_wins = 0 # set to 1 iff b makes path irrelevant
- if path == "":
- b_wins = 1
-
- elif isabs(b):
- # This probably wipes out path so far. However, it's more
- # complicated if path begins with a drive letter:
- # 1. join('c:', '/a') == 'c:/a'
- # 2. join('c:/', '/a') == 'c:/a'
- # But
- # 3. join('c:/a', '/b') == '/b'
- # 4. join('c:', 'd:/') = 'd:/'
- # 5. join('c:/', 'd:/') = 'd:/'
- if path[1:2] != ":" or b[1:2] == ":":
- # Path doesn't start with a drive letter, or cases 4 and 5.
- b_wins = 1
-
- # Else path has a drive letter, and b doesn't but is absolute.
- elif len(path) > 3 or (len(path) == 3 and
- path[-1] not in "/\\"):
- # case 3
- b_wins = 1
-
- if b_wins:
- path = b
- else:
- # Join, and ensure there's a separator.
- assert len(path) > 0
- if path[-1] in "/\\":
- if b and b[0] in "/\\":
- path += b[1:]
- else:
- path += b
- elif path[-1] == ":":
- path += b
- elif b:
- if b[0] in "/\\":
- path += b
- else:
- path += "\\" + b
- else:
- # path is not empty and does not end with a backslash,
- # but b is empty; since, e.g., split('a/') produces
- # ('a', ''), it's best if join() adds a backslash in
- # this case.
- path += '\\'
-
- return path
+def join(path, *paths):
+ """Join two or more pathname components, inserting "\\" as needed."""
+ result_drive, result_path = splitdrive(path)
+ for p in paths:
+ p_drive, p_path = splitdrive(p)
+ if p_path and p_path[0] in '\\/':
+ # 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 '\\/':
+ result_path = result_path + '\\'
+ result_path = result_path + p_path
+ return result_drive + result_path
# Split a path in a drive specification (a drive letter followed by a