blob: 5d5c9a9dcbc518acc90f10d9bfdea54d3f3480cb [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
Mark Hammond51a0ae32002-09-11 13:22:35 +000014 try:
Christian Heimes33fe8092008-04-13 13:53:33 +000015 file.write(formatwarning(message, category, filename, lineno, line))
Andrew Svetlovf7a17b42012-12-25 16:47:37 +020016 except OSError:
Mark Hammond51a0ae32002-09-11 13:22:35 +000017 pass # the file (probably stderr) is invalid - this warning gets lost.
Guido van Rossum2a862c62000-12-15 21:59:53 +000018
Christian Heimes33fe8092008-04-13 13:53:33 +000019def formatwarning(message, category, filename, lineno, line=None):
Guido van Rossum9464a7d2001-01-14 14:08:40 +000020 """Function to format a warning the standard way."""
Antoine Pitrou7cb11fa2013-10-24 22:23:42 +020021 import linecache
Guido van Rossum2a862c62000-12-15 21:59:53 +000022 s = "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message)
Christian Heimes33fe8092008-04-13 13:53:33 +000023 line = linecache.getline(filename, lineno) if line is None else line
Guido van Rossum2a862c62000-12-15 21:59:53 +000024 if line:
Christian Heimes33fe8092008-04-13 13:53:33 +000025 line = line.strip()
26 s += " %s\n" % line
Guido van Rossum2a862c62000-12-15 21:59:53 +000027 return s
28
Guido van Rossum9464a7d2001-01-14 14:08:40 +000029def filterwarnings(action, message="", category=Warning, module="", lineno=0,
Georg Brandlfe991052009-09-16 15:54:04 +000030 append=False):
Guido van Rossum2a862c62000-12-15 21:59:53 +000031 """Insert an entry into the list of warnings filters (at the front).
32
Georg Brandl495f7b52009-10-27 15:28:25 +000033 'action' -- one of "error", "ignore", "always", "default", "module",
34 or "once"
35 'message' -- a regex that the warning message must match
36 'category' -- a class that the warning must be a subclass of
37 'module' -- a regex that the module name must match
38 'lineno' -- an integer line number, 0 matches all warnings
39 'append' -- if true, append to the list of filters
40 """
Skip Montanarod8f21202003-05-14 17:33:53 +000041 import re
Guido van Rossum2a862c62000-12-15 21:59:53 +000042 assert action in ("error", "ignore", "always", "default", "module",
Walter Dörwald70a6b492004-02-12 17:35:32 +000043 "once"), "invalid action: %r" % (action,)
Guido van Rossum3172c5d2007-10-16 18:12:55 +000044 assert isinstance(message, str), "message must be a string"
Guido van Rossum13257902007-06-07 23:15:56 +000045 assert isinstance(category, type), "category must be a class"
Guido van Rossum2a862c62000-12-15 21:59:53 +000046 assert issubclass(category, Warning), "category must be a Warning subclass"
Guido van Rossum3172c5d2007-10-16 18:12:55 +000047 assert isinstance(module, str), "module must be a string"
Walter Dörwald65230a22002-06-03 15:58:32 +000048 assert isinstance(lineno, int) and lineno >= 0, \
Guido van Rossum2a862c62000-12-15 21:59:53 +000049 "lineno must be an int >= 0"
Guido van Rossum9464a7d2001-01-14 14:08:40 +000050 item = (action, re.compile(message, re.I), category,
51 re.compile(module), lineno)
52 if append:
53 filters.append(item)
54 else:
55 filters.insert(0, item)
Antoine Pitroucb0a0062014-09-18 02:40:46 +020056 _filters_mutated()
Guido van Rossum2a862c62000-12-15 21:59:53 +000057
Georg Brandlfe991052009-09-16 15:54:04 +000058def simplefilter(action, category=Warning, lineno=0, append=False):
Jeremy Hylton85014662003-07-11 15:37:59 +000059 """Insert a simple entry into the list of warnings filters (at the front).
60
61 A simple filter matches all modules and messages.
Georg Brandl495f7b52009-10-27 15:28:25 +000062 'action' -- one of "error", "ignore", "always", "default", "module",
63 or "once"
64 'category' -- a class that the warning must be a subclass of
65 'lineno' -- an integer line number, 0 matches all warnings
66 'append' -- if true, append to the list of filters
Jeremy Hylton85014662003-07-11 15:37:59 +000067 """
68 assert action in ("error", "ignore", "always", "default", "module",
Walter Dörwald70a6b492004-02-12 17:35:32 +000069 "once"), "invalid action: %r" % (action,)
Jeremy Hylton85014662003-07-11 15:37:59 +000070 assert isinstance(lineno, int) and lineno >= 0, \
71 "lineno must be an int >= 0"
72 item = (action, None, category, None, lineno)
73 if append:
74 filters.append(item)
75 else:
76 filters.insert(0, item)
Antoine Pitroucb0a0062014-09-18 02:40:46 +020077 _filters_mutated()
Jeremy Hylton85014662003-07-11 15:37:59 +000078
Guido van Rossum2a862c62000-12-15 21:59:53 +000079def resetwarnings():
Tim Petersd0cc4f02002-04-16 01:51:25 +000080 """Clear the list of warning filters, so that no filters are active."""
Guido van Rossum2a862c62000-12-15 21:59:53 +000081 filters[:] = []
Antoine Pitroucb0a0062014-09-18 02:40:46 +020082 _filters_mutated()
Guido van Rossum2a862c62000-12-15 21:59:53 +000083
84class _OptionError(Exception):
85 """Exception used by option processing helpers."""
86 pass
87
88# Helper to process -W options passed via sys.warnoptions
89def _processoptions(args):
90 for arg in args:
91 try:
92 _setoption(arg)
Guido van Rossumb940e112007-01-10 16:19:56 +000093 except _OptionError as msg:
Guido van Rossumbe19ed72007-02-09 05:37:30 +000094 print("Invalid -W option ignored:", msg, file=sys.stderr)
Guido van Rossum2a862c62000-12-15 21:59:53 +000095
96# Helper for _processoptions()
97def _setoption(arg):
Skip Montanarod8f21202003-05-14 17:33:53 +000098 import re
Tim Peterse1190062001-01-15 03:34:38 +000099 parts = arg.split(':')
100 if len(parts) > 5:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000101 raise _OptionError("too many fields (max 5): %r" % (arg,))
Tim Peterse1190062001-01-15 03:34:38 +0000102 while len(parts) < 5:
103 parts.append('')
104 action, message, category, module, lineno = [s.strip()
105 for s in parts]
106 action = _getaction(action)
107 message = re.escape(message)
108 category = _getcategory(category)
109 module = re.escape(module)
110 if module:
111 module = module + '$'
112 if lineno:
113 try:
114 lineno = int(lineno)
115 if lineno < 0:
116 raise ValueError
117 except (ValueError, OverflowError):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000118 raise _OptionError("invalid lineno %r" % (lineno,))
Tim Peterse1190062001-01-15 03:34:38 +0000119 else:
120 lineno = 0
121 filterwarnings(action, message, category, module, lineno)
Guido van Rossum2a862c62000-12-15 21:59:53 +0000122
123# Helper for _setoption()
124def _getaction(action):
125 if not action:
126 return "default"
127 if action == "all": return "always" # Alias
Raymond Hettingerdbecd932005-02-06 06:57:08 +0000128 for a in ('default', 'always', 'ignore', 'module', 'once', 'error'):
Guido van Rossum2a862c62000-12-15 21:59:53 +0000129 if a.startswith(action):
130 return a
Walter Dörwald70a6b492004-02-12 17:35:32 +0000131 raise _OptionError("invalid action: %r" % (action,))
Guido van Rossum2a862c62000-12-15 21:59:53 +0000132
133# Helper for _setoption()
134def _getcategory(category):
Skip Montanarod8f21202003-05-14 17:33:53 +0000135 import re
Guido van Rossum2a862c62000-12-15 21:59:53 +0000136 if not category:
137 return Warning
138 if re.match("^[a-zA-Z0-9_]+$", category):
139 try:
140 cat = eval(category)
Guido van Rossumd1db30b2000-12-19 03:04:50 +0000141 except NameError:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000142 raise _OptionError("unknown warning category: %r" % (category,))
Guido van Rossum2a862c62000-12-15 21:59:53 +0000143 else:
144 i = category.rfind(".")
145 module = category[:i]
146 klass = category[i+1:]
Guido van Rossumd1db30b2000-12-19 03:04:50 +0000147 try:
Brett Cannoncd171c82013-07-04 17:43:24 -0400148 m = __import__(module, None, None, [klass])
149 except ImportError:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000150 raise _OptionError("invalid module name: %r" % (module,))
Guido van Rossumd1db30b2000-12-19 03:04:50 +0000151 try:
152 cat = getattr(m, klass)
153 except AttributeError:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000154 raise _OptionError("unknown warning category: %r" % (category,))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000155 if not issubclass(cat, Warning):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000156 raise _OptionError("invalid warning category: %r" % (category,))
Guido van Rossum2a862c62000-12-15 21:59:53 +0000157 return cat
158
Christian Heimes33fe8092008-04-13 13:53:33 +0000159
160# Code typically replaced by _warnings
161def warn(message, category=None, stacklevel=1):
162 """Issue a warning, or maybe ignore it or raise an exception."""
163 # Check if message is already a Warning object
164 if isinstance(message, Warning):
165 category = message.__class__
166 # Check category argument
167 if category is None:
168 category = UserWarning
169 assert issubclass(category, Warning)
170 # Get context information
171 try:
172 caller = sys._getframe(stacklevel)
173 except ValueError:
174 globals = sys.__dict__
175 lineno = 1
176 else:
177 globals = caller.f_globals
178 lineno = caller.f_lineno
179 if '__name__' in globals:
180 module = globals['__name__']
181 else:
182 module = "<string>"
183 filename = globals.get('__file__')
184 if filename:
185 fnl = filename.lower()
186 if fnl.endswith((".pyc", ".pyo")):
187 filename = filename[:-1]
188 else:
189 if module == "__main__":
190 try:
191 filename = sys.argv[0]
192 except AttributeError:
193 # embedded interpreters don't have sys.argv, see bug #839151
194 filename = '__main__'
195 if not filename:
196 filename = module
197 registry = globals.setdefault("__warningregistry__", {})
198 warn_explicit(message, category, filename, lineno, module, registry,
199 globals)
200
201def warn_explicit(message, category, filename, lineno,
202 module=None, registry=None, module_globals=None):
Brett Cannondb734912008-06-27 00:52:15 +0000203 lineno = int(lineno)
Christian Heimes33fe8092008-04-13 13:53:33 +0000204 if module is None:
205 module = filename or "<unknown>"
206 if module[-3:].lower() == ".py":
207 module = module[:-3] # XXX What about leading pathname?
208 if registry is None:
209 registry = {}
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200210 if registry.get('version', 0) != _filters_version:
211 registry.clear()
212 registry['version'] = _filters_version
Christian Heimes33fe8092008-04-13 13:53:33 +0000213 if isinstance(message, Warning):
214 text = str(message)
215 category = message.__class__
216 else:
217 text = message
218 message = category(message)
219 key = (text, category, lineno)
220 # Quick test for common case
221 if registry.get(key):
222 return
223 # Search the filters
224 for item in filters:
225 action, msg, cat, mod, ln = item
226 if ((msg is None or msg.match(text)) and
227 issubclass(category, cat) and
228 (mod is None or mod.match(module)) and
229 (ln == 0 or lineno == ln)):
230 break
231 else:
232 action = defaultaction
233 # Early exit actions
234 if action == "ignore":
235 registry[key] = 1
236 return
237
238 # Prime the linecache for formatting, in case the
239 # "file" is actually in a zipfile or something.
Antoine Pitrou7cb11fa2013-10-24 22:23:42 +0200240 import linecache
Christian Heimes33fe8092008-04-13 13:53:33 +0000241 linecache.getlines(filename, module_globals)
242
243 if action == "error":
244 raise message
245 # Other actions
246 if action == "once":
247 registry[key] = 1
248 oncekey = (text, category)
249 if onceregistry.get(oncekey):
250 return
251 onceregistry[oncekey] = 1
252 elif action == "always":
253 pass
254 elif action == "module":
255 registry[key] = 1
256 altkey = (text, category, 0)
257 if registry.get(altkey):
258 return
259 registry[altkey] = 1
260 elif action == "default":
261 registry[key] = 1
262 else:
263 # Unrecognized actions are errors
264 raise RuntimeError(
265 "Unrecognized action (%r) in warnings.filters:\n %s" %
266 (action, item))
Florent Xicluna5d1155c2011-10-28 14:45:05 +0200267 if not callable(showwarning):
Christian Heimes8dc226f2008-05-06 23:45:46 +0000268 raise TypeError("warnings.showwarning() must be set to a "
269 "function or method")
Christian Heimes33fe8092008-04-13 13:53:33 +0000270 # Print message and context
271 showwarning(message, category, filename, lineno)
272
273
Brett Cannonec92e182008-09-02 02:46:59 +0000274class WarningMessage(object):
275
276 """Holds the result of a single showwarning() call."""
277
278 _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file",
279 "line")
280
281 def __init__(self, message, category, filename, lineno, file=None,
282 line=None):
283 local_values = locals()
284 for attr in self._WARNING_DETAILS:
285 setattr(self, attr, local_values[attr])
286 self._category_name = category.__name__ if category else None
287
288 def __str__(self):
289 return ("{message : %r, category : %r, filename : %r, lineno : %s, "
290 "line : %r}" % (self.message, self._category_name,
291 self.filename, self.lineno, self.line))
292
293
Brett Cannonec92e182008-09-02 02:46:59 +0000294class catch_warnings(object):
295
Brett Cannon1cd02472008-09-09 01:52:27 +0000296 """A context manager that copies and restores the warnings filter upon
297 exiting the context.
Brett Cannonec92e182008-09-02 02:46:59 +0000298
Brett Cannon1cd02472008-09-09 01:52:27 +0000299 The 'record' argument specifies whether warnings should be captured by a
300 custom implementation of warnings.showwarning() and be appended to a list
301 returned by the context manager. Otherwise None is returned by the context
302 manager. The objects appended to the list are arguments whose attributes
303 mirror the arguments to showwarning().
304
305 The 'module' argument is to specify an alternative module to the module
306 named 'warnings' and imported under that name. This argument is only useful
307 when testing the warnings module itself.
Brett Cannonec92e182008-09-02 02:46:59 +0000308
309 """
310
311 def __init__(self, *, record=False, module=None):
312 """Specify whether to record warnings and if an alternative module
313 should be used other than sys.modules['warnings'].
314
315 For compatibility with Python 3.0, please consider all arguments to be
316 keyword-only.
317
318 """
Brett Cannon1cd02472008-09-09 01:52:27 +0000319 self._record = record
Brett Cannonec92e182008-09-02 02:46:59 +0000320 self._module = sys.modules['warnings'] if module is None else module
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000321 self._entered = False
322
323 def __repr__(self):
324 args = []
325 if self._record:
326 args.append("record=True")
327 if self._module is not sys.modules['warnings']:
328 args.append("module=%r" % self._module)
329 name = type(self).__name__
330 return "%s(%s)" % (name, ", ".join(args))
Brett Cannonec92e182008-09-02 02:46:59 +0000331
332 def __enter__(self):
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000333 if self._entered:
334 raise RuntimeError("Cannot enter %r twice" % self)
335 self._entered = True
Brett Cannonec92e182008-09-02 02:46:59 +0000336 self._filters = self._module.filters
337 self._module.filters = self._filters[:]
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200338 self._module._filters_mutated()
Brett Cannonec92e182008-09-02 02:46:59 +0000339 self._showwarning = self._module.showwarning
Brett Cannon1cd02472008-09-09 01:52:27 +0000340 if self._record:
341 log = []
342 def showwarning(*args, **kwargs):
343 log.append(WarningMessage(*args, **kwargs))
344 self._module.showwarning = showwarning
345 return log
346 else:
347 return None
Brett Cannonec92e182008-09-02 02:46:59 +0000348
349 def __exit__(self, *exc_info):
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000350 if not self._entered:
351 raise RuntimeError("Cannot exit %r without entering first" % self)
Brett Cannonec92e182008-09-02 02:46:59 +0000352 self._module.filters = self._filters
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200353 self._module._filters_mutated()
Brett Cannonec92e182008-09-02 02:46:59 +0000354 self._module.showwarning = self._showwarning
355
356
Christian Heimes33fe8092008-04-13 13:53:33 +0000357# filters contains a sequence of filter 5-tuples
358# The components of the 5-tuple are:
359# - an action: error, ignore, always, default, module, or once
360# - a compiled regex that must match the warning message
361# - a class representing the warning category
362# - a compiled regex that must match the module that is being warned
363# - a line number for the line being warning, or 0 to mean any line
364# If either if the compiled regexs are None, match anything.
365_warnings_defaults = False
366try:
Brett Cannonef0e6c32010-09-04 18:24:04 +0000367 from _warnings import (filters, _defaultaction, _onceregistry,
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200368 warn, warn_explicit, _filters_mutated)
Brett Cannonef0e6c32010-09-04 18:24:04 +0000369 defaultaction = _defaultaction
370 onceregistry = _onceregistry
Christian Heimes33fe8092008-04-13 13:53:33 +0000371 _warnings_defaults = True
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200372
Brett Cannoncd171c82013-07-04 17:43:24 -0400373except ImportError:
Christian Heimes33fe8092008-04-13 13:53:33 +0000374 filters = []
375 defaultaction = "default"
376 onceregistry = {}
377
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200378 _filters_version = 1
379
380 def _filters_mutated():
381 global _filters_version
382 _filters_version += 1
383
Christian Heimes33fe8092008-04-13 13:53:33 +0000384
Guido van Rossum2a862c62000-12-15 21:59:53 +0000385# Module initialization
Tim Peters66025202004-03-21 17:06:20 +0000386_processoptions(sys.warnoptions)
Christian Heimes33fe8092008-04-13 13:53:33 +0000387if not _warnings_defaults:
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +0000388 silence = [ImportWarning, PendingDeprecationWarning]
389 silence.append(DeprecationWarning)
390 for cls in silence:
391 simplefilter("ignore", category=cls)
Christian Heimes33fe8092008-04-13 13:53:33 +0000392 bytes_warning = sys.flags.bytes_warning
393 if bytes_warning > 1:
394 bytes_action = "error"
395 elif bytes_warning:
396 bytes_action = "default"
397 else:
398 bytes_action = "ignore"
399 simplefilter(bytes_action, category=BytesWarning, append=1)
Georg Brandl08be72d2010-10-24 15:11:22 +0000400 # resource usage warnings are enabled by default in pydebug mode
401 if hasattr(sys, 'gettotalrefcount'):
402 resource_action = "always"
403 else:
404 resource_action = "ignore"
405 simplefilter(resource_action, category=ResourceWarning, append=1)
406
Christian Heimes33fe8092008-04-13 13:53:33 +0000407del _warnings_defaults