Skip to content

Rename pathlib hook parameters #9363

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Dec 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions changelog/8144.feature.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
The following hooks now receive an additional ``pathlib.Path`` argument, equivalent to an existing ``py.path.local`` argument:

- :func:`pytest_ignore_collect <_pytest.hookspec.pytest_ignore_collect>` - The ``fspath`` parameter (equivalent to existing ``path`` parameter).
- :func:`pytest_collect_file <_pytest.hookspec.pytest_collect_file>` - The ``fspath`` parameter (equivalent to existing ``path`` parameter).
- :func:`pytest_pycollect_makemodule <_pytest.hookspec.pytest_pycollect_makemodule>` - The ``fspath`` parameter (equivalent to existing ``path`` parameter).
- :func:`pytest_report_header <_pytest.hookspec.pytest_report_header>` - The ``startpath`` parameter (equivalent to existing ``startdir`` parameter).
- :func:`pytest_report_collectionfinish <_pytest.hookspec.pytest_report_collectionfinish>` - The ``startpath`` parameter (equivalent to existing ``startdir`` parameter).
- :func:`pytest_ignore_collect <_pytest.hookspec.pytest_ignore_collect>` - The ``collection_path`` parameter (equivalent to existing ``path`` parameter).
- :func:`pytest_collect_file <_pytest.hookspec.pytest_collect_file>` - The ``file_path`` parameter (equivalent to existing ``path`` parameter).
- :func:`pytest_pycollect_makemodule <_pytest.hookspec.pytest_pycollect_makemodule>` - The ``module_path`` parameter (equivalent to existing ``path`` parameter).
- :func:`pytest_report_header <_pytest.hookspec.pytest_report_header>` - The ``start_path`` parameter (equivalent to existing ``startdir`` parameter).
- :func:`pytest_report_collectionfinish <_pytest.hookspec.pytest_report_collectionfinish>` - The ``start_path`` parameter (equivalent to existing ``startdir`` parameter).
10 changes: 5 additions & 5 deletions doc/en/deprecations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ drop any other usage of the ``py`` library if possible.

In order to support the transition from ``py.path.local`` to :mod:`pathlib`, the following hooks now receive additional arguments:

* :func:`pytest_ignore_collect(fspath: pathlib.Path) <_pytest.hookspec.pytest_ignore_collect>` instead of ``path``
* :func:`pytest_collect_file(fspath: pathlib.Path) <_pytest.hookspec.pytest_collect_file>` instead of ``path``
* :func:`pytest_pycollect_makemodule(fspath: pathlib.Path) <_pytest.hookspec.pytest_pycollect_makemodule>` instead of ``path``
* :func:`pytest_report_header(startpath: pathlib.Path) <_pytest.hookspec.pytest_report_header>` instead of ``startdir``
* :func:`pytest_report_collectionfinish(startpath: pathlib.Path) <_pytest.hookspec.pytest_report_collectionfinish>` instead of ``startdir``
* :func:`pytest_ignore_collect(collection_path: pathlib.Path) <_pytest.hookspec.pytest_ignore_collect>` as equivalent to ``path``
* :func:`pytest_collect_file(file_path: pathlib.Path) <_pytest.hookspec.pytest_collect_file>` as equivalent to ``path``
* :func:`pytest_pycollect_makemodule(module_path: pathlib.Path) <_pytest.hookspec.pytest_pycollect_makemodule>` as equivalent to ``path``
* :func:`pytest_report_header(start_path: pathlib.Path) <_pytest.hookspec.pytest_report_header>` as equivalent to ``startdir``
* :func:`pytest_report_collectionfinish(start_path: pathlib.Path) <_pytest.hookspec.pytest_report_collectionfinish>` as equivalent to ``startdir``

The accompanying ``py.path.local`` based paths have been deprecated: plugins which manually invoke those hooks should only pass the new ``pathlib.Path`` arguments, and users should change their hook implementations to use the new ``pathlib.Path`` arguments.

Expand Down
10 changes: 5 additions & 5 deletions src/_pytest/config/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@

# hookname: (Path, LEGACY_PATH)
imply_paths_hooks = {
"pytest_ignore_collect": ("fspath", "path"),
"pytest_collect_file": ("fspath", "path"),
"pytest_pycollect_makemodule": ("fspath", "path"),
"pytest_report_header": ("startpath", "startdir"),
"pytest_report_collectionfinish": ("startpath", "startdir"),
"pytest_ignore_collect": ("collection_path", "path"),
"pytest_collect_file": ("file_path", "path"),
"pytest_pycollect_makemodule": ("module_path", "path"),
"pytest_report_header": ("start_path", "startdir"),
"pytest_report_collectionfinish": ("start_path", "startdir"),
}


Expand Down
12 changes: 6 additions & 6 deletions src/_pytest/doctest.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,18 +120,18 @@ def pytest_unconfigure() -> None:


def pytest_collect_file(
fspath: Path,
file_path: Path,
parent: Collector,
) -> Optional[Union["DoctestModule", "DoctestTextfile"]]:
config = parent.config
if fspath.suffix == ".py":
if file_path.suffix == ".py":
if config.option.doctestmodules and not any(
(_is_setup_py(fspath), _is_main_py(fspath))
(_is_setup_py(file_path), _is_main_py(file_path))
):
mod: DoctestModule = DoctestModule.from_parent(parent, path=fspath)
mod: DoctestModule = DoctestModule.from_parent(parent, path=file_path)
return mod
elif _is_doctest(config, fspath, parent):
txt: DoctestTextfile = DoctestTextfile.from_parent(parent, path=fspath)
elif _is_doctest(config, file_path, parent):
txt: DoctestTextfile = DoctestTextfile.from_parent(parent, path=file_path)
return txt
return None

Expand Down
30 changes: 15 additions & 15 deletions src/_pytest/hookspec.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ def pytest_collection_finish(session: "Session") -> None:

@hookspec(firstresult=True)
def pytest_ignore_collect(
fspath: Path, path: "LEGACY_PATH", config: "Config"
collection_path: Path, path: "LEGACY_PATH", config: "Config"
) -> Optional[bool]:
"""Return True to prevent considering this path for collection.

Expand All @@ -271,29 +271,29 @@ def pytest_ignore_collect(

Stops at first non-None result, see :ref:`firstresult`.

:param pathlib.Path fspath: The path to analyze.
:param pathlib.Path collection_path : The path to analyze.
:param LEGACY_PATH path: The path to analyze (deprecated).
:param pytest.Config config: The pytest config object.

.. versionchanged:: 7.0.0
The ``fspath`` parameter was added as a :class:`pathlib.Path`
The ``collection_path`` parameter was added as a :class:`pathlib.Path`
equivalent of the ``path`` parameter. The ``path`` parameter
has been deprecated.
"""


def pytest_collect_file(
fspath: Path, path: "LEGACY_PATH", parent: "Collector"
file_path: Path, path: "LEGACY_PATH", parent: "Collector"
) -> "Optional[Collector]":
"""Create a Collector for the given path, or None if not relevant.

The new node needs to have the specified ``parent`` as a parent.

:param pathlib.Path fspath: The path to analyze.
:param pathlib.Path file_path: The path to analyze.
:param LEGACY_PATH path: The path to collect (deprecated).

.. versionchanged:: 7.0.0
The ``fspath`` parameter was added as a :class:`pathlib.Path`
The ``file_path`` parameter was added as a :class:`pathlib.Path`
equivalent of the ``path`` parameter. The ``path`` parameter
has been deprecated.
"""
Expand Down Expand Up @@ -337,7 +337,7 @@ def pytest_make_collect_report(collector: "Collector") -> "Optional[CollectRepor

@hookspec(firstresult=True)
def pytest_pycollect_makemodule(
fspath: Path, path: "LEGACY_PATH", parent
module_path: Path, path: "LEGACY_PATH", parent
) -> Optional["Module"]:
"""Return a Module collector or None for the given path.

Expand All @@ -347,11 +347,11 @@ def pytest_pycollect_makemodule(

Stops at first non-None result, see :ref:`firstresult`.

:param pathlib.Path fspath: The path of the module to collect.
:param pathlib.Path module_path: The path of the module to collect.
:param LEGACY_PATH path: The path of the module to collect (deprecated).

.. versionchanged:: 7.0.0
The ``fspath`` parameter was added as a :class:`pathlib.Path`
The ``module_path`` parameter was added as a :class:`pathlib.Path`
equivalent of the ``path`` parameter.

The ``path`` parameter has been deprecated in favor of ``fspath``.
Expand Down Expand Up @@ -674,12 +674,12 @@ def pytest_assertion_pass(item: "Item", lineno: int, orig: str, expl: str) -> No


def pytest_report_header(
config: "Config", startpath: Path, startdir: "LEGACY_PATH"
config: "Config", start_path: Path, startdir: "LEGACY_PATH"
) -> Union[str, List[str]]:
"""Return a string or list of strings to be displayed as header info for terminal reporting.

:param pytest.Config config: The pytest config object.
:param Path startpath: The starting dir.
:param Path start_path: The starting dir.
:param LEGACY_PATH startdir: The starting dir (deprecated).

.. note::
Expand All @@ -696,15 +696,15 @@ def pytest_report_header(
:ref:`discovers plugins during startup <pluginorder>`.

.. versionchanged:: 7.0.0
The ``startpath`` parameter was added as a :class:`pathlib.Path`
The ``start_path`` parameter was added as a :class:`pathlib.Path`
equivalent of the ``startdir`` parameter. The ``startdir`` parameter
has been deprecated.
"""


def pytest_report_collectionfinish(
config: "Config",
startpath: Path,
start_path: Path,
startdir: "LEGACY_PATH",
items: Sequence["Item"],
) -> Union[str, List[str]]:
Expand All @@ -716,7 +716,7 @@ def pytest_report_collectionfinish(
.. versionadded:: 3.2

:param pytest.Config config: The pytest config object.
:param Path startpath: The starting dir.
:param Path start_path: The starting dir.
:param LEGACY_PATH startdir: The starting dir (deprecated).
:param items: List of pytest items that are going to be executed; this list should not be modified.

Expand All @@ -728,7 +728,7 @@ def pytest_report_collectionfinish(
:ref:`trylast=True <plugin-hookorder>`.

.. versionchanged:: 7.0.0
The ``startpath`` parameter was added as a :class:`pathlib.Path`
The ``start_path`` parameter was added as a :class:`pathlib.Path`
equivalent of the ``startdir`` parameter. The ``startdir`` parameter
has been deprecated.
"""
Expand Down
18 changes: 9 additions & 9 deletions src/_pytest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,31 +372,31 @@ def _in_venv(path: Path) -> bool:
return any(fname.name in activates for fname in bindir.iterdir())


def pytest_ignore_collect(fspath: Path, config: Config) -> Optional[bool]:
def pytest_ignore_collect(collection_path: Path, config: Config) -> Optional[bool]:
ignore_paths = config._getconftest_pathlist(
"collect_ignore", path=fspath.parent, rootpath=config.rootpath
"collect_ignore", path=collection_path.parent, rootpath=config.rootpath
)
ignore_paths = ignore_paths or []
excludeopt = config.getoption("ignore")
if excludeopt:
ignore_paths.extend(absolutepath(x) for x in excludeopt)

if fspath in ignore_paths:
if collection_path in ignore_paths:
return True

ignore_globs = config._getconftest_pathlist(
"collect_ignore_glob", path=fspath.parent, rootpath=config.rootpath
"collect_ignore_glob", path=collection_path.parent, rootpath=config.rootpath
)
ignore_globs = ignore_globs or []
excludeglobopt = config.getoption("ignore_glob")
if excludeglobopt:
ignore_globs.extend(absolutepath(x) for x in excludeglobopt)

if any(fnmatch.fnmatch(str(fspath), str(glob)) for glob in ignore_globs):
if any(fnmatch.fnmatch(str(collection_path), str(glob)) for glob in ignore_globs):
return True

allow_in_venv = config.getoption("collect_in_virtualenv")
if not allow_in_venv and _in_venv(fspath):
if not allow_in_venv and _in_venv(collection_path):
return True
return None

Expand Down Expand Up @@ -557,7 +557,7 @@ def _recurse(self, direntry: "os.DirEntry[str]") -> bool:
return False
fspath = Path(direntry.path)
ihook = self.gethookproxy(fspath.parent)
if ihook.pytest_ignore_collect(fspath=fspath, config=self.config):
if ihook.pytest_ignore_collect(collection_path=fspath, config=self.config):
return False
norecursepatterns = self.config.getini("norecursedirs")
if any(fnmatch_ex(pat, fspath) for pat in norecursepatterns):
Expand All @@ -574,7 +574,7 @@ def _collectfile(
)
ihook = self.gethookproxy(fspath)
if not self.isinitpath(fspath):
if ihook.pytest_ignore_collect(fspath=fspath, config=self.config):
if ihook.pytest_ignore_collect(collection_path=fspath, config=self.config):
return ()

if handle_dupes:
Expand All @@ -586,7 +586,7 @@ def _collectfile(
else:
duplicate_paths.add(fspath)

return ihook.pytest_collect_file(fspath=fspath, parent=self) # type: ignore[no-any-return]
return ihook.pytest_collect_file(file_path=fspath, parent=self) # type: ignore[no-any-return]

@overload
def perform_collect(
Expand Down
28 changes: 15 additions & 13 deletions src/_pytest/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,15 +195,17 @@ def pytest_pyfunc_call(pyfuncitem: "Function") -> Optional[object]:
return True


def pytest_collect_file(fspath: Path, parent: nodes.Collector) -> Optional["Module"]:
if fspath.suffix == ".py":
if not parent.session.isinitpath(fspath):
def pytest_collect_file(file_path: Path, parent: nodes.Collector) -> Optional["Module"]:
if file_path.suffix == ".py":
if not parent.session.isinitpath(file_path):
if not path_matches_patterns(
fspath, parent.config.getini("python_files") + ["__init__.py"]
file_path, parent.config.getini("python_files") + ["__init__.py"]
):
return None
ihook = parent.session.gethookproxy(fspath)
module: Module = ihook.pytest_pycollect_makemodule(fspath=fspath, parent=parent)
ihook = parent.session.gethookproxy(file_path)
module: Module = ihook.pytest_pycollect_makemodule(
module_path=file_path, parent=parent
)
return module
return None

Expand All @@ -213,11 +215,11 @@ def path_matches_patterns(path: Path, patterns: Iterable[str]) -> bool:
return any(fnmatch_ex(pattern, path) for pattern in patterns)


def pytest_pycollect_makemodule(fspath: Path, parent) -> "Module":
if fspath.name == "__init__.py":
pkg: Package = Package.from_parent(parent, path=fspath)
def pytest_pycollect_makemodule(module_path: Path, parent) -> "Module":
if module_path.name == "__init__.py":
pkg: Package = Package.from_parent(parent, path=module_path)
return pkg
mod: Module = Module.from_parent(parent, path=fspath)
mod: Module = Module.from_parent(parent, path=module_path)
return mod


Expand Down Expand Up @@ -676,7 +678,7 @@ def _recurse(self, direntry: "os.DirEntry[str]") -> bool:
return False
fspath = Path(direntry.path)
ihook = self.session.gethookproxy(fspath.parent)
if ihook.pytest_ignore_collect(fspath=fspath, config=self.config):
if ihook.pytest_ignore_collect(collection_path=fspath, config=self.config):
return False
norecursepatterns = self.config.getini("norecursedirs")
if any(fnmatch_ex(pat, fspath) for pat in norecursepatterns):
Expand All @@ -693,7 +695,7 @@ def _collectfile(
)
ihook = self.session.gethookproxy(fspath)
if not self.session.isinitpath(fspath):
if ihook.pytest_ignore_collect(fspath=fspath, config=self.config):
if ihook.pytest_ignore_collect(collection_path=fspath, config=self.config):
return ()

if handle_dupes:
Expand All @@ -705,7 +707,7 @@ def _collectfile(
else:
duplicate_paths.add(fspath)

return ihook.pytest_collect_file(fspath=fspath, parent=self) # type: ignore[no-any-return]
return ihook.pytest_collect_file(file_path=fspath, parent=self) # type: ignore[no-any-return]

def collect(self) -> Iterable[Union[nodes.Item, nodes.Collector]]:
this_path = self.path.parent
Expand Down
4 changes: 2 additions & 2 deletions src/_pytest/terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,7 @@ def pytest_sessionstart(self, session: "Session") -> None:
msg += " -- " + str(sys.executable)
self.write_line(msg)
lines = self.config.hook.pytest_report_header(
config=self.config, startpath=self.startpath
config=self.config, start_path=self.startpath
)
self._write_report_lines_from_hooks(lines)

Expand Down Expand Up @@ -738,7 +738,7 @@ def pytest_collection_finish(self, session: "Session") -> None:

lines = self.config.hook.pytest_report_collectionfinish(
config=self.config,
startpath=self.startpath,
start_path=self.startpath,
items=session.items,
)
self._write_report_lines_from_hooks(lines)
Expand Down
6 changes: 3 additions & 3 deletions testing/acceptance_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,9 +303,9 @@ def runtest(self):
class MyCollector(pytest.File):
def collect(self):
return [MyItem.from_parent(name="xyz", parent=self)]
def pytest_collect_file(fspath, parent):
if fspath.name.startswith("conftest"):
return MyCollector.from_parent(path=fspath, parent=parent)
def pytest_collect_file(file_path, parent):
if file_path.name.startswith("conftest"):
return MyCollector.from_parent(path=file_path, parent=parent)
"""
)
result = pytester.runpytest(c.name + "::" + "xyz")
Expand Down
6 changes: 3 additions & 3 deletions testing/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ def dummy_yaml_custom_test(pytester: Pytester):
"""
import pytest

def pytest_collect_file(parent, fspath):
if fspath.suffix == ".yaml" and fspath.name.startswith("test"):
return YamlFile.from_parent(path=fspath, parent=parent)
def pytest_collect_file(parent, file_path):
if file_path.suffix == ".yaml" and file_path.name.startswith("test"):
return YamlFile.from_parent(path=file_path, parent=parent)

class YamlFile(pytest.File):
def collect(self):
Expand Down
Loading