deprecation.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. # -*- coding: utf-8 -*-
  2. """
  3. flaskbb.deprecation
  4. ~~~~~~~~~~~~~~~~~~~
  5. Module used for deprecation handling in FlaskBB
  6. :copyright: (c) 2018 the FlaskBB Team.
  7. :license: BSD, see LICENSE for more details.
  8. """
  9. from abc import ABC
  10. import inspect
  11. import warnings
  12. from abc import abstractproperty
  13. from functools import wraps
  14. from flask_babelplus import gettext as _
  15. class FlaskBBWarning(Warning):
  16. """
  17. Base class for any warnings that FlaskBB itself needs to issue, provided
  18. for convenient filtering.
  19. """
  20. pass
  21. class FlaskBBDeprecation(DeprecationWarning, FlaskBBWarning, ABC):
  22. """
  23. Base class for deprecations originating from FlaskBB, subclasses must
  24. provide a version attribute that represents when deprecation becomes a
  25. removal::
  26. class RemovedInPluginv3(FlaskBBDeprecation):
  27. version = (3, 0, 0)
  28. """
  29. version = abstractproperty(lambda self: None)
  30. class RemovedInFlaskBB3(FlaskBBDeprecation):
  31. """
  32. warning for features removed in FlaskBB3
  33. """
  34. version = (3, 0, 0)
  35. def deprecated(message="", category=RemovedInFlaskBB3):
  36. """
  37. Flags a function or method as deprecated, should not be used on
  38. classes as it will break inheritance and introspection.
  39. :param message: Optional message to display along with deprecation warning.
  40. :param category: Warning category to use, defaults to RemovedInFlaskBB3,
  41. if provided must be a subclass of FlaskBBDeprecation.
  42. """
  43. def deprecation_decorator(f):
  44. if not issubclass(category, FlaskBBDeprecation):
  45. raise ValueError(
  46. "Expected subclass of FlaskBBDeprecation for category, got {}".format( # noqa
  47. str(category)
  48. )
  49. )
  50. version = ".".join([str(x) for x in category.version])
  51. warning = _(
  52. "%(name)s is deprecated and will be removed in version %(version)s.", # noqa
  53. name=f.__name__,
  54. version=version,
  55. )
  56. if message:
  57. warning = "{} {}".format(warning, message)
  58. docstring = f.__doc__
  59. if docstring:
  60. docstring = "\n".join([docstring, warning])
  61. else:
  62. docstring = warning
  63. f.__doc__ = docstring
  64. @wraps(f)
  65. def wrapper(*a, **k):
  66. frame = inspect.currentframe().f_back
  67. warnings.warn_explicit(
  68. warning,
  69. category=category,
  70. filename=inspect.getfile(frame.f_code),
  71. lineno=frame.f_lineno,
  72. )
  73. return f(*a, **k)
  74. return wrapper
  75. return deprecation_decorator