8000 bpo-30177: pathlib: include the full path in resolve(strict=False) (#… · python/cpython@add98eb · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit add98eb

Browse files
seirlzooba
authored andcommitted
bpo-30177: pathlib: include the full path in resolve(strict=False) (#1893)
1 parent ff48739 commit add98eb

File tree

3 files changed

+21
-20
lines changed

3 files changed

+21
-20
lines changed

Lib/pathlib.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -183,19 +183,18 @@ def resolve(self, path, strict=False):
183183
if strict:
184184
return self._ext_to_normal(_getfinalpathname(s))
185185
else:
186+
tail_parts = [] # End of the path after the first one not found
186187
while True:
187188
try:
188189
s = self._ext_to_normal(_getfinalpathname(s))
189190
except FileNotFoundError:
190191
previous_s = s
191-
s = os.path.dirname(s)
192+
s, tail = os.path.split(s)
193+
tail_parts.append(tail)
192194
if previous_s == s:
193195
return path
194196
else:
195-
if previous_s is None:
196-
return s
197-
else:
198-
return s + os.path.sep + os.path.basename(previous_s)
197+
return os.path.join(s, *reversed(tail_parts))
199198
# Means fallback on absolute
200199
return None
201200

@@ -326,12 +325,10 @@ def _resolve(path, rest):
326325
try:
327326
target = accessor.readlink(newpath)
328327
except OSError as e:
329-
if e.errno != EINVAL:
330-
if strict:
331-
raise
332-
else:
333-
return newpath
334-
# Not a symlink
328+
if e.errno != EINVAL and strict:
329+
raise
330+
# Not a symlink, or non-strict mode. We just leave the path
331+
# untouched.
335332
path = newpath
336333
else:
337334
seen[newpath] = None # not resolved symlink

Lib/test/test_pathlib.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1492,10 +1492,10 @@ def test_resolve_common(self):
14921492
os.path.join(BASE, 'foo'))
14931493
p = P(BASE, 'foo', 'in', 'spam')
14941494
self.assertEqual(str(p.resolve(strict=False)),
1495-
os.path.join(BASE, 'foo'))
1495+
os.path.join(BASE, 'foo', 'in', 'spam'))
14961496
p = P(BASE, '..', 'foo', 'in', 'spam')
14971497
self.assertEqual(str(p.resolve(strict=False)),
1498-
os.path.abspath(os.path.join('foo')))
1498+
os.path.abspath(os.path.join('foo', 'in', 'spam')))
14991499
# These are all 10000 relative symlinks
15001500
p = P(BASE, 'dirB', 'fileB')
15011501
self._check_resolve_relative(p, p)
@@ -1507,16 +1507,18 @@ def test_resolve_common(self):
15071507
self._check_resolve_relative(p, P(BASE, 'dirB', 'fileB'))
15081508
# Non-strict
15091509
p = P(BASE, 'dirA', 'linkC', 'fileB', 'foo', 'in', 'spam')
1510-
self._check_resolve_relative(p, P(BASE, 'dirB', 'fileB', 'foo'), False)
1510+
self._check_resolve_relative(p, P(BASE, 'dirB', 'fileB', 'foo', 'in',
1511+
'spam'), False)
15111512
p = P(BASE, 'dirA', 'linkC', '..', 'foo', 'in', 'spam')
15121513
if os.name == 'nt':
15131514
# In Windows, if linkY points to dirB, 'dirA\linkY\..'
15141515
# resolves to 'dirA' without resolving linkY first.
1515-
self._check_resolve_relative(p, P(BASE, 'dirA', 'foo'), False)
1516+
self._check_resolve_relative(p, P(BASE, 'dirA', 'foo', 'in',
1517+
'spam'), False)
15161518
else:
15171519
# In Posix, if linkY points to dirB, 'dirA/linkY/..'
15181520
# resolves to 'dirB/..' first before resolving to parent of dirB.
1519-
self._check_resolve_relative(p, P(BASE, 'foo'), False)
1521+
self._check_resolve_relative(p, P(BASE, 'foo', 'in', 'spam'), False)
15201522
# Now create absolute symlinks
15211523
d = tempfile.mkdtemp(suffix='-dirD')
15221524
self.addCleanup(support.rmtree, d)
@@ -1526,16 +1528,17 @@ def test_resolve_common(self):
15261528
self._check_resolve_absolute(p, P(BASE, 'dirB', 'fileB'))
15271529
# Non-strict
15281530
p = P(BASE, 'dirA', 'linkX', 'linkY', 'foo', 'in', 'spam')
1529-
self._check_resolve_relative(p, P(BASE, 'dirB', 'foo'), False)
1531+
self._check_resolve_relative(p, P(BASE, 'dirB', 'foo', 'in', 'spam'),
1532+
False)
15301533
p = P(BASE, 'dirA', 'linkX', 'linkY', '..', 'foo', 'in', 'spam')
15311534
if os.name == 'nt':
15321535
# In Windows, if linkY points to dirB, 'dirA\linkY\..'
15331536
# resolves to 'dirA' without resolving linkY first.
1534-
self._check_resolve_relative(p, P(d, 'foo'), False)
1537+
self._check_resolve_relative(p, P(d, 'foo', 'in', 'spam'), False)
15351538
else:
15361539
# In Posix, if linkY points to dirB, 'dirA/linkY/..'
15371540
# resolves to 'dirB/..' first before resolving to parent of dirB.
1538-
self._check_resolve_relative(p, P(BASE, 'foo'), False)
1541+
self._check_resolve_relative(p, P(BASE, 'foo', 'in', 'spam'), False)
15391542

15401543
@support.skip_unless_symlink
15411544
def test_resolve_dot(self):
@@ -1549,7 +1552,7 @@ def test_resolve_dot(self):
15491552
r = q / '3' / '4'
15501553
self.assertRaises(FileNotFoundError, r.resolve, strict=True)
15511554
# Non-strict
1552-
self.assertEqual(r.resolve(strict=False), p / '3')
1555+
self.assertEqual(r.resolve(strict=False), p / '3' / '4')
15531556

15541557
def test_with(self):
15551558
p = self.cls(BASE)

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,7 @@ Steve Piercy
12011201
Jim St. Pierre
12021202
Dan Pierson
12031203
Martijn Pieters
1204+
Antoine Pietri
12041205
Anand B. Pillai
12051206
François Pinard
12061207
Tom Pinckney

0 commit comments

Comments
 (0)
0