Skip to content

Commit

Permalink
Do not raise windows error when calling resolve on a non-existing pat…
Browse files Browse the repository at this point in the history
…h in Python 2.7, to match behaviour on Python 3.x.

Closes issue #54.
  • Loading branch information
mcmtroffaes committed May 14, 2019
1 parent 6e59948 commit 0d62f36
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 6 deletions.
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ install:
build: off

test_script:
- "%PYTHON%/Scripts/py.test tests/test_pathlib2.py --cov=pathlib2"
- "%PYTHON%/Scripts/py.test . --cov=pathlib2"

after_test:
- "SET PATH=%PYTHON%/Scripts;%PATH%"
Expand Down
47 changes: 42 additions & 5 deletions pathlib2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,25 @@ def _try_except_filenotfounderror(try_func, except_func):
try_func()
except FileNotFoundError as exc:
except_func(exc)
elif os.name != 'nt':
try:
try_func()
except EnvironmentError as exc:
if exc.errno != ENOENT:
raise
else:
except_func(exc)
else:
try:
try_func()
except WindowsError as exc:
# errno contains winerror
# 2 = file not found
# 3 = path not found
if exc.errno not in (2, 3):
raise
else:
except_func(exc)
except EnvironmentError as exc:
if exc.errno != ENOENT:
raise
Expand Down Expand Up @@ -354,16 +370,26 @@ def resolve(self, path, strict=False):
else:
# End of the path after the first one not found
tail_parts = []

def _try_func():
result[0] = self._ext_to_normal(_getfinalpathname(s))
# if there was no exception, set flag to 0
result[1] = 0

def _exc_func(exc):
pass

while True:
try:
s = self._ext_to_normal(_getfinalpathname(s))
except FileNotFoundError:
result = [None, 1]
_try_except_filenotfounderror(_try_func, _exc_func)
if result[1] == 1: # file not found exception raised
previous_s = s
s, tail = os.path.split(s)
tail_parts.append(tail)
if previous_s == s:
return path
else:
s = result[0]
return os.path.join(s, *reversed(tail_parts))
# Means fallback on absolute
return None
Expand Down Expand Up @@ -1378,9 +1404,20 @@ def resolve(self, strict=False):
s = self._flavour.resolve(self, strict=strict)
if s is None:
# No symlink resolution => for consistency, raise an error if
# the path doesn't exist or is forbidden
self.stat()
# the path is forbidden
# but not raise error if file does not exist (see issue #54).

def _try_func():
self.stat()

def _exc_func(exc):
pass

_try_except_filenotfounderror(_try_func, _exc_func)
s = str(self.absolute())
else:
# ensure s is a string (normpath requires this on older python)
s = str(s)
# Now we have no symlinks in the path, it's safe to normalize it.
normed = self._flavour.pathmod.normpath(s)
obj = self._from_parts((normed,), init=False)
Expand Down
5 changes: 5 additions & 0 deletions tests/test_pathlib2.py
Original file line number Diff line number Diff line change
Expand Up @@ -2393,6 +2393,11 @@ def check():
check()


# extra test to ensure coverage of issue #54
def test_resolve_extra():
pathlib.Path("~/does_not_exist").resolve()


def main():
unittest.main(__name__)

Expand Down

0 comments on commit 0d62f36

Please sign in to comment.