blob: 00f740ca3a95baaeca5b50a4810c59e956d7629f [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 Stinner2c07c492018-11-13 02:41:00 +010036 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
Victor Stinner2c07c492018-11-13 02:41:00 +010057 # 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:
Victor Stinner2c07c492018-11-13 02:41:00 +010060 # don't suggest to enable tracemalloc if it's not available
61 tracing = True
Victor Stinnere091d322016-03-25 00:33:12 +010062 tb = None
Victor Stinner2c07c492018-11-13 02:41:00 +010063 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
Victor Stinner2c07c492018-11-13 02:41:00 +010088 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,
Xtreakbe7c4602019-03-01 22:47:55 +0530127 msg.filename, msg.lineno, 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__
Thomas Kluyver11a89662018-06-08 21:28:37 +0200317 filename = "sys"
Christian Heimes33fe8092008-04-13 13:53:33 +0000318 lineno = 1
319 else:
Larry Hastings714e4932015-09-06 00:39:37 -0700320 globals = frame.f_globals
Thomas Kluyver11a89662018-06-08 21:28:37 +0200321 filename = frame.f_code.co_filename
Larry Hastings714e4932015-09-06 00:39:37 -0700322 lineno = frame.f_lineno
Christian Heimes33fe8092008-04-13 13:53:33 +0000323 if '__name__' in globals:
324 module = globals['__name__']
325 else:
326 module = "<string>"
Christian Heimes33fe8092008-04-13 13:53:33 +0000327 registry = globals.setdefault("__warningregistry__", {})
328 warn_explicit(message, category, filename, lineno, module, registry,
Victor Stinnere19558a2016-03-23 00:28:08 +0100329 globals, source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000330
331def warn_explicit(message, category, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100332 module=None, registry=None, module_globals=None,
333 source=None):
Brett Cannondb734912008-06-27 00:52:15 +0000334 lineno = int(lineno)
Christian Heimes33fe8092008-04-13 13:53:33 +0000335 if module is None:
336 module = filename or "<unknown>"
337 if module[-3:].lower() == ".py":
338 module = module[:-3] # XXX What about leading pathname?
339 if registry is None:
340 registry = {}
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200341 if registry.get('version', 0) != _filters_version:
342 registry.clear()
343 registry['version'] = _filters_version
Christian Heimes33fe8092008-04-13 13:53:33 +0000344 if isinstance(message, Warning):
345 text = str(message)
346 category = message.__class__
347 else:
348 text = message
349 message = category(message)
350 key = (text, category, lineno)
351 # Quick test for common case
352 if registry.get(key):
353 return
354 # Search the filters
355 for item in filters:
356 action, msg, cat, mod, ln = item
357 if ((msg is None or msg.match(text)) and
358 issubclass(category, cat) and
359 (mod is None or mod.match(module)) and
360 (ln == 0 or lineno == ln)):
361 break
362 else:
363 action = defaultaction
364 # Early exit actions
365 if action == "ignore":
Christian Heimes33fe8092008-04-13 13:53:33 +0000366 return
367
368 # Prime the linecache for formatting, in case the
369 # "file" is actually in a zipfile or something.
Antoine Pitrou7cb11fa2013-10-24 22:23:42 +0200370 import linecache
Christian Heimes33fe8092008-04-13 13:53:33 +0000371 linecache.getlines(filename, module_globals)
372
373 if action == "error":
374 raise message
375 # Other actions
376 if action == "once":
377 registry[key] = 1
378 oncekey = (text, category)
379 if onceregistry.get(oncekey):
380 return
381 onceregistry[oncekey] = 1
382 elif action == "always":
383 pass
384 elif action == "module":
385 registry[key] = 1
386 altkey = (text, category, 0)
387 if registry.get(altkey):
388 return
389 registry[altkey] = 1
390 elif action == "default":
391 registry[key] = 1
392 else:
393 # Unrecognized actions are errors
394 raise RuntimeError(
395 "Unrecognized action (%r) in warnings.filters:\n %s" %
396 (action, item))
397 # Print message and context
Victor Stinner914cde82016-03-19 01:03:51 +0100398 msg = WarningMessage(message, category, filename, lineno, source)
Victor Stinner1231a462016-03-19 00:47:17 +0100399 _showwarnmsg(msg)
Christian Heimes33fe8092008-04-13 13:53:33 +0000400
401
Brett Cannonec92e182008-09-02 02:46:59 +0000402class WarningMessage(object):
403
Brett Cannonec92e182008-09-02 02:46:59 +0000404 _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file",
Victor Stinner914cde82016-03-19 01:03:51 +0100405 "line", "source")
Brett Cannonec92e182008-09-02 02:46:59 +0000406
407 def __init__(self, message, category, filename, lineno, file=None,
Victor Stinner914cde82016-03-19 01:03:51 +0100408 line=None, source=None):
Alex Gaynor5de3a642017-06-04 11:34:16 -0400409 self.message = message
410 self.category = category
411 self.filename = filename
412 self.lineno = lineno
413 self.file = file
414 self.line = line
415 self.source = source
Brett Cannonec92e182008-09-02 02:46:59 +0000416 self._category_name = category.__name__ if category else None
417
418 def __str__(self):
419 return ("{message : %r, category : %r, filename : %r, lineno : %s, "
420 "line : %r}" % (self.message, self._category_name,
421 self.filename, self.lineno, self.line))
422
423
Brett Cannonec92e182008-09-02 02:46:59 +0000424class catch_warnings(object):
425
Brett Cannon1cd02472008-09-09 01:52:27 +0000426 """A context manager that copies and restores the warnings filter upon
427 exiting the context.
Brett Cannonec92e182008-09-02 02:46:59 +0000428
Brett Cannon1cd02472008-09-09 01:52:27 +0000429 The 'record' argument specifies whether warnings should be captured by a
430 custom implementation of warnings.showwarning() and be appended to a list
431 returned by the context manager. Otherwise None is returned by the context
432 manager. The objects appended to the list are arguments whose attributes
433 mirror the arguments to showwarning().
434
435 The 'module' argument is to specify an alternative module to the module
436 named 'warnings' and imported under that name. This argument is only useful
437 when testing the warnings module itself.
Brett Cannonec92e182008-09-02 02:46:59 +0000438
439 """
440
441 def __init__(self, *, record=False, module=None):
442 """Specify whether to record warnings and if an alternative module
443 should be used other than sys.modules['warnings'].
444
445 For compatibility with Python 3.0, please consider all arguments to be
446 keyword-only.
447
448 """
Brett Cannon1cd02472008-09-09 01:52:27 +0000449 self._record = record
Brett Cannonec92e182008-09-02 02:46:59 +0000450 self._module = sys.modules['warnings'] if module is None else module
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000451 self._entered = False
452
453 def __repr__(self):
454 args = []
455 if self._record:
456 args.append("record=True")
457 if self._module is not sys.modules['warnings']:
458 args.append("module=%r" % self._module)
459 name = type(self).__name__
460 return "%s(%s)" % (name, ", ".join(args))
Brett Cannonec92e182008-09-02 02:46:59 +0000461
462 def __enter__(self):
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000463 if self._entered:
464 raise RuntimeError("Cannot enter %r twice" % self)
465 self._entered = True
Brett Cannonec92e182008-09-02 02:46:59 +0000466 self._filters = self._module.filters
467 self._module.filters = self._filters[:]
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200468 self._module._filters_mutated()
Brett Cannonec92e182008-09-02 02:46:59 +0000469 self._showwarning = self._module.showwarning
Victor Stinner8ef46be2016-12-06 10:53:52 +0100470 self._showwarnmsg_impl = self._module._showwarnmsg_impl
Brett Cannon1cd02472008-09-09 01:52:27 +0000471 if self._record:
472 log = []
Ned Deilyc1c32922016-12-06 17:12:47 -0500473 self._module._showwarnmsg_impl = log.append
Victor Stinner8ef46be2016-12-06 10:53:52 +0100474 # Reset showwarning() to the default implementation to make sure
475 # that _showwarnmsg() calls _showwarnmsg_impl()
Ned Deilyc1c32922016-12-06 17:12:47 -0500476 self._module.showwarning = self._module._showwarning_orig
Brett Cannon1cd02472008-09-09 01:52:27 +0000477 return log
478 else:
479 return None
Brett Cannonec92e182008-09-02 02:46:59 +0000480
481 def __exit__(self, *exc_info):
Benjamin Petersonfcf5d632008-10-16 23:24:44 +0000482 if not self._entered:
483 raise RuntimeError("Cannot exit %r without entering first" % self)
Brett Cannonec92e182008-09-02 02:46:59 +0000484 self._module.filters = self._filters
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200485 self._module._filters_mutated()
Brett Cannonec92e182008-09-02 02:46:59 +0000486 self._module.showwarning = self._showwarning
Victor Stinner8ef46be2016-12-06 10:53:52 +0100487 self._module._showwarnmsg_impl = self._showwarnmsg_impl
Brett Cannonec92e182008-09-02 02:46:59 +0000488
489
Nathaniel J. Smithfc2f4072018-01-21 06:44:07 -0800490# Private utility function called by _PyErr_WarnUnawaitedCoroutine
491def _warn_unawaited_coroutine(coro):
492 msg_lines = [
493 f"coroutine '{coro.__qualname__}' was never awaited\n"
494 ]
495 if coro.cr_origin is not None:
496 import linecache, traceback
497 def extract():
498 for filename, lineno, funcname in reversed(coro.cr_origin):
499 line = linecache.getline(filename, lineno)
500 yield (filename, lineno, funcname, line)
501 msg_lines.append("Coroutine created at (most recent call last)\n")
502 msg_lines += traceback.format_list(list(extract()))
503 msg = "".join(msg_lines).rstrip("\n")
504 # Passing source= here means that if the user happens to have tracemalloc
505 # enabled and tracking where the coroutine was created, the warning will
506 # contain that traceback. This does mean that if they have *both*
507 # coroutine origin tracking *and* tracemalloc enabled, they'll get two
508 # partially-redundant tracebacks. If we wanted to be clever we could
509 # probably detect this case and avoid it, but for now we don't bother.
510 warn(msg, category=RuntimeWarning, stacklevel=2, source=coro)
511
512
Christian Heimes33fe8092008-04-13 13:53:33 +0000513# filters contains a sequence of filter 5-tuples
514# The components of the 5-tuple are:
515# - an action: error, ignore, always, default, module, or once
516# - a compiled regex that must match the warning message
517# - a class representing the warning category
518# - a compiled regex that must match the module that is being warned
519# - a line number for the line being warning, or 0 to mean any line
520# If either if the compiled regexs are None, match anything.
Christian Heimes33fe8092008-04-13 13:53:33 +0000521try:
Brett Cannonef0e6c32010-09-04 18:24:04 +0000522 from _warnings import (filters, _defaultaction, _onceregistry,
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200523 warn, warn_explicit, _filters_mutated)
Brett Cannonef0e6c32010-09-04 18:24:04 +0000524 defaultaction = _defaultaction
525 onceregistry = _onceregistry
Christian Heimes33fe8092008-04-13 13:53:33 +0000526 _warnings_defaults = True
Brett Cannoncd171c82013-07-04 17:43:24 -0400527except ImportError:
Christian Heimes33fe8092008-04-13 13:53:33 +0000528 filters = []
529 defaultaction = "default"
530 onceregistry = {}
531
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200532 _filters_version = 1
533
534 def _filters_mutated():
535 global _filters_version
536 _filters_version += 1
537
Victor Stinner09f3a8a2017-11-20 17:32:40 -0800538 _warnings_defaults = False
539
Christian Heimes33fe8092008-04-13 13:53:33 +0000540
Guido van Rossum2a862c62000-12-15 21:59:53 +0000541# Module initialization
Tim Peters66025202004-03-21 17:06:20 +0000542_processoptions(sys.warnoptions)
Christian Heimes33fe8092008-04-13 13:53:33 +0000543if not _warnings_defaults:
Nick Coghlan9b997472018-01-08 12:45:02 +1000544 # Several warning categories are ignored by default in regular builds
Victor Stinner747f48e2017-12-12 22:59:48 +0100545 if not hasattr(sys, 'gettotalrefcount'):
Nick Coghlan9b997472018-01-08 12:45:02 +1000546 filterwarnings("default", category=DeprecationWarning,
547 module="__main__", append=1)
Victor Stinner747f48e2017-12-12 22:59:48 +0100548 simplefilter("ignore", category=DeprecationWarning, append=1)
549 simplefilter("ignore", category=PendingDeprecationWarning, append=1)
550 simplefilter("ignore", category=ImportWarning, append=1)
551 simplefilter("ignore", category=ResourceWarning, append=1)
Victor Stinner09f3a8a2017-11-20 17:32:40 -0800552
Christian Heimes33fe8092008-04-13 13:53:33 +0000553del _warnings_defaults