Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/4174.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix "ValueError: Plugin already registered" with conftest plugins via symlink.
2 changes: 1 addition & 1 deletion src/_pytest/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ def _getconftestmodules(self, path):
# and allow users to opt into looking into the rootdir parent
# directories instead of requiring to specify confcutdir
clist = []
for parent in directory.parts():
for parent in directory.realpath().parts():
if self._confcutdir and self._confcutdir.relto(parent):
continue
conftestpath = parent.join("conftest.py")
Expand Down
8 changes: 7 additions & 1 deletion testing/test_conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,10 @@ def pytest_addoption(parser):
)
def test_conftest_symlink(testdir):
"""Ensure that conftest.py is used for resolved symlinks."""
realtests = testdir.tmpdir.mkdir("real").mkdir("app").mkdir("tests")
real = testdir.tmpdir.mkdir("real")
realtests = real.mkdir("app").mkdir("tests")
testdir.tmpdir.join("symlinktests").mksymlinkto(realtests)
testdir.tmpdir.join("symlink").mksymlinkto(real)
testdir.makepyfile(
**{
"real/app/tests/test_foo.py": "def test1(fixture): pass",
Expand All @@ -220,6 +222,10 @@ def fixture():
)
assert result.ret == EXIT_OK

# Should not cause "ValueError: Plugin already registered" (#4174).
result = testdir.runpytest("-vs", "symlink")
assert result.ret == EXIT_OK

realtests.ensure("__init__.py")
result = testdir.runpytest("-vs", "symlinktests/test_foo.py::test1")
result.stdout.fnmatch_lines(
Expand Down