_depr_module.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. """
  2. This module houses a utility class for mocking deprecated modules.
  3. It is for internal use only and should not be used beyond this purpose.
  4. """
  5. import importlib
  6. import warnings
  7. class _DeprecatedModule(object):
  8. """ Class for mocking deprecated modules.
  9. Parameters
  10. ----------
  11. deprmod : name of module to be deprecated.
  12. deprmodto : name of module as a replacement, optional.
  13. If not given, the __module__ attribute will
  14. be used when needed.
  15. removals : objects or methods in module that will no longer be
  16. accessible once module is removed.
  17. moved : dict, optional
  18. dictionary of function name -> new location for moved
  19. objects
  20. """
  21. def __init__(self, deprmod, deprmodto=None, removals=None,
  22. moved=None):
  23. self.deprmod = deprmod
  24. self.deprmodto = deprmodto
  25. self.removals = removals
  26. if self.removals is not None:
  27. self.removals = frozenset(self.removals)
  28. self.moved = moved
  29. # For introspection purposes.
  30. self.self_dir = frozenset(dir(self.__class__))
  31. def __dir__(self):
  32. deprmodule = self._import_deprmod()
  33. return dir(deprmodule)
  34. def __repr__(self):
  35. deprmodule = self._import_deprmod()
  36. return repr(deprmodule)
  37. __str__ = __repr__
  38. def __getattr__(self, name):
  39. if name in self.self_dir:
  40. return object.__getattribute__(self, name)
  41. try:
  42. deprmodule = self._import_deprmod(self.deprmod)
  43. except ImportError:
  44. if self.deprmodto is None:
  45. raise
  46. # a rename
  47. deprmodule = self._import_deprmod(self.deprmodto)
  48. obj = getattr(deprmodule, name)
  49. if self.removals is not None and name in self.removals:
  50. warnings.warn(
  51. "{deprmod}.{name} is deprecated and will be removed in "
  52. "a future version.".format(deprmod=self.deprmod, name=name),
  53. FutureWarning, stacklevel=2)
  54. elif self.moved is not None and name in self.moved:
  55. warnings.warn(
  56. "{deprmod} is deprecated and will be removed in "
  57. "a future version.\nYou can access {name} as {moved}".format(
  58. deprmod=self.deprmod,
  59. name=name,
  60. moved=self.moved[name]),
  61. FutureWarning, stacklevel=2)
  62. else:
  63. deprmodto = self.deprmodto
  64. if deprmodto is False:
  65. warnings.warn(
  66. "{deprmod}.{name} is deprecated and will be removed in "
  67. "a future version.".format(
  68. deprmod=self.deprmod, name=name),
  69. FutureWarning, stacklevel=2)
  70. else:
  71. if deprmodto is None:
  72. deprmodto = obj.__module__
  73. # The object is actually located in another module.
  74. warnings.warn(
  75. "{deprmod}.{name} is deprecated. Please use "
  76. "{deprmodto}.{name} instead.".format(
  77. deprmod=self.deprmod, name=name, deprmodto=deprmodto),
  78. FutureWarning, stacklevel=2)
  79. return obj
  80. def _import_deprmod(self, mod=None):
  81. if mod is None:
  82. mod = self.deprmod
  83. with warnings.catch_warnings():
  84. warnings.filterwarnings('ignore', category=FutureWarning)
  85. deprmodule = importlib.import_module(mod)
  86. return deprmodule