deprecation.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import inspect
  2. import warnings
  3. class RemovedInDjango19Warning(PendingDeprecationWarning):
  4. pass
  5. class RemovedInDjango18Warning(DeprecationWarning):
  6. pass
  7. RemovedInNextVersionWarning = RemovedInDjango18Warning
  8. class warn_about_renamed_method(object):
  9. def __init__(self, class_name, old_method_name, new_method_name, deprecation_warning):
  10. self.class_name = class_name
  11. self.old_method_name = old_method_name
  12. self.new_method_name = new_method_name
  13. self.deprecation_warning = deprecation_warning
  14. def __call__(self, f):
  15. def wrapped(*args, **kwargs):
  16. warnings.warn(
  17. "`%s.%s` is deprecated, use `%s` instead." %
  18. (self.class_name, self.old_method_name, self.new_method_name),
  19. self.deprecation_warning, 2)
  20. return f(*args, **kwargs)
  21. return wrapped
  22. class RenameMethodsBase(type):
  23. """
  24. Handles the deprecation paths when renaming a method.
  25. It does the following:
  26. 1) Define the new method if missing and complain about it.
  27. 2) Define the old method if missing.
  28. 3) Complain whenever an old method is called.
  29. See #15363 for more details.
  30. """
  31. renamed_methods = ()
  32. def __new__(cls, name, bases, attrs):
  33. new_class = super(RenameMethodsBase, cls).__new__(cls, name, bases, attrs)
  34. for base in inspect.getmro(new_class):
  35. class_name = base.__name__
  36. for renamed_method in cls.renamed_methods:
  37. old_method_name = renamed_method[0]
  38. old_method = base.__dict__.get(old_method_name)
  39. new_method_name = renamed_method[1]
  40. new_method = base.__dict__.get(new_method_name)
  41. deprecation_warning = renamed_method[2]
  42. wrapper = warn_about_renamed_method(class_name, *renamed_method)
  43. # Define the new method if missing and complain about it
  44. if not new_method and old_method:
  45. warnings.warn(
  46. "`%s.%s` method should be renamed `%s`." %
  47. (class_name, old_method_name, new_method_name),
  48. deprecation_warning, 2)
  49. setattr(base, new_method_name, old_method)
  50. setattr(base, old_method_name, wrapper(old_method))
  51. # Define the old method as a wrapped call to the new method.
  52. if not old_method and new_method:
  53. setattr(base, old_method_name, wrapper(new_method))
  54. return new_class