Skip to content

Commit be15ad8

Browse files
committed
Fix collection of direct symlinked files not in python_files
Fixes #4325.
1 parent 7ab3d81 commit be15ad8

File tree

4 files changed

+58
-2
lines changed

4 files changed

+58
-2
lines changed

changelog/4321.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix ``item.nodeid`` with resolved symlinks.

changelog/4325.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix collection of direct symlinked files, where the target does not match ``python_files``.

src/_pytest/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@ def _collect(self, arg):
488488
from _pytest.python import Package
489489

490490
names = self._parsearg(arg)
491-
argpath = names.pop(0).realpath()
491+
argpath = names.pop(0)
492492

493493
# Start with a Session root, and delve to argpath item (dir or file)
494494
# and stack all Packages found on the way.
@@ -636,7 +636,7 @@ def _parsearg(self, arg):
636636
"file or package not found: " + arg + " (missing __init__.py?)"
637637
)
638638
raise UsageError("file not found: " + arg)
639-
parts[0] = path
639+
parts[0] = path.realpath()
640640
return parts
641641

642642
def matchnodes(self, matching, names):

testing/test_collection.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import sys
77
import textwrap
88

9+
import py
10+
911
import pytest
1012
from _pytest.main import _in_venv
1113
from _pytest.main import EXIT_NOTESTSCOLLECTED
@@ -1051,3 +1053,55 @@ def test_1():
10511053
result = testdir.runpytest()
10521054
assert result.ret == 0
10531055
result.stdout.fnmatch_lines(["*1 passed in*"])
1056+
1057+
1058+
@pytest.mark.skipif(
1059+
not hasattr(py.path.local, "mksymlinkto"),
1060+
reason="symlink not available on this platform",
1061+
)
1062+
def test_collect_symlink_file_arg(testdir):
1063+
"""Test that collecting a direct symlink, where the target does not match python_files works (#4325)."""
1064+
real = testdir.makepyfile(
1065+
real="""
1066+
def test_nodeid(request):
1067+
assert request.node.nodeid == "real.py::test_nodeid"
1068+
"""
1069+
)
1070+
symlink = testdir.tmpdir.join("symlink.py")
1071+
symlink.mksymlinkto(real)
1072+
result = testdir.runpytest("-v", symlink)
1073+
result.stdout.fnmatch_lines(["real.py::test_nodeid PASSED*", "*1 passed in*"])
1074+
assert result.ret == 0
1075+
1076+
1077+
@pytest.mark.skipif(
1078+
not hasattr(py.path.local, "mksymlinkto"),
1079+
reason="symlink not available on this platform",
1080+
)
1081+
def test_collect_symlink_out_of_tree(testdir):
1082+
"""Test collection of symlink via out-of-tree rootdir."""
1083+
sub = testdir.tmpdir.join("sub")
1084+
real = sub.join("test_real.py")
1085+
real.write(
1086+
textwrap.dedent(
1087+
"""
1088+
def test_nodeid(request):
1089+
# Should not contain sub/ prefix.
1090+
assert request.node.nodeid == "test_real.py::test_nodeid"
1091+
"""
1092+
),
1093+
ensure=True,
1094+
)
1095+
1096+
out_of_tree = testdir.tmpdir.join("out_of_tree").ensure(dir=True)
1097+
symlink_to_sub = out_of_tree.join("symlink_to_sub")
1098+
symlink_to_sub.mksymlinkto(sub)
1099+
sub.chdir()
1100+
result = testdir.runpytest("-vs", "--rootdir=%s" % sub, symlink_to_sub)
1101+
result.stdout.fnmatch_lines(
1102+
[
1103+
# Should not contain "sub/"!
1104+
"test_real.py::test_nodeid PASSED"
1105+
]
1106+
)
1107+
assert result.ret == 0

0 commit comments

Comments
 (0)