Skip to content

Commit

Permalink
get_dirs_from_args handles paths with invalid syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
nicoddemus committed Aug 12, 2020
1 parent 15d8293 commit 36c8bb4
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 14 deletions.
1 change: 1 addition & 0 deletions changelog/7638.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix handling of command-line options that appear as paths but trigger an OS-level syntax error on Windows, such as the options used internally by ``pytest-xdist``.
20 changes: 6 additions & 14 deletions src/_pytest/config/findpaths.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import itertools
import os
import sys
from typing import Dict
from typing import Iterable
from typing import List
Expand Down Expand Up @@ -146,20 +145,13 @@ def get_dir_from_path(path: Path) -> Path:
return path
return path.parent

if sys.version_info < (3, 8):

def safe_exists(path: Path) -> bool:
# On Python<3.8, this can throw on paths that contain characters
# unrepresentable at the OS level.
try:
return path.exists()
except OSError:
return False

else:

def safe_exists(path: Path) -> bool:
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
try:
return path.exists()
except OSError:
return False

# These look like paths but may not exist
possible_paths = (
Expand Down
15 changes: 15 additions & 0 deletions testing/test_findpaths.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import pytest
from _pytest.config.findpaths import get_common_ancestor
from _pytest.config.findpaths import get_dirs_from_args
from _pytest.config.findpaths import load_config_dict_from_file
from _pytest.pathlib import Path

Expand Down Expand Up @@ -108,3 +109,17 @@ def test_single_file(self, tmp_path: Path) -> None:
fn = tmp_path / "foo.py"
fn.touch()
assert get_common_ancestor([fn]) == tmp_path


def test_get_dirs_from_args(tmp_path):
"""get_dirs_from_args() skips over non-existing directories and files"""
fn = tmp_path / "foo.py"
fn.touch()
d = tmp_path / "tests"
d.mkdir()
option = "--foobar=/foo.txt"
# xdist uses options in this format for its rsync feature (#7638)
xdist_rsync_option = "popen=c:/dest"
assert get_dirs_from_args(
[str(fn), str(tmp_path / "does_not_exist"), str(d), option, xdist_rsync_option]
) == [fn.parent, d]

0 comments on commit 36c8bb4

Please sign in to comment.