blob: 3c7357baf0c116ae91cb9e99bc7cb322afa463d3 [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
Skip Montanaro40fc1602001-03-01 04:27:19 +000010__all__ = ["warn", "showwarning", "formatwarning", "filterwarnings",
11 "resetwarnings"]
12
Guido van Rossum2a862c62000-12-15 21:59:53 +000013
Christian Heimes28104c52007-11-27 23:16:44 +000014def warnpy3k(message, category=None, stacklevel=1):
15 """Issue a deprecation warning for Python 3.x related changes.
16
17 Warnings are omitted unless Python is started with the -3 option.
18 """
19 if sys.py3kwarning:
20 if category is None:
21 category = DeprecationWarning
22 warn(message, category, stacklevel+1)
23
Brett Cannone9746892008-04-12 23:44:07 +000024def showwarning(message, category, filename, lineno, file=None, line=None):
Guido van Rossum2a862c62000-12-15 21:59:53 +000025 """Hook to write a warning to a file; replace if you like."""
26 if file is None:
27 file = sys.stderr
Mark Hammond51a0ae32002-09-11 13:22:35 +000028 try:
Brett Cannone9746892008-04-12 23:44:07 +000029 file.write(formatwarning(message, category, filename, lineno, line))
Mark Hammond51a0ae32002-09-11 13:22:35 +000030 except IOError:
31 pass # the file (probably stderr) is invalid - this warning gets lost.
Guido van Rossum2a862c62000-12-15 21:59:53 +000032
Brett Cannone9746892008-04-12 23:44:07 +000033def formatwarning(message, category, filename, lineno, line=None):
Guido van Rossum9464a7d2001-01-14 14:08:40 +000034 """Function to format a warning the standard way."""
Guido van Rossum2a862c62000-12-15 21:59:53 +000035 s = "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message)
Brett Cannone9746892008-04-12 23:44:07 +000036 line = linecache.getline(filename, lineno) if line is None else line
Guido van Rossum2a862c62000-12-15 21:59:53 +000037 if line:
Brett Cannone9746892008-04-12 23:44:07 +000038 line = line.strip()
39 s += " %s\n" % line
Guido van Rossum2a862c62000-12-15 21:59:53 +000040 return s
41
Guido van Rossum9464a7d2001-01-14 14:08:40 +000042def filterwarnings(action, message="", category=Warning, module="", lineno=0,
43 append=0):
Guido van Rossum2a862c62000-12-15 21:59:53 +000044 """Insert an entry into the list of warnings filters (at the front).
45
46 Use assertions to check that all arguments have the right type."""
Skip Montanarod8f21202003-05-14 17:33:53 +000047 import re
Guido van Rossum2a862c62000-12-15 21:59:53 +000048 assert action in ("error", "ignore", "always", "default", "module",
Walter Dörwald70a6b492004-02-12 17:35:32 +000049 "once"), "invalid action: %r" % (action,)
Martin v. Löwisff9284b2002-10-14 21:06:02 +000050 assert isinstance(message, basestring), "message must be a string"
Brett Cannonbf364092006-03-01 04:25:17 +000051 assert isinstance(category, (type, types.ClassType)), \
52 "category must be a class"
Guido van Rossum2a862c62000-12-15 21:59:53 +000053 assert issubclass(category, Warning), "category must be a Warning subclass"
Martin v. Löwisff9284b2002-10-14 21:06:02 +000054 assert isinstance(module, basestring), "module must be a string"
Walter Dörwald65230a22002-06-03 15:58:32 +000055 assert isinstance(lineno, int) and lineno >= 0, \
Guido van Rossum2a862c62000-12-15 21:59:53 +000056 "lineno must be an int >= 0"
Guido van Rossum9464a7d2001-01-14 14:08:40 +000057 item = (action, re.compile(message, re.I), category,
58 re.compile(module), lineno)
59 if append:
60 filters.append(item)
61 else:
62 filters.insert(0, item)
Guido van Rossum2a862c62000-12-15 21:59:53 +000063
Jeremy Hylton85014662003-07-11 15:37:59 +000064def simplefilter(action, category=Warning, lineno=0, append=0):
65 """Insert a simple entry into the list of warnings filters (at the front).
66
67 A simple filter matches all modules and messages.
68 """
69 assert action in ("error", "ignore", "always", "default", "module",
Walter Dörwald70a6b492004-02-12 17:35:32 +000070 "once"), "invalid action: %r" % (action,)
Jeremy Hylton85014662003-07-11 15:37:59 +000071 assert isinstance(lineno, int) and lineno >= 0, \
72 "lineno must be an int >= 0"
73 item = (action, None, category, None, lineno)
74 if append:
75 filters.append(item)
76 else:
77 filters.insert(0, item)
78
Guido van Rossum2a862c62000-12-15 21:59:53 +000079def resetwarnings():
Tim Petersd0cc4f02002-04-16 01:51:25 +000080 """Clear the list of warning filters, so that no filters are active."""
Guido van Rossum2a862c62000-12-15 21:59:53 +000081 filters[:] = []
82
83class _OptionError(Exception):
84 """Exception used by option processing helpers."""
85 pass
86
87# Helper to process -W options passed via sys.warnoptions
88def _processoptions(args):
89 for arg in args:
90 try:
91 _setoption(arg)
92 except _OptionError, msg:
93 print >>sys.stderr, "Invalid -W option ignored:", msg
94
95# Helper for _processoptions()
96def _setoption(arg):
Skip Montanarod8f21202003-05-14 17:33:53 +000097 import re
Tim Peterse1190062001-01-15 03:34:38 +000098 parts = arg.split(':')
99 if len(parts) > 5:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000100 raise _OptionError("too many fields (max 5): %r" % (arg,))
Tim Peterse1190062001-01-15 03:34:38 +0000101 while len(parts) < 5:
102 parts.append('')
103 action, message, category, module, lineno = [s.strip()
104 for s in parts]
105 action = _getaction(action)
106 message = re.escape(message)
107 category = _getcategory(category)
108 module = re.escape(module)
109 if module:
110 module = module + '$'
111 if lineno:
112 try:
113 lineno = int(lineno)
114 if lineno < 0:
115 raise ValueError
116 except (ValueError, OverflowError):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000117 raise _OptionError("invalid lineno %r" % (lineno,))
Tim Peterse1190062001-01-15 03:34:38 +0000118 else:
119 lineno = 0
120 filterwarnings(action, message, category, module, lineno)
Guido van Rossum2a862c62000-12-15 21:59:53 +0000121
122# Helper for _setoption()
123def _getaction(action):
124 if not action:
125 return "default"
126 if action == "all": return "always" # Alias
Raymond Hettingerdbecd932005-02-06 06:57:08 +0000127 for a in ('default', 'always', 'ignore', 'module', 'once', 'error'):
Guido van Rossum2a862c62000-12-15 21:59:53 +0000128 if a.startswith(action):
129 return a
Walter Dörwald70a6b492004-02-12 17:35:32 +0000130 raise _OptionError("invalid action: %r" % (action,))
Guido van Rossum2a862c62000-12-15 21:59:53 +0000131
132# Helper for _setoption()
133def _getcategory(category):
Skip Montanarod8f21202003-05-14 17:33:53 +0000134 import re
Guido van Rossum2a862c62000-12-15 21:59:53 +0000135 if not category:
136 return Warning
137 if re.match("^[a-zA-Z0-9_]+$", category):
138 try:
139 cat = eval(category)
Guido van Rossumd1db30b2000-12-19 03:04:50 +0000140 except NameError:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000141 raise _OptionError("unknown warning category: %r" % (category,))
Guido van Rossum2a862c62000-12-15 21:59:53 +0000142 else:
143 i = category.rfind(".")
144 module = category[:i]
145 klass = category[i+1:]
Guido van Rossumd1db30b2000-12-19 03:04:50 +0000146 try:
147 m = __import__(module, None, None, [klass])
148 except ImportError:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000149 raise _OptionError("invalid module name: %r" % (module,))
Guido van Rossumd1db30b2000-12-19 03:04:50 +0000150 try:
151 cat = getattr(m, klass)
152 except AttributeError:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000153 raise _OptionError("unknown warning category: %r" % (category,))
Brett Cannon53ab5b72006-06-22 16:49:14 +0000154 if not issubclass(cat, Warning):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000155 raise _OptionError("invalid warning category: %r" % (category,))
Guido van Rossum2a862c62000-12-15 21:59:53 +0000156 return cat
157
Brett Cannone9746892008-04-12 23:44:07 +0000158
159# Code typically replaced by _warnings
160def warn(message, category=None, stacklevel=1):
161 """Issue a warning, or maybe ignore it or raise an exception."""
162 # Check if message is already a Warning object
163 if isinstance(message, Warning):
164 category = message.__class__
165 # Check category argument
166 if category is None:
167 category = UserWarning
168 assert issubclass(category, Warning)
169 # Get context information
170 try:
171 caller = sys._getframe(stacklevel)
172 except ValueError:
173 globals = sys.__dict__
174 lineno = 1
175 else:
176 globals = caller.f_globals
177 lineno = caller.f_lineno
178 if '__name__' in globals:
179 module = globals['__name__']
180 else:
181 module = "<string>"
182 filename = globals.get('__file__')
183 if filename:
184 fnl = filename.lower()
185 if fnl.endswith((".pyc", ".pyo")):
186 filename = filename[:-1]
187 else:
188 if module == "__main__":
189 try:
190 filename = sys.argv[0]
191 except AttributeError:
192 # embedded interpreters don't have sys.argv, see bug #839151
193 filename = '__main__'
194 if not filename:
195 filename = module
196 registry = globals.setdefault("__warningregistry__", {})
197 warn_explicit(message, category, filename, lineno, module, registry,
198 globals)
199
200def warn_explicit(message, category, filename, lineno,
201 module=None, registry=None, module_globals=None):
202 if module is None:
203 module = filename or "<unknown>"
204 if module[-3:].lower() == ".py":
205 module = module[:-3] # XXX What about leading pathname?
206 if registry is None:
207 registry = {}
208 if isinstance(message, Warning):
209 text = str(message)
210 category = message.__class__
211 else:
212 text = message
213 message = category(message)
214 key = (text, category, lineno)
215 # Quick test for common case
216 if registry.get(key):
217 return
218 # Search the filters
219 for item in filters:
220 action, msg, cat, mod, ln = item
221 if ((msg is None or msg.match(text)) and
222 issubclass(category, cat) and
223 (mod is None or mod.match(module)) and
224 (ln == 0 or lineno == ln)):
225 break
226 else:
227 action = defaultaction
228 # Early exit actions
229 if action == "ignore":
230 registry[key] = 1
231 return
232
233 # Prime the linecache for formatting, in case the
234 # "file" is actually in a zipfile or something.
235 linecache.getlines(filename, module_globals)
236
237 if action == "error":
238 raise message
239 # Other actions
240 if action == "once":
241 registry[key] = 1
242 oncekey = (text, category)
243 if onceregistry.get(oncekey):
244 return
245 onceregistry[oncekey] = 1
246 elif action == "always":
247 pass
248 elif action == "module":
249 registry[key] = 1
250 altkey = (text, category, 0)
251 if registry.get(altkey):
252 return
253 registry[altkey] = 1
254 elif action == "default":
255 registry[key] = 1
256 else:
257 # Unrecognized actions are errors
258 raise RuntimeError(
259 "Unrecognized action (%r) in warnings.filters:\n %s" %
260 (action, item))
261 # Print message and context
262 showwarning(message, category, filename, lineno)
263
264
265# filters contains a sequence of filter 5-tuples
266# The components of the 5-tuple are:
267# - an action: error, ignore, always, default, module, or once
268# - a compiled regex that must match the warning message
269# - a class representing the warning category
270# - a compiled regex that must match the module that is being warned
271# - a line number for the line being warning, or 0 to mean any line
272# If either if the compiled regexs are None, match anything.
273_warnings_defaults = False
274try:
275 from _warnings import (filters, default_action, once_registry,
276 warn, warn_explicit)
277 defaultaction = default_action
278 onceregistry = once_registry
279 _warnings_defaults = True
280except ImportError:
281 filters = []
282 defaultaction = "default"
283 onceregistry = {}
284
285
Guido van Rossum2a862c62000-12-15 21:59:53 +0000286# Module initialization
Tim Peters66025202004-03-21 17:06:20 +0000287_processoptions(sys.warnoptions)
Brett Cannone9746892008-04-12 23:44:07 +0000288if not _warnings_defaults:
289 simplefilter("ignore", category=PendingDeprecationWarning, append=1)
290 simplefilter("ignore", category=ImportWarning, append=1)
291 bytes_warning = sys.flags.bytes_warning
292 if bytes_warning > 1:
293 bytes_action = "error"
294 elif bytes_warning:
295 bytes_action = "default"
296 else:
297 bytes_action = "ignore"
298 simplefilter(bytes_action, category=BytesWarning, append=1)
299del _warnings_defaults