blob: 6830b602de9ab2a88013dd4e1e1a6e16b4b6b7b2 [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__
Thomas Kluyver11a89662018-06-08 21:28:37 +0200306 filename = "sys"
Christian Heimes33fe8092008-04-13 13:53:33 +0000307 lineno = 1
308 else:
Larry Hastings714e4932015-09-06 00:39:37 -0700309 globals = frame.f_globals
Thomas Kluyver11a89662018-06-08 21:28:37 +0200310 filename = frame.f_code.co_filename
Larry Hastings714e4932015-09-06 00:39:37 -0700311 lineno = frame.f_lineno
Christian Heimes33fe8092008-04-13 13:53:33 +0000312 if '__name__' in globals:
313 module = globals['__name__']
314 else:
315 module = "<string>"
Christian Heimes33fe8092008-04-13 13:53:33 +0000316 registry = globals.setdefault("__warningregistry__", {})
317 warn_explicit(message, category, filename, lineno, module, registry,
Victor Stinnere19558a2016-03-23 00:28:08 +0100318 globals, source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000319
320def warn_explicit(message, category, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100321 module=None, registry=None, module_globals=None,
322 source=None):
Brett Cannondb734912008-06-27 00:52:15 +0000323 lineno = int(lineno)
Christian Heimes33fe8092008-04-13 13:53:33 +0000324 if module is None:
325 module = filename or "<unknown>"
326 if module[-3:].lower() == ".py":
327 module = module[:-3] # XXX What about leading pathname?
328 if registry is None:
329 registry = {}
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200330 if registry.get('version', 0) != _filters_version:
331 registry.clear()
332 registry['version'] = _filters_version
Christian Heimes33fe8092008-04-13 13:53:33 +0000333 if isinstance(message, Warning):
334 text = str(message)
335 category = message.__class__
336 else:
337 text = message
338 message = category(message)
339 key = (text, category, lineno)
340 # Quick test for common case
341 if registry.get(key):
342 return
343 # Search the filters
344 for item in filters:
345 action, msg, cat, mod, ln = item
346 if ((msg is None or msg.match(text)) and
347 issubclass(category, cat) and
348 (mod is None or mod.match(module)) and
349 (ln == 0 or lineno == ln)):
350 break
351 else:
352 action = defaultaction
353 # Early exit actions
354 if action == "ignore":
Christian Heimes33fe8092008-04-13 13:53:33 +0000355 return
356
357 # Prime the linecache for formatting, in case the
358 # "file" is actually in a zipfile or something.
Antoine Pitrou7cb11fa2013-10-24 22:23:42 +0200359 import linecache
Christian Heimes33fe8092008-04-13 13:53:33 +0000360 linecache.getlines(filename, module_globals)
361
362 if action == "error":
363 raise message
364 # Other actions
365 if action == "once":
366 registry[key] = 1
367 oncekey = (text, category)
368 if onceregistry.get(oncekey):
369 return
370 onceregistry[oncekey] = 1
371 elif action == "always":
372 pass
373 elif action == "module":
374 registry[key] = 1
375 altkey = (text, category, 0)
376 if registry.get(altkey):
377 return
378 registry[altkey] = 1
379 elif action == "default":
380 registry[key] = 1
381 else:
382 # Unrecognized actions are errors
383 raise RuntimeError(
384 "Unrecognized action (%r) in warnings.filters:\n %s" %
385 (action, item))
386 # Print message and context
Victor Stinner914cde82016-03-19 01:03:51 +0100387 msg = WarningMessage(message, category, filename, lineno, source)
Victor Stinner1231a462016-03-19 00:47:17 +0100388 _showwarnmsg(msg)
Christian Heimes33fe8092008-04-13 13:53:33 +0000389
390
Brett Cannonec92e182008-09-02 02:46:59 +0000391class WarningMessage(object):
392
Brett Cannonec92e182008-09-02 02:46:59 +0000393 _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file",
Victor Stinner914cde82016-03-19 01:03:51 +0100394 "line", "source")
Brett Cannonec92e182008-09-02 02:46:59 +0000395
396 def __init__(self, message, category, filename, lineno, file=None,
Victor Stinner914cde82016-03-19 01:03:51 +0100397 line=None, source=None):
Alex Gaynor5de3a642017-06-04 11:34:16 -0400398 self.message = message
399 self.category = category
400 self.filename = filename
401 self.lineno = lineno
402 self.file = file
403 self.line = line
404 self.source = source
Brett Cannonec92e182008-09-02 02:46:59 +0000405 self._category_name = category.__name__ if category else None
406
407 def __str__(self):
408 return ("{message : %r, category : %r, filename : %r, lineno : %s, "
409 "line : %r}" % (self.message, self._category_name,
410 self.filename, self.lineno, self.line))
411
412
Brett Cannonec92e182008-09-02 02:46:59 +0000413class catch_warnings(object):
414
Brett Cannon1cd02472008-09-09 01:52:27 +0000415 """A context manager that copies and restores the warnings filter upon
416 exiting the context.
Brett Cannonec92e182008-09-02 02:46:59 +0000417
Brett Cannon1cd02472008-09-09 01:52:27 +0000418 The 'record' argument specifies whether warnings should be captured by a
419 custom implementation of warnings.showwarning() and be appended to a list
420 returned by the context manager. Otherwise None is returned by the context
421 manager. The objects appended to the list are arguments whose attributes
422 mirror the arguments to showwarning().
423
424 The 'module' argument is to specify an alternative module to the module
425 named 'warnings' and imported under that name. This argument is only useful
426 when testing the warnings module itself.
Brett Cannonec92e182008-09-02 02:46:59 +0000427
428 """
429
430 def __init__(self, *, record=False, module=None):
431 """Specify whether to record warnings and if an alternative module
432 should be used other than sys.modules['warnings'].
433
434 For compatibility with Python 3.0, please consider all arguments to be
435 keyword-only.
436
437 """
Brett Cannon1cd02472008-09-09 01:52:27 +0000438 self._record = record
Brett Cannonec92e182008-09-02 02:46:59 +0000439 self._module = sys.modules['warnings'] if module is None else module
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000440 self._entered = False
441
442 def __repr__(self):
443 args = []
444 if self._record:
445 args.append("record=True")
446 if self._module is not sys.modules['warnings']:
447 args.append("module=%r" % self._module)
448 name = type(self).__name__
449 return "%s(%s)" % (name, ", ".join(args))
Brett Cannonec92e182008-09-02 02:46:59 +0000450
451 def __enter__(self):
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000452 if self._entered:
453 raise RuntimeError("Cannot enter %r twice" % self)
454 self._entered = True
Brett Cannonec92e182008-09-02 02:46:59 +0000455 self._filters = self._module.filters
456 self._module.filters = self._filters[:]
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200457 self._module._filters_mutated()
Brett Cannonec92e182008-09-02 02:46:59 +0000458 self._showwarning = self._module.showwarning
Victor Stinner8ef46be2016-12-06 10:53:52 +0100459 self._showwarnmsg_impl = self._module._showwarnmsg_impl
Brett Cannon1cd02472008-09-09 01:52:27 +0000460 if self._record:
461 log = []
Ned Deilyc1c32922016-12-06 17:12:47 -0500462 self._module._showwarnmsg_impl = log.append
Victor Stinner8ef46be2016-12-06 10:53:52 +0100463 # Reset showwarning() to the default implementation to make sure
464 # that _showwarnmsg() calls _showwarnmsg_impl()
Ned Deilyc1c32922016-12-06 17:12:47 -0500465 self._module.showwarning = self._module._showwarning_orig
Brett Cannon1cd02472008-09-09 01:52:27 +0000466 return log
467 else:
468 return None
Brett Cannonec92e182008-09-02 02:46:59 +0000469
470 def __exit__(self, *exc_info):
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000471 if not self._entered:
472 raise RuntimeError("Cannot exit %r without entering first" % self)
Brett Cannonec92e182008-09-02 02:46:59 +0000473 self._module.filters = self._filters
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200474 self._module._filters_mutated()
Brett Cannonec92e182008-09-02 02:46:59 +0000475 self._module.showwarning = self._showwarning
Victor Stinner8ef46be2016-12-06 10:53:52 +0100476 self._module._showwarnmsg_impl = self._showwarnmsg_impl
Brett Cannonec92e182008-09-02 02:46:59 +0000477
478
Nathaniel J. Smithfc2f4072018-01-21 06:44:07 -0800479# Private utility function called by _PyErr_WarnUnawaitedCoroutine
480def _warn_unawaited_coroutine(coro):
481 msg_lines = [
482 f"coroutine '{coro.__qualname__}' was never awaited\n"
483 ]
484 if coro.cr_origin is not None:
485 import linecache, traceback
486 def extract():
487 for filename, lineno, funcname in reversed(coro.cr_origin):
488 line = linecache.getline(filename, lineno)
489 yield (filename, lineno, funcname, line)
490 msg_lines.append("Coroutine created at (most recent call last)\n")
491 msg_lines += traceback.format_list(list(extract()))
492 msg = "".join(msg_lines).rstrip("\n")
493 # Passing source= here means that if the user happens to have tracemalloc
494 # enabled and tracking where the coroutine was created, the warning will
495 # contain that traceback. This does mean that if they have *both*
496 # coroutine origin tracking *and* tracemalloc enabled, they'll get two
497 # partially-redundant tracebacks. If we wanted to be clever we could
498 # probably detect this case and avoid it, but for now we don't bother.
499 warn(msg, category=RuntimeWarning, stacklevel=2, source=coro)
500
501
Christian Heimes33fe8092008-04-13 13:53:33 +0000502# filters contains a sequence of filter 5-tuples
503# The components of the 5-tuple are:
504# - an action: error, ignore, always, default, module, or once
505# - a compiled regex that must match the warning message
506# - a class representing the warning category
507# - a compiled regex that must match the module that is being warned
508# - a line number for the line being warning, or 0 to mean any line
509# If either if the compiled regexs are None, match anything.
Christian Heimes33fe8092008-04-13 13:53:33 +0000510try:
Brett Cannonef0e6c32010-09-04 18:24:04 +0000511 from _warnings import (filters, _defaultaction, _onceregistry,
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200512 warn, warn_explicit, _filters_mutated)
Brett Cannonef0e6c32010-09-04 18:24:04 +0000513 defaultaction = _defaultaction
514 onceregistry = _onceregistry
Christian Heimes33fe8092008-04-13 13:53:33 +0000515 _warnings_defaults = True
Brett Cannoncd171c82013-07-04 17:43:24 -0400516except ImportError:
Christian Heimes33fe8092008-04-13 13:53:33 +0000517 filters = []
518 defaultaction = "default"
519 onceregistry = {}
520
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200521 _filters_version = 1
522
523 def _filters_mutated():
524 global _filters_version
525 _filters_version += 1
526
Victor Stinner09f3a8a2017-11-20 17:32:40 -0800527 _warnings_defaults = False
528
Christian Heimes33fe8092008-04-13 13:53:33 +0000529
Guido van Rossum2a862c62000-12-15 21:59:53 +0000530# Module initialization
Tim Peters66025202004-03-21 17:06:20 +0000531_processoptions(sys.warnoptions)
Christian Heimes33fe8092008-04-13 13:53:33 +0000532if not _warnings_defaults:
Nick Coghlan9b997472018-01-08 12:45:02 +1000533 # Several warning categories are ignored by default in regular builds
Victor Stinner747f48e2017-12-12 22:59:48 +0100534 if not hasattr(sys, 'gettotalrefcount'):
Nick Coghlan9b997472018-01-08 12:45:02 +1000535 filterwarnings("default", category=DeprecationWarning,
536 module="__main__", append=1)
Victor Stinner747f48e2017-12-12 22:59:48 +0100537 simplefilter("ignore", category=DeprecationWarning, append=1)
538 simplefilter("ignore", category=PendingDeprecationWarning, append=1)
539 simplefilter("ignore", category=ImportWarning, append=1)
540 simplefilter("ignore", category=ResourceWarning, append=1)
Victor Stinner09f3a8a2017-11-20 17:32:40 -0800541
Christian Heimes33fe8092008-04-13 13:53:33 +0000542del _warnings_defaults