compat.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import sys
  2. from warnings import WarningMessage
  3. class catch_warnings(object):
  4. """A context manager that copies and restores the warnings filter upon
  5. exiting the context.
  6. The 'record' argument specifies whether warnings should be captured by a
  7. custom implementation of warnings.showwarning() and be appended to a list
  8. returned by the context manager. Otherwise None is returned by the context
  9. manager. The objects appended to the list are arguments whose attributes
  10. mirror the arguments to showwarning().
  11. The 'module' argument is to specify an alternative module to the module
  12. named 'warnings' and imported under that name. This argument is only
  13. useful when testing the warnings module itself.
  14. """
  15. def __init__(self, record=False, module=None):
  16. """Specify whether to record warnings and if an alternative module
  17. should be used other than sys.modules['warnings'].
  18. For compatibility with Python 3.0, please consider all arguments to be
  19. keyword-only.
  20. """
  21. self._record = record
  22. self._module = sys.modules['warnings'] if module is None else module
  23. self._entered = False
  24. def __repr__(self):
  25. args = []
  26. if self._record:
  27. args.append("record=True")
  28. if self._module is not sys.modules['warnings']:
  29. args.append("module=%r" % self._module)
  30. name = type(self).__name__
  31. return "%s(%s)" % (name, ", ".join(args))
  32. def __enter__(self):
  33. if self._entered:
  34. raise RuntimeError("Cannot enter %r twice" % self)
  35. self._entered = True
  36. self._filters = self._module.filters
  37. self._module.filters = self._filters[:]
  38. self._showwarning = self._module.showwarning
  39. if self._record:
  40. log = []
  41. def showwarning(*args, **kwargs):
  42. log.append(WarningMessage(*args, **kwargs))
  43. self._module.showwarning = showwarning
  44. return log
  45. else:
  46. return None
  47. def __exit__(self, *exc_info):
  48. if not self._entered:
  49. raise RuntimeError("Cannot exit %r without entering first" % self)
  50. self._module.filters = self._filters
  51. self._module.showwarning = self._showwarning