@@ -1780,6 +1780,41 @@ def test_collect_short_file_windows(pytester: Pytester) -> None:
1780
1780
assert result .parseoutcomes () == {"passed" : 1 }
1781
1781
1782
1782
1783
+ def test_collect_short_file_windows_multi_level_symlink (
1784
+ pytester : Pytester ,
1785
+ request : FixtureRequest ,
1786
+ ) -> None :
1787
+ """Regression test for multi-level Windows short-path comparison with
1788
+ symlinks.
1789
+
1790
+ Previously, when matching collection arguments against collected nodes on
1791
+ Windows, the short path fallback resolved symlinks. With a chain a -> b ->
1792
+ target, comparing 'a' against 'b' would incorrectly succeed because both
1793
+ resolved to 'target', which could cause incorrect matching or duplicate
1794
+ collection.
1795
+ """
1796
+ # Prepare target directory with a test file.
1797
+ short_path = Path (tempfile .mkdtemp ())
1798
+ request .addfinalizer (lambda : shutil .rmtree (short_path , ignore_errors = True ))
1799
+ target = short_path / "target"
1800
+ target .mkdir ()
1801
+ (target / "test_chain.py" ).write_text ("def test_chain(): pass" , encoding = "UTF-8" )
1802
+
1803
+ # Create multi-level symlink chain: a -> b -> target.
1804
+ b = short_path / "b"
1805
+ a = short_path / "a"
1806
+ symlink_or_skip (target , b , target_is_directory = True )
1807
+ symlink_or_skip (b , a , target_is_directory = True )
1808
+
1809
+ # Collect via the first symlink; should find exactly one test.
1810
+ result = pytester .runpytest (a )
1811
+ result .assert_outcomes (passed = 1 )
1812
+
1813
+ # Collect via the intermediate symlink; also exactly one test.
1814
+ result = pytester .runpytest (b )
1815
+ result .assert_outcomes (passed = 1 )
1816
+
1817
+
1783
1818
def test_pyargs_collection_tree (pytester : Pytester , monkeypatch : MonkeyPatch ) -> None :
1784
1819
"""When using `--pyargs`, the collection tree of a pyargs collection
1785
1820
argument should only include parents in the import path, not up to confcutdir.
0 commit comments