unify paths.py and pathlib.py

This commit is contained in:
Ronny Pfannschmidt 2018-10-01 13:44:52 +02:00
parent 00716177b4
commit 2831cb9ab5
5 changed files with 53 additions and 57 deletions

View File

@ -19,7 +19,7 @@ import py
from _pytest.assertion import util from _pytest.assertion import util
from _pytest.pathlib import PurePath from _pytest.pathlib import PurePath
from _pytest.compat import spec_from_file_location from _pytest.compat import spec_from_file_location
from _pytest.paths import fnmatch_ex from _pytest.pathlib import fnmatch_ex
# pytest caches rewritten pycs in __pycache__. # pytest caches rewritten pycs in __pycache__.
if hasattr(imp, "get_tag"): if hasattr(imp, "get_tag"):

View File

@ -15,9 +15,8 @@ import pytest
import json import json
import shutil import shutil
from . import paths
from .compat import _PY2 as PY2 from .compat import _PY2 as PY2
from .pathlib import Path from .pathlib import Path, resolve_from_str
README_CONTENT = u"""\ README_CONTENT = u"""\
# pytest cache directory # # pytest cache directory #
@ -46,7 +45,7 @@ class Cache(object):
@staticmethod @staticmethod
def cache_dir_from_config(config): def cache_dir_from_config(config):
return paths.resolve_from_str(config.getini("cache_dir"), config.rootdir) return resolve_from_str(config.getini("cache_dir"), config.rootdir)
def warn(self, fmt, **args): def warn(self, fmt, **args):
from _pytest.warnings import _issue_config_warning from _pytest.warnings import _issue_config_warning

View File

@ -4,14 +4,19 @@ import errno
import atexit import atexit
import operator import operator
import six import six
import sys
from functools import reduce from functools import reduce
import uuid import uuid
from six.moves import map from six.moves import map
import itertools import itertools
import shutil import shutil
from os.path import expanduser, expandvars, isabs, sep
from posixpath import sep as posix_sep
import fnmatch
from .compat import PY36 from .compat import PY36
if PY36: if PY36:
from pathlib import Path, PurePath from pathlib import Path, PurePath
else: else:
@ -181,3 +186,47 @@ def make_numbered_dir_with_cleanup(root, prefix, keep, lock_timeout):
return p return p
assert e is not None assert e is not None
raise e raise e
def resolve_from_str(input, root):
assert not isinstance(input, Path), "would break on py2"
root = Path(root)
input = expanduser(input)
input = expandvars(input)
if isabs(input):
return Path(input)
else:
return root.joinpath(input)
def fnmatch_ex(pattern, path):
"""FNMatcher port from py.path.common which works with PurePath() instances.
The difference between this algorithm and PurePath.match() is that the latter matches "**" glob expressions
for each part of the path, while this algorithm uses the whole path instead.
For example:
"tests/foo/bar/doc/test_foo.py" matches pattern "tests/**/doc/test*.py" with this algorithm, but not with
PurePath.match().
This algorithm was ported to keep backward-compatibility with existing settings which assume paths match according
this logic.
References:
* https://bugs.python.org/issue29249
* https://bugs.python.org/issue34731
"""
path = PurePath(path)
iswin32 = sys.platform.startswith("win")
if iswin32 and sep not in pattern and posix_sep in pattern:
# Running on Windows, the pattern has no Windows path separators,
# and the pattern has one or more Posix path separators. Replace
# the Posix path separators with the Windows path separator.
pattern = pattern.replace(posix_sep, sep)
if sep not in pattern:
name = path.name
else:
name = six.text_type(path)
return fnmatch.fnmatch(name, pattern)

View File

@ -1,52 +0,0 @@
from os.path import expanduser, expandvars, isabs, sep
from posixpath import sep as posix_sep
import fnmatch
import sys
import six
from .pathlib import Path, PurePath
def resolve_from_str(input, root):
assert not isinstance(input, Path), "would break on py2"
root = Path(root)
input = expanduser(input)
input = expandvars(input)
if isabs(input):
return Path(input)
else:
return root.joinpath(input)
def fnmatch_ex(pattern, path):
"""FNMatcher port from py.path.common which works with PurePath() instances.
The difference between this algorithm and PurePath.match() is that the latter matches "**" glob expressions
for each part of the path, while this algorithm uses the whole path instead.
For example:
"tests/foo/bar/doc/test_foo.py" matches pattern "tests/**/doc/test*.py" with this algorithm, but not with
PurePath.match().
This algorithm was ported to keep backward-compatibility with existing settings which assume paths match according
this logic.
References:
* https://bugs.python.org/issue29249
* https://bugs.python.org/issue34731
"""
path = PurePath(path)
iswin32 = sys.platform.startswith("win")
if iswin32 and sep not in pattern and posix_sep in pattern:
# Running on Windows, the pattern has no Windows path separators,
# and the pattern has one or more Posix path separators. Replace
# the Posix path separators with the Windows path separator.
pattern = pattern.replace(posix_sep, sep)
if sep not in pattern:
name = path.name
else:
name = six.text_type(path)
return fnmatch.fnmatch(name, pattern)

View File

@ -4,7 +4,7 @@ import py
import pytest import pytest
from _pytest.paths import fnmatch_ex from _pytest.pathlib import fnmatch_ex
class TestPort: class TestPort: