bpo-30177: pathlib: include the full path in resolve(strict=False) (#1893)
This commit is contained in:
parent
ff48739ed0
commit
add98eb4fe
|
@ -183,19 +183,18 @@ class _WindowsFlavour(_Flavour):
|
||||||
if strict:
|
if strict:
|
||||||
return self._ext_to_normal(_getfinalpathname(s))
|
return self._ext_to_normal(_getfinalpathname(s))
|
||||||
else:
|
else:
|
||||||
|
tail_parts = [] # End of the path after the first one not found
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
s = self._ext_to_normal(_getfinalpathname(s))
|
s = self._ext_to_normal(_getfinalpathname(s))
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
previous_s = s
|
previous_s = s
|
||||||
s = os.path.dirname(s)
|
s, tail = os.path.split(s)
|
||||||
|
tail_parts.append(tail)
|
||||||
if previous_s == s:
|
if previous_s == s:
|
||||||
return path
|
return path
|
||||||
else:
|
else:
|
||||||
if previous_s is None:
|
return os.path.join(s, *reversed(tail_parts))
|
||||||
return s
|
|
||||||
else:
|
|
||||||
return s + os.path.sep + os.path.basename(previous_s)
|
|
||||||
# Means fallback on absolute
|
# Means fallback on absolute
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -326,12 +325,10 @@ class _PosixFlavour(_Flavour):
|
||||||
try:
|
try:
|
||||||
target = accessor.readlink(newpath)
|
target = accessor.readlink(newpath)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
if e.errno != EINVAL:
|
if e.errno != EINVAL and strict:
|
||||||
if strict:
|
raise
|
||||||
raise
|
# Not a symlink, or non-strict mode. We just leave the path
|
||||||
else:
|
# untouched.
|
||||||
return newpath
|
|
||||||
# Not a symlink
|
|
||||||
path = newpath
|
path = newpath
|
||||||
else:
|
else:
|
||||||
seen[newpath] = None # not resolved symlink
|
seen[newpath] = None # not resolved symlink
|
||||||
|
|
|
@ -1492,10 +1492,10 @@ class _BasePathTest(object):
|
||||||
os.path.join(BASE, 'foo'))
|
os.path.join(BASE, 'foo'))
|
||||||
p = P(BASE, 'foo', 'in', 'spam')
|
p = P(BASE, 'foo', 'in', 'spam')
|
||||||
self.assertEqual(str(p.resolve(strict=False)),
|
self.assertEqual(str(p.resolve(strict=False)),
|
||||||
os.path.join(BASE, 'foo'))
|
os.path.join(BASE, 'foo', 'in', 'spam'))
|
||||||
p = P(BASE, '..', 'foo', 'in', 'spam')
|
p = P(BASE, '..', 'foo', 'in', 'spam')
|
||||||
self.assertEqual(str(p.resolve(strict=False)),
|
self.assertEqual(str(p.resolve(strict=False)),
|
||||||
os.path.abspath(os.path.join('foo')))
|
os.path.abspath(os.path.join('foo', 'in', 'spam')))
|
||||||
# These are all relative symlinks
|
# These are all relative symlinks
|
||||||
p = P(BASE, 'dirB', 'fileB')
|
p = P(BASE, 'dirB', 'fileB')
|
||||||
self._check_resolve_relative(p, p)
|
self._check_resolve_relative(p, p)
|
||||||
|
@ -1507,16 +1507,18 @@ class _BasePathTest(object):
|
||||||
self._check_resolve_relative(p, P(BASE, 'dirB', 'fileB'))
|
self._check_resolve_relative(p, P(BASE, 'dirB', 'fileB'))
|
||||||
# Non-strict
|
# Non-strict
|
||||||
p = P(BASE, 'dirA', 'linkC', 'fileB', 'foo', 'in', 'spam')
|
p = P(BASE, 'dirA', 'linkC', 'fileB', 'foo', 'in', 'spam')
|
||||||
self._check_resolve_relative(p, P(BASE, 'dirB', 'fileB', 'foo'), False)
|
self._check_resolve_relative(p, P(BASE, 'dirB', 'fileB', 'foo', 'in',
|
||||||
|
'spam'), False)
|
||||||
p = P(BASE, 'dirA', 'linkC', '..', 'foo', 'in', 'spam')
|
p = P(BASE, 'dirA', 'linkC', '..', 'foo', 'in', 'spam')
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
# In Windows, if linkY points to dirB, 'dirA\linkY\..'
|
# In Windows, if linkY points to dirB, 'dirA\linkY\..'
|
||||||
# resolves to 'dirA' without resolving linkY first.
|
# resolves to 'dirA' without resolving linkY first.
|
||||||
self._check_resolve_relative(p, P(BASE, 'dirA', 'foo'), False)
|
self._check_resolve_relative(p, P(BASE, 'dirA', 'foo', 'in',
|
||||||
|
'spam'), False)
|
||||||
else:
|
else:
|
||||||
# In Posix, if linkY points to dirB, 'dirA/linkY/..'
|
# In Posix, if linkY points to dirB, 'dirA/linkY/..'
|
||||||
# resolves to 'dirB/..' first before resolving to parent of dirB.
|
# resolves to 'dirB/..' first before resolving to parent of dirB.
|
||||||
self._check_resolve_relative(p, P(BASE, 'foo'), False)
|
self._check_resolve_relative(p, P(BASE, 'foo', 'in', 'spam'), False)
|
||||||
# Now create absolute symlinks
|
# Now create absolute symlinks
|
||||||
d = tempfile.mkdtemp(suffix='-dirD')
|
d = tempfile.mkdtemp(suffix='-dirD')
|
||||||
self.addCleanup(support.rmtree, d)
|
self.addCleanup(support.rmtree, d)
|
||||||
|
@ -1526,16 +1528,17 @@ class _BasePathTest(object):
|
||||||
self._check_resolve_absolute(p, P(BASE, 'dirB', 'fileB'))
|
self._check_resolve_absolute(p, P(BASE, 'dirB', 'fileB'))
|
||||||
# Non-strict
|
# Non-strict
|
||||||
p = P(BASE, 'dirA', 'linkX', 'linkY', 'foo', 'in', 'spam')
|
p = P(BASE, 'dirA', 'linkX', 'linkY', 'foo', 'in', 'spam')
|
||||||
self._check_resolve_relative(p, P(BASE, 'dirB', 'foo'), False)
|
self._check_resolve_relative(p, P(BASE, 'dirB', 'foo', 'in', 'spam'),
|
||||||
|
False)
|
||||||
p = P(BASE, 'dirA', 'linkX', 'linkY', '..', 'foo', 'in', 'spam')
|
p = P(BASE, 'dirA', 'linkX', 'linkY', '..', 'foo', 'in', 'spam')
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
# In Windows, if linkY points to dirB, 'dirA\linkY\..'
|
# In Windows, if linkY points to dirB, 'dirA\linkY\..'
|
||||||
# resolves to 'dirA' without resolving linkY first.
|
# resolves to 'dirA' without resolving linkY first.
|
||||||
self._check_resolve_relative(p, P(d, 'foo'), False)
|
self._check_resolve_relative(p, P(d, 'foo', 'in', 'spam'), False)
|
||||||
else:
|
else:
|
||||||
# In Posix, if linkY points to dirB, 'dirA/linkY/..'
|
# In Posix, if linkY points to dirB, 'dirA/linkY/..'
|
||||||
# resolves to 'dirB/..' first before resolving to parent of dirB.
|
# resolves to 'dirB/..' first before resolving to parent of dirB.
|
||||||
self._check_resolve_relative(p, P(BASE, 'foo'), False)
|
self._check_resolve_relative(p, P(BASE, 'foo', 'in', 'spam'), False)
|
||||||
|
|
||||||
@support.skip_unless_symlink
|
@support.skip_unless_symlink
|
||||||
def test_resolve_dot(self):
|
def test_resolve_dot(self):
|
||||||
|
@ -1549,7 +1552,7 @@ class _BasePathTest(object):
|
||||||
r = q / '3' / '4'
|
r = q / '3' / '4'
|
||||||
self.assertRaises(FileNotFoundError, r.resolve, strict=True)
|
self.assertRaises(FileNotFoundError, r.resolve, strict=True)
|
||||||
# Non-strict
|
# Non-strict
|
||||||
self.assertEqual(r.resolve(strict=False), p / '3')
|
self.assertEqual(r.resolve(strict=False), p / '3' / '4')
|
||||||
|
|
||||||
def test_with(self):
|
def test_with(self):
|
||||||
p = self.cls(BASE)
|
p = self.cls(BASE)
|
||||||
|
|
Loading…
Reference in New Issue