From 0f500deca6b59826ef89064e9bd6f1893737ba57 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 30 Nov 2019 12:11:29 -0300 Subject: [PATCH] Ensure cache supporting files still exist after --cache-clear Fix #6290 --- changelog/6290.bugfix.rst | 1 + src/_pytest/cacheprovider.py | 27 ++++++++++++++++++++------- testing/test_cacheprovider.py | 1 + 3 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 changelog/6290.bugfix.rst diff --git a/changelog/6290.bugfix.rst b/changelog/6290.bugfix.rst new file mode 100644 index 00000000000..f6f1560d493 --- /dev/null +++ b/changelog/6290.bugfix.rst @@ -0,0 +1 @@ +The supporting files in the ``.pytest_cache`` directory are kept with ``--cache-clear``, which only clears cached values now. diff --git a/src/_pytest/cacheprovider.py b/src/_pytest/cacheprovider.py index 6e53545d630..802c5212267 100755 --- a/src/_pytest/cacheprovider.py +++ b/src/_pytest/cacheprovider.py @@ -44,14 +44,27 @@ class Cache: _cachedir = attr.ib(repr=False) _config = attr.ib(repr=False) + # sub-directory under cache-dir for directories created by "makedir" + _CACHE_PREFIX_DIRS = "d" + + # sub-directory under cache-dir for values created by "set" + _CACHE_PREFIX_VALUES = "v" + @classmethod def for_config(cls, config): cachedir = cls.cache_dir_from_config(config) - if config.getoption("cacheclear") and cachedir.exists(): - rm_rf(cachedir) - cachedir.mkdir() + if config.getoption("cacheclear") and cachedir.is_dir(): + cls.clear_cache(cachedir) return cls(cachedir, config) + @classmethod + def clear_cache(cls, cachedir: Path): + """Clears the sub-directories used to hold cached directories and values.""" + for prefix in (cls._CACHE_PREFIX_DIRS, cls._CACHE_PREFIX_VALUES): + d = cachedir / prefix + if d.is_dir(): + rm_rf(d) + @staticmethod def cache_dir_from_config(config): return resolve_from_str(config.getini("cache_dir"), config.rootdir) @@ -79,12 +92,12 @@ def makedir(self, name): name = Path(name) if len(name.parts) > 1: raise ValueError("name is not allowed to contain path separators") - res = self._cachedir.joinpath("d", name) + res = self._cachedir.joinpath(self._CACHE_PREFIX_DIRS, name) res.mkdir(exist_ok=True, parents=True) return py.path.local(res) def _getvaluepath(self, key): - return self._cachedir.joinpath("v", Path(key)) + return self._cachedir.joinpath(self._CACHE_PREFIX_VALUES, Path(key)) def get(self, key, default): """ return cached value for the given key. If no value @@ -417,7 +430,7 @@ def cacheshow(config, session): dummy = object() basedir = config.cache._cachedir - vdir = basedir / "v" + vdir = basedir / Cache._CACHE_PREFIX_VALUES tw.sep("-", "cache values for %r" % glob) for valpath in sorted(x for x in vdir.rglob(glob) if x.is_file()): key = valpath.relative_to(vdir) @@ -429,7 +442,7 @@ def cacheshow(config, session): for line in pformat(val).splitlines(): tw.line(" " + line) - ddir = basedir / "d" + ddir = basedir / Cache._CACHE_PREFIX_DIRS if ddir.is_dir(): contents = sorted(ddir.rglob(glob)) tw.sep("-", "cache directories for %r" % glob) diff --git a/testing/test_cacheprovider.py b/testing/test_cacheprovider.py index 0e1194b02a0..f0b279abf31 100644 --- a/testing/test_cacheprovider.py +++ b/testing/test_cacheprovider.py @@ -270,6 +270,7 @@ def test_3(): assert 0 ) result = testdir.runpytest(str(p), "--lf", "--cache-clear") result.stdout.fnmatch_lines(["*1 failed*2 passed*"]) + assert testdir.tmpdir.join(".pytest_cache", "README.md").isfile() # Run this again to make sure clear-cache is robust if os.path.isdir(".pytest_cache"):