_deprecate.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  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. stacklevel: int = 3,
  12. ) -> None:
  13. """
  14. Deprecations helper.
  15. :param deprecated: Name of thing to be deprecated.
  16. :param when: Pillow major version to be removed in.
  17. :param replacement: Name of replacement.
  18. :param action: Instead of "replacement", give a custom call to action
  19. e.g. "Upgrade to new thing".
  20. :param plural: if the deprecated thing is plural, needing "are" instead of "is".
  21. Usually of the form:
  22. "[deprecated] is deprecated and will be removed in Pillow [when] (yyyy-mm-dd).
  23. Use [replacement] instead."
  24. You can leave out the replacement sentence:
  25. "[deprecated] is deprecated and will be removed in Pillow [when] (yyyy-mm-dd)"
  26. Or with another call to action:
  27. "[deprecated] is deprecated and will be removed in Pillow [when] (yyyy-mm-dd).
  28. [action]."
  29. """
  30. is_ = "are" if plural else "is"
  31. if when is None:
  32. removed = "a future version"
  33. elif when <= int(__version__.split(".")[0]):
  34. msg = f"{deprecated} {is_} deprecated and should be removed."
  35. raise RuntimeError(msg)
  36. elif when == 13:
  37. removed = "Pillow 13 (2026-10-15)"
  38. elif when == 14:
  39. removed = "Pillow 14 (2027-10-15)"
  40. else:
  41. msg = f"Unknown removal version: {when}. Update {__name__}?"
  42. raise ValueError(msg)
  43. if replacement and action:
  44. msg = "Use only one of 'replacement' and 'action'"
  45. raise ValueError(msg)
  46. if replacement:
  47. action = f". Use {replacement} instead."
  48. elif action:
  49. action = f". {action.rstrip('.')}."
  50. else:
  51. action = ""
  52. warnings.warn(
  53. f"{deprecated} {is_} deprecated and will be removed in {removed}{action}",
  54. DeprecationWarning,
  55. stacklevel=stacklevel,
  56. )