blob: 0be20e05e3d0fb4c1830845f58dbdad0165f0975 [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
Christian Heimes33fe8092008-04-13 13:53:33 +00007import sys
Guido van Rossum2a862c62000-12-15 21:59:53 +00008
Skip Montanaro40fc1602001-03-01 04:27:19 +00009__all__ = ["warn", "showwarning", "formatwarning", "filterwarnings",
10 "resetwarnings"]
11
Guido van Rossum2a862c62000-12-15 21:59:53 +000012
Christian Heimes33fe8092008-04-13 13:53:33 +000013def showwarning(message, category, filename, lineno, file=None, line=None):
Guido van Rossum2a862c62000-12-15 21:59:53 +000014 """Hook to write a warning to a file; replace if you like."""
15 if file is None:
16 file = sys.stderr
Mark Hammond51a0ae32002-09-11 13:22:35 +000017 try:
Christian Heimes33fe8092008-04-13 13:53:33 +000018 file.write(formatwarning(message, category, filename, lineno, line))
Mark Hammond51a0ae32002-09-11 13:22:35 +000019 except IOError:
20 pass # the file (probably stderr) is invalid - this warning gets lost.
Guido van Rossum2a862c62000-12-15 21:59:53 +000021
Christian Heimes33fe8092008-04-13 13:53:33 +000022def formatwarning(message, category, filename, lineno, line=None):
Guido van Rossum9464a7d2001-01-14 14:08:40 +000023 """Function to format a warning the standard way."""
Guido van Rossum2a862c62000-12-15 21:59:53 +000024 s = "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message)
Christian Heimes33fe8092008-04-13 13:53:33 +000025 line = linecache.getline(filename, lineno) if line is None else line
Guido van Rossum2a862c62000-12-15 21:59:53 +000026 if line:
Christian Heimes33fe8092008-04-13 13:53:33 +000027 line = line.strip()
28 s += " %s\n" % line
Guido van Rossum2a862c62000-12-15 21:59:53 +000029 return s
30
Guido van Rossum9464a7d2001-01-14 14:08:40 +000031def filterwarnings(action, message="", category=Warning, module="", lineno=0,
32 append=0):
Guido van Rossum2a862c62000-12-15 21:59:53 +000033 """Insert an entry into the list of warnings filters (at the front).
34
35 Use assertions to check that all arguments have the right type."""
Skip Montanarod8f21202003-05-14 17:33:53 +000036 import re
Guido van Rossum2a862c62000-12-15 21:59:53 +000037 assert action in ("error", "ignore", "always", "default", "module",
Walter Dörwald70a6b492004-02-12 17:35:32 +000038 "once"), "invalid action: %r" % (action,)
Guido van Rossum3172c5d2007-10-16 18:12:55 +000039 assert isinstance(message, str), "message must be a string"
Guido van Rossum13257902007-06-07 23:15:56 +000040 assert isinstance(category, type), "category must be a class"
Guido van Rossum2a862c62000-12-15 21:59:53 +000041 assert issubclass(category, Warning), "category must be a Warning subclass"
Guido van Rossum3172c5d2007-10-16 18:12:55 +000042 assert isinstance(module, str), "module must be a string"
Walter Dörwald65230a22002-06-03 15:58:32 +000043 assert isinstance(lineno, int) and lineno >= 0, \
Guido van Rossum2a862c62000-12-15 21:59:53 +000044 "lineno must be an int >= 0"
Guido van Rossum9464a7d2001-01-14 14:08:40 +000045 item = (action, re.compile(message, re.I), category,
46 re.compile(module), lineno)
47 if append:
48 filters.append(item)
49 else:
50 filters.insert(0, item)
Guido van Rossum2a862c62000-12-15 21:59:53 +000051
Jeremy Hylton85014662003-07-11 15:37:59 +000052def simplefilter(action, category=Warning, lineno=0, append=0):
53 """Insert a simple entry into the list of warnings filters (at the front).
54
55 A simple filter matches all modules and messages.
56 """
57 assert action in ("error", "ignore", "always", "default", "module",
Walter Dörwald70a6b492004-02-12 17:35:32 +000058 "once"), "invalid action: %r" % (action,)
Jeremy Hylton85014662003-07-11 15:37:59 +000059 assert isinstance(lineno, int) and lineno >= 0, \
60 "lineno must be an int >= 0"
61 item = (action, None, category, None, lineno)
62 if append:
63 filters.append(item)
64 else:
65 filters.insert(0, item)
66
Guido van Rossum2a862c62000-12-15 21:59:53 +000067def resetwarnings():
Tim Petersd0cc4f02002-04-16 01:51:25 +000068 """Clear the list of warning filters, so that no filters are active."""
Guido van Rossum2a862c62000-12-15 21:59:53 +000069 filters[:] = []
70
71class _OptionError(Exception):
72 """Exception used by option processing helpers."""
73 pass
74
75# Helper to process -W options passed via sys.warnoptions
76def _processoptions(args):
77 for arg in args:
78 try:
79 _setoption(arg)
Guido van Rossumb940e112007-01-10 16:19:56 +000080 except _OptionError as msg:
Guido van Rossumbe19ed72007-02-09 05:37:30 +000081 print("Invalid -W option ignored:", msg, file=sys.stderr)
Guido van Rossum2a862c62000-12-15 21:59:53 +000082
83# Helper for _processoptions()
84def _setoption(arg):
Skip Montanarod8f21202003-05-14 17:33:53 +000085 import re
Tim Peterse1190062001-01-15 03:34:38 +000086 parts = arg.split(':')
87 if len(parts) > 5:
Walter Dörwald70a6b492004-02-12 17:35:32 +000088 raise _OptionError("too many fields (max 5): %r" % (arg,))
Tim Peterse1190062001-01-15 03:34:38 +000089 while len(parts) < 5:
90 parts.append('')
91 action, message, category, module, lineno = [s.strip()
92 for s in parts]
93 action = _getaction(action)
94 message = re.escape(message)
95 category = _getcategory(category)
96 module = re.escape(module)
97 if module:
98 module = module + '$'
99 if lineno:
100 try:
101 lineno = int(lineno)
102 if lineno < 0:
103 raise ValueError
104 except (ValueError, OverflowError):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000105 raise _OptionError("invalid lineno %r" % (lineno,))
Tim Peterse1190062001-01-15 03:34:38 +0000106 else:
107 lineno = 0
108 filterwarnings(action, message, category, module, lineno)
Guido van Rossum2a862c62000-12-15 21:59:53 +0000109
110# Helper for _setoption()
111def _getaction(action):
112 if not action:
113 return "default"
114 if action == "all": return "always" # Alias
Raymond Hettingerdbecd932005-02-06 06:57:08 +0000115 for a in ('default', 'always', 'ignore', 'module', 'once', 'error'):
Guido van Rossum2a862c62000-12-15 21:59:53 +0000116 if a.startswith(action):
117 return a
Walter Dörwald70a6b492004-02-12 17:35:32 +0000118 raise _OptionError("invalid action: %r" % (action,))
Guido van Rossum2a862c62000-12-15 21:59:53 +0000119
120# Helper for _setoption()
121def _getcategory(category):
Skip Montanarod8f21202003-05-14 17:33:53 +0000122 import re
Guido van Rossum2a862c62000-12-15 21:59:53 +0000123 if not category:
124 return Warning
125 if re.match("^[a-zA-Z0-9_]+$", category):
126 try:
127 cat = eval(category)
Guido van Rossumd1db30b2000-12-19 03:04:50 +0000128 except NameError:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000129 raise _OptionError("unknown warning category: %r" % (category,))
Guido van Rossum2a862c62000-12-15 21:59:53 +0000130 else:
131 i = category.rfind(".")
132 module = category[:i]
133 klass = category[i+1:]
Guido van Rossumd1db30b2000-12-19 03:04:50 +0000134 try:
135 m = __import__(module, None, None, [klass])
136 except ImportError:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000137 raise _OptionError("invalid module name: %r" % (module,))
Guido van Rossumd1db30b2000-12-19 03:04:50 +0000138 try:
139 cat = getattr(m, klass)
140 except AttributeError:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000141 raise _OptionError("unknown warning category: %r" % (category,))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000142 if not issubclass(cat, Warning):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000143 raise _OptionError("invalid warning category: %r" % (category,))
Guido van Rossum2a862c62000-12-15 21:59:53 +0000144 return cat
145
Christian Heimes33fe8092008-04-13 13:53:33 +0000146
147# Code typically replaced by _warnings
148def warn(message, category=None, stacklevel=1):
149 """Issue a warning, or maybe ignore it or raise an exception."""
150 # Check if message is already a Warning object
151 if isinstance(message, Warning):
152 category = message.__class__
153 # Check category argument
154 if category is None:
155 category = UserWarning
156 assert issubclass(category, Warning)
157 # Get context information
158 try:
159 caller = sys._getframe(stacklevel)
160 except ValueError:
161 globals = sys.__dict__
162 lineno = 1
163 else:
164 globals = caller.f_globals
165 lineno = caller.f_lineno
166 if '__name__' in globals:
167 module = globals['__name__']
168 else:
169 module = "<string>"
170 filename = globals.get('__file__')
171 if filename:
172 fnl = filename.lower()
173 if fnl.endswith((".pyc", ".pyo")):
174 filename = filename[:-1]
175 else:
176 if module == "__main__":
177 try:
178 filename = sys.argv[0]
179 except AttributeError:
180 # embedded interpreters don't have sys.argv, see bug #839151
181 filename = '__main__'
182 if not filename:
183 filename = module
184 registry = globals.setdefault("__warningregistry__", {})
185 warn_explicit(message, category, filename, lineno, module, registry,
186 globals)
187
188def warn_explicit(message, category, filename, lineno,
189 module=None, registry=None, module_globals=None):
Brett Cannondb734912008-06-27 00:52:15 +0000190 lineno = int(lineno)
Christian Heimes33fe8092008-04-13 13:53:33 +0000191 if module is None:
192 module = filename or "<unknown>"
193 if module[-3:].lower() == ".py":
194 module = module[:-3] # XXX What about leading pathname?
195 if registry is None:
196 registry = {}
197 if isinstance(message, Warning):
198 text = str(message)
199 category = message.__class__
200 else:
201 text = message
202 message = category(message)
203 key = (text, category, lineno)
204 # Quick test for common case
205 if registry.get(key):
206 return
207 # Search the filters
208 for item in filters:
209 action, msg, cat, mod, ln = item
210 if ((msg is None or msg.match(text)) and
211 issubclass(category, cat) and
212 (mod is None or mod.match(module)) and
213 (ln == 0 or lineno == ln)):
214 break
215 else:
216 action = defaultaction
217 # Early exit actions
218 if action == "ignore":
219 registry[key] = 1
220 return
221
222 # Prime the linecache for formatting, in case the
223 # "file" is actually in a zipfile or something.
224 linecache.getlines(filename, module_globals)
225
226 if action == "error":
227 raise message
228 # Other actions
229 if action == "once":
230 registry[key] = 1
231 oncekey = (text, category)
232 if onceregistry.get(oncekey):
233 return
234 onceregistry[oncekey] = 1
235 elif action == "always":
236 pass
237 elif action == "module":
238 registry[key] = 1
239 altkey = (text, category, 0)
240 if registry.get(altkey):
241 return
242 registry[altkey] = 1
243 elif action == "default":
244 registry[key] = 1
245 else:
246 # Unrecognized actions are errors
247 raise RuntimeError(
248 "Unrecognized action (%r) in warnings.filters:\n %s" %
249 (action, item))
Christian Heimes8dc226f2008-05-06 23:45:46 +0000250 if not hasattr(showwarning, "__call__"):
251 raise TypeError("warnings.showwarning() must be set to a "
252 "function or method")
Christian Heimes33fe8092008-04-13 13:53:33 +0000253 # Print message and context
254 showwarning(message, category, filename, lineno)
255
256
257# filters contains a sequence of filter 5-tuples
258# The components of the 5-tuple are:
259# - an action: error, ignore, always, default, module, or once
260# - a compiled regex that must match the warning message
261# - a class representing the warning category
262# - a compiled regex that must match the module that is being warned
263# - a line number for the line being warning, or 0 to mean any line
264# If either if the compiled regexs are None, match anything.
265_warnings_defaults = False
266try:
267 from _warnings import (filters, default_action, once_registry,
268 warn, warn_explicit)
269 defaultaction = default_action
270 onceregistry = once_registry
271 _warnings_defaults = True
272except ImportError:
273 filters = []
274 defaultaction = "default"
275 onceregistry = {}
276
277
Guido van Rossum2a862c62000-12-15 21:59:53 +0000278# Module initialization
Tim Peters66025202004-03-21 17:06:20 +0000279_processoptions(sys.warnoptions)
Christian Heimes33fe8092008-04-13 13:53:33 +0000280if not _warnings_defaults:
281 simplefilter("ignore", category=PendingDeprecationWarning, append=1)
282 simplefilter("ignore", category=ImportWarning, append=1)
283 bytes_warning = sys.flags.bytes_warning
284 if bytes_warning > 1:
285 bytes_action = "error"
286 elif bytes_warning:
287 bytes_action = "default"
288 else:
289 bytes_action = "ignore"
290 simplefilter(bytes_action, category=BytesWarning, append=1)
291del _warnings_defaults