diff --git a/Lib/posixpath.py b/Lib/posixpath.py index 259baa64b1..feff7857be 100644 --- a/Lib/posixpath.py +++ b/Lib/posixpath.py @@ -336,6 +336,7 @@ def expandvars(path): def normpath(path): """Normalize path, eliminating double slashes, etc.""" + normalize_dotdot = True path = os.fspath(path) if isinstance(path, bytes): sep = b'/' @@ -360,11 +361,20 @@ def normpath(path): 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)): + try: + os.lstat(sep.join(new_comps)) + except OSError: + normalize_dotdot = False + + comp_dotdot = comp == dotdot + if ((comp_dotdot and not normalize_dotdot) or not 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: @@ -430,7 +440,8 @@ def _joinrealpath(path, rest, strict, seen): except OSError: if strict: raise - is_link = False + # Return already resolved part + rest of the path unchanged. + return join(newpath, rest), False else: is_link = stat.S_ISLNK(st.st_mode) if not is_link: