blob: dfa13ee3fc5bfeb6150bf2ae3a90ad4fdf002e6c [file] [log] [blame]
Guido van Rossum2a862c62000-12-15 21:59:53 +00001"""Python part of the warnings subsystem."""
2
Christian Heimes33fe8092008-04-13 13:53:33 +00003import sys
Guido van Rossum2a862c62000-12-15 21:59:53 +00004
Brett Cannon14ad5312014-08-22 10:44:47 -04005__all__ = ["warn", "warn_explicit", "showwarning",
6 "formatwarning", "filterwarnings", "simplefilter",
Brett Cannon1cd02472008-09-09 01:52:27 +00007 "resetwarnings", "catch_warnings"]
Skip Montanaro40fc1602001-03-01 04:27:19 +00008
Guido van Rossum2a862c62000-12-15 21:59:53 +00009
Christian Heimes33fe8092008-04-13 13:53:33 +000010def showwarning(message, category, filename, lineno, file=None, line=None):
Guido van Rossum2a862c62000-12-15 21:59:53 +000011 """Hook to write a warning to a file; replace if you like."""
12 if file is None:
13 file = sys.stderr
Serhiy Storchaka60599522014-12-10 22:59:55 +020014 if file is None:
Serhiy Storchakaeb9a9b62014-12-14 10:53:00 +020015 # sys.stderr is None when run with pythonw.exe - warnings get lost
Serhiy Storchaka60599522014-12-10 22:59:55 +020016 return
Mark Hammond51a0ae32002-09-11 13:22:35 +000017 try:
Christian Heimes33fe8092008-04-13 13:53:33 +000018 file.write(formatwarning(message, category, filename, lineno, line))
Andrew Svetlovf7a17b42012-12-25 16:47:37 +020019 except OSError:
Mark Hammond51a0ae32002-09-11 13:22:35 +000020 pass # the file (probably stderr) is invalid - this warning gets lost.
Guido van Rossum2a862c62000-12-15 21:59:53 +000021
Christian Heimes33fe8092008-04-13 13:53:33 +000022def formatwarning(message, category, filename, lineno, line=None):
Guido van Rossum9464a7d2001-01-14 14:08:40 +000023 """Function to format a warning the standard way."""
Guido van Rossum2a862c62000-12-15 21:59:53 +000024 s = "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message)
Victor Stinner27461682016-03-25 00:30:32 +010025 if line is None:
26 try:
27 import linecache
28 line = linecache.getline(filename, lineno)
29 except Exception:
30 # When a warning is logged during Python shutdown, linecache
Martin Pantercc71a792016-04-05 06:19:42 +000031 # and the import machinery don't work anymore
Victor Stinner27461682016-03-25 00:30:32 +010032 line = None
Guido van Rossum2a862c62000-12-15 21:59:53 +000033 if line:
Christian Heimes33fe8092008-04-13 13:53:33 +000034 line = line.strip()
35 s += " %s\n" % line
Guido van Rossum2a862c62000-12-15 21:59:53 +000036 return s
37
Guido van Rossum9464a7d2001-01-14 14:08:40 +000038def filterwarnings(action, message="", category=Warning, module="", lineno=0,
Georg Brandlfe991052009-09-16 15:54:04 +000039 append=False):
Guido van Rossum2a862c62000-12-15 21:59:53 +000040 """Insert an entry into the list of warnings filters (at the front).
41
Georg Brandl495f7b52009-10-27 15:28:25 +000042 'action' -- one of "error", "ignore", "always", "default", "module",
43 or "once"
44 'message' -- a regex that the warning message must match
45 'category' -- a class that the warning must be a subclass of
46 'module' -- a regex that the module name must match
47 'lineno' -- an integer line number, 0 matches all warnings
48 'append' -- if true, append to the list of filters
49 """
Skip Montanarod8f21202003-05-14 17:33:53 +000050 import re
Guido van Rossum2a862c62000-12-15 21:59:53 +000051 assert action in ("error", "ignore", "always", "default", "module",
Walter Dörwald70a6b492004-02-12 17:35:32 +000052 "once"), "invalid action: %r" % (action,)
Guido van Rossum3172c5d2007-10-16 18:12:55 +000053 assert isinstance(message, str), "message must be a string"
Guido van Rossum13257902007-06-07 23:15:56 +000054 assert isinstance(category, type), "category must be a class"
Guido van Rossum2a862c62000-12-15 21:59:53 +000055 assert issubclass(category, Warning), "category must be a Warning subclass"
Guido van Rossum3172c5d2007-10-16 18:12:55 +000056 assert isinstance(module, str), "module must be a string"
Walter Dörwald65230a22002-06-03 15:58:32 +000057 assert isinstance(lineno, int) and lineno >= 0, \
Guido van Rossum2a862c62000-12-15 21:59:53 +000058 "lineno must be an int >= 0"
Guido van Rossum9464a7d2001-01-14 14:08:40 +000059 item = (action, re.compile(message, re.I), category,
60 re.compile(module), lineno)
61 if append:
62 filters.append(item)
63 else:
64 filters.insert(0, item)
Antoine Pitroucb0a0062014-09-18 02:40:46 +020065 _filters_mutated()
Guido van Rossum2a862c62000-12-15 21:59:53 +000066
Georg Brandlfe991052009-09-16 15:54:04 +000067def simplefilter(action, category=Warning, lineno=0, append=False):
Jeremy Hylton85014662003-07-11 15:37:59 +000068 """Insert a simple entry into the list of warnings filters (at the front).
69
70 A simple filter matches all modules and messages.
Georg Brandl495f7b52009-10-27 15:28:25 +000071 'action' -- one of "error", "ignore", "always", "default", "module",
72 or "once"
73 'category' -- a class that the warning must be a subclass of
74 'lineno' -- an integer line number, 0 matches all warnings
75 'append' -- if true, append to the list of filters
Jeremy Hylton85014662003-07-11 15:37:59 +000076 """
77 assert action in ("error", "ignore", "always", "default", "module",
Walter Dörwald70a6b492004-02-12 17:35:32 +000078 "once"), "invalid action: %r" % (action,)
Jeremy Hylton85014662003-07-11 15:37:59 +000079 assert isinstance(lineno, int) and lineno >= 0, \
80 "lineno must be an int >= 0"
81 item = (action, None, category, None, lineno)
82 if append:
83 filters.append(item)
84 else:
85 filters.insert(0, item)
Antoine Pitroucb0a0062014-09-18 02:40:46 +020086 _filters_mutated()
Jeremy Hylton85014662003-07-11 15:37:59 +000087
Guido van Rossum2a862c62000-12-15 21:59:53 +000088def resetwarnings():
Tim Petersd0cc4f02002-04-16 01:51:25 +000089 """Clear the list of warning filters, so that no filters are active."""
Guido van Rossum2a862c62000-12-15 21:59:53 +000090 filters[:] = []
Antoine Pitroucb0a0062014-09-18 02:40:46 +020091 _filters_mutated()
Guido van Rossum2a862c62000-12-15 21:59:53 +000092
93class _OptionError(Exception):
94 """Exception used by option processing helpers."""
95 pass
96
97# Helper to process -W options passed via sys.warnoptions
98def _processoptions(args):
99 for arg in args:
100 try:
101 _setoption(arg)
Guido van Rossumb940e112007-01-10 16:19:56 +0000102 except _OptionError as msg:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000103 print("Invalid -W option ignored:", msg, file=sys.stderr)
Guido van Rossum2a862c62000-12-15 21:59:53 +0000104
105# Helper for _processoptions()
106def _setoption(arg):
Skip Montanarod8f21202003-05-14 17:33:53 +0000107 import re
Tim Peterse1190062001-01-15 03:34:38 +0000108 parts = arg.split(':')
109 if len(parts) > 5:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000110 raise _OptionError("too many fields (max 5): %r" % (arg,))
Tim Peterse1190062001-01-15 03:34:38 +0000111 while len(parts) < 5:
112 parts.append('')
113 action, message, category, module, lineno = [s.strip()
114 for s in parts]
115 action = _getaction(action)
116 message = re.escape(message)
117 category = _getcategory(category)
118 module = re.escape(module)
119 if module:
120 module = module + '$'
121 if lineno:
122 try:
123 lineno = int(lineno)
124 if lineno < 0:
125 raise ValueError
126 except (ValueError, OverflowError):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000127 raise _OptionError("invalid lineno %r" % (lineno,))
Tim Peterse1190062001-01-15 03:34:38 +0000128 else:
129 lineno = 0
130 filterwarnings(action, message, category, module, lineno)
Guido van Rossum2a862c62000-12-15 21:59:53 +0000131
132# Helper for _setoption()
133def _getaction(action):
134 if not action:
135 return "default"
136 if action == "all": return "always" # Alias
Raymond Hettingerdbecd932005-02-06 06:57:08 +0000137 for a in ('default', 'always', 'ignore', 'module', 'once', 'error'):
Guido van Rossum2a862c62000-12-15 21:59:53 +0000138 if a.startswith(action):
139 return a
Walter Dörwald70a6b492004-02-12 17:35:32 +0000140 raise _OptionError("invalid action: %r" % (action,))
Guido van Rossum2a862c62000-12-15 21:59:53 +0000141
142# Helper for _setoption()
143def _getcategory(category):
Skip Montanarod8f21202003-05-14 17:33:53 +0000144 import re
Guido van Rossum2a862c62000-12-15 21:59:53 +0000145 if not category:
146 return Warning
147 if re.match("^[a-zA-Z0-9_]+$", category):
148 try:
149 cat = eval(category)
Guido van Rossumd1db30b2000-12-19 03:04:50 +0000150 except NameError:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000151 raise _OptionError("unknown warning category: %r" % (category,))
Guido van Rossum2a862c62000-12-15 21:59:53 +0000152 else:
153 i = category.rfind(".")
154 module = category[:i]
155 klass = category[i+1:]
Guido van Rossumd1db30b2000-12-19 03:04:50 +0000156 try:
Brett Cannoncd171c82013-07-04 17:43:24 -0400157 m = __import__(module, None, None, [klass])
158 except ImportError:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000159 raise _OptionError("invalid module name: %r" % (module,))
Guido van Rossumd1db30b2000-12-19 03:04:50 +0000160 try:
161 cat = getattr(m, klass)
162 except AttributeError:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000163 raise _OptionError("unknown warning category: %r" % (category,))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000164 if not issubclass(cat, Warning):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000165 raise _OptionError("invalid warning category: %r" % (category,))
Guido van Rossum2a862c62000-12-15 21:59:53 +0000166 return cat
167
Christian Heimes33fe8092008-04-13 13:53:33 +0000168
Larry Hastings714e4932015-09-06 00:39:37 -0700169def _is_internal_frame(frame):
170 """Signal whether the frame is an internal CPython implementation detail."""
171 filename = frame.f_code.co_filename
172 return 'importlib' in filename and '_bootstrap' in filename
173
174
175def _next_external_frame(frame):
176 """Find the next frame that doesn't involve CPython internals."""
177 frame = frame.f_back
178 while frame is not None and _is_internal_frame(frame):
179 frame = frame.f_back
180 return frame
181
182
Christian Heimes33fe8092008-04-13 13:53:33 +0000183# Code typically replaced by _warnings
184def warn(message, category=None, stacklevel=1):
185 """Issue a warning, or maybe ignore it or raise an exception."""
186 # Check if message is already a Warning object
187 if isinstance(message, Warning):
188 category = message.__class__
189 # Check category argument
190 if category is None:
191 category = UserWarning
Berker Peksagd8089e02014-07-11 19:50:25 +0300192 if not (isinstance(category, type) and issubclass(category, Warning)):
193 raise TypeError("category must be a Warning subclass, "
194 "not '{:s}'".format(type(category).__name__))
Christian Heimes33fe8092008-04-13 13:53:33 +0000195 # Get context information
196 try:
Larry Hastings714e4932015-09-06 00:39:37 -0700197 if stacklevel <= 1 or _is_internal_frame(sys._getframe(1)):
198 # If frame is too small to care or if the warning originated in
199 # internal code, then do not try to hide any frames.
200 frame = sys._getframe(stacklevel)
201 else:
202 frame = sys._getframe(1)
203 # Look for one frame less since the above line starts us off.
204 for x in range(stacklevel-1):
205 frame = _next_external_frame(frame)
206 if frame is None:
207 raise ValueError
Christian Heimes33fe8092008-04-13 13:53:33 +0000208 except ValueError:
209 globals = sys.__dict__
210 lineno = 1
211 else:
Larry Hastings714e4932015-09-06 00:39:37 -0700212 globals = frame.f_globals
213 lineno = frame.f_lineno
Christian Heimes33fe8092008-04-13 13:53:33 +0000214 if '__name__' in globals:
215 module = globals['__name__']
216 else:
217 module = "<string>"
218 filename = globals.get('__file__')
219 if filename:
220 fnl = filename.lower()
Brett Cannonf299abd2015-04-13 14:21:02 -0400221 if fnl.endswith(".pyc"):
Christian Heimes33fe8092008-04-13 13:53:33 +0000222 filename = filename[:-1]
223 else:
224 if module == "__main__":
225 try:
226 filename = sys.argv[0]
227 except AttributeError:
228 # embedded interpreters don't have sys.argv, see bug #839151
229 filename = '__main__'
230 if not filename:
231 filename = module
232 registry = globals.setdefault("__warningregistry__", {})
233 warn_explicit(message, category, filename, lineno, module, registry,
234 globals)
235
236def warn_explicit(message, category, filename, lineno,
237 module=None, registry=None, module_globals=None):
Brett Cannondb734912008-06-27 00:52:15 +0000238 lineno = int(lineno)
Christian Heimes33fe8092008-04-13 13:53:33 +0000239 if module is None:
240 module = filename or "<unknown>"
241 if module[-3:].lower() == ".py":
242 module = module[:-3] # XXX What about leading pathname?
243 if registry is None:
244 registry = {}
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200245 if registry.get('version', 0) != _filters_version:
246 registry.clear()
247 registry['version'] = _filters_version
Christian Heimes33fe8092008-04-13 13:53:33 +0000248 if isinstance(message, Warning):
249 text = str(message)
250 category = message.__class__
251 else:
252 text = message
253 message = category(message)
254 key = (text, category, lineno)
255 # Quick test for common case
256 if registry.get(key):
257 return
258 # Search the filters
259 for item in filters:
260 action, msg, cat, mod, ln = item
261 if ((msg is None or msg.match(text)) and
262 issubclass(category, cat) and
263 (mod is None or mod.match(module)) and
264 (ln == 0 or lineno == ln)):
265 break
266 else:
267 action = defaultaction
268 # Early exit actions
269 if action == "ignore":
270 registry[key] = 1
271 return
272
273 # Prime the linecache for formatting, in case the
274 # "file" is actually in a zipfile or something.
Antoine Pitrou7cb11fa2013-10-24 22:23:42 +0200275 import linecache
Christian Heimes33fe8092008-04-13 13:53:33 +0000276 linecache.getlines(filename, module_globals)
277
278 if action == "error":
279 raise message
280 # Other actions
281 if action == "once":
282 registry[key] = 1
283 oncekey = (text, category)
284 if onceregistry.get(oncekey):
285 return
286 onceregistry[oncekey] = 1
287 elif action == "always":
288 pass
289 elif action == "module":
290 registry[key] = 1
291 altkey = (text, category, 0)
292 if registry.get(altkey):
293 return
294 registry[altkey] = 1
295 elif action == "default":
296 registry[key] = 1
297 else:
298 # Unrecognized actions are errors
299 raise RuntimeError(
300 "Unrecognized action (%r) in warnings.filters:\n %s" %
301 (action, item))
Florent Xicluna5d1155c2011-10-28 14:45:05 +0200302 if not callable(showwarning):
Christian Heimes8dc226f2008-05-06 23:45:46 +0000303 raise TypeError("warnings.showwarning() must be set to a "
304 "function or method")
Christian Heimes33fe8092008-04-13 13:53:33 +0000305 # Print message and context
306 showwarning(message, category, filename, lineno)
307
308
Brett Cannonec92e182008-09-02 02:46:59 +0000309class WarningMessage(object):
310
311 """Holds the result of a single showwarning() call."""
312
313 _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file",
314 "line")
315
316 def __init__(self, message, category, filename, lineno, file=None,
317 line=None):
318 local_values = locals()
319 for attr in self._WARNING_DETAILS:
320 setattr(self, attr, local_values[attr])
321 self._category_name = category.__name__ if category else None
322
323 def __str__(self):
324 return ("{message : %r, category : %r, filename : %r, lineno : %s, "
325 "line : %r}" % (self.message, self._category_name,
326 self.filename, self.lineno, self.line))
327
328
Brett Cannonec92e182008-09-02 02:46:59 +0000329class catch_warnings(object):
330
Brett Cannon1cd02472008-09-09 01:52:27 +0000331 """A context manager that copies and restores the warnings filter upon
332 exiting the context.
Brett Cannonec92e182008-09-02 02:46:59 +0000333
Brett Cannon1cd02472008-09-09 01:52:27 +0000334 The 'record' argument specifies whether warnings should be captured by a
335 custom implementation of warnings.showwarning() and be appended to a list
336 returned by the context manager. Otherwise None is returned by the context
337 manager. The objects appended to the list are arguments whose attributes
338 mirror the arguments to showwarning().
339
340 The 'module' argument is to specify an alternative module to the module
341 named 'warnings' and imported under that name. This argument is only useful
342 when testing the warnings module itself.
Brett Cannonec92e182008-09-02 02:46:59 +0000343
344 """
345
346 def __init__(self, *, record=False, module=None):
347 """Specify whether to record warnings and if an alternative module
348 should be used other than sys.modules['warnings'].
349
350 For compatibility with Python 3.0, please consider all arguments to be
351 keyword-only.
352
353 """
Brett Cannon1cd02472008-09-09 01:52:27 +0000354 self._record = record
Brett Cannonec92e182008-09-02 02:46:59 +0000355 self._module = sys.modules['warnings'] if module is None else module
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000356 self._entered = False
357
358 def __repr__(self):
359 args = []
360 if self._record:
361 args.append("record=True")
362 if self._module is not sys.modules['warnings']:
363 args.append("module=%r" % self._module)
364 name = type(self).__name__
365 return "%s(%s)" % (name, ", ".join(args))
Brett Cannonec92e182008-09-02 02:46:59 +0000366
367 def __enter__(self):
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000368 if self._entered:
369 raise RuntimeError("Cannot enter %r twice" % self)
370 self._entered = True
Brett Cannonec92e182008-09-02 02:46:59 +0000371 self._filters = self._module.filters
372 self._module.filters = self._filters[:]
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200373 self._module._filters_mutated()
Brett Cannonec92e182008-09-02 02:46:59 +0000374 self._showwarning = self._module.showwarning
Brett Cannon1cd02472008-09-09 01:52:27 +0000375 if self._record:
376 log = []
377 def showwarning(*args, **kwargs):
378 log.append(WarningMessage(*args, **kwargs))
379 self._module.showwarning = showwarning
380 return log
381 else:
382 return None
Brett Cannonec92e182008-09-02 02:46:59 +0000383
384 def __exit__(self, *exc_info):
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000385 if not self._entered:
386 raise RuntimeError("Cannot exit %r without entering first" % self)
Brett Cannonec92e182008-09-02 02:46:59 +0000387 self._module.filters = self._filters
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200388 self._module._filters_mutated()
Brett Cannonec92e182008-09-02 02:46:59 +0000389 self._module.showwarning = self._showwarning
390
391
Christian Heimes33fe8092008-04-13 13:53:33 +0000392# filters contains a sequence of filter 5-tuples
393# The components of the 5-tuple are:
394# - an action: error, ignore, always, default, module, or once
395# - a compiled regex that must match the warning message
396# - a class representing the warning category
397# - a compiled regex that must match the module that is being warned
398# - a line number for the line being warning, or 0 to mean any line
399# If either if the compiled regexs are None, match anything.
400_warnings_defaults = False
401try:
Brett Cannonef0e6c32010-09-04 18:24:04 +0000402 from _warnings import (filters, _defaultaction, _onceregistry,
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200403 warn, warn_explicit, _filters_mutated)
Brett Cannonef0e6c32010-09-04 18:24:04 +0000404 defaultaction = _defaultaction
405 onceregistry = _onceregistry
Christian Heimes33fe8092008-04-13 13:53:33 +0000406 _warnings_defaults = True
Brett Cannoncd171c82013-07-04 17:43:24 -0400407except ImportError:
Christian Heimes33fe8092008-04-13 13:53:33 +0000408 filters = []
409 defaultaction = "default"
410 onceregistry = {}
411
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200412 _filters_version = 1
413
414 def _filters_mutated():
415 global _filters_version
416 _filters_version += 1
417
Christian Heimes33fe8092008-04-13 13:53:33 +0000418
Guido van Rossum2a862c62000-12-15 21:59:53 +0000419# Module initialization
Tim Peters66025202004-03-21 17:06:20 +0000420_processoptions(sys.warnoptions)
Christian Heimes33fe8092008-04-13 13:53:33 +0000421if not _warnings_defaults:
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +0000422 silence = [ImportWarning, PendingDeprecationWarning]
423 silence.append(DeprecationWarning)
424 for cls in silence:
425 simplefilter("ignore", category=cls)
Christian Heimes33fe8092008-04-13 13:53:33 +0000426 bytes_warning = sys.flags.bytes_warning
427 if bytes_warning > 1:
428 bytes_action = "error"
429 elif bytes_warning:
430 bytes_action = "default"
431 else:
432 bytes_action = "ignore"
433 simplefilter(bytes_action, category=BytesWarning, append=1)
Georg Brandl08be72d2010-10-24 15:11:22 +0000434 # resource usage warnings are enabled by default in pydebug mode
435 if hasattr(sys, 'gettotalrefcount'):
436 resource_action = "always"
437 else:
438 resource_action = "ignore"
439 simplefilter(resource_action, category=ResourceWarning, append=1)
440
Christian Heimes33fe8092008-04-13 13:53:33 +0000441del _warnings_defaults