test_link_resolve.py
Overview
`test_link_resolve.py` is a test module designed to validate how file paths are resolved and displayed when running pytest on files accessed via substituted or symlinked paths. The core purpose is to ensure that error reports generated by pytest show relative paths instead of fully resolved absolute paths. This behavior addresses a specific issue tracked in the pytest project ([issue #5965](https://github.com/pytest-dev/pytest/issues/5965)).
The file achieves this by:
Creating temporary directories with test files.
Using platform-specific methods to create virtual paths to these files:
On Windows: Using
substcommand to map a directory to a drive letter.On Linux: Using symbolic links to create alternative directory paths.
Running pytest on these virtual paths and asserting the output paths in error messages.
This test ensures pytest’s error reporting respects virtual file system paths rather than resolving them to canonical absolute paths, improving clarity in test output.
Detailed Explanations
Context Managers
These context managers temporarily create a virtual or substituted path pointing to a directory containing test files. They yield a new path that can be used to run pytest.
subst_path_windows(filepath: Path) -> Iterator[Path]
**Purpose:** Creates a temporary `subst` drive letter (from H: to Z:) that maps to the directory of `filepath`. This allows testing how pytest behaves when files are accessed via a substituted drive path on Windows.
**Parameters:**
filepath(Path): The path to the target file whose directory will be subst’d.
**Yields:**
Path: A new file path with the substituted drive letter as root.
**Behavior:**
Finds the first available drive letter from H: to Z: that is not currently used.
Runs the
substcommand to map that drive letter tofilepath’s parent directory.Yields a new
Pathcombining the subst drive and the original filename.Upon exit, removes the subst drive mapping.
**Example Usage:**
with subst_path_windows(Path(r"C:\Users\example\test_foo.py")) as subst_path:
# subst_path might be something like H:\test_foo.py
run_pytest_on(subst_path)
subst_path_linux(filepath: Path) -> Iterator[Path]
**Purpose:** Creates a symbolic link `sub2` pointing to the directory of `filepath`. This simulates a substituted or linked path under Linux for testing purposes.
**Parameters:**
filepath(Path): The path to the target file whose directory will be symlinked.
**Yields:**
Path: A new file path with the symlink directory as root.
**Behavior:**
Creates a symlink
sub2one directory above the target directory, linking back tofilepath’s directory.Yields a new
Pathcombining the symlinksub2and the original filename.Does not unlink the symlink on exit (assumes running in temporary test directories).
**Example Usage:**
with subst_path_linux(Path("/home/user/project/sub1/test_foo.py")) as subst_path:
# subst_path might be /home/user/project/sub2/test_foo.py
run_pytest_on(subst_path)
Test Function
test_link_resolve(pytester: Pytester) -> None
**Purpose:** Tests that pytest reports error paths relative to the substituted or symlinked path rather than the fully resolved absolute path.
**Parameters:**
pytester(Pytester): A pytest fixture that provides utilities to create test files/directories and invoke pytest programmatically.
**Returns:**
None
**Detailed Steps:**
Creates a new test directory
sub1with a test filetest_foo.pythat always fails with anAssertionError.Depending on the platform, selects the appropriate substitution context manager (
subst_path_windowsorsubst_path_linux).Uses the substitution manager to get a virtual path to the test file.
Runs pytest on this virtual path with verbosity enabled (
-v).Captures the output and asserts:
The error message does not contain the fully resolved relative path
"sub1/test_foo.py".The error message does contain the substituted path:
On Windows: the path with the new drive letter.
On Linux: the symlink path
"sub2/test_foo.py".
**Usage Example:**
This test is intended to be run automatically as part of pytest’s test suite:
pytest test_link_resolve.py
Important Implementation Details & Algorithms
The Windows substitution uses the
substcommand line tool to create a temporary drive letter mapped to a directory. The code searches for an unused drive letter between H: and Z: and asserts failure if none are free.The Linux substitution uses symlinks created in a temporary directory structure, taking advantage of the fact that symlinks do not need explicit cleanup in this controlled environment.
The test checks how pytest internally resolves file paths when reporting errors, ensuring that the virtual paths provided by these substitutions are preserved in output, rather than being resolved to the real physical paths.
This is important for debugging and clarity when tests are run in complex file system scenarios such as network drives, mounted volumes, or containerized environments.
Interaction with Other Parts of the System
Pytester Fixture: This file depends on the
_pytest.pytester.Pytesterfixture, which is part of the pytest internal test utilities.Pytesterallows programmatic creation of test files and running of pytest sessions.Pytest Core: This test verifies behavior in the core pytest reporting and path resolution mechanisms.
Operating System Utilities: Uses
subprocesscalls tosubston Windows and nativeos.symlinkon Linux to create virtualized file paths.File System: Manipulates filesystem paths and temporary directories created by the pytester fixture.
This file is part of the pytest test suite and serves as a regression test for a specific issue in path reporting.
Mermaid Class Diagram
classDiagram
class subst_path_windows {
+filepath: Path
+__enter__(): Path
+__exit__(): None
}
class subst_path_linux {
+filepath: Path
+__enter__(): Path
+__exit__(): None
}
class test_link_resolve {
+pytester: Pytester
+__call__(): None
}
subst_path_windows ..> Path : uses
subst_path_linux ..> Path : uses
test_link_resolve ..> Pytester : uses
test_link_resolve ..> subst_path_windows : calls on win32
test_link_resolve ..> subst_path_linux : calls on linux
Summary
This file tests the correctness of pytest’s error path reporting when test files are accessed through substituted or symlinked paths.
It uses platform-specific context managers to create virtual paths.
Runs pytest on these paths and asserts output correctness.
Helps ensure user-friendly error messages in complex filesystem environments.
The combination of OS-specific path substitution and pytest execution allows this test to serve as a robust regression test for a known issue in pytest path resolution.