# in the case of paths with these prefixes:
# \\.\ -> device names
# \\?\ -> literal paths
- # do not do any normalization, but return the path unchanged
+ # do not do any normalization, but return the path
+ # unchanged apart from the call to os.fspath()
return path
path = path.replace(altsep, sep)
prefix, path = splitdrive(path)
return abspath(tail)
def realpath(path):
- path = os.fspath(path)
+ path = normpath(path)
if isinstance(path, bytes):
prefix = b'\\\\?\\'
unc_prefix = b'\\\\?\\UNC\\'
unc_prefix = '\\\\?\\UNC\\'
new_unc_prefix = '\\\\'
cwd = os.getcwd()
+ did_not_exist = not exists(path)
had_prefix = path.startswith(prefix)
path = _getfinalpathname_nonstrict(path)
# The path returned by _getfinalpathname will always start with \\?\ -
if _getfinalpathname(spath) == path:
path = spath
except OSError as ex:
- pass
+ # If the path does not exist and originally did not exist, then
+ # strip the prefix anyway.
+ if ex.winerror in {2, 3} and did_not_exist:
+ path = spath
return path
self.assertEqual(ntpath.realpath(ABSTFN + "1\\.."),
ntpath.dirname(ABSTFN))
self.assertEqual(ntpath.realpath(ABSTFN + "1\\..\\x"),
- ntpath.dirname(P + ABSTFN) + "\\x")
+ ntpath.dirname(ABSTFN) + "\\x")
os.symlink(ABSTFN + "x", ABSTFN + "y")
self.assertEqual(ntpath.realpath(ABSTFN + "1\\..\\"
+ ntpath.basename(ABSTFN) + "y"),
- P + ABSTFN + "x")
+ ABSTFN + "x")
self.assertIn(ntpath.realpath(ABSTFN + "1\\..\\"
+ ntpath.basename(ABSTFN) + "1"),
expected)