From bad1963697ab8d6538368a3e86f7848bfe8c63ea Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Mon, 29 Mar 2021 22:29:35 +0200 Subject: [PATCH] fix #8361: address review/quality comments --- doc/en/deprecations.rst | 14 ++++++++++++++ src/_pytest/config/compat.py | 19 ++++++++++++++++--- src/_pytest/deprecated.py | 4 +++- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/doc/en/deprecations.rst b/doc/en/deprecations.rst index 6ecb37b38..d6b108d50 100644 --- a/doc/en/deprecations.rst +++ b/doc/en/deprecations.rst @@ -19,6 +19,20 @@ Below is a complete list of all pytest features which are considered deprecated. :class:`PytestWarning` or subclasses, which can be filtered using :ref:`standard warning filters `. +``py.path.local`` arguments for hooks replaced with ``pathlib.Path`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In order to support the transition oto pathlib, the following hooks added additional arugments: + +* ``pytest_ignore_collect(fspath: pathlib.Path)`` +* ``pytest_collect_file(fspath: pathlib.Path)`` +* ``pytest_pycollect_makemodule(fspath: pathlib.Path)`` +* ``pytest_report_header(startpath: pathlib.Path)`` +* ``pytest_report_collectionfinish(startpath: pathlib.Path)`` + +The accompanying ``py.path.local`` based paths have been deprecated. + + ``Node.fspath`` in favor of ``pathlib`` and ``Node.path`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/_pytest/config/compat.py b/src/_pytest/config/compat.py index 82572a970..d9e6e280c 100644 --- a/src/_pytest/config/compat.py +++ b/src/_pytest/config/compat.py @@ -1,3 +1,4 @@ +import functools import warnings from pathlib import Path from typing import Optional @@ -17,20 +18,31 @@ imply_paths_hooks = { class PathAwareHookProxy: + """ + this helper wraps around hook callers + until pluggy supports fixingcalls, this one will do + + it currently doesnt return full hook caller proxies for fixed hooks, + this may have to be changed later depending on bugs + """ + def __init__(self, hook_caller): self.__hook_caller = hook_caller def __dir__(self): return dir(self.__hook_caller) - def __getattr__(self, key): + def __getattr__(self, key, _wraps=functools.wraps): + hook = getattr(self.__hook_caller, key) if key not in imply_paths_hooks: - return getattr(self.__hook_caller, key) + self.__dict__[key] = hook + return hook else: - hook = getattr(self.__hook_caller, key) path_var, fspath_var = imply_paths_hooks[key] + @_wraps(hook) def fixed_hook(**kw): + path_value: Optional[Path] = kw.pop(path_var, None) fspath_value: Optional[LEGACY_PATH] = kw.pop(fspath_var, None) if fspath_value is not None: @@ -45,4 +57,5 @@ class PathAwareHookProxy: return hook(**kw) fixed_hook.__name__ = key + self.__dict__[key] = fixed_hook return fixed_hook diff --git a/src/_pytest/deprecated.py b/src/_pytest/deprecated.py index 9ac4d81b4..7a09d5163 100644 --- a/src/_pytest/deprecated.py +++ b/src/_pytest/deprecated.py @@ -97,7 +97,9 @@ NODE_FSPATH = UnformattedWarning( HOOK_LEGACY_PATH_ARG = UnformattedWarning( PytestDeprecationWarning, - "{pylib_path_arg} : py.path.local is deprecated, please use {pathlib_path_arg} : pathlib.Path", + "The ({pylib_path_arg}: py.path.local) argument is deprecated, please use ({pathlib_path_arg}: pathlib.Path)\n" + "see https://docs.pytest.org/en/latest/deprecations.html" + "#py-path-local-arguments-for-hooks-replaced-with-pathlib-path", ) # You want to make some `__init__` or function "private". #