compat.py 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import functools
  2. import warnings
  3. from pathlib import Path
  4. from typing import Optional
  5. from ..compat import LEGACY_PATH
  6. from ..compat import legacy_path
  7. from ..deprecated import HOOK_LEGACY_PATH_ARG
  8. from _pytest.nodes import _check_path
  9. # hookname: (Path, LEGACY_PATH)
  10. imply_paths_hooks = {
  11. "pytest_ignore_collect": ("collection_path", "path"),
  12. "pytest_collect_file": ("file_path", "path"),
  13. "pytest_pycollect_makemodule": ("module_path", "path"),
  14. "pytest_report_header": ("start_path", "startdir"),
  15. "pytest_report_collectionfinish": ("start_path", "startdir"),
  16. }
  17. class PathAwareHookProxy:
  18. """
  19. this helper wraps around hook callers
  20. until pluggy supports fixingcalls, this one will do
  21. it currently doesn't return full hook caller proxies for fixed hooks,
  22. this may have to be changed later depending on bugs
  23. """
  24. def __init__(self, hook_caller):
  25. self.__hook_caller = hook_caller
  26. def __dir__(self):
  27. return dir(self.__hook_caller)
  28. def __getattr__(self, key, _wraps=functools.wraps):
  29. hook = getattr(self.__hook_caller, key)
  30. if key not in imply_paths_hooks:
  31. self.__dict__[key] = hook
  32. return hook
  33. else:
  34. path_var, fspath_var = imply_paths_hooks[key]
  35. @_wraps(hook)
  36. def fixed_hook(**kw):
  37. path_value: Optional[Path] = kw.pop(path_var, None)
  38. fspath_value: Optional[LEGACY_PATH] = kw.pop(fspath_var, None)
  39. if fspath_value is not None:
  40. warnings.warn(
  41. HOOK_LEGACY_PATH_ARG.format(
  42. pylib_path_arg=fspath_var, pathlib_path_arg=path_var
  43. ),
  44. stacklevel=2,
  45. )
  46. if path_value is not None:
  47. if fspath_value is not None:
  48. _check_path(path_value, fspath_value)
  49. else:
  50. fspath_value = legacy_path(path_value)
  51. else:
  52. assert fspath_value is not None
  53. path_value = Path(fspath_value)
  54. kw[path_var] = path_value
  55. kw[fspath_var] = fspath_value
  56. return hook(**kw)
  57. fixed_hook.__name__ = key
  58. self.__dict__[key] = fixed_hook
  59. return fixed_hook