blob: 5b62569c977350db5f9d1dc8b2eb41300dc8098f [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
Victor Stinner914cde82016-03-19 01:03:51 +01005
Brett Cannon14ad5312014-08-22 10:44:47 -04006__all__ = ["warn", "warn_explicit", "showwarning",
7 "formatwarning", "filterwarnings", "simplefilter",
Brett Cannon1cd02472008-09-09 01:52:27 +00008 "resetwarnings", "catch_warnings"]
Skip Montanaro40fc1602001-03-01 04:27:19 +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."""
Victor Stinner1231a462016-03-19 00:47:17 +010012 msg = WarningMessage(message, category, filename, lineno, file, line)
Victor Stinnereedf13f2016-03-19 02:11:56 +010013 _showwarnmsg_impl(msg)
Guido van Rossum2a862c62000-12-15 21:59:53 +000014
Christian Heimes33fe8092008-04-13 13:53:33 +000015def formatwarning(message, category, filename, lineno, line=None):
Guido van Rossum9464a7d2001-01-14 14:08:40 +000016 """Function to format a warning the standard way."""
Victor Stinner1231a462016-03-19 00:47:17 +010017 msg = WarningMessage(message, category, filename, lineno, None, line)
Victor Stinnereedf13f2016-03-19 02:11:56 +010018 return _formatwarnmsg_impl(msg)
Victor Stinner1231a462016-03-19 00:47:17 +010019
Victor Stinnereedf13f2016-03-19 02:11:56 +010020def _showwarnmsg_impl(msg):
Victor Stinner1231a462016-03-19 00:47:17 +010021 file = msg.file
22 if file is None:
23 file = sys.stderr
24 if file is None:
25 # sys.stderr is None when run with pythonw.exe:
26 # warnings get lost
27 return
28 text = _formatwarnmsg(msg)
29 try:
30 file.write(text)
31 except OSError:
32 # the file (probably stderr) is invalid - this warning gets lost.
33 pass
34
Victor Stinnereedf13f2016-03-19 02:11:56 +010035def _formatwarnmsg_impl(msg):
Victor Stinner1231a462016-03-19 00:47:17 +010036 s = ("%s:%s: %s: %s\n"
37 % (msg.filename, msg.lineno, msg.category.__name__,
38 msg.message))
Victor Stinnere091d322016-03-25 00:33:12 +010039
Victor Stinner1231a462016-03-19 00:47:17 +010040 if msg.line is None:
Victor Stinner27461682016-03-25 00:30:32 +010041 try:
42 import linecache
Victor Stinnere091d322016-03-25 00:33:12 +010043 line = linecache.getline(msg.filename, msg.lineno)
Victor Stinner27461682016-03-25 00:30:32 +010044 except Exception:
45 # When a warning is logged during Python shutdown, linecache
Martin Pantercc71a792016-04-05 06:19:42 +000046 # and the import machinery don't work anymore
Victor Stinner27461682016-03-25 00:30:32 +010047 line = None
Victor Stinnere091d322016-03-25 00:33:12 +010048 linecache = None
Victor Stinner1231a462016-03-19 00:47:17 +010049 else:
50 line = msg.line
Guido van Rossum2a862c62000-12-15 21:59:53 +000051 if line:
Christian Heimes33fe8092008-04-13 13:53:33 +000052 line = line.strip()
53 s += " %s\n" % line
Victor Stinnere091d322016-03-25 00:33:12 +010054
Victor Stinner914cde82016-03-19 01:03:51 +010055 if msg.source is not None:
Victor Stinnere091d322016-03-25 00:33:12 +010056 try:
57 import tracemalloc
58 tb = tracemalloc.get_object_traceback(msg.source)
59 except Exception:
60 # When a warning is logged during Python shutdown, tracemalloc
61 # and the import machinery don't work anymore
62 tb = None
63
Victor Stinner914cde82016-03-19 01:03:51 +010064 if tb is not None:
65 s += 'Object allocated at (most recent call first):\n'
66 for frame in tb:
67 s += (' File "%s", lineno %s\n'
68 % (frame.filename, frame.lineno))
Victor Stinnere091d322016-03-25 00:33:12 +010069
70 try:
71 if linecache is not None:
72 line = linecache.getline(frame.filename, frame.lineno)
73 else:
74 line = None
75 except Exception:
76 line = None
Victor Stinner914cde82016-03-19 01:03:51 +010077 if line:
78 line = line.strip()
79 s += ' %s\n' % line
Guido van Rossum2a862c62000-12-15 21:59:53 +000080 return s
81
Victor Stinnereedf13f2016-03-19 02:11:56 +010082# Keep a reference to check if the function was replaced
Ned Deilyc1c32922016-12-06 17:12:47 -050083_showwarning_orig = showwarning
Victor Stinnereedf13f2016-03-19 02:11:56 +010084
85def _showwarnmsg(msg):
86 """Hook to write a warning to a file; replace if you like."""
Ned Deilyc1c32922016-12-06 17:12:47 -050087 try:
88 sw = showwarning
89 except NameError:
90 pass
91 else:
92 if sw is not _showwarning_orig:
93 # warnings.showwarning() was replaced
94 if not callable(sw):
95 raise TypeError("warnings.showwarning() must be set to a "
96 "function or method")
Victor Stinnereedf13f2016-03-19 02:11:56 +010097
Ned Deilyc1c32922016-12-06 17:12:47 -050098 sw(msg.message, msg.category, msg.filename, msg.lineno,
99 msg.file, msg.line)
100 return
Victor Stinnereedf13f2016-03-19 02:11:56 +0100101 _showwarnmsg_impl(msg)
102
103# Keep a reference to check if the function was replaced
Ned Deilyc1c32922016-12-06 17:12:47 -0500104_formatwarning_orig = formatwarning
Victor Stinnereedf13f2016-03-19 02:11:56 +0100105
106def _formatwarnmsg(msg):
107 """Function to format a warning the standard way."""
Ned Deilyc1c32922016-12-06 17:12:47 -0500108 try:
109 fw = formatwarning
110 except NameError:
111 pass
112 else:
113 if fw is not _formatwarning_orig:
114 # warnings.formatwarning() was replaced
115 return fw(msg.message, msg.category,
116 msg.filename, msg.lineno, line=msg.line)
Victor Stinnereedf13f2016-03-19 02:11:56 +0100117 return _formatwarnmsg_impl(msg)
118
Guido van Rossum9464a7d2001-01-14 14:08:40 +0000119def filterwarnings(action, message="", category=Warning, module="", lineno=0,
Georg Brandlfe991052009-09-16 15:54:04 +0000120 append=False):
Guido van Rossum2a862c62000-12-15 21:59:53 +0000121 """Insert an entry into the list of warnings filters (at the front).
122
Georg Brandl495f7b52009-10-27 15:28:25 +0000123 'action' -- one of "error", "ignore", "always", "default", "module",
124 or "once"
125 'message' -- a regex that the warning message must match
126 'category' -- a class that the warning must be a subclass of
127 'module' -- a regex that the module name must match
128 'lineno' -- an integer line number, 0 matches all warnings
129 'append' -- if true, append to the list of filters
130 """
Guido van Rossum2a862c62000-12-15 21:59:53 +0000131 assert action in ("error", "ignore", "always", "default", "module",
Walter Dörwald70a6b492004-02-12 17:35:32 +0000132 "once"), "invalid action: %r" % (action,)
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000133 assert isinstance(message, str), "message must be a string"
Guido van Rossum13257902007-06-07 23:15:56 +0000134 assert isinstance(category, type), "category must be a class"
Guido van Rossum2a862c62000-12-15 21:59:53 +0000135 assert issubclass(category, Warning), "category must be a Warning subclass"
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000136 assert isinstance(module, str), "module must be a string"
Walter Dörwald65230a22002-06-03 15:58:32 +0000137 assert isinstance(lineno, int) and lineno >= 0, \
Guido van Rossum2a862c62000-12-15 21:59:53 +0000138 "lineno must be an int >= 0"
Victor Stinner82656272017-11-22 23:51:42 +0100139
140 if message or module:
141 import re
142
143 if message:
144 message = re.compile(message, re.I)
145 else:
146 message = None
147 if module:
148 module = re.compile(module)
149 else:
150 module = None
151
152 _add_filter(action, message, category, module, lineno, append=append)
Guido van Rossum2a862c62000-12-15 21:59:53 +0000153
Georg Brandlfe991052009-09-16 15:54:04 +0000154def simplefilter(action, category=Warning, lineno=0, append=False):
Jeremy Hylton85014662003-07-11 15:37:59 +0000155 """Insert a simple entry into the list of warnings filters (at the front).
156
157 A simple filter matches all modules and messages.
Georg Brandl495f7b52009-10-27 15:28:25 +0000158 'action' -- one of "error", "ignore", "always", "default", "module",
159 or "once"
160 'category' -- a class that the warning must be a subclass of
161 'lineno' -- an integer line number, 0 matches all warnings
162 'append' -- if true, append to the list of filters
Jeremy Hylton85014662003-07-11 15:37:59 +0000163 """
164 assert action in ("error", "ignore", "always", "default", "module",
Walter Dörwald70a6b492004-02-12 17:35:32 +0000165 "once"), "invalid action: %r" % (action,)
Jeremy Hylton85014662003-07-11 15:37:59 +0000166 assert isinstance(lineno, int) and lineno >= 0, \
167 "lineno must be an int >= 0"
Martin Panter43593a12016-05-26 09:10:55 +0000168 _add_filter(action, None, category, None, lineno, append=append)
169
170def _add_filter(*item, append):
171 # Remove possible duplicate filters, so new one will be placed
172 # in correct place. If append=True and duplicate exists, do nothing.
173 if not append:
174 try:
175 filters.remove(item)
176 except ValueError:
177 pass
Jeremy Hylton85014662003-07-11 15:37:59 +0000178 filters.insert(0, item)
Martin Panter43593a12016-05-26 09:10:55 +0000179 else:
180 if item not in filters:
181 filters.append(item)
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200182 _filters_mutated()
Jeremy Hylton85014662003-07-11 15:37:59 +0000183
Guido van Rossum2a862c62000-12-15 21:59:53 +0000184def resetwarnings():
Tim Petersd0cc4f02002-04-16 01:51:25 +0000185 """Clear the list of warning filters, so that no filters are active."""
Guido van Rossum2a862c62000-12-15 21:59:53 +0000186 filters[:] = []
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200187 _filters_mutated()
Guido van Rossum2a862c62000-12-15 21:59:53 +0000188
189class _OptionError(Exception):
190 """Exception used by option processing helpers."""
191 pass
192
193# Helper to process -W options passed via sys.warnoptions
194def _processoptions(args):
195 for arg in args:
196 try:
197 _setoption(arg)
Guido van Rossumb940e112007-01-10 16:19:56 +0000198 except _OptionError as msg:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000199 print("Invalid -W option ignored:", msg, file=sys.stderr)
Guido van Rossum2a862c62000-12-15 21:59:53 +0000200
201# Helper for _processoptions()
202def _setoption(arg):
Skip Montanarod8f21202003-05-14 17:33:53 +0000203 import re
Tim Peterse1190062001-01-15 03:34:38 +0000204 parts = arg.split(':')
205 if len(parts) > 5:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000206 raise _OptionError("too many fields (max 5): %r" % (arg,))
Tim Peterse1190062001-01-15 03:34:38 +0000207 while len(parts) < 5:
208 parts.append('')
209 action, message, category, module, lineno = [s.strip()
210 for s in parts]
211 action = _getaction(action)
212 message = re.escape(message)
213 category = _getcategory(category)
214 module = re.escape(module)
215 if module:
216 module = module + '$'
217 if lineno:
218 try:
219 lineno = int(lineno)
220 if lineno < 0:
221 raise ValueError
222 except (ValueError, OverflowError):
Serhiy Storchaka5affd232017-04-05 09:37:24 +0300223 raise _OptionError("invalid lineno %r" % (lineno,)) from None
Tim Peterse1190062001-01-15 03:34:38 +0000224 else:
225 lineno = 0
226 filterwarnings(action, message, category, module, lineno)
Guido van Rossum2a862c62000-12-15 21:59:53 +0000227
228# Helper for _setoption()
229def _getaction(action):
230 if not action:
231 return "default"
232 if action == "all": return "always" # Alias
Raymond Hettingerdbecd932005-02-06 06:57:08 +0000233 for a in ('default', 'always', 'ignore', 'module', 'once', 'error'):
Guido van Rossum2a862c62000-12-15 21:59:53 +0000234 if a.startswith(action):
235 return a
Walter Dörwald70a6b492004-02-12 17:35:32 +0000236 raise _OptionError("invalid action: %r" % (action,))
Guido van Rossum2a862c62000-12-15 21:59:53 +0000237
238# Helper for _setoption()
239def _getcategory(category):
Skip Montanarod8f21202003-05-14 17:33:53 +0000240 import re
Guido van Rossum2a862c62000-12-15 21:59:53 +0000241 if not category:
242 return Warning
243 if re.match("^[a-zA-Z0-9_]+$", category):
244 try:
245 cat = eval(category)
Guido van Rossumd1db30b2000-12-19 03:04:50 +0000246 except NameError:
Serhiy Storchaka5affd232017-04-05 09:37:24 +0300247 raise _OptionError("unknown warning category: %r" % (category,)) from None
Guido van Rossum2a862c62000-12-15 21:59:53 +0000248 else:
249 i = category.rfind(".")
250 module = category[:i]
251 klass = category[i+1:]
Guido van Rossumd1db30b2000-12-19 03:04:50 +0000252 try:
Brett Cannoncd171c82013-07-04 17:43:24 -0400253 m = __import__(module, None, None, [klass])
254 except ImportError:
Serhiy Storchaka5affd232017-04-05 09:37:24 +0300255 raise _OptionError("invalid module name: %r" % (module,)) from None
Guido van Rossumd1db30b2000-12-19 03:04:50 +0000256 try:
257 cat = getattr(m, klass)
258 except AttributeError:
Serhiy Storchaka5affd232017-04-05 09:37:24 +0300259 raise _OptionError("unknown warning category: %r" % (category,)) from None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000260 if not issubclass(cat, Warning):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000261 raise _OptionError("invalid warning category: %r" % (category,))
Guido van Rossum2a862c62000-12-15 21:59:53 +0000262 return cat
263
Christian Heimes33fe8092008-04-13 13:53:33 +0000264
Larry Hastings714e4932015-09-06 00:39:37 -0700265def _is_internal_frame(frame):
266 """Signal whether the frame is an internal CPython implementation detail."""
267 filename = frame.f_code.co_filename
268 return 'importlib' in filename and '_bootstrap' in filename
269
270
271def _next_external_frame(frame):
272 """Find the next frame that doesn't involve CPython internals."""
273 frame = frame.f_back
274 while frame is not None and _is_internal_frame(frame):
275 frame = frame.f_back
276 return frame
277
278
Christian Heimes33fe8092008-04-13 13:53:33 +0000279# Code typically replaced by _warnings
Victor Stinnere19558a2016-03-23 00:28:08 +0100280def warn(message, category=None, stacklevel=1, source=None):
Christian Heimes33fe8092008-04-13 13:53:33 +0000281 """Issue a warning, or maybe ignore it or raise an exception."""
282 # Check if message is already a Warning object
283 if isinstance(message, Warning):
284 category = message.__class__
285 # Check category argument
286 if category is None:
287 category = UserWarning
Berker Peksagd8089e02014-07-11 19:50:25 +0300288 if not (isinstance(category, type) and issubclass(category, Warning)):
289 raise TypeError("category must be a Warning subclass, "
290 "not '{:s}'".format(type(category).__name__))
Christian Heimes33fe8092008-04-13 13:53:33 +0000291 # Get context information
292 try:
Larry Hastings714e4932015-09-06 00:39:37 -0700293 if stacklevel <= 1 or _is_internal_frame(sys._getframe(1)):
294 # If frame is too small to care or if the warning originated in
295 # internal code, then do not try to hide any frames.
296 frame = sys._getframe(stacklevel)
297 else:
298 frame = sys._getframe(1)
299 # Look for one frame less since the above line starts us off.
300 for x in range(stacklevel-1):
301 frame = _next_external_frame(frame)
302 if frame is None:
303 raise ValueError
Christian Heimes33fe8092008-04-13 13:53:33 +0000304 except ValueError:
305 globals = sys.__dict__
306 lineno = 1
307 else:
Larry Hastings714e4932015-09-06 00:39:37 -0700308 globals = frame.f_globals
309 lineno = frame.f_lineno
Christian Heimes33fe8092008-04-13 13:53:33 +0000310 if '__name__' in globals:
311 module = globals['__name__']
312 else:
313 module = "<string>"
314 filename = globals.get('__file__')
315 if filename:
316 fnl = filename.lower()
Brett Cannonf299abd2015-04-13 14:21:02 -0400317 if fnl.endswith(".pyc"):
Christian Heimes33fe8092008-04-13 13:53:33 +0000318 filename = filename[:-1]
319 else:
320 if module == "__main__":
321 try:
322 filename = sys.argv[0]
323 except AttributeError:
324 # embedded interpreters don't have sys.argv, see bug #839151
325 filename = '__main__'
326 if not filename:
327 filename = module
328 registry = globals.setdefault("__warningregistry__", {})
329 warn_explicit(message, category, filename, lineno, module, registry,
Victor Stinnere19558a2016-03-23 00:28:08 +0100330 globals, source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000331
332def warn_explicit(message, category, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100333 module=None, registry=None, module_globals=None,
334 source=None):
Brett Cannondb734912008-06-27 00:52:15 +0000335 lineno = int(lineno)
Christian Heimes33fe8092008-04-13 13:53:33 +0000336 if module is None:
337 module = filename or "<unknown>"
338 if module[-3:].lower() == ".py":
339 module = module[:-3] # XXX What about leading pathname?
340 if registry is None:
341 registry = {}
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200342 if registry.get('version', 0) != _filters_version:
343 registry.clear()
344 registry['version'] = _filters_version
Christian Heimes33fe8092008-04-13 13:53:33 +0000345 if isinstance(message, Warning):
346 text = str(message)
347 category = message.__class__
348 else:
349 text = message
350 message = category(message)
351 key = (text, category, lineno)
352 # Quick test for common case
353 if registry.get(key):
354 return
355 # Search the filters
356 for item in filters:
357 action, msg, cat, mod, ln = item
358 if ((msg is None or msg.match(text)) and
359 issubclass(category, cat) and
360 (mod is None or mod.match(module)) and
361 (ln == 0 or lineno == ln)):
362 break
363 else:
364 action = defaultaction
365 # Early exit actions
366 if action == "ignore":
367 registry[key] = 1
368 return
369
370 # Prime the linecache for formatting, in case the
371 # "file" is actually in a zipfile or something.
Antoine Pitrou7cb11fa2013-10-24 22:23:42 +0200372 import linecache
Christian Heimes33fe8092008-04-13 13:53:33 +0000373 linecache.getlines(filename, module_globals)
374
375 if action == "error":
376 raise message
377 # Other actions
378 if action == "once":
379 registry[key] = 1
380 oncekey = (text, category)
381 if onceregistry.get(oncekey):
382 return
383 onceregistry[oncekey] = 1
384 elif action == "always":
385 pass
386 elif action == "module":
387 registry[key] = 1
388 altkey = (text, category, 0)
389 if registry.get(altkey):
390 return
391 registry[altkey] = 1
392 elif action == "default":
393 registry[key] = 1
394 else:
395 # Unrecognized actions are errors
396 raise RuntimeError(
397 "Unrecognized action (%r) in warnings.filters:\n %s" %
398 (action, item))
399 # Print message and context
Victor Stinner914cde82016-03-19 01:03:51 +0100400 msg = WarningMessage(message, category, filename, lineno, source)
Victor Stinner1231a462016-03-19 00:47:17 +0100401 _showwarnmsg(msg)
Christian Heimes33fe8092008-04-13 13:53:33 +0000402
403
Brett Cannonec92e182008-09-02 02:46:59 +0000404class WarningMessage(object):
405
Brett Cannonec92e182008-09-02 02:46:59 +0000406 _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file",
Victor Stinner914cde82016-03-19 01:03:51 +0100407 "line", "source")
Brett Cannonec92e182008-09-02 02:46:59 +0000408
409 def __init__(self, message, category, filename, lineno, file=None,
Victor Stinner914cde82016-03-19 01:03:51 +0100410 line=None, source=None):
Alex Gaynor5de3a642017-06-04 11:34:16 -0400411 self.message = message
412 self.category = category
413 self.filename = filename
414 self.lineno = lineno
415 self.file = file
416 self.line = line
417 self.source = source
Brett Cannonec92e182008-09-02 02:46:59 +0000418 self._category_name = category.__name__ if category else None
419
420 def __str__(self):
421 return ("{message : %r, category : %r, filename : %r, lineno : %s, "
422 "line : %r}" % (self.message, self._category_name,
423 self.filename, self.lineno, self.line))
424
425
Brett Cannonec92e182008-09-02 02:46:59 +0000426class catch_warnings(object):
427
Brett Cannon1cd02472008-09-09 01:52:27 +0000428 """A context manager that copies and restores the warnings filter upon
429 exiting the context.
Brett Cannonec92e182008-09-02 02:46:59 +0000430
Brett Cannon1cd02472008-09-09 01:52:27 +0000431 The 'record' argument specifies whether warnings should be captured by a
432 custom implementation of warnings.showwarning() and be appended to a list
433 returned by the context manager. Otherwise None is returned by the context
434 manager. The objects appended to the list are arguments whose attributes
435 mirror the arguments to showwarning().
436
437 The 'module' argument is to specify an alternative module to the module
438 named 'warnings' and imported under that name. This argument is only useful
439 when testing the warnings module itself.
Brett Cannonec92e182008-09-02 02:46:59 +0000440
441 """
442
443 def __init__(self, *, record=False, module=None):
444 """Specify whether to record warnings and if an alternative module
445 should be used other than sys.modules['warnings'].
446
447 For compatibility with Python 3.0, please consider all arguments to be
448 keyword-only.
449
450 """
Brett Cannon1cd02472008-09-09 01:52:27 +0000451 self._record = record
Brett Cannonec92e182008-09-02 02:46:59 +0000452 self._module = sys.modules['warnings'] if module is None else module
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000453 self._entered = False
454
455 def __repr__(self):
456 args = []
457 if self._record:
458 args.append("record=True")
459 if self._module is not sys.modules['warnings']:
460 args.append("module=%r" % self._module)
461 name = type(self).__name__
462 return "%s(%s)" % (name, ", ".join(args))
Brett Cannonec92e182008-09-02 02:46:59 +0000463
464 def __enter__(self):
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000465 if self._entered:
466 raise RuntimeError("Cannot enter %r twice" % self)
467 self._entered = True
Brett Cannonec92e182008-09-02 02:46:59 +0000468 self._filters = self._module.filters
469 self._module.filters = self._filters[:]
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200470 self._module._filters_mutated()
Brett Cannonec92e182008-09-02 02:46:59 +0000471 self._showwarning = self._module.showwarning
Victor Stinner8ef46be2016-12-06 10:53:52 +0100472 self._showwarnmsg_impl = self._module._showwarnmsg_impl
Brett Cannon1cd02472008-09-09 01:52:27 +0000473 if self._record:
474 log = []
Ned Deilyc1c32922016-12-06 17:12:47 -0500475 self._module._showwarnmsg_impl = log.append
Victor Stinner8ef46be2016-12-06 10:53:52 +0100476 # Reset showwarning() to the default implementation to make sure
477 # that _showwarnmsg() calls _showwarnmsg_impl()
Ned Deilyc1c32922016-12-06 17:12:47 -0500478 self._module.showwarning = self._module._showwarning_orig
Brett Cannon1cd02472008-09-09 01:52:27 +0000479 return log
480 else:
481 return None
Brett Cannonec92e182008-09-02 02:46:59 +0000482
483 def __exit__(self, *exc_info):
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000484 if not self._entered:
485 raise RuntimeError("Cannot exit %r without entering first" % self)
Brett Cannonec92e182008-09-02 02:46:59 +0000486 self._module.filters = self._filters
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200487 self._module._filters_mutated()
Brett Cannonec92e182008-09-02 02:46:59 +0000488 self._module.showwarning = self._showwarning
Victor Stinner8ef46be2016-12-06 10:53:52 +0100489 self._module._showwarnmsg_impl = self._showwarnmsg_impl
Brett Cannonec92e182008-09-02 02:46:59 +0000490
491
Christian Heimes33fe8092008-04-13 13:53:33 +0000492# filters contains a sequence of filter 5-tuples
493# The components of the 5-tuple are:
494# - an action: error, ignore, always, default, module, or once
495# - a compiled regex that must match the warning message
496# - a class representing the warning category
497# - a compiled regex that must match the module that is being warned
498# - a line number for the line being warning, or 0 to mean any line
499# If either if the compiled regexs are None, match anything.
Christian Heimes33fe8092008-04-13 13:53:33 +0000500try:
Brett Cannonef0e6c32010-09-04 18:24:04 +0000501 from _warnings import (filters, _defaultaction, _onceregistry,
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200502 warn, warn_explicit, _filters_mutated)
Brett Cannonef0e6c32010-09-04 18:24:04 +0000503 defaultaction = _defaultaction
504 onceregistry = _onceregistry
Christian Heimes33fe8092008-04-13 13:53:33 +0000505 _warnings_defaults = True
Brett Cannoncd171c82013-07-04 17:43:24 -0400506except ImportError:
Christian Heimes33fe8092008-04-13 13:53:33 +0000507 filters = []
508 defaultaction = "default"
509 onceregistry = {}
510
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200511 _filters_version = 1
512
513 def _filters_mutated():
514 global _filters_version
515 _filters_version += 1
516
Victor Stinner09f3a8a2017-11-20 17:32:40 -0800517 _warnings_defaults = False
518
Christian Heimes33fe8092008-04-13 13:53:33 +0000519
Guido van Rossum2a862c62000-12-15 21:59:53 +0000520# Module initialization
Tim Peters66025202004-03-21 17:06:20 +0000521_processoptions(sys.warnoptions)
Christian Heimes33fe8092008-04-13 13:53:33 +0000522if not _warnings_defaults:
Victor Stinner09f3a8a2017-11-20 17:32:40 -0800523 dev_mode = ('dev' in getattr(sys, '_xoptions', {}))
Victor Stinner895862a2017-11-20 09:47:03 -0800524 py_debug = hasattr(sys, 'gettotalrefcount')
Victor Stinner09f3a8a2017-11-20 17:32:40 -0800525
526 if not(dev_mode or py_debug):
Victor Stinner895862a2017-11-20 09:47:03 -0800527 silence = [ImportWarning, PendingDeprecationWarning]
528 silence.append(DeprecationWarning)
529 for cls in silence:
530 simplefilter("ignore", category=cls)
531
Christian Heimes33fe8092008-04-13 13:53:33 +0000532 bytes_warning = sys.flags.bytes_warning
533 if bytes_warning > 1:
534 bytes_action = "error"
535 elif bytes_warning:
536 bytes_action = "default"
537 else:
538 bytes_action = "ignore"
539 simplefilter(bytes_action, category=BytesWarning, append=1)
Victor Stinner895862a2017-11-20 09:47:03 -0800540
Georg Brandl08be72d2010-10-24 15:11:22 +0000541 # resource usage warnings are enabled by default in pydebug mode
Victor Stinner09f3a8a2017-11-20 17:32:40 -0800542 if dev_mode or py_debug:
Georg Brandl08be72d2010-10-24 15:11:22 +0000543 resource_action = "always"
544 else:
545 resource_action = "ignore"
546 simplefilter(resource_action, category=ResourceWarning, append=1)
547
Victor Stinner09f3a8a2017-11-20 17:32:40 -0800548 if dev_mode:
549 simplefilter("default", category=Warning, append=1)
550
551 del py_debug, dev_mode
552
Christian Heimes33fe8092008-04-13 13:53:33 +0000553del _warnings_defaults