_deprecate.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. from __future__ import annotations
  2. import warnings
  3. from . import __version__
  4. def deprecate(
  5. deprecated: str,
  6. when: int | None,
  7. replacement: str | None = None,
  8. *,
  9. action: str | None = None,
  10. plural: bool = False,
  11. ) -> None:
  12. """
  13. Deprecations helper.
  14. :param deprecated: Name of thing to be deprecated.
  15. :param when: Pillow major version to be removed in.
  16. :param replacement: Name of replacement.
  17. :param action: Instead of "replacement", give a custom call to action
  18. e.g. "Upgrade to new thing".
  19. :param plural: if the deprecated thing is plural, needing "are" instead of "is".
  20. Usually of the form:
  21. "[deprecated] is deprecated and will be removed in Pillow [when] (yyyy-mm-dd).
  22. Use [replacement] instead."
  23. You can leave out the replacement sentence:
  24. "[deprecated] is deprecated and will be removed in Pillow [when] (yyyy-mm-dd)"
  25. Or with another call to action:
  26. "[deprecated] is deprecated and will be removed in Pillow [when] (yyyy-mm-dd).
  27. [action]."
  28. """
  29. is_ = "are" if plural else "is"
  30. if when is None:
  31. removed = "a future version"
  32. elif when <= int(__version__.split(".")[0]):
  33. raise RuntimeError(f"{deprecated} {is_} deprecated and should be removed.")
  34. elif when == 10:
  35. removed = "Pillow 10 (2023-07-01)"
  36. else:
  37. raise ValueError(f"Unknown removal version, update {__name__}?")
  38. if replacement and action:
  39. raise ValueError("Use only one of 'replacement' and 'action'")
  40. if replacement:
  41. action = f". Use {replacement} instead."
  42. elif action:
  43. action = f". {action.rstrip('.')}."
  44. else:
  45. action = ""
  46. warnings.warn(
  47. f"{deprecated} {is_} deprecated and will be removed in {removed}{action}",
  48. DeprecationWarning,
  49. stacklevel=3,
  50. )