blob: 76ad4dac01849623cc864606ea92fdbbbbd2b99b [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:
Jesse-Bakker706e10b2017-11-30 00:05:07 +010065 s += 'Object allocated at (most recent call last):\n'
Victor Stinner914cde82016-03-19 01:03:51 +010066 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":
Christian Heimes33fe8092008-04-13 13:53:33 +0000367 return
368
369 # Prime the linecache for formatting, in case the
370 # "file" is actually in a zipfile or something.
Antoine Pitrou7cb11fa2013-10-24 22:23:42 +0200371 import linecache
Christian Heimes33fe8092008-04-13 13:53:33 +0000372 linecache.getlines(filename, module_globals)
373
374 if action == "error":
375 raise message
376 # Other actions
377 if action == "once":
378 registry[key] = 1
379 oncekey = (text, category)
380 if onceregistry.get(oncekey):
381 return
382 onceregistry[oncekey] = 1
383 elif action == "always":
384 pass
385 elif action == "module":
386 registry[key] = 1
387 altkey = (text, category, 0)
388 if registry.get(altkey):
389 return
390 registry[altkey] = 1
391 elif action == "default":
392 registry[key] = 1
393 else:
394 # Unrecognized actions are errors
395 raise RuntimeError(
396 "Unrecognized action (%r) in warnings.filters:\n %s" %
397 (action, item))
398 # Print message and context
Victor Stinner914cde82016-03-19 01:03:51 +0100399 msg = WarningMessage(message, category, filename, lineno, source)
Victor Stinner1231a462016-03-19 00:47:17 +0100400 _showwarnmsg(msg)
Christian Heimes33fe8092008-04-13 13:53:33 +0000401
402
Brett Cannonec92e182008-09-02 02:46:59 +0000403class WarningMessage(object):
404
Brett Cannonec92e182008-09-02 02:46:59 +0000405 _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file",
Victor Stinner914cde82016-03-19 01:03:51 +0100406 "line", "source")
Brett Cannonec92e182008-09-02 02:46:59 +0000407
408 def __init__(self, message, category, filename, lineno, file=None,
Victor Stinner914cde82016-03-19 01:03:51 +0100409 line=None, source=None):
Alex Gaynor5de3a642017-06-04 11:34:16 -0400410 self.message = message
411 self.category = category
412 self.filename = filename
413 self.lineno = lineno
414 self.file = file
415 self.line = line
416 self.source = source
Brett Cannonec92e182008-09-02 02:46:59 +0000417 self._category_name = category.__name__ if category else None
418
419 def __str__(self):
420 return ("{message : %r, category : %r, filename : %r, lineno : %s, "
421 "line : %r}" % (self.message, self._category_name,
422 self.filename, self.lineno, self.line))
423
424
Brett Cannonec92e182008-09-02 02:46:59 +0000425class catch_warnings(object):
426
Brett Cannon1cd02472008-09-09 01:52:27 +0000427 """A context manager that copies and restores the warnings filter upon
428 exiting the context.
Brett Cannonec92e182008-09-02 02:46:59 +0000429
Brett Cannon1cd02472008-09-09 01:52:27 +0000430 The 'record' argument specifies whether warnings should be captured by a
431 custom implementation of warnings.showwarning() and be appended to a list
432 returned by the context manager. Otherwise None is returned by the context
433 manager. The objects appended to the list are arguments whose attributes
434 mirror the arguments to showwarning().
435
436 The 'module' argument is to specify an alternative module to the module
437 named 'warnings' and imported under that name. This argument is only useful
438 when testing the warnings module itself.
Brett Cannonec92e182008-09-02 02:46:59 +0000439
440 """
441
442 def __init__(self, *, record=False, module=None):
443 """Specify whether to record warnings and if an alternative module
444 should be used other than sys.modules['warnings'].
445
446 For compatibility with Python 3.0, please consider all arguments to be
447 keyword-only.
448
449 """
Brett Cannon1cd02472008-09-09 01:52:27 +0000450 self._record = record
Brett Cannonec92e182008-09-02 02:46:59 +0000451 self._module = sys.modules['warnings'] if module is None else module
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000452 self._entered = False
453
454 def __repr__(self):
455 args = []
456 if self._record:
457 args.append("record=True")
458 if self._module is not sys.modules['warnings']:
459 args.append("module=%r" % self._module)
460 name = type(self).__name__
461 return "%s(%s)" % (name, ", ".join(args))
Brett Cannonec92e182008-09-02 02:46:59 +0000462
463 def __enter__(self):
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000464 if self._entered:
465 raise RuntimeError("Cannot enter %r twice" % self)
466 self._entered = True
Brett Cannonec92e182008-09-02 02:46:59 +0000467 self._filters = self._module.filters
468 self._module.filters = self._filters[:]
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200469 self._module._filters_mutated()
Brett Cannonec92e182008-09-02 02:46:59 +0000470 self._showwarning = self._module.showwarning
Victor Stinner8ef46be2016-12-06 10:53:52 +0100471 self._showwarnmsg_impl = self._module._showwarnmsg_impl
Brett Cannon1cd02472008-09-09 01:52:27 +0000472 if self._record:
473 log = []
Ned Deilyc1c32922016-12-06 17:12:47 -0500474 self._module._showwarnmsg_impl = log.append
Victor Stinner8ef46be2016-12-06 10:53:52 +0100475 # Reset showwarning() to the default implementation to make sure
476 # that _showwarnmsg() calls _showwarnmsg_impl()
Ned Deilyc1c32922016-12-06 17:12:47 -0500477 self._module.showwarning = self._module._showwarning_orig
Brett Cannon1cd02472008-09-09 01:52:27 +0000478 return log
479 else:
480 return None
Brett Cannonec92e182008-09-02 02:46:59 +0000481
482 def __exit__(self, *exc_info):
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000483 if not self._entered:
484 raise RuntimeError("Cannot exit %r without entering first" % self)
Brett Cannonec92e182008-09-02 02:46:59 +0000485 self._module.filters = self._filters
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200486 self._module._filters_mutated()
Brett Cannonec92e182008-09-02 02:46:59 +0000487 self._module.showwarning = self._showwarning
Victor Stinner8ef46be2016-12-06 10:53:52 +0100488 self._module._showwarnmsg_impl = self._showwarnmsg_impl
Brett Cannonec92e182008-09-02 02:46:59 +0000489
490
Christian Heimes33fe8092008-04-13 13:53:33 +0000491# filters contains a sequence of filter 5-tuples
492# The components of the 5-tuple are:
493# - an action: error, ignore, always, default, module, or once
494# - a compiled regex that must match the warning message
495# - a class representing the warning category
496# - a compiled regex that must match the module that is being warned
497# - a line number for the line being warning, or 0 to mean any line
498# If either if the compiled regexs are None, match anything.
Christian Heimes33fe8092008-04-13 13:53:33 +0000499try:
Brett Cannonef0e6c32010-09-04 18:24:04 +0000500 from _warnings import (filters, _defaultaction, _onceregistry,
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200501 warn, warn_explicit, _filters_mutated)
Brett Cannonef0e6c32010-09-04 18:24:04 +0000502 defaultaction = _defaultaction
503 onceregistry = _onceregistry
Christian Heimes33fe8092008-04-13 13:53:33 +0000504 _warnings_defaults = True
Brett Cannoncd171c82013-07-04 17:43:24 -0400505except ImportError:
Christian Heimes33fe8092008-04-13 13:53:33 +0000506 filters = []
507 defaultaction = "default"
508 onceregistry = {}
509
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200510 _filters_version = 1
511
512 def _filters_mutated():
513 global _filters_version
514 _filters_version += 1
515
Victor Stinner09f3a8a2017-11-20 17:32:40 -0800516 _warnings_defaults = False
517
Christian Heimes33fe8092008-04-13 13:53:33 +0000518
Guido van Rossum2a862c62000-12-15 21:59:53 +0000519# Module initialization
Tim Peters66025202004-03-21 17:06:20 +0000520_processoptions(sys.warnoptions)
Christian Heimes33fe8092008-04-13 13:53:33 +0000521if not _warnings_defaults:
Nick Coghlan9b997472018-01-08 12:45:02 +1000522 # Several warning categories are ignored by default in regular builds
Victor Stinner747f48e2017-12-12 22:59:48 +0100523 if not hasattr(sys, 'gettotalrefcount'):
Nick Coghlan9b997472018-01-08 12:45:02 +1000524 filterwarnings("default", category=DeprecationWarning,
525 module="__main__", append=1)
Victor Stinner747f48e2017-12-12 22:59:48 +0100526 simplefilter("ignore", category=DeprecationWarning, append=1)
527 simplefilter("ignore", category=PendingDeprecationWarning, append=1)
528 simplefilter("ignore", category=ImportWarning, append=1)
529 simplefilter("ignore", category=ResourceWarning, append=1)
Victor Stinner09f3a8a2017-11-20 17:32:40 -0800530
Christian Heimes33fe8092008-04-13 13:53:33 +0000531del _warnings_defaults