Skip to content

Commit 5f50343

Browse files
committed
Reset the hook proxy cache if the number of conftests changes
1 parent 64193ad commit 5f50343

File tree

5 files changed

+65
-19
lines changed

5 files changed

+65
-19
lines changed

CHANGELOG.rst

+6
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
once by the ``pytest_plugins`` mechanism.
2727
Thanks `@nicoddemus`_ for the PR.
2828

29+
* Remove an internal cache which could cause hooks from ``conftest.py`` files in
30+
sub-directories to be called in other directories incorrectly (`#2016`_).
31+
Thanks `@d-b-w`_ for the report and `@nicoddemus`_ for the PR.
32+
2933
* Remove internal code meant to support earlier Python 3 versions that produced the side effect
3034
of leaving ``None`` in ``sys.modules`` when expressions were evaluated by pytest (for example passing a condition
3135
as a string to ``pytest.mark.skipif``)(`#2103`_).
@@ -40,6 +44,7 @@
4044

4145
.. _@mbukatov: https://github.com/mbukatov
4246
.. _@dupuy: https://bitbucket.org/dupuy/
47+
.. _@d-b-w: https://bitbucket.org/d-b-w/
4348
.. _@lwm: https://github.com/lwm
4449
.. _@adler-j: https://github.com/adler-j
4550
.. _@DuncanBetts: https://github.com/DuncanBetts
@@ -49,6 +54,7 @@
4954
.. _#2089: https://github.com/pytest-dev/pytest/issues/2089
5055
.. _#478: https://github.com/pytest-dev/pytest/issues/478
5156
.. _#687: https://github.com/pytest-dev/pytest/issues/687
57+
.. _#2016: https://github.com/pytest-dev/pytest/issues/2016
5258
.. _#2034: https://github.com/pytest-dev/pytest/issues/2034
5359
.. _#2038: https://github.com/pytest-dev/pytest/issues/2038
5460
.. _#2078: https://github.com/pytest-dev/pytest/issues/2078

_pytest/main.py

+12-18
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,6 @@ class Session(FSCollector):
539539
def __init__(self, config):
540540
FSCollector.__init__(self, config.rootdir, parent=None,
541541
config=config, session=self)
542-
self._fs2hookproxy = {}
543542
self.testsfailed = 0
544543
self.testscollected = 0
545544
self.shouldstop = False
@@ -570,23 +569,18 @@ def isinitpath(self, path):
570569
return path in self._initialpaths
571570

572571
def gethookproxy(self, fspath):
573-
try:
574-
return self._fs2hookproxy[fspath]
575-
except KeyError:
576-
# check if we have the common case of running
577-
# hooks with all conftest.py filesall conftest.py
578-
pm = self.config.pluginmanager
579-
my_conftestmodules = pm._getconftestmodules(fspath)
580-
remove_mods = pm._conftest_plugins.difference(my_conftestmodules)
581-
if remove_mods:
582-
# one or more conftests are not in use at this fspath
583-
proxy = FSHookProxy(fspath, pm, remove_mods)
584-
else:
585-
# all plugis are active for this fspath
586-
proxy = self.config.hook
587-
588-
self._fs2hookproxy[fspath] = proxy
589-
return proxy
572+
# check if we have the common case of running
573+
# hooks with all conftest.py filesall conftest.py
574+
pm = self.config.pluginmanager
575+
my_conftestmodules = pm._getconftestmodules(fspath)
576+
remove_mods = pm._conftest_plugins.difference(my_conftestmodules)
577+
if remove_mods:
578+
# one or more conftests are not in use at this fspath
579+
proxy = FSHookProxy(fspath, pm, remove_mods)
580+
else:
581+
# all plugis are active for this fspath
582+
proxy = self.config.hook
583+
return proxy
590584

591585
def perform_collect(self, args=None, genitems=True):
592586
hook = self.config.hook

_pytest/pytester.py

+1
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,7 @@ def _makefile(self, ext, args, kwargs):
478478
ret = None
479479
for name, value in items:
480480
p = self.tmpdir.join(name).new(ext=ext)
481+
p.dirpath().ensure_dir()
481482
source = Source(value)
482483

483484
def my_totext(s, encoding="utf-8"):

testing/test_conftest.py

+25
Original file line numberDiff line numberDiff line change
@@ -423,3 +423,28 @@ def test_some():
423423
res = testdir.runpytest()
424424
assert res.ret == 4
425425
assert 'raise ValueError()' in [line.strip() for line in res.errlines]
426+
427+
428+
def test_hook_proxy(testdir):
429+
"""Session's gethookproxy() would cache conftests incorrectly (#2016).
430+
It was decided to remove the cache altogether.
431+
"""
432+
testdir.makepyfile(**{
433+
'root/demo-0/test_foo1.py': "def test1(): pass",
434+
435+
'root/demo-a/test_foo2.py': "def test1(): pass",
436+
'root/demo-a/conftest.py': """
437+
def pytest_ignore_collect(path, config):
438+
return True
439+
""",
440+
441+
'root/demo-b/test_foo3.py': "def test1(): pass",
442+
'root/demo-c/test_foo4.py': "def test1(): pass",
443+
})
444+
result = testdir.runpytest()
445+
result.stdout.fnmatch_lines([
446+
'*test_foo1.py*',
447+
'*test_foo3.py*',
448+
'*test_foo4.py*',
449+
'*3 passed*',
450+
])

testing/test_pluginmanager.py

+21-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
import os
55

66
from _pytest.config import get_config, PytestPluginManager
7-
from _pytest.main import EXIT_NOTESTSCOLLECTED
7+
from _pytest.main import EXIT_NOTESTSCOLLECTED, Session
8+
89

910
@pytest.fixture
1011
def pytestpm():
@@ -133,6 +134,25 @@ def pytest_plugin_registered(self):
133134
finally:
134135
undo()
135136

137+
def test_hook_proxy(self, testdir):
138+
"""Test the gethookproxy function(#2016)"""
139+
config = testdir.parseconfig()
140+
session = Session(config)
141+
testdir.makepyfile(**{
142+
'tests/conftest.py': '',
143+
'tests/subdir/conftest.py': '',
144+
})
145+
146+
conftest1 = testdir.tmpdir.join('tests/conftest.py')
147+
conftest2 = testdir.tmpdir.join('tests/subdir/conftest.py')
148+
149+
config.pluginmanager._importconftest(conftest1)
150+
ihook_a = session.gethookproxy(testdir.tmpdir.join('tests'))
151+
assert ihook_a is not None
152+
config.pluginmanager._importconftest(conftest2)
153+
ihook_b = session.gethookproxy(testdir.tmpdir.join('tests'))
154+
assert ihook_a is not ihook_b
155+
136156
def test_warn_on_deprecated_multicall(self, pytestpm):
137157
warnings = []
138158

0 commit comments

Comments
 (0)