blob: ae4295e120f69fea805b4de8aac33e950d649ee5 [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):
Miss Islington (bot)0091f342018-12-04 12:25:57 -080036 category = msg.category.__name__
37 s = f"{msg.filename}:{msg.lineno}: {category}: {msg.message}\n"
Victor Stinnere091d322016-03-25 00:33:12 +010038
Victor Stinner1231a462016-03-19 00:47:17 +010039 if msg.line is None:
Victor Stinner27461682016-03-25 00:30:32 +010040 try:
41 import linecache
Victor Stinnere091d322016-03-25 00:33:12 +010042 line = linecache.getline(msg.filename, msg.lineno)
Victor Stinner27461682016-03-25 00:30:32 +010043 except Exception:
44 # When a warning is logged during Python shutdown, linecache
Martin Pantercc71a792016-04-05 06:19:42 +000045 # and the import machinery don't work anymore
Victor Stinner27461682016-03-25 00:30:32 +010046 line = None
Victor Stinnere091d322016-03-25 00:33:12 +010047 linecache = None
Victor Stinner1231a462016-03-19 00:47:17 +010048 else:
49 line = msg.line
Guido van Rossum2a862c62000-12-15 21:59:53 +000050 if line:
Christian Heimes33fe8092008-04-13 13:53:33 +000051 line = line.strip()
52 s += " %s\n" % line
Victor Stinnere091d322016-03-25 00:33:12 +010053
Victor Stinner914cde82016-03-19 01:03:51 +010054 if msg.source is not None:
Victor Stinnere091d322016-03-25 00:33:12 +010055 try:
56 import tracemalloc
Miss Islington (bot)0091f342018-12-04 12:25:57 -080057 # Logging a warning should not raise a new exception:
58 # catch Exception, not only ImportError and RecursionError.
Victor Stinnere091d322016-03-25 00:33:12 +010059 except Exception:
Miss Islington (bot)0091f342018-12-04 12:25:57 -080060 # don't suggest to enable tracemalloc if it's not available
61 tracing = True
Victor Stinnere091d322016-03-25 00:33:12 +010062 tb = None
Miss Islington (bot)0091f342018-12-04 12:25:57 -080063 else:
64 tracing = tracemalloc.is_tracing()
65 try:
66 tb = tracemalloc.get_object_traceback(msg.source)
67 except Exception:
68 # When a warning is logged during Python shutdown, tracemalloc
69 # and the import machinery don't work anymore
70 tb = None
Victor Stinnere091d322016-03-25 00:33:12 +010071
Victor Stinner914cde82016-03-19 01:03:51 +010072 if tb is not None:
Jesse-Bakker706e10b2017-11-30 00:05:07 +010073 s += 'Object allocated at (most recent call last):\n'
Victor Stinner914cde82016-03-19 01:03:51 +010074 for frame in tb:
75 s += (' File "%s", lineno %s\n'
76 % (frame.filename, frame.lineno))
Victor Stinnere091d322016-03-25 00:33:12 +010077
78 try:
79 if linecache is not None:
80 line = linecache.getline(frame.filename, frame.lineno)
81 else:
82 line = None
83 except Exception:
84 line = None
Victor Stinner914cde82016-03-19 01:03:51 +010085 if line:
86 line = line.strip()
87 s += ' %s\n' % line
Miss Islington (bot)0091f342018-12-04 12:25:57 -080088 elif not tracing:
89 s += (f'{category}: Enable tracemalloc to get the object '
90 f'allocation traceback\n')
Guido van Rossum2a862c62000-12-15 21:59:53 +000091 return s
92
Victor Stinnereedf13f2016-03-19 02:11:56 +010093# Keep a reference to check if the function was replaced
Ned Deilyc1c32922016-12-06 17:12:47 -050094_showwarning_orig = showwarning
Victor Stinnereedf13f2016-03-19 02:11:56 +010095
96def _showwarnmsg(msg):
97 """Hook to write a warning to a file; replace if you like."""
Ned Deilyc1c32922016-12-06 17:12:47 -050098 try:
99 sw = showwarning
100 except NameError:
101 pass
102 else:
103 if sw is not _showwarning_orig:
104 # warnings.showwarning() was replaced
105 if not callable(sw):
106 raise TypeError("warnings.showwarning() must be set to a "
107 "function or method")
Victor Stinnereedf13f2016-03-19 02:11:56 +0100108
Ned Deilyc1c32922016-12-06 17:12:47 -0500109 sw(msg.message, msg.category, msg.filename, msg.lineno,
110 msg.file, msg.line)
111 return
Victor Stinnereedf13f2016-03-19 02:11:56 +0100112 _showwarnmsg_impl(msg)
113
114# Keep a reference to check if the function was replaced
Ned Deilyc1c32922016-12-06 17:12:47 -0500115_formatwarning_orig = formatwarning
Victor Stinnereedf13f2016-03-19 02:11:56 +0100116
117def _formatwarnmsg(msg):
118 """Function to format a warning the standard way."""
Ned Deilyc1c32922016-12-06 17:12:47 -0500119 try:
120 fw = formatwarning
121 except NameError:
122 pass
123 else:
124 if fw is not _formatwarning_orig:
125 # warnings.formatwarning() was replaced
126 return fw(msg.message, msg.category,
127 msg.filename, msg.lineno, line=msg.line)
Victor Stinnereedf13f2016-03-19 02:11:56 +0100128 return _formatwarnmsg_impl(msg)
129
Guido van Rossum9464a7d2001-01-14 14:08:40 +0000130def filterwarnings(action, message="", category=Warning, module="", lineno=0,
Georg Brandlfe991052009-09-16 15:54:04 +0000131 append=False):
Guido van Rossum2a862c62000-12-15 21:59:53 +0000132 """Insert an entry into the list of warnings filters (at the front).
133
Georg Brandl495f7b52009-10-27 15:28:25 +0000134 'action' -- one of "error", "ignore", "always", "default", "module",
135 or "once"
136 'message' -- a regex that the warning message must match
137 'category' -- a class that the warning must be a subclass of
138 'module' -- a regex that the module name must match
139 'lineno' -- an integer line number, 0 matches all warnings
140 'append' -- if true, append to the list of filters
141 """
Guido van Rossum2a862c62000-12-15 21:59:53 +0000142 assert action in ("error", "ignore", "always", "default", "module",
Walter Dörwald70a6b492004-02-12 17:35:32 +0000143 "once"), "invalid action: %r" % (action,)
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000144 assert isinstance(message, str), "message must be a string"
Guido van Rossum13257902007-06-07 23:15:56 +0000145 assert isinstance(category, type), "category must be a class"
Guido van Rossum2a862c62000-12-15 21:59:53 +0000146 assert issubclass(category, Warning), "category must be a Warning subclass"
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000147 assert isinstance(module, str), "module must be a string"
Walter Dörwald65230a22002-06-03 15:58:32 +0000148 assert isinstance(lineno, int) and lineno >= 0, \
Guido van Rossum2a862c62000-12-15 21:59:53 +0000149 "lineno must be an int >= 0"
Victor Stinner82656272017-11-22 23:51:42 +0100150
151 if message or module:
152 import re
153
154 if message:
155 message = re.compile(message, re.I)
156 else:
157 message = None
158 if module:
159 module = re.compile(module)
160 else:
161 module = None
162
163 _add_filter(action, message, category, module, lineno, append=append)
Guido van Rossum2a862c62000-12-15 21:59:53 +0000164
Georg Brandlfe991052009-09-16 15:54:04 +0000165def simplefilter(action, category=Warning, lineno=0, append=False):
Jeremy Hylton85014662003-07-11 15:37:59 +0000166 """Insert a simple entry into the list of warnings filters (at the front).
167
168 A simple filter matches all modules and messages.
Georg Brandl495f7b52009-10-27 15:28:25 +0000169 'action' -- one of "error", "ignore", "always", "default", "module",
170 or "once"
171 'category' -- a class that the warning must be a subclass of
172 'lineno' -- an integer line number, 0 matches all warnings
173 'append' -- if true, append to the list of filters
Jeremy Hylton85014662003-07-11 15:37:59 +0000174 """
175 assert action in ("error", "ignore", "always", "default", "module",
Walter Dörwald70a6b492004-02-12 17:35:32 +0000176 "once"), "invalid action: %r" % (action,)
Jeremy Hylton85014662003-07-11 15:37:59 +0000177 assert isinstance(lineno, int) and lineno >= 0, \
178 "lineno must be an int >= 0"
Martin Panter43593a12016-05-26 09:10:55 +0000179 _add_filter(action, None, category, None, lineno, append=append)
180
181def _add_filter(*item, append):
182 # Remove possible duplicate filters, so new one will be placed
183 # in correct place. If append=True and duplicate exists, do nothing.
184 if not append:
185 try:
186 filters.remove(item)
187 except ValueError:
188 pass
Jeremy Hylton85014662003-07-11 15:37:59 +0000189 filters.insert(0, item)
Martin Panter43593a12016-05-26 09:10:55 +0000190 else:
191 if item not in filters:
192 filters.append(item)
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200193 _filters_mutated()
Jeremy Hylton85014662003-07-11 15:37:59 +0000194
Guido van Rossum2a862c62000-12-15 21:59:53 +0000195def resetwarnings():
Tim Petersd0cc4f02002-04-16 01:51:25 +0000196 """Clear the list of warning filters, so that no filters are active."""
Guido van Rossum2a862c62000-12-15 21:59:53 +0000197 filters[:] = []
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200198 _filters_mutated()
Guido van Rossum2a862c62000-12-15 21:59:53 +0000199
200class _OptionError(Exception):
201 """Exception used by option processing helpers."""
202 pass
203
204# Helper to process -W options passed via sys.warnoptions
205def _processoptions(args):
206 for arg in args:
207 try:
208 _setoption(arg)
Guido van Rossumb940e112007-01-10 16:19:56 +0000209 except _OptionError as msg:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000210 print("Invalid -W option ignored:", msg, file=sys.stderr)
Guido van Rossum2a862c62000-12-15 21:59:53 +0000211
212# Helper for _processoptions()
213def _setoption(arg):
Skip Montanarod8f21202003-05-14 17:33:53 +0000214 import re
Tim Peterse1190062001-01-15 03:34:38 +0000215 parts = arg.split(':')
216 if len(parts) > 5:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000217 raise _OptionError("too many fields (max 5): %r" % (arg,))
Tim Peterse1190062001-01-15 03:34:38 +0000218 while len(parts) < 5:
219 parts.append('')
220 action, message, category, module, lineno = [s.strip()
221 for s in parts]
222 action = _getaction(action)
223 message = re.escape(message)
224 category = _getcategory(category)
225 module = re.escape(module)
226 if module:
227 module = module + '$'
228 if lineno:
229 try:
230 lineno = int(lineno)
231 if lineno < 0:
232 raise ValueError
233 except (ValueError, OverflowError):
Serhiy Storchaka5affd232017-04-05 09:37:24 +0300234 raise _OptionError("invalid lineno %r" % (lineno,)) from None
Tim Peterse1190062001-01-15 03:34:38 +0000235 else:
236 lineno = 0
237 filterwarnings(action, message, category, module, lineno)
Guido van Rossum2a862c62000-12-15 21:59:53 +0000238
239# Helper for _setoption()
240def _getaction(action):
241 if not action:
242 return "default"
243 if action == "all": return "always" # Alias
Raymond Hettingerdbecd932005-02-06 06:57:08 +0000244 for a in ('default', 'always', 'ignore', 'module', 'once', 'error'):
Guido van Rossum2a862c62000-12-15 21:59:53 +0000245 if a.startswith(action):
246 return a
Walter Dörwald70a6b492004-02-12 17:35:32 +0000247 raise _OptionError("invalid action: %r" % (action,))
Guido van Rossum2a862c62000-12-15 21:59:53 +0000248
249# Helper for _setoption()
250def _getcategory(category):
Skip Montanarod8f21202003-05-14 17:33:53 +0000251 import re
Guido van Rossum2a862c62000-12-15 21:59:53 +0000252 if not category:
253 return Warning
254 if re.match("^[a-zA-Z0-9_]+$", category):
255 try:
256 cat = eval(category)
Guido van Rossumd1db30b2000-12-19 03:04:50 +0000257 except NameError:
Serhiy Storchaka5affd232017-04-05 09:37:24 +0300258 raise _OptionError("unknown warning category: %r" % (category,)) from None
Guido van Rossum2a862c62000-12-15 21:59:53 +0000259 else:
260 i = category.rfind(".")
261 module = category[:i]
262 klass = category[i+1:]
Guido van Rossumd1db30b2000-12-19 03:04:50 +0000263 try:
Brett Cannoncd171c82013-07-04 17:43:24 -0400264 m = __import__(module, None, None, [klass])
265 except ImportError:
Serhiy Storchaka5affd232017-04-05 09:37:24 +0300266 raise _OptionError("invalid module name: %r" % (module,)) from None
Guido van Rossumd1db30b2000-12-19 03:04:50 +0000267 try:
268 cat = getattr(m, klass)
269 except AttributeError:
Serhiy Storchaka5affd232017-04-05 09:37:24 +0300270 raise _OptionError("unknown warning category: %r" % (category,)) from None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000271 if not issubclass(cat, Warning):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000272 raise _OptionError("invalid warning category: %r" % (category,))
Guido van Rossum2a862c62000-12-15 21:59:53 +0000273 return cat
274
Christian Heimes33fe8092008-04-13 13:53:33 +0000275
Larry Hastings714e4932015-09-06 00:39:37 -0700276def _is_internal_frame(frame):
277 """Signal whether the frame is an internal CPython implementation detail."""
278 filename = frame.f_code.co_filename
279 return 'importlib' in filename and '_bootstrap' in filename
280
281
282def _next_external_frame(frame):
283 """Find the next frame that doesn't involve CPython internals."""
284 frame = frame.f_back
285 while frame is not None and _is_internal_frame(frame):
286 frame = frame.f_back
287 return frame
288
289
Christian Heimes33fe8092008-04-13 13:53:33 +0000290# Code typically replaced by _warnings
Victor Stinnere19558a2016-03-23 00:28:08 +0100291def warn(message, category=None, stacklevel=1, source=None):
Christian Heimes33fe8092008-04-13 13:53:33 +0000292 """Issue a warning, or maybe ignore it or raise an exception."""
293 # Check if message is already a Warning object
294 if isinstance(message, Warning):
295 category = message.__class__
296 # Check category argument
297 if category is None:
298 category = UserWarning
Berker Peksagd8089e02014-07-11 19:50:25 +0300299 if not (isinstance(category, type) and issubclass(category, Warning)):
300 raise TypeError("category must be a Warning subclass, "
301 "not '{:s}'".format(type(category).__name__))
Christian Heimes33fe8092008-04-13 13:53:33 +0000302 # Get context information
303 try:
Larry Hastings714e4932015-09-06 00:39:37 -0700304 if stacklevel <= 1 or _is_internal_frame(sys._getframe(1)):
305 # If frame is too small to care or if the warning originated in
306 # internal code, then do not try to hide any frames.
307 frame = sys._getframe(stacklevel)
308 else:
309 frame = sys._getframe(1)
310 # Look for one frame less since the above line starts us off.
311 for x in range(stacklevel-1):
312 frame = _next_external_frame(frame)
313 if frame is None:
314 raise ValueError
Christian Heimes33fe8092008-04-13 13:53:33 +0000315 except ValueError:
316 globals = sys.__dict__
317 lineno = 1
318 else:
Larry Hastings714e4932015-09-06 00:39:37 -0700319 globals = frame.f_globals
320 lineno = frame.f_lineno
Christian Heimes33fe8092008-04-13 13:53:33 +0000321 if '__name__' in globals:
322 module = globals['__name__']
323 else:
324 module = "<string>"
325 filename = globals.get('__file__')
326 if filename:
327 fnl = filename.lower()
Brett Cannonf299abd2015-04-13 14:21:02 -0400328 if fnl.endswith(".pyc"):
Christian Heimes33fe8092008-04-13 13:53:33 +0000329 filename = filename[:-1]
330 else:
331 if module == "__main__":
332 try:
333 filename = sys.argv[0]
334 except AttributeError:
335 # embedded interpreters don't have sys.argv, see bug #839151
336 filename = '__main__'
337 if not filename:
338 filename = module
339 registry = globals.setdefault("__warningregistry__", {})
340 warn_explicit(message, category, filename, lineno, module, registry,
Victor Stinnere19558a2016-03-23 00:28:08 +0100341 globals, source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000342
343def warn_explicit(message, category, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100344 module=None, registry=None, module_globals=None,
345 source=None):
Brett Cannondb734912008-06-27 00:52:15 +0000346 lineno = int(lineno)
Christian Heimes33fe8092008-04-13 13:53:33 +0000347 if module is None:
348 module = filename or "<unknown>"
349 if module[-3:].lower() == ".py":
350 module = module[:-3] # XXX What about leading pathname?
351 if registry is None:
352 registry = {}
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200353 if registry.get('version', 0) != _filters_version:
354 registry.clear()
355 registry['version'] = _filters_version
Christian Heimes33fe8092008-04-13 13:53:33 +0000356 if isinstance(message, Warning):
357 text = str(message)
358 category = message.__class__
359 else:
360 text = message
361 message = category(message)
362 key = (text, category, lineno)
363 # Quick test for common case
364 if registry.get(key):
365 return
366 # Search the filters
367 for item in filters:
368 action, msg, cat, mod, ln = item
369 if ((msg is None or msg.match(text)) and
370 issubclass(category, cat) and
371 (mod is None or mod.match(module)) and
372 (ln == 0 or lineno == ln)):
373 break
374 else:
375 action = defaultaction
376 # Early exit actions
377 if action == "ignore":
Christian Heimes33fe8092008-04-13 13:53:33 +0000378 return
379
380 # Prime the linecache for formatting, in case the
381 # "file" is actually in a zipfile or something.
Antoine Pitrou7cb11fa2013-10-24 22:23:42 +0200382 import linecache
Christian Heimes33fe8092008-04-13 13:53:33 +0000383 linecache.getlines(filename, module_globals)
384
385 if action == "error":
386 raise message
387 # Other actions
388 if action == "once":
389 registry[key] = 1
390 oncekey = (text, category)
391 if onceregistry.get(oncekey):
392 return
393 onceregistry[oncekey] = 1
394 elif action == "always":
395 pass
396 elif action == "module":
397 registry[key] = 1
398 altkey = (text, category, 0)
399 if registry.get(altkey):
400 return
401 registry[altkey] = 1
402 elif action == "default":
403 registry[key] = 1
404 else:
405 # Unrecognized actions are errors
406 raise RuntimeError(
407 "Unrecognized action (%r) in warnings.filters:\n %s" %
408 (action, item))
409 # Print message and context
Victor Stinner914cde82016-03-19 01:03:51 +0100410 msg = WarningMessage(message, category, filename, lineno, source)
Victor Stinner1231a462016-03-19 00:47:17 +0100411 _showwarnmsg(msg)
Christian Heimes33fe8092008-04-13 13:53:33 +0000412
413
Brett Cannonec92e182008-09-02 02:46:59 +0000414class WarningMessage(object):
415
Brett Cannonec92e182008-09-02 02:46:59 +0000416 _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file",
Victor Stinner914cde82016-03-19 01:03:51 +0100417 "line", "source")
Brett Cannonec92e182008-09-02 02:46:59 +0000418
419 def __init__(self, message, category, filename, lineno, file=None,
Victor Stinner914cde82016-03-19 01:03:51 +0100420 line=None, source=None):
Alex Gaynor5de3a642017-06-04 11:34:16 -0400421 self.message = message
422 self.category = category
423 self.filename = filename
424 self.lineno = lineno
425 self.file = file
426 self.line = line
427 self.source = source
Brett Cannonec92e182008-09-02 02:46:59 +0000428 self._category_name = category.__name__ if category else None
429
430 def __str__(self):
431 return ("{message : %r, category : %r, filename : %r, lineno : %s, "
432 "line : %r}" % (self.message, self._category_name,
433 self.filename, self.lineno, self.line))
434
435
Brett Cannonec92e182008-09-02 02:46:59 +0000436class catch_warnings(object):
437
Brett Cannon1cd02472008-09-09 01:52:27 +0000438 """A context manager that copies and restores the warnings filter upon
439 exiting the context.
Brett Cannonec92e182008-09-02 02:46:59 +0000440
Brett Cannon1cd02472008-09-09 01:52:27 +0000441 The 'record' argument specifies whether warnings should be captured by a
442 custom implementation of warnings.showwarning() and be appended to a list
443 returned by the context manager. Otherwise None is returned by the context
444 manager. The objects appended to the list are arguments whose attributes
445 mirror the arguments to showwarning().
446
447 The 'module' argument is to specify an alternative module to the module
448 named 'warnings' and imported under that name. This argument is only useful
449 when testing the warnings module itself.
Brett Cannonec92e182008-09-02 02:46:59 +0000450
451 """
452
453 def __init__(self, *, record=False, module=None):
454 """Specify whether to record warnings and if an alternative module
455 should be used other than sys.modules['warnings'].
456
457 For compatibility with Python 3.0, please consider all arguments to be
458 keyword-only.
459
460 """
Brett Cannon1cd02472008-09-09 01:52:27 +0000461 self._record = record
Brett Cannonec92e182008-09-02 02:46:59 +0000462 self._module = sys.modules['warnings'] if module is None else module
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000463 self._entered = False
464
465 def __repr__(self):
466 args = []
467 if self._record:
468 args.append("record=True")
469 if self._module is not sys.modules['warnings']:
470 args.append("module=%r" % self._module)
471 name = type(self).__name__
472 return "%s(%s)" % (name, ", ".join(args))
Brett Cannonec92e182008-09-02 02:46:59 +0000473
474 def __enter__(self):
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000475 if self._entered:
476 raise RuntimeError("Cannot enter %r twice" % self)
477 self._entered = True
Brett Cannonec92e182008-09-02 02:46:59 +0000478 self._filters = self._module.filters
479 self._module.filters = self._filters[:]
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200480 self._module._filters_mutated()
Brett Cannonec92e182008-09-02 02:46:59 +0000481 self._showwarning = self._module.showwarning
Victor Stinner8ef46be2016-12-06 10:53:52 +0100482 self._showwarnmsg_impl = self._module._showwarnmsg_impl
Brett Cannon1cd02472008-09-09 01:52:27 +0000483 if self._record:
484 log = []
Ned Deilyc1c32922016-12-06 17:12:47 -0500485 self._module._showwarnmsg_impl = log.append
Victor Stinner8ef46be2016-12-06 10:53:52 +0100486 # Reset showwarning() to the default implementation to make sure
487 # that _showwarnmsg() calls _showwarnmsg_impl()
Ned Deilyc1c32922016-12-06 17:12:47 -0500488 self._module.showwarning = self._module._showwarning_orig
Brett Cannon1cd02472008-09-09 01:52:27 +0000489 return log
490 else:
491 return None
Brett Cannonec92e182008-09-02 02:46:59 +0000492
493 def __exit__(self, *exc_info):
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000494 if not self._entered:
495 raise RuntimeError("Cannot exit %r without entering first" % self)
Brett Cannonec92e182008-09-02 02:46:59 +0000496 self._module.filters = self._filters
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200497 self._module._filters_mutated()
Brett Cannonec92e182008-09-02 02:46:59 +0000498 self._module.showwarning = self._showwarning
Victor Stinner8ef46be2016-12-06 10:53:52 +0100499 self._module._showwarnmsg_impl = self._showwarnmsg_impl
Brett Cannonec92e182008-09-02 02:46:59 +0000500
501
Nathaniel J. Smithfc2f4072018-01-21 06:44:07 -0800502# Private utility function called by _PyErr_WarnUnawaitedCoroutine
503def _warn_unawaited_coroutine(coro):
504 msg_lines = [
505 f"coroutine '{coro.__qualname__}' was never awaited\n"
506 ]
507 if coro.cr_origin is not None:
508 import linecache, traceback
509 def extract():
510 for filename, lineno, funcname in reversed(coro.cr_origin):
511 line = linecache.getline(filename, lineno)
512 yield (filename, lineno, funcname, line)
513 msg_lines.append("Coroutine created at (most recent call last)\n")
514 msg_lines += traceback.format_list(list(extract()))
515 msg = "".join(msg_lines).rstrip("\n")
516 # Passing source= here means that if the user happens to have tracemalloc
517 # enabled and tracking where the coroutine was created, the warning will
518 # contain that traceback. This does mean that if they have *both*
519 # coroutine origin tracking *and* tracemalloc enabled, they'll get two
520 # partially-redundant tracebacks. If we wanted to be clever we could
521 # probably detect this case and avoid it, but for now we don't bother.
522 warn(msg, category=RuntimeWarning, stacklevel=2, source=coro)
523
524
Christian Heimes33fe8092008-04-13 13:53:33 +0000525# filters contains a sequence of filter 5-tuples
526# The components of the 5-tuple are:
527# - an action: error, ignore, always, default, module, or once
528# - a compiled regex that must match the warning message
529# - a class representing the warning category
530# - a compiled regex that must match the module that is being warned
531# - a line number for the line being warning, or 0 to mean any line
532# If either if the compiled regexs are None, match anything.
Christian Heimes33fe8092008-04-13 13:53:33 +0000533try:
Brett Cannonef0e6c32010-09-04 18:24:04 +0000534 from _warnings import (filters, _defaultaction, _onceregistry,
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200535 warn, warn_explicit, _filters_mutated)
Brett Cannonef0e6c32010-09-04 18:24:04 +0000536 defaultaction = _defaultaction
537 onceregistry = _onceregistry
Christian Heimes33fe8092008-04-13 13:53:33 +0000538 _warnings_defaults = True
Brett Cannoncd171c82013-07-04 17:43:24 -0400539except ImportError:
Christian Heimes33fe8092008-04-13 13:53:33 +0000540 filters = []
541 defaultaction = "default"
542 onceregistry = {}
543
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200544 _filters_version = 1
545
546 def _filters_mutated():
547 global _filters_version
548 _filters_version += 1
549
Victor Stinner09f3a8a2017-11-20 17:32:40 -0800550 _warnings_defaults = False
551
Christian Heimes33fe8092008-04-13 13:53:33 +0000552
Guido van Rossum2a862c62000-12-15 21:59:53 +0000553# Module initialization
Tim Peters66025202004-03-21 17:06:20 +0000554_processoptions(sys.warnoptions)
Christian Heimes33fe8092008-04-13 13:53:33 +0000555if not _warnings_defaults:
Nick Coghlan9b997472018-01-08 12:45:02 +1000556 # Several warning categories are ignored by default in regular builds
Victor Stinner747f48e2017-12-12 22:59:48 +0100557 if not hasattr(sys, 'gettotalrefcount'):
Nick Coghlan9b997472018-01-08 12:45:02 +1000558 filterwarnings("default", category=DeprecationWarning,
559 module="__main__", append=1)
Victor Stinner747f48e2017-12-12 22:59:48 +0100560 simplefilter("ignore", category=DeprecationWarning, append=1)
561 simplefilter("ignore", category=PendingDeprecationWarning, append=1)
562 simplefilter("ignore", category=ImportWarning, append=1)
563 simplefilter("ignore", category=ResourceWarning, append=1)
Victor Stinner09f3a8a2017-11-20 17:32:40 -0800564
Christian Heimes33fe8092008-04-13 13:53:33 +0000565del _warnings_defaults