PageRenderTime 59ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/python/lib/Lib/warnings.py

http://github.com/JetBrains/intellij-community
Python | 266 lines | 229 code | 10 blank | 27 comment | 41 complexity | 665ef131e9587fe817d051c1622c4c9e MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0, MPL-2.0-no-copyleft-exception, MIT, EPL-1.0, AGPL-1.0
  1. """Python part of the warnings subsystem."""
  2. # Note: function level imports should *not* be used
  3. # in this module as it may cause import lock deadlock.
  4. # See bug 683658.
  5. import sys, types
  6. import linecache
  7. __all__ = ["warn", "showwarning", "formatwarning", "filterwarnings",
  8. "resetwarnings"]
  9. # filters contains a sequence of filter 5-tuples
  10. # The components of the 5-tuple are:
  11. # - an action: error, ignore, always, default, module, or once
  12. # - a compiled regex that must match the warning message
  13. # - a class representing the warning category
  14. # - a compiled regex that must match the module that is being warned
  15. # - a line number for the line being warning, or 0 to mean any line
  16. # If either if the compiled regexs are None, match anything.
  17. filters = []
  18. defaultaction = "default"
  19. onceregistry = {}
  20. def warn(message, category=None, stacklevel=1):
  21. """Issue a warning, or maybe ignore it or raise an exception."""
  22. # Check if message is already a Warning object
  23. if isinstance(message, Warning):
  24. category = message.__class__
  25. # Check category argument
  26. if category is None:
  27. category = UserWarning
  28. assert issubclass(category, Warning)
  29. # Get context information
  30. try:
  31. caller = sys._getframe(stacklevel)
  32. except ValueError:
  33. globals = sys.__dict__
  34. lineno = 1
  35. else:
  36. globals = caller.f_globals
  37. lineno = caller.f_lineno
  38. if '__name__' in globals:
  39. module = globals['__name__']
  40. else:
  41. module = "<string>"
  42. filename = globals.get('__file__')
  43. if filename:
  44. fnl = filename.lower()
  45. if fnl.endswith((".pyc", ".pyo")):
  46. filename = filename[:-1]
  47. elif fnl.endswith("$py.class"):
  48. filename = filename[:-9] + '.py'
  49. else:
  50. if module == "__main__":
  51. try:
  52. filename = sys.argv[0]
  53. except AttributeError:
  54. # embedded interpreters don't have sys.argv, see bug #839151
  55. filename = '__main__'
  56. if not filename:
  57. filename = module
  58. registry = globals.setdefault("__warningregistry__", {})
  59. warn_explicit(message, category, filename, lineno, module, registry,
  60. globals)
  61. def warn_explicit(message, category, filename, lineno,
  62. module=None, registry=None, module_globals=None):
  63. if module is None:
  64. module = filename or "<unknown>"
  65. if module[-3:].lower() == ".py":
  66. module = module[:-3] # XXX What about leading pathname?
  67. if registry is None:
  68. registry = {}
  69. if isinstance(message, Warning):
  70. text = str(message)
  71. category = message.__class__
  72. else:
  73. text = message
  74. message = category(message)
  75. key = (text, category, lineno)
  76. # Quick test for common case
  77. if registry.get(key):
  78. return
  79. # Search the filters
  80. for item in filters:
  81. action, msg, cat, mod, ln = item
  82. if ((msg is None or msg.match(text)) and
  83. issubclass(category, cat) and
  84. (mod is None or mod.match(module)) and
  85. (ln == 0 or lineno == ln)):
  86. break
  87. else:
  88. action = defaultaction
  89. # Early exit actions
  90. if action == "ignore":
  91. registry[key] = 1
  92. return
  93. # Prime the linecache for formatting, in case the
  94. # "file" is actually in a zipfile or something.
  95. linecache.getlines(filename, module_globals)
  96. if action == "error":
  97. raise message
  98. # Other actions
  99. if action == "once":
  100. registry[key] = 1
  101. oncekey = (text, category)
  102. if onceregistry.get(oncekey):
  103. return
  104. onceregistry[oncekey] = 1
  105. elif action == "always":
  106. pass
  107. elif action == "module":
  108. registry[key] = 1
  109. altkey = (text, category, 0)
  110. if registry.get(altkey):
  111. return
  112. registry[altkey] = 1
  113. elif action == "default":
  114. registry[key] = 1
  115. else:
  116. # Unrecognized actions are errors
  117. raise RuntimeError(
  118. "Unrecognized action (%r) in warnings.filters:\n %s" %
  119. (action, item))
  120. # Print message and context
  121. showwarning(message, category, filename, lineno)
  122. def showwarning(message, category, filename, lineno, file=None):
  123. """Hook to write a warning to a file; replace if you like."""
  124. if file is None:
  125. file = sys.stderr
  126. try:
  127. file.write(formatwarning(message, category, filename, lineno))
  128. except IOError:
  129. pass # the file (probably stderr) is invalid - this warning gets lost.
  130. def formatwarning(message, category, filename, lineno):
  131. """Function to format a warning the standard way."""
  132. s = "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message)
  133. line = linecache.getline(filename, lineno).strip()
  134. if line:
  135. s = s + " " + line + "\n"
  136. return s
  137. def filterwarnings(action, message="", category=Warning, module="", lineno=0,
  138. append=0):
  139. """Insert an entry into the list of warnings filters (at the front).
  140. Use assertions to check that all arguments have the right type."""
  141. import re
  142. assert action in ("error", "ignore", "always", "default", "module",
  143. "once"), "invalid action: %r" % (action,)
  144. assert isinstance(message, basestring), "message must be a string"
  145. assert isinstance(category, (type, types.ClassType)), \
  146. "category must be a class"
  147. assert issubclass(category, Warning), "category must be a Warning subclass"
  148. assert isinstance(module, basestring), "module must be a string"
  149. assert isinstance(lineno, int) and lineno >= 0, \
  150. "lineno must be an int >= 0"
  151. item = (action, re.compile(message, re.I), category,
  152. re.compile(module), lineno)
  153. if append:
  154. filters.append(item)
  155. else:
  156. filters.insert(0, item)
  157. def simplefilter(action, category=Warning, lineno=0, append=0):
  158. """Insert a simple entry into the list of warnings filters (at the front).
  159. A simple filter matches all modules and messages.
  160. """
  161. assert action in ("error", "ignore", "always", "default", "module",
  162. "once"), "invalid action: %r" % (action,)
  163. assert isinstance(lineno, int) and lineno >= 0, \
  164. "lineno must be an int >= 0"
  165. item = (action, None, category, None, lineno)
  166. if append:
  167. filters.append(item)
  168. else:
  169. filters.insert(0, item)
  170. def resetwarnings():
  171. """Clear the list of warning filters, so that no filters are active."""
  172. filters[:] = []
  173. class _OptionError(Exception):
  174. """Exception used by option processing helpers."""
  175. pass
  176. # Helper to process -W options passed via sys.warnoptions
  177. def _processoptions(args):
  178. for arg in args:
  179. try:
  180. _setoption(arg)
  181. except _OptionError, msg:
  182. print >>sys.stderr, "Invalid -W option ignored:", msg
  183. # Helper for _processoptions()
  184. def _setoption(arg):
  185. import re
  186. parts = arg.split(':')
  187. if len(parts) > 5:
  188. raise _OptionError("too many fields (max 5): %r" % (arg,))
  189. while len(parts) < 5:
  190. parts.append('')
  191. action, message, category, module, lineno = [s.strip()
  192. for s in parts]
  193. action = _getaction(action)
  194. message = re.escape(message)
  195. category = _getcategory(category)
  196. module = re.escape(module)
  197. if module:
  198. module = module + '$'
  199. if lineno:
  200. try:
  201. lineno = int(lineno)
  202. if lineno < 0:
  203. raise ValueError
  204. except (ValueError, OverflowError):
  205. raise _OptionError("invalid lineno %r" % (lineno,))
  206. else:
  207. lineno = 0
  208. filterwarnings(action, message, category, module, lineno)
  209. # Helper for _setoption()
  210. def _getaction(action):
  211. if not action:
  212. return "default"
  213. if action == "all": return "always" # Alias
  214. for a in ('default', 'always', 'ignore', 'module', 'once', 'error'):
  215. if a.startswith(action):
  216. return a
  217. raise _OptionError("invalid action: %r" % (action,))
  218. # Helper for _setoption()
  219. def _getcategory(category):
  220. import re
  221. if not category:
  222. return Warning
  223. if re.match("^[a-zA-Z0-9_]+$", category):
  224. try:
  225. cat = eval(category)
  226. except NameError:
  227. raise _OptionError("unknown warning category: %r" % (category,))
  228. else:
  229. i = category.rfind(".")
  230. module = category[:i]
  231. klass = category[i+1:]
  232. try:
  233. m = __import__(module, None, None, [klass])
  234. except ImportError:
  235. raise _OptionError("invalid module name: %r" % (module,))
  236. try:
  237. cat = getattr(m, klass)
  238. except AttributeError:
  239. raise _OptionError("unknown warning category: %r" % (category,))
  240. if not issubclass(cat, Warning):
  241. raise _OptionError("invalid warning category: %r" % (category,))
  242. return cat
  243. # Module initialization
  244. _processoptions(sys.warnoptions)
  245. simplefilter("ignore", category=PendingDeprecationWarning, append=1)
  246. simplefilter("ignore", category=ImportWarning, append=1)