diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index cde230fdb..eb03b6338 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -59,6 +59,7 @@ from _pytest.pathlib import bestrelpath from _pytest.pathlib import import_path from _pytest.pathlib import ImportMode from _pytest.pathlib import resolve_package_path +from _pytest.pathlib import safe_exists from _pytest.stash import Stash from _pytest.warning_types import PytestConfigWarning from _pytest.warning_types import warn_explicit_for @@ -562,12 +563,8 @@ class PytestPluginManager(PluginManager): anchor = absolutepath(current / path) # Ensure we do not break if what appears to be an anchor - # is in fact a very long option (#10169). - try: - anchor_exists = anchor.exists() - except OSError: # pragma: no cover - anchor_exists = False - if anchor_exists: + # is in fact a very long option (#10169, #11394). + if safe_exists(anchor): self._try_load_conftest(anchor, importmode, rootpath) foundanchor = True if not foundanchor: diff --git a/src/_pytest/config/findpaths.py b/src/_pytest/config/findpaths.py index 9c76947a4..fc30533b6 100644 --- a/src/_pytest/config/findpaths.py +++ b/src/_pytest/config/findpaths.py @@ -15,6 +15,7 @@ from .exceptions import UsageError from _pytest.outcomes import fail from _pytest.pathlib import absolutepath from _pytest.pathlib import commonpath +from _pytest.pathlib import safe_exists def _parse_ini_config(path: Path) -> iniconfig.IniConfig: @@ -147,14 +148,6 @@ def get_dirs_from_args(args: Iterable[str]) -> List[Path]: return path return path.parent - def safe_exists(path: Path) -> bool: - # This can throw on paths that contain characters unrepresentable at the OS level, - # or with invalid syntax on Windows (https://bugs.python.org/issue35306) - try: - return path.exists() - except OSError: - return False - # These look like paths but may not exist possible_paths = ( absolutepath(get_file_part_from_node_id(arg)) diff --git a/src/_pytest/pathlib.py b/src/_pytest/pathlib.py index f44180f1a..63b1345b4 100644 --- a/src/_pytest/pathlib.py +++ b/src/_pytest/pathlib.py @@ -1,6 +1,5 @@ import atexit import contextlib -import errno import fnmatch import importlib.util import itertools @@ -780,7 +779,7 @@ def safe_exists(p: Path) -> bool: """Like Path.exists(), but account for input arguments that might be too long (#11394).""" try: return p.exists() - except OSError as e: - if e.errno == errno.ENAMETOOLONG: - return False - raise + except (ValueError, OSError): + # ValueError: stat: path too long for Windows + # OSError: [WinError 123] The filename, directory name, or volume label syntax is incorrect + return False diff --git a/testing/test_pathlib.py b/testing/test_pathlib.py index 8a9659aab..678fd27fe 100644 --- a/testing/test_pathlib.py +++ b/testing/test_pathlib.py @@ -688,7 +688,6 @@ def test_safe_exists(tmp_path: Path) -> None: Path, "exists", autospec=True, - side_effect=OSError(errno.EIO, "another kind of error"), + side_effect=ValueError("name too long"), ): - with pytest.raises(OSError): - _ = safe_exists(p) + assert safe_exists(p) is False