diff --git a/CHANGELOG b/CHANGELOG index daabcb5da..f04362ade 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -15,6 +15,7 @@ - fix issue 877: properly handle assertion explanations with non-ascii repr Thanks Mathieu Agopian for the report and Ronny Pfannschmidt for the PR. +- fix issue 1029: transform errors when writing cache values into pytest-warnings 2.8.0 ----------------------------- diff --git a/_pytest/cacheprovider.py b/_pytest/cacheprovider.py index 977647fee..e4ae64ab3 100755 --- a/_pytest/cacheprovider.py +++ b/_pytest/cacheprovider.py @@ -69,10 +69,22 @@ class Cache(object): like e. g. lists of dictionaries. """ path = self._getvaluepath(key) - path.dirpath().ensure_dir() - with path.open("w") as f: - self.trace("cache-write %s: %r" % (key, value,)) - json.dump(value, f, indent=2, sort_keys=True) + try: + path.dirpath().ensure_dir() + except (py.error.EEXIST, py.error.EACCES): + self.config.warn( + code='I9', message='could not create cache path %s' % (path,) + ) + return + try: + f = path.open('w') + except py.error.ENOTDIR: + self.config.warn( + code='I9', message='cache could not write path %s' % (path,)) + else: + with f: + self.trace("cache-write %s: %r" % (key, value,)) + json.dump(value, f, indent=2, sort_keys=True) class LFPlugin: diff --git a/testing/test_cache.py b/testing/test_cache.py index 8eac4e8e0..0538be9d7 100755 --- a/testing/test_cache.py +++ b/testing/test_cache.py @@ -1,3 +1,4 @@ +import sys import pytest import os import shutil @@ -25,6 +26,36 @@ class TestNewAPI: val = config.cache.get("key/name", -2) assert val == -2 + def test_cache_writefail_cachfile_silent(self, testdir): + testdir.makeini("[pytest]") + testdir.tmpdir.join('.cache').write('gone wrong') + config = testdir.parseconfigure() + cache = config.cache + cache.set('test/broken', []) + + @pytest.mark.skipif(sys.platform.startswith('win'), reason='no chmod on windows') + def test_cache_writefail_permissions(self, testdir): + testdir.makeini("[pytest]") + testdir.tmpdir.ensure_dir('.cache').chmod(0) + config = testdir.parseconfigure() + cache = config.cache + cache.set('test/broken', []) + + @pytest.mark.skipif(sys.platform.startswith('win'), reason='no chmod on windows') + def test_cache_failure_warns(self, testdir): + testdir.tmpdir.ensure_dir('.cache').chmod(0) + testdir.makepyfile(""" + def test_pass(): + pass + + """) + result = testdir.runpytest('-rw') + assert result.ret == 0 + result.stdout.fnmatch_lines([ + "*could not create cache path*", + "*1 pytest-warnings*", + ]) + def test_config_cache(self, testdir): testdir.makeconftest(""" def pytest_configure(config):