Skip to content

Commit 54c91bf

Browse files
committed
Merge branch '58-write-wrapper-so-that-path-fspath-deprecation-warning-in-pytest-is-not-triggered' into 'master'
Resolve "Write wrapper so that path/fspath deprecation warning in pytest is not triggered" Closes #58 See merge request ins/nettowel/nettowel-nuts!28
2 parents cf1cf61 + 0ec7959 commit 54c91bf

File tree

2 files changed

+39
-9
lines changed

2 files changed

+39
-9
lines changed

nuts/yamlloader.py

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
Based on https://docs.pytest.org/en/stable/example/nonpython.html#yaml-plugin
33
"""
44
import importlib
5+
import pathlib
56
import types
67
from importlib import util
78
from typing import Iterable, Union, Any, Optional, List, Set, Dict, Tuple
@@ -13,24 +14,53 @@
1314
from _pytest.nodes import Node
1415
from _pytest.python import Metafunc
1516

16-
from nuts.helpers.errors import NutsUsageError
17+
from nuts.helpers.errors import NutsUsageError, NutsSetupError
1718
from nuts.index import ModuleIndex
1819

1920

2021
class NutsYamlFile(pytest.File):
2122
def collect(self) -> Iterable[Union[nodes.Item, nodes.Collector]]:
22-
with self.fspath.open() as f:
23-
raw = yaml.safe_load(f)
23+
# path uses pathlib.Path and is meant to replace fspath, which uses py.path.local
24+
# both variants will be used for some time in parallel within pytest.
25+
# If fspath is used in a newer pytest version, it triggers a deprecation warning.
26+
# We therefore use a wrapper that can use both path types
27+
if hasattr(self, "path"):
28+
yield from self._collect_path()
29+
else:
30+
yield from self._collect_fspath()
31+
32+
def _collect_path(self) -> Iterable[Union[nodes.Item, nodes.Collector]]:
33+
try:
34+
with self.path.open() as f: # type: ignore[attr-defined]
35+
raw = yaml.safe_load(f)
36+
except OSError as e:
37+
raise NutsSetupError(f"Could not open YAML file containing test bundle:\n{e}")
2438

2539
for test_entry in raw:
26-
module_path = find_module_path(test_entry.get("test_module"), test_entry.get("test_class"))
27-
module = load_module(module_path)
40+
module = find_and_load_module(test_entry)
41+
yield NutsTestFile.from_parent(self, path=self.path, obj=module, test_entry=test_entry) # type: ignore[attr-defined, call-arg]
42+
43+
def _collect_fspath(self) -> Iterable[Union[nodes.Item, nodes.Collector]]:
44+
try:
45+
with self.fspath.open() as f:
46+
raw = yaml.safe_load(f)
47+
except OSError as e:
48+
raise NutsSetupError(f"Could not open YAML file containing test bundle:\n{e}")
49+
50+
for test_entry in raw:
51+
module = find_and_load_module(test_entry)
2852
yield NutsTestFile.from_parent(self, fspath=self.fspath, obj=module, test_entry=test_entry)
2953

3054

31-
def find_module_path(module_path: Optional[str], class_name: str) -> str:
32-
if not class_name:
55+
def find_and_load_module(test_entry: dict):
56+
test_class = test_entry.get("test_class")
57+
if not test_class:
3358
raise NutsUsageError("Class name of the specific test missing in YAML file.")
59+
module_path = find_module_path(test_entry.get("test_module"), test_class)
60+
return load_module(module_path)
61+
62+
63+
def find_module_path(module_path: Optional[str], class_name: str) -> str:
3464
if not module_path:
3565
module_path = ModuleIndex().find_test_module_of_class(class_name)
3666
if not module_path:

poetry.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)