blob: b0d53aa0321bacc0ffba88dc6f60cc9cad973a2a [file] [log] [blame]
Guido van Rossum2a862c62000-12-15 21:59:53 +00001"""Python part of the warnings subsystem."""
2
Mark Hammonda43fd0c2003-02-19 00:33:33 +00003# Note: function level imports should *not* be used
4# in this module as it may cause import lock deadlock.
5# See bug 683658.
Mark Hammonda43fd0c2003-02-19 00:33:33 +00006import linecache
Brett Cannone9746892008-04-12 23:44:07 +00007import sys
8import types
Guido van Rossum2a862c62000-12-15 21:59:53 +00009
Brett Cannon01408452014-08-22 10:50:47 -040010__all__ = ["warn", "warn_explicit", "showwarning",
11 "formatwarning", "filterwarnings", "simplefilter",
Brett Cannon672237d2008-09-09 00:49:16 +000012 "resetwarnings", "catch_warnings"]
Skip Montanaro40fc1602001-03-01 04:27:19 +000013
Guido van Rossum2a862c62000-12-15 21:59:53 +000014
Christian Heimes28104c52007-11-27 23:16:44 +000015def warnpy3k(message, category=None, stacklevel=1):
16 """Issue a deprecation warning for Python 3.x related changes.
17
18 Warnings are omitted unless Python is started with the -3 option.
19 """
20 if sys.py3kwarning:
21 if category is None:
22 category = DeprecationWarning
23 warn(message, category, stacklevel+1)
24
Brett Cannon8a232cc2008-05-05 05:32:07 +000025def _show_warning(message, category, filename, lineno, file=None, line=None):
Guido van Rossum2a862c62000-12-15 21:59:53 +000026 """Hook to write a warning to a file; replace if you like."""
27 if file is None:
28 file = sys.stderr
Serhiy Storchakae6b42432014-12-10 23:05:33 +020029 if file is None:
30 # sys.stderr is None - warnings get lost
31 return
Mark Hammond51a0ae32002-09-11 13:22:35 +000032 try:
Brett Cannone9746892008-04-12 23:44:07 +000033 file.write(formatwarning(message, category, filename, lineno, line))
Serhiy Storchakaf40fcb32015-05-16 16:42:18 +030034 except (IOError, UnicodeError):
Mark Hammond51a0ae32002-09-11 13:22:35 +000035 pass # the file (probably stderr) is invalid - this warning gets lost.
Florent Xicluna1f3b4e12010-03-07 12:14:25 +000036# Keep a working version around in case the deprecation of the old API is
Brett Cannon8a232cc2008-05-05 05:32:07 +000037# triggered.
38showwarning = _show_warning
Guido van Rossum2a862c62000-12-15 21:59:53 +000039
Brett Cannone9746892008-04-12 23:44:07 +000040def formatwarning(message, category, filename, lineno, line=None):
Guido van Rossum9464a7d2001-01-14 14:08:40 +000041 """Function to format a warning the standard way."""
Serhiy Storchakaf40fcb32015-05-16 16:42:18 +030042 try:
43 unicodetype = unicode
44 except NameError:
45 unicodetype = ()
46 try:
47 message = str(message)
48 except UnicodeEncodeError:
49 pass
50 s = "%s: %s: %s\n" % (lineno, category.__name__, message)
Brett Cannone9746892008-04-12 23:44:07 +000051 line = linecache.getline(filename, lineno) if line is None else line
Guido van Rossum2a862c62000-12-15 21:59:53 +000052 if line:
Brett Cannone9746892008-04-12 23:44:07 +000053 line = line.strip()
Serhiy Storchakaf40fcb32015-05-16 16:42:18 +030054 if isinstance(s, unicodetype) and isinstance(line, str):
55 line = unicode(line, 'latin1')
Brett Cannone9746892008-04-12 23:44:07 +000056 s += " %s\n" % line
Serhiy Storchakaf40fcb32015-05-16 16:42:18 +030057 if isinstance(s, unicodetype) and isinstance(filename, str):
58 enc = sys.getfilesystemencoding()
59 if enc:
60 try:
61 filename = unicode(filename, enc)
62 except UnicodeDecodeError:
63 pass
64 s = "%s:%s" % (filename, s)
Guido van Rossum2a862c62000-12-15 21:59:53 +000065 return s
66
Guido van Rossum9464a7d2001-01-14 14:08:40 +000067def filterwarnings(action, message="", category=Warning, module="", lineno=0,
68 append=0):
Guido van Rossum2a862c62000-12-15 21:59:53 +000069 """Insert an entry into the list of warnings filters (at the front).
70
Neil Schemenauerd87affe2009-10-23 19:58:17 +000071 'action' -- one of "error", "ignore", "always", "default", "module",
72 or "once"
73 'message' -- a regex that the warning message must match
74 'category' -- a class that the warning must be a subclass of
75 'module' -- a regex that the module name must match
76 'lineno' -- an integer line number, 0 matches all warnings
77 'append' -- if true, append to the list of filters
78 """
Skip Montanarod8f21202003-05-14 17:33:53 +000079 import re
Guido van Rossum2a862c62000-12-15 21:59:53 +000080 assert action in ("error", "ignore", "always", "default", "module",
Walter Dörwald70a6b492004-02-12 17:35:32 +000081 "once"), "invalid action: %r" % (action,)
Martin v. Löwisff9284b2002-10-14 21:06:02 +000082 assert isinstance(message, basestring), "message must be a string"
Brett Cannonbf364092006-03-01 04:25:17 +000083 assert isinstance(category, (type, types.ClassType)), \
84 "category must be a class"
Guido van Rossum2a862c62000-12-15 21:59:53 +000085 assert issubclass(category, Warning), "category must be a Warning subclass"
Martin v. Löwisff9284b2002-10-14 21:06:02 +000086 assert isinstance(module, basestring), "module must be a string"
Walter Dörwald65230a22002-06-03 15:58:32 +000087 assert isinstance(lineno, int) and lineno >= 0, \
Guido van Rossum2a862c62000-12-15 21:59:53 +000088 "lineno must be an int >= 0"
Guido van Rossum9464a7d2001-01-14 14:08:40 +000089 item = (action, re.compile(message, re.I), category,
90 re.compile(module), lineno)
91 if append:
92 filters.append(item)
93 else:
94 filters.insert(0, item)
Guido van Rossum2a862c62000-12-15 21:59:53 +000095
Jeremy Hylton85014662003-07-11 15:37:59 +000096def simplefilter(action, category=Warning, lineno=0, append=0):
97 """Insert a simple entry into the list of warnings filters (at the front).
98
99 A simple filter matches all modules and messages.
Neil Schemenauerd87affe2009-10-23 19:58:17 +0000100 'action' -- one of "error", "ignore", "always", "default", "module",
101 or "once"
102 'category' -- a class that the warning must be a subclass of
103 'lineno' -- an integer line number, 0 matches all warnings
104 'append' -- if true, append to the list of filters
Jeremy Hylton85014662003-07-11 15:37:59 +0000105 """
106 assert action in ("error", "ignore", "always", "default", "module",
Walter Dörwald70a6b492004-02-12 17:35:32 +0000107 "once"), "invalid action: %r" % (action,)
Jeremy Hylton85014662003-07-11 15:37:59 +0000108 assert isinstance(lineno, int) and lineno >= 0, \
109 "lineno must be an int >= 0"
110 item = (action, None, category, None, lineno)
111 if append:
112 filters.append(item)
113 else:
114 filters.insert(0, item)
115
Guido van Rossum2a862c62000-12-15 21:59:53 +0000116def resetwarnings():
Tim Petersd0cc4f02002-04-16 01:51:25 +0000117 """Clear the list of warning filters, so that no filters are active."""
Guido van Rossum2a862c62000-12-15 21:59:53 +0000118 filters[:] = []
119
120class _OptionError(Exception):
121 """Exception used by option processing helpers."""
122 pass
123
124# Helper to process -W options passed via sys.warnoptions
125def _processoptions(args):
126 for arg in args:
127 try:
128 _setoption(arg)
129 except _OptionError, msg:
130 print >>sys.stderr, "Invalid -W option ignored:", msg
131
132# Helper for _processoptions()
133def _setoption(arg):
Skip Montanarod8f21202003-05-14 17:33:53 +0000134 import re
Tim Peterse1190062001-01-15 03:34:38 +0000135 parts = arg.split(':')
136 if len(parts) > 5:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000137 raise _OptionError("too many fields (max 5): %r" % (arg,))
Tim Peterse1190062001-01-15 03:34:38 +0000138 while len(parts) < 5:
139 parts.append('')
140 action, message, category, module, lineno = [s.strip()
141 for s in parts]
142 action = _getaction(action)
143 message = re.escape(message)
144 category = _getcategory(category)
145 module = re.escape(module)
146 if module:
147 module = module + '$'
148 if lineno:
149 try:
150 lineno = int(lineno)
151 if lineno < 0:
152 raise ValueError
153 except (ValueError, OverflowError):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000154 raise _OptionError("invalid lineno %r" % (lineno,))
Tim Peterse1190062001-01-15 03:34:38 +0000155 else:
156 lineno = 0
157 filterwarnings(action, message, category, module, lineno)
Guido van Rossum2a862c62000-12-15 21:59:53 +0000158
159# Helper for _setoption()
160def _getaction(action):
161 if not action:
162 return "default"
163 if action == "all": return "always" # Alias
Raymond Hettingerdbecd932005-02-06 06:57:08 +0000164 for a in ('default', 'always', 'ignore', 'module', 'once', 'error'):
Guido van Rossum2a862c62000-12-15 21:59:53 +0000165 if a.startswith(action):
166 return a
Walter Dörwald70a6b492004-02-12 17:35:32 +0000167 raise _OptionError("invalid action: %r" % (action,))
Guido van Rossum2a862c62000-12-15 21:59:53 +0000168
169# Helper for _setoption()
170def _getcategory(category):
Skip Montanarod8f21202003-05-14 17:33:53 +0000171 import re
Guido van Rossum2a862c62000-12-15 21:59:53 +0000172 if not category:
173 return Warning
174 if re.match("^[a-zA-Z0-9_]+$", category):
175 try:
176 cat = eval(category)
Guido van Rossumd1db30b2000-12-19 03:04:50 +0000177 except NameError:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000178 raise _OptionError("unknown warning category: %r" % (category,))
Guido van Rossum2a862c62000-12-15 21:59:53 +0000179 else:
180 i = category.rfind(".")
181 module = category[:i]
182 klass = category[i+1:]
Guido van Rossumd1db30b2000-12-19 03:04:50 +0000183 try:
184 m = __import__(module, None, None, [klass])
185 except ImportError:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000186 raise _OptionError("invalid module name: %r" % (module,))
Guido van Rossumd1db30b2000-12-19 03:04:50 +0000187 try:
188 cat = getattr(m, klass)
189 except AttributeError:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000190 raise _OptionError("unknown warning category: %r" % (category,))
Brett Cannon53ab5b72006-06-22 16:49:14 +0000191 if not issubclass(cat, Warning):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000192 raise _OptionError("invalid warning category: %r" % (category,))
Guido van Rossum2a862c62000-12-15 21:59:53 +0000193 return cat
194
Brett Cannone9746892008-04-12 23:44:07 +0000195
196# Code typically replaced by _warnings
197def warn(message, category=None, stacklevel=1):
198 """Issue a warning, or maybe ignore it or raise an exception."""
199 # Check if message is already a Warning object
200 if isinstance(message, Warning):
201 category = message.__class__
202 # Check category argument
203 if category is None:
204 category = UserWarning
205 assert issubclass(category, Warning)
206 # Get context information
207 try:
208 caller = sys._getframe(stacklevel)
209 except ValueError:
210 globals = sys.__dict__
211 lineno = 1
212 else:
213 globals = caller.f_globals
214 lineno = caller.f_lineno
215 if '__name__' in globals:
216 module = globals['__name__']
217 else:
218 module = "<string>"
219 filename = globals.get('__file__')
220 if filename:
221 fnl = filename.lower()
222 if fnl.endswith((".pyc", ".pyo")):
223 filename = filename[:-1]
224 else:
225 if module == "__main__":
226 try:
227 filename = sys.argv[0]
228 except AttributeError:
229 # embedded interpreters don't have sys.argv, see bug #839151
230 filename = '__main__'
231 if not filename:
232 filename = module
233 registry = globals.setdefault("__warningregistry__", {})
234 warn_explicit(message, category, filename, lineno, module, registry,
235 globals)
236
237def warn_explicit(message, category, filename, lineno,
238 module=None, registry=None, module_globals=None):
Brett Cannondea1b562008-06-27 00:31:13 +0000239 lineno = int(lineno)
Brett Cannone9746892008-04-12 23:44:07 +0000240 if module is None:
241 module = filename or "<unknown>"
242 if module[-3:].lower() == ".py":
243 module = module[:-3] # XXX What about leading pathname?
244 if registry is None:
245 registry = {}
246 if isinstance(message, Warning):
247 text = str(message)
248 category = message.__class__
249 else:
250 text = message
251 message = category(message)
252 key = (text, category, lineno)
253 # Quick test for common case
254 if registry.get(key):
255 return
256 # Search the filters
257 for item in filters:
258 action, msg, cat, mod, ln = item
259 if ((msg is None or msg.match(text)) and
260 issubclass(category, cat) and
261 (mod is None or mod.match(module)) and
262 (ln == 0 or lineno == ln)):
263 break
264 else:
265 action = defaultaction
266 # Early exit actions
267 if action == "ignore":
268 registry[key] = 1
269 return
270
271 # Prime the linecache for formatting, in case the
272 # "file" is actually in a zipfile or something.
273 linecache.getlines(filename, module_globals)
274
275 if action == "error":
276 raise message
277 # Other actions
278 if action == "once":
279 registry[key] = 1
280 oncekey = (text, category)
281 if onceregistry.get(oncekey):
282 return
283 onceregistry[oncekey] = 1
284 elif action == "always":
285 pass
286 elif action == "module":
287 registry[key] = 1
288 altkey = (text, category, 0)
289 if registry.get(altkey):
290 return
291 registry[altkey] = 1
292 elif action == "default":
293 registry[key] = 1
294 else:
295 # Unrecognized actions are errors
296 raise RuntimeError(
297 "Unrecognized action (%r) in warnings.filters:\n %s" %
298 (action, item))
Brett Cannon9c19bc62008-05-05 16:57:38 +0000299 # Print message and context
Brett Cannone9746892008-04-12 23:44:07 +0000300 showwarning(message, category, filename, lineno)
301
302
Brett Cannon1eaf0742008-09-02 01:25:16 +0000303class WarningMessage(object):
304
305 """Holds the result of a single showwarning() call."""
306
307 _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file",
308 "line")
309
310 def __init__(self, message, category, filename, lineno, file=None,
311 line=None):
312 local_values = locals()
313 for attr in self._WARNING_DETAILS:
314 setattr(self, attr, local_values[attr])
315 self._category_name = category.__name__ if category else None
316
317 def __str__(self):
318 return ("{message : %r, category : %r, filename : %r, lineno : %s, "
319 "line : %r}" % (self.message, self._category_name,
320 self.filename, self.lineno, self.line))
321
322
Brett Cannon1eaf0742008-09-02 01:25:16 +0000323class catch_warnings(object):
324
Brett Cannon672237d2008-09-09 00:49:16 +0000325 """A context manager that copies and restores the warnings filter upon
326 exiting the context.
Brett Cannon1eaf0742008-09-02 01:25:16 +0000327
Brett Cannon672237d2008-09-09 00:49:16 +0000328 The 'record' argument specifies whether warnings should be captured by a
329 custom implementation of warnings.showwarning() and be appended to a list
330 returned by the context manager. Otherwise None is returned by the context
331 manager. The objects appended to the list are arguments whose attributes
332 mirror the arguments to showwarning().
333
334 The 'module' argument is to specify an alternative module to the module
335 named 'warnings' and imported under that name. This argument is only useful
336 when testing the warnings module itself.
Brett Cannon1eaf0742008-09-02 01:25:16 +0000337
338 """
339
340 def __init__(self, record=False, module=None):
341 """Specify whether to record warnings and if an alternative module
342 should be used other than sys.modules['warnings'].
343
344 For compatibility with Python 3.0, please consider all arguments to be
345 keyword-only.
346
347 """
Brett Cannon672237d2008-09-09 00:49:16 +0000348 self._record = record
Brett Cannon1eaf0742008-09-02 01:25:16 +0000349 self._module = sys.modules['warnings'] if module is None else module
Nick Coghland2e09382008-09-11 12:11:06 +0000350 self._entered = False
351
352 def __repr__(self):
353 args = []
354 if self._record:
355 args.append("record=True")
356 if self._module is not sys.modules['warnings']:
357 args.append("module=%r" % self._module)
358 name = type(self).__name__
359 return "%s(%s)" % (name, ", ".join(args))
Brett Cannon1eaf0742008-09-02 01:25:16 +0000360
361 def __enter__(self):
Nick Coghland2e09382008-09-11 12:11:06 +0000362 if self._entered:
363 raise RuntimeError("Cannot enter %r twice" % self)
364 self._entered = True
Brett Cannon1eaf0742008-09-02 01:25:16 +0000365 self._filters = self._module.filters
366 self._module.filters = self._filters[:]
367 self._showwarning = self._module.showwarning
Brett Cannon672237d2008-09-09 00:49:16 +0000368 if self._record:
369 log = []
370 def showwarning(*args, **kwargs):
371 log.append(WarningMessage(*args, **kwargs))
372 self._module.showwarning = showwarning
373 return log
374 else:
375 return None
Brett Cannon1eaf0742008-09-02 01:25:16 +0000376
377 def __exit__(self, *exc_info):
Nick Coghland2e09382008-09-11 12:11:06 +0000378 if not self._entered:
379 raise RuntimeError("Cannot exit %r without entering first" % self)
Brett Cannon1eaf0742008-09-02 01:25:16 +0000380 self._module.filters = self._filters
381 self._module.showwarning = self._showwarning
382
383
Brett Cannone9746892008-04-12 23:44:07 +0000384# filters contains a sequence of filter 5-tuples
385# The components of the 5-tuple are:
386# - an action: error, ignore, always, default, module, or once
387# - a compiled regex that must match the warning message
388# - a class representing the warning category
389# - a compiled regex that must match the module that is being warned
390# - a line number for the line being warning, or 0 to mean any line
391# If either if the compiled regexs are None, match anything.
392_warnings_defaults = False
393try:
394 from _warnings import (filters, default_action, once_registry,
395 warn, warn_explicit)
396 defaultaction = default_action
397 onceregistry = once_registry
398 _warnings_defaults = True
399except ImportError:
400 filters = []
401 defaultaction = "default"
402 onceregistry = {}
403
404
Guido van Rossum2a862c62000-12-15 21:59:53 +0000405# Module initialization
Tim Peters66025202004-03-21 17:06:20 +0000406_processoptions(sys.warnoptions)
Brett Cannone9746892008-04-12 23:44:07 +0000407if not _warnings_defaults:
Brett Cannon3ffa43d2010-01-14 20:00:28 +0000408 silence = [ImportWarning, PendingDeprecationWarning]
Brett Cannon19949692010-04-25 22:33:36 +0000409 # Don't silence DeprecationWarning if -3 or -Q was used.
410 if not sys.py3kwarning and not sys.flags.division_warning:
Brett Cannon3ffa43d2010-01-14 20:00:28 +0000411 silence.append(DeprecationWarning)
412 for cls in silence:
413 simplefilter("ignore", category=cls)
Brett Cannone9746892008-04-12 23:44:07 +0000414 bytes_warning = sys.flags.bytes_warning
415 if bytes_warning > 1:
416 bytes_action = "error"
417 elif bytes_warning:
418 bytes_action = "default"
419 else:
420 bytes_action = "ignore"
421 simplefilter(bytes_action, category=BytesWarning, append=1)
422del _warnings_defaults