You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a test directory is nested within a symlinked directory, it can lead to errors when the 'rootdir' or the invocation directory targets the unresolved path, especially when the symlink targets a different storage structure.
> ln -s /tmp/test /path/to/test/path
>cd /tmp/test
> pytest --rootdir=/tmp/test .
==================================== ERRORS ====================================
________________________ ERROR collecting test session _________________________
...
/usr/lib/python3.10/path lib.py:1097: PermissionError
=========================== Short test summary info ============================
ERROR ../../path/to/test/path::dir - PermissionError: [Errno 13] Permission denied: '/..../__init__.py'
=============================== 1 error in 0.14s ===============================
> pytest --rootdir=. /tmp/test
# Same error ...
This issue does not occur when both the 'rootdir' and invocation directory use the same path (resolved or unresolved).
The invocation directory defaults to Path.cwd() which resolves the symlink, and relative entries seem to be normalized via pathlib.absolutepath (using os.path.abspath under the hood), which also returns a resolved path in some situations:
By default, the 'confcutdir' value is inferred from the 'rootdir' value, which is inferred from the invocation path, so it doesn't seem to be a problem. But in cases where the invocation path is defined to use the resolved path, while the 'rootdir' value is defined to use the unresolved path (or vice versa), the Session collector may encounter difficulties determining where to stop when searching for configs:
# Add relevant parents of the path, from the root, e.g.
# /a/b/c.py -> [/, /a, /a/b, /a/b/c.py]
ifmodule_nameisNone:
# Paths outside of the confcutdir should not be considered.
forpathinargpath.parents:
ifnotpm._is_in_confcutdir(path):
break
paths.insert(0, path)
This issue could be solved by automatically resolving the value used for 'rootdir', but I'm not sure if there are any drawbacks to this approach (aside from performance).
I ran these tests on MacOS and Linux using Pytest 8.2.0 and Python 3.10.
When a test directory is nested within a symlinked directory, it can lead to errors when the 'rootdir' or the invocation directory targets the unresolved path, especially when the symlink targets a different storage structure.
This issue does not occur when both the 'rootdir' and invocation directory use the same path (resolved or unresolved).
The invocation directory defaults to Path.cwd() which resolves the symlink, and relative entries seem to be normalized via pathlib.absolutepath (using
os.path.abspath
under the hood), which also returns a resolved path in some situations:By default, the 'confcutdir' value is inferred from the 'rootdir' value, which is inferred from the invocation path, so it doesn't seem to be a problem. But in cases where the invocation path is defined to use the resolved path, while the 'rootdir' value is defined to use the unresolved path (or vice versa), the Session collector may encounter difficulties determining where to stop when searching for configs:
pytest/src/_pytest/main.py
Lines 861 to 869 in 84e59af
This issue could be solved by automatically resolving the value used for 'rootdir', but I'm not sure if there are any drawbacks to this approach (aside from performance).
I ran these tests on MacOS and Linux using Pytest 8.2.0 and Python 3.10.
I also setup a small repository to reproduce the errors via a Github workflow for more details:
https://github.com/buddly27/pytest-issue/actions/runs/8973032152/job/24642315352
The text was updated successfully, but these errors were encountered: