From 2a1e661384a4c8790b65e34376f0b8c7cbfca679 Mon Sep 17 00:00:00 2001 From: "V.Kuznetsov" Date: Thu, 6 Jul 2017 11:31:02 +0300 Subject: [PATCH 1/8] cache_dir ini option --- _pytest/cacheprovider.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/_pytest/cacheprovider.py b/_pytest/cacheprovider.py index 7fc08fff368..5a857b98641 100755 --- a/_pytest/cacheprovider.py +++ b/_pytest/cacheprovider.py @@ -8,13 +8,14 @@ import py import pytest import json -from os.path import sep as _sep, altsep as _altsep +from os.path import sep as _sep, altsep as _altsep, \ + isabs as _isabs, expanduser as _expanduser class Cache(object): def __init__(self, config): self.config = config - self._cachedir = config.rootdir.join(".cache") + self._cachedir = Cache.cache_dir_from_config(config) self.trace = config.trace.root.get("cache") if config.getvalue("cacheclear"): self.trace("clearing cachedir") @@ -22,6 +23,14 @@ def __init__(self, config): self._cachedir.remove() self._cachedir.mkdir() + @staticmethod + def cache_dir_from_config(config): + cache_dir = config.getini("cache_dir") + if _isabs(_expanduser(cache_dir)): + return py.path.local(cache_dir, expanduser=True) + else: + return config.rootdir.join(cache_dir) + def makedir(self, name): """ return a directory path object with the given name. If the directory does not yet exist, it will be created. You can use it @@ -171,6 +180,9 @@ def pytest_addoption(parser): group.addoption( '--cache-clear', action='store_true', dest="cacheclear", help="remove all cache contents at start of test run.") + parser.addini( + "cache_dir", default='.cache', + help="cache directory path.") def pytest_cmdline_main(config): From c0e5701e11108e3219993664cbb72d725adf143b Mon Sep 17 00:00:00 2001 From: "V.Kuznetsov" Date: Thu, 6 Jul 2017 11:32:05 +0300 Subject: [PATCH 2/8] tests for cache_dir ini option --- testing/test_cache.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/testing/test_cache.py b/testing/test_cache.py index 600b5e6d9fc..0c940a448d3 100755 --- a/testing/test_cache.py +++ b/testing/test_cache.py @@ -1,6 +1,6 @@ from __future__ import absolute_import, division, print_function import sys - +import py import _pytest import pytest import os @@ -87,6 +87,25 @@ def test_cachefuncarg(cache): assert result.ret == 0 result.stdout.fnmatch_lines(["*1 passed*"]) + def test_custom_rel_cache_dir(self, testdir): + rel_cache_dir = os.path.join('custom_cache_dir', 'subdir') + testdir.makeini(""" + [pytest] + cache_dir = {cache_dir} + """.format(cache_dir=rel_cache_dir)) + testdir.makepyfile(test_errored='def test_error():\n assert False') + testdir.runpytest() + assert testdir.tmpdir.join(rel_cache_dir).isdir() + + def test_custom_abs_cache_dir(self, testdir): + abs_cache_dir = os.path.abspath(testdir.tmpdir.join('custom_cache_dir').strpath) + testdir.makeini(""" + [pytest] + cache_dir = {cache_dir} + """.format(cache_dir=abs_cache_dir)) + testdir.makepyfile(test_errored='def test_error():\n assert False') + testdir.runpytest() + assert py.path.local(abs_cache_dir).isdir() def test_cache_reportheader(testdir): From 931823e7a80d0497ccb8b927b36dd0c1720da42c Mon Sep 17 00:00:00 2001 From: "V.Kuznetsov" Date: Thu, 6 Jul 2017 11:32:44 +0300 Subject: [PATCH 3/8] docs for cache_dir ini option --- doc/en/cache.rst | 2 ++ doc/en/customize.rst | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/doc/en/cache.rst b/doc/en/cache.rst index 688b6dd0468..e4071a8f8ab 100644 --- a/doc/en/cache.rst +++ b/doc/en/cache.rst @@ -1,3 +1,5 @@ +.. _`cache_provider`: + Cache: working with cross-testrun state ======================================= diff --git a/doc/en/customize.rst b/doc/en/customize.rst index ce0a36c11a2..b570d568710 100644 --- a/doc/en/customize.rst +++ b/doc/en/customize.rst @@ -243,7 +243,6 @@ Builtin configuration file options from ``pytest.ini``/``tox.ini``/``setup.cfg`` of the project if any, or up to the file-system root. - .. confval:: filterwarnings .. versionadded:: 3.1 @@ -262,3 +261,13 @@ Builtin configuration file options This tells pytest to ignore deprecation warnings and turn all other warnings into errors. For more information please refer to :ref:`warnings`. + +.. confval:: cache_dir + + .. versionadded:: 3.2 + + Sets a directory where stores content of cache plugin. Default directory is + ``.cache`` which is created in :ref:`rootdir `. Directory may be + relative or absolute path. If setting relative path, then directory is created + relative to :ref:`rootdir `. For more information about cache plugin + please refer to :ref:`cache_provider`. From 41161e6aed9ddf1006a490e51f42d3cf28e3e776 Mon Sep 17 00:00:00 2001 From: "V.Kuznetsov" Date: Thu, 6 Jul 2017 18:09:44 +0300 Subject: [PATCH 4/8] support of env vars in cache_dir --- _pytest/cacheprovider.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/_pytest/cacheprovider.py b/_pytest/cacheprovider.py index 5a857b98641..8e64f5b8dc9 100755 --- a/_pytest/cacheprovider.py +++ b/_pytest/cacheprovider.py @@ -8,8 +8,8 @@ import py import pytest import json -from os.path import sep as _sep, altsep as _altsep, \ - isabs as _isabs, expanduser as _expanduser +import os +from os.path import sep as _sep, altsep as _altsep class Cache(object): @@ -26,8 +26,10 @@ def __init__(self, config): @staticmethod def cache_dir_from_config(config): cache_dir = config.getini("cache_dir") - if _isabs(_expanduser(cache_dir)): - return py.path.local(cache_dir, expanduser=True) + cache_dir = os.path.expanduser(cache_dir) + cache_dir = os.path.expandvars(cache_dir) + if os.path.isabs(cache_dir): + return py.path.local(cache_dir) else: return config.rootdir.join(cache_dir) From c00b57a147236a20d0d08c3f20bca53c989ffde1 Mon Sep 17 00:00:00 2001 From: "V.Kuznetsov" Date: Thu, 6 Jul 2017 18:12:58 +0300 Subject: [PATCH 5/8] test for support of env vars in cache_dir --- testing/test_cache.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/testing/test_cache.py b/testing/test_cache.py index 0c940a448d3..9fb86dd60a8 100755 --- a/testing/test_cache.py +++ b/testing/test_cache.py @@ -107,6 +107,15 @@ def test_custom_abs_cache_dir(self, testdir): testdir.runpytest() assert py.path.local(abs_cache_dir).isdir() + def test_custom_cache_dir_with_env_var(self, testdir, monkeypatch): + monkeypatch.setenv('env_var', 'custom_cache_dir') + testdir.makeini(""" + [pytest] + cache_dir = {cache_dir} + """.format(cache_dir='$env_var')) + testdir.makepyfile(test_errored='def test_error():\n assert False') + testdir.runpytest() + assert testdir.tmpdir.join('custom_cache_dir').isdir() def test_cache_reportheader(testdir): testdir.makepyfile(""" From 35469a77b799fd08a0ff0a19c8fceff176522e35 Mon Sep 17 00:00:00 2001 From: "V.Kuznetsov" Date: Thu, 6 Jul 2017 18:14:34 +0300 Subject: [PATCH 6/8] docs for support of env vars in cache_dir --- doc/en/customize.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/en/customize.rst b/doc/en/customize.rst index b570d568710..0e484e37df5 100644 --- a/doc/en/customize.rst +++ b/doc/en/customize.rst @@ -269,5 +269,6 @@ Builtin configuration file options Sets a directory where stores content of cache plugin. Default directory is ``.cache`` which is created in :ref:`rootdir `. Directory may be relative or absolute path. If setting relative path, then directory is created - relative to :ref:`rootdir `. For more information about cache plugin + relative to :ref:`rootdir `. Additionally path may contain environment + variables, that will be expanded. For more information about cache plugin please refer to :ref:`cache_provider`. From 16a72799bd271acad4ca54b8fc4b50a57cd732a9 Mon Sep 17 00:00:00 2001 From: "V.Kuznetsov" Date: Fri, 7 Jul 2017 09:43:49 +0300 Subject: [PATCH 7/8] improving test for absolute path --- testing/test_cache.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/testing/test_cache.py b/testing/test_cache.py index 9fb86dd60a8..c7e92063b1a 100755 --- a/testing/test_cache.py +++ b/testing/test_cache.py @@ -97,8 +97,9 @@ def test_custom_rel_cache_dir(self, testdir): testdir.runpytest() assert testdir.tmpdir.join(rel_cache_dir).isdir() - def test_custom_abs_cache_dir(self, testdir): - abs_cache_dir = os.path.abspath(testdir.tmpdir.join('custom_cache_dir').strpath) + def test_custom_abs_cache_dir(self, testdir, tmpdir_factory): + tmp = str(tmpdir_factory.mktemp('tmp')) + abs_cache_dir = os.path.join(tmp, 'custom_cache_dir') testdir.makeini(""" [pytest] cache_dir = {cache_dir} From 14aac9c19b366162c3125dea6b59b35c1f1925eb Mon Sep 17 00:00:00 2001 From: "V.Kuznetsov" Date: Fri, 7 Jul 2017 09:56:20 +0300 Subject: [PATCH 8/8] changelog for new cache_dir ini option --- CHANGELOG.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 87af5d72a24..754c2206d93 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -8,6 +8,17 @@ .. towncrier release notes start + +Pytest 3.2.0 (unreleased) +========================= + +- New ``cache_dir`` ini option: sets a directory where stores content of cache plugin. + Default directory is ``.cache`` which is created in :ref:`rootdir `. + Directory may be relative or absolute path. If setting relative path, then directory + is created relative to :ref:`rootdir `. Additionally path may contain environment + variables, that will be expanded. + + Pytest 3.1.2 (2017-06-08) =========================