Skip to content

Commit f456e37

Browse files
committed
refine tmpdir handling and docs
- clear tmpdir specified with --basetemp - remove config.mktmp and config.getbasetemp methods
1 parent 158e160 commit f456e37

File tree

9 files changed

+116
-86
lines changed

9 files changed

+116
-86
lines changed

_pytest/config.py

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
""" command line configuration, ini-file and conftest.py processing. """
1+
""" command line options, ini-file and conftest.py processing. """
22

33
import py
44
import sys, os
@@ -245,8 +245,6 @@ def __repr__(self):
245245

246246
class Config(object):
247247
""" access to configuration values, pluginmanager and plugin hooks. """
248-
basetemp = None
249-
250248
def __init__(self, pluginmanager=None):
251249
#: command line option values, usually added via parser.addoption(...)
252250
#: or parser.getgroup(...).addoption(...) calls
@@ -330,29 +328,6 @@ def parse(self, args):
330328
args.append(py.std.os.getcwd())
331329
self.args = args
332330

333-
def ensuretemp(self, string, dir=True):
334-
return self.getbasetemp().ensure(string, dir=dir)
335-
336-
def getbasetemp(self):
337-
if self.basetemp is None:
338-
basetemp = self.option.basetemp
339-
if basetemp:
340-
basetemp = py.path.local(basetemp)
341-
if not basetemp.check(dir=1):
342-
basetemp.mkdir()
343-
else:
344-
basetemp = py.path.local.make_numbered_dir(prefix='pytest-')
345-
self.basetemp = basetemp
346-
return self.basetemp
347-
348-
def mktemp(self, basename, numbered=False):
349-
basetemp = self.getbasetemp()
350-
if not numbered:
351-
return basetemp.mkdir(basename)
352-
else:
353-
return py.path.local.make_numbered_dir(prefix=basename,
354-
keep=0, rootdir=basetemp, lock_timeout=None)
355-
356331
def getini(self, name):
357332
""" return configuration value from an ini file. If the
358333
specified name hasn't been registered through a prior ``parse.addini``

_pytest/pytester.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ def __init__(self, request):
173173
self.Config = request.config.__class__
174174
self._pytest = request.getfuncargvalue("_pytest")
175175
# XXX remove duplication with tmpdir plugin
176-
basetmp = request.config.ensuretemp("testdir")
176+
basetmp = request.config._tmpdirhandler.ensuretemp("testdir")
177177
name = request.function.__name__
178178
for i in range(100):
179179
try:
@@ -350,7 +350,12 @@ def parseconfig(self, *args):
350350
if not args:
351351
args = (self.tmpdir,)
352352
config = self.config_preparse()
353-
args = list(args) + ["--basetemp=%s" % self.tmpdir.dirpath('basetemp')]
353+
args = list(args)
354+
for x in args:
355+
if str(x).startswith('--basetemp'):
356+
break
357+
else:
358+
args.append("--basetemp=%s" % self.tmpdir.dirpath('basetemp'))
354359
config.parse(args)
355360
return config
356361

@@ -361,7 +366,8 @@ def reparseconfig(self, args=None):
361366
oldconfig = getattr(py.test, 'config', None)
362367
try:
363368
c = py.test.config = self.Config()
364-
c.basetemp = oldconfig.mktemp("reparse", numbered=True)
369+
c.basetemp = py.path.local.make_numbered_dir(prefix="reparse",
370+
keep=0, rootdir=self.tmpdir, lock_timeout=None)
365371
c.parse(args)
366372
return c
367373
finally:

_pytest/tmpdir.py

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,61 @@
11
""" support for providing temporary directories to test functions. """
22
import pytest, py
3+
from _pytest.monkeypatch import monkeypatch
34

4-
def pytest_configure(config):
5-
def ensuretemp(string, dir=1):
5+
class TempdirHandler:
6+
def __init__(self, config):
7+
self.config = config
8+
self.trace = config.trace.get("tmpdir")
9+
10+
def ensuretemp(self, string, dir=1):
611
""" (deprecated) return temporary directory path with
712
the given string as the trailing part. It is usually
8-
better to use the 'tmpdir' function argument which will
9-
take care to provide empty unique directories for each
10-
test call even if the test is called multiple times.
13+
better to use the 'tmpdir' function argument which
14+
provides an empty unique-per-test-invocation directory
15+
and is guaranteed to be empty.
1116
"""
1217
#py.log._apiwarn(">1.1", "use tmpdir function argument")
13-
return config.ensuretemp(string, dir=dir)
14-
pytest.ensuretemp = ensuretemp
18+
return self.getbasetemp().ensure(string, dir=dir)
19+
20+
def mktemp(self, basename, numbered=True):
21+
basetemp = self.getbasetemp()
22+
if not numbered:
23+
p = basetemp.mkdir(basename)
24+
else:
25+
p = py.path.local.make_numbered_dir(prefix=basename,
26+
keep=0, rootdir=basetemp, lock_timeout=None)
27+
self.trace("mktemp", p)
28+
return p
29+
30+
def getbasetemp(self):
31+
""" return base temporary directory. """
32+
try:
33+
return self._basetemp
34+
except AttributeError:
35+
basetemp = self.config.option.basetemp
36+
if basetemp:
37+
basetemp = py.path.local(basetemp)
38+
if basetemp.check():
39+
basetemp.remove()
40+
basetemp.mkdir()
41+
else:
42+
basetemp = py.path.local.make_numbered_dir(prefix='pytest-')
43+
self._basetemp = t = basetemp
44+
self.trace("new basetemp", t)
45+
return t
46+
47+
def finish(self):
48+
self.trace("finish")
49+
50+
def pytest_configure(config):
51+
config._mp = mp = monkeypatch()
52+
t = TempdirHandler(config)
53+
mp.setattr(config, '_tmpdirhandler', t, raising=False)
54+
mp.setattr(pytest, 'ensuretemp', t.ensuretemp, raising=False)
55+
56+
def pytest_unconfigure(config):
57+
config._tmpdirhandler.finish()
58+
config._mp.undo()
1559

1660
def pytest_funcarg__tmpdir(request):
1761
"""return a temporary directory path object
@@ -22,5 +66,6 @@ def pytest_funcarg__tmpdir(request):
2266
"""
2367
name = request._pyfuncitem.name
2468
name = py.std.re.sub("[\W]", "_", name)
25-
x = request.config.mktemp(name, numbered=True)
69+
x = request.config._tmpdirhandler.mktemp(name, numbered=True)
2670
return x.realpath()
71+

doc/index.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ py.test: no-boilerplate testing with Python
55

66
.. note::
77
version 2.0 introduces ``pytest`` as the main Python import name
8-
but for compatibility reasons you can continue to use ``import py``
9-
and ``py.test.XYZ`` to access :ref:`pytest helpers` in your test code.
8+
in examples but you can continue to use ``import py`` and
9+
``py.test.XYZ`` to access :ref:`pytest helpers` in your test code.
1010

1111
Welcome to ``py.test`` documentation:
1212

doc/tmpdir.txt

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,12 @@ Running this would result in a passed test except for the last
5454
the default base temporary directory
5555
-----------------------------------------------
5656

57-
..
58-
You can create directories by calling one of two methods
59-
on the config object:
60-
- ``config.mktemp(basename)``: create and return a new tempdir
61-
- ``config.ensuretemp(basename)``: create or return a new tempdir
62-
6357
Temporary directories are by default created as sub directories of
64-
the system temporary directory. The name will be ``pytest-NUM`` where
58+
the system temporary directory. The base name will be ``pytest-NUM`` where
6559
``NUM`` will be incremenated with each test run. Moreover, entries older
6660
than 3 temporary directories will be removed.
6761

68-
You can override the default temporary directory logic and set it like this::
62+
You can override the default temporary directory setting like this::
6963

7064
py.test --basetemp=mydir
7165

testing/acceptance_test.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,6 @@ def test_option(pytestconfig):
3333
'*1 passed*',
3434
])
3535

36-
def test_basetemp(self, testdir):
37-
mytemp = testdir.tmpdir.mkdir("mytemp")
38-
p = testdir.makepyfile("""
39-
def test_1(pytestconfig):
40-
pytestconfig.getbasetemp().ensure("hello")
41-
""")
42-
result = testdir.runpytest(p, '--basetemp=%s' % mytemp)
43-
assert result.ret == 0
44-
assert mytemp.join('hello').check()
45-
4636
def test_assertion_magic(self, testdir):
4737
p = testdir.makepyfile("""
4838
def test_this():

testing/test_config.py

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -81,33 +81,6 @@ def test_parsing_again_fails(self, testdir):
8181
pytest.raises(AssertionError, "config.parse([])")
8282

8383

84-
class TestConfigTmpdir:
85-
def test_getbasetemp(self, testdir):
86-
config = testdir.Config()
87-
config.basetemp = "hello"
88-
config.getbasetemp() == "hello"
89-
90-
def test_mktemp(self, testdir):
91-
config = testdir.Config()
92-
config.basetemp = testdir.mkdir("hello")
93-
tmp = config.mktemp("world")
94-
assert tmp.relto(config.basetemp) == "world"
95-
tmp = config.mktemp("this", numbered=True)
96-
assert tmp.relto(config.basetemp).startswith("this")
97-
tmp2 = config.mktemp("this", numbered=True)
98-
assert tmp2.relto(config.basetemp).startswith("this")
99-
assert tmp2 != tmp
100-
101-
def test_reparse(self, testdir):
102-
config2 = testdir.reparseconfig([])
103-
config3 = testdir.reparseconfig([])
104-
assert config2.getbasetemp() != config3.getbasetemp()
105-
assert not config2.getbasetemp().relto(config3.getbasetemp())
106-
assert not config3.getbasetemp().relto(config2.getbasetemp())
107-
108-
def test_reparse_filename_too_long(self, testdir):
109-
config = testdir.reparseconfig(["--basetemp=%s" % ("123"*300)])
110-
11184
class TestConfigAPI:
11285

11386
def test_config_trace(self, testdir):

testing/test_tmpdir.py

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import py, pytest
22

3-
from _pytest.tmpdir import pytest_funcarg__tmpdir
3+
from _pytest.tmpdir import pytest_funcarg__tmpdir, TempdirHandler
44
from _pytest.python import FuncargRequest
55

66
def test_funcarg(testdir):
@@ -27,3 +27,51 @@ def test_ensuretemp(recwarn):
2727
assert d1 == d2
2828
assert d1.check(dir=1)
2929

30+
class TestTempdirHandler:
31+
def test_mktemp(self, testdir):
32+
config = testdir.Config()
33+
config.option.basetemp = testdir.mkdir("hello")
34+
t = TempdirHandler(config)
35+
tmp = t.mktemp("world")
36+
assert tmp.relto(t.getbasetemp()) == "world0"
37+
tmp = t.mktemp("this")
38+
assert tmp.relto(t.getbasetemp()).startswith("this")
39+
tmp2 = t.mktemp("this")
40+
assert tmp2.relto(t.getbasetemp()).startswith("this")
41+
assert tmp2 != tmp
42+
43+
class TestConfigTmpdir:
44+
def test_getbasetemp_custom_removes_old(self, testdir):
45+
p = testdir.tmpdir.join("xyz")
46+
config = testdir.parseconfigure("--basetemp=xyz")
47+
b = config._tmpdirhandler.getbasetemp()
48+
assert b == p
49+
h = b.ensure("hello")
50+
config._tmpdirhandler.getbasetemp()
51+
assert h.check()
52+
config = testdir.parseconfigure("--basetemp=xyz")
53+
b2 = config._tmpdirhandler.getbasetemp()
54+
assert b2.check()
55+
assert not h.check()
56+
57+
def test_reparse(self, testdir):
58+
config2 = testdir.reparseconfig([])
59+
config3 = testdir.reparseconfig([])
60+
assert config2.basetemp != config3.basetemp
61+
assert not config2.basetemp.relto(config3.basetemp)
62+
assert not config3.basetemp.relto(config2.basetemp)
63+
64+
def test_reparse_filename_too_long(self, testdir):
65+
config = testdir.reparseconfig(["--basetemp=%s" % ("123"*300)])
66+
67+
68+
def test_basetemp(testdir):
69+
mytemp = testdir.tmpdir.mkdir("mytemp")
70+
p = testdir.makepyfile("""
71+
import pytest
72+
def test_1():
73+
pytest.ensuretemp("hello")
74+
""")
75+
result = testdir.runpytest(p, '--basetemp=%s' % mytemp)
76+
assert result.ret == 0
77+
assert mytemp.join('hello').check()

tox.ini

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,3 @@ minversion=2.0
6666
plugins=pytester
6767
addopts= -rxf --pyargs --doctest-modules
6868
rsyncdirs=tox.ini pytest.py _pytest testing
69-

0 commit comments

Comments
 (0)