1 """Python part of the warnings subsystem."""
3 # Note: function level imports should *not* be used
4 # in this module as it may cause import lock deadlock.
10 __all__
= ["warn", "showwarning", "formatwarning", "filterwarnings",
11 "resetwarnings", "catch_warnings"]
14 def warnpy3k(message
, category
=None, stacklevel
=1):
15 """Issue a deprecation warning for Python 3.x related changes.
17 Warnings are omitted unless Python is started with the -3 option.
21 category
= DeprecationWarning
22 warn(message
, category
, stacklevel
+1)
24 def _show_warning(message
, category
, filename
, lineno
, file=None, line
=None):
25 """Hook to write a warning to a file; replace if you like."""
29 file.write(formatwarning(message
, category
, filename
, lineno
, line
))
31 pass # the file (probably stderr) is invalid - this warning gets lost.
32 # Keep a worrking version around in case the deprecation of the old API is
34 showwarning
= _show_warning
36 def formatwarning(message
, category
, filename
, lineno
, line
=None):
37 """Function to format a warning the standard way."""
38 s
= "%s:%s: %s: %s\n" % (filename
, lineno
, category
.__name
__, message
)
39 line
= linecache
.getline(filename
, lineno
) if line
is None else line
45 def filterwarnings(action
, message
="", category
=Warning, module
="", lineno
=0,
47 """Insert an entry into the list of warnings filters (at the front).
49 Use assertions to check that all arguments have the right type."""
51 assert action
in ("error", "ignore", "always", "default", "module",
52 "once"), "invalid action: %r" % (action
,)
53 assert isinstance(message
, basestring
), "message must be a string"
54 assert isinstance(category
, (type, types
.ClassType
)), \
55 "category must be a class"
56 assert issubclass(category
, Warning), "category must be a Warning subclass"
57 assert isinstance(module
, basestring
), "module must be a string"
58 assert isinstance(lineno
, int) and lineno
>= 0, \
59 "lineno must be an int >= 0"
60 item
= (action
, re
.compile(message
, re
.I
), category
,
61 re
.compile(module
), lineno
)
65 filters
.insert(0, item
)
67 def simplefilter(action
, category
=Warning, lineno
=0, append
=0):
68 """Insert a simple entry into the list of warnings filters (at the front).
70 A simple filter matches all modules and messages.
72 assert action
in ("error", "ignore", "always", "default", "module",
73 "once"), "invalid action: %r" % (action
,)
74 assert isinstance(lineno
, int) and lineno
>= 0, \
75 "lineno must be an int >= 0"
76 item
= (action
, None, category
, None, lineno
)
80 filters
.insert(0, item
)
83 """Clear the list of warning filters, so that no filters are active."""
86 class _OptionError(Exception):
87 """Exception used by option processing helpers."""
90 # Helper to process -W options passed via sys.warnoptions
91 def _processoptions(args
):
95 except _OptionError
, msg
:
96 print >>sys
.stderr
, "Invalid -W option ignored:", msg
98 # Helper for _processoptions()
101 parts
= arg
.split(':')
103 raise _OptionError("too many fields (max 5): %r" % (arg
,))
104 while len(parts
) < 5:
106 action
, message
, category
, module
, lineno
= [s
.strip()
108 action
= _getaction(action
)
109 message
= re
.escape(message
)
110 category
= _getcategory(category
)
111 module
= re
.escape(module
)
113 module
= module
+ '$'
119 except (ValueError, OverflowError):
120 raise _OptionError("invalid lineno %r" % (lineno
,))
123 filterwarnings(action
, message
, category
, module
, lineno
)
125 # Helper for _setoption()
126 def _getaction(action
):
129 if action
== "all": return "always" # Alias
130 for a
in ('default', 'always', 'ignore', 'module', 'once', 'error'):
131 if a
.startswith(action
):
133 raise _OptionError("invalid action: %r" % (action
,))
135 # Helper for _setoption()
136 def _getcategory(category
):
140 if re
.match("^[a-zA-Z0-9_]+$", category
):
144 raise _OptionError("unknown warning category: %r" % (category
,))
146 i
= category
.rfind(".")
147 module
= category
[:i
]
148 klass
= category
[i
+1:]
150 m
= __import__(module
, None, None, [klass
])
152 raise _OptionError("invalid module name: %r" % (module
,))
154 cat
= getattr(m
, klass
)
155 except AttributeError:
156 raise _OptionError("unknown warning category: %r" % (category
,))
157 if not issubclass(cat
, Warning):
158 raise _OptionError("invalid warning category: %r" % (category
,))
162 # Code typically replaced by _warnings
163 def warn(message
, category
=None, stacklevel
=1):
164 """Issue a warning, or maybe ignore it or raise an exception."""
165 # Check if message is already a Warning object
166 if isinstance(message
, Warning):
167 category
= message
.__class
__
168 # Check category argument
170 category
= UserWarning
171 assert issubclass(category
, Warning)
172 # Get context information
174 caller
= sys
._getframe
(stacklevel
)
176 globals = sys
.__dict
__
179 globals = caller
.f_globals
180 lineno
= caller
.f_lineno
181 if '__name__' in globals:
182 module
= globals['__name__']
185 filename
= globals.get('__file__')
187 fnl
= filename
.lower()
188 if fnl
.endswith((".pyc", ".pyo")):
189 filename
= filename
[:-1]
191 if module
== "__main__":
193 filename
= sys
.argv
[0]
194 except AttributeError:
195 # embedded interpreters don't have sys.argv, see bug #839151
196 filename
= '__main__'
199 registry
= globals.setdefault("__warningregistry__", {})
200 warn_explicit(message
, category
, filename
, lineno
, module
, registry
,
203 def warn_explicit(message
, category
, filename
, lineno
,
204 module
=None, registry
=None, module_globals
=None):
207 module
= filename
or "<unknown>"
208 if module
[-3:].lower() == ".py":
209 module
= module
[:-3] # XXX What about leading pathname?
212 if isinstance(message
, Warning):
214 category
= message
.__class
__
217 message
= category(message
)
218 key
= (text
, category
, lineno
)
219 # Quick test for common case
220 if registry
.get(key
):
224 action
, msg
, cat
, mod
, ln
= item
225 if ((msg
is None or msg
.match(text
)) and
226 issubclass(category
, cat
) and
227 (mod
is None or mod
.match(module
)) and
228 (ln
== 0 or lineno
== ln
)):
231 action
= defaultaction
233 if action
== "ignore":
237 # Prime the linecache for formatting, in case the
238 # "file" is actually in a zipfile or something.
239 linecache
.getlines(filename
, module_globals
)
241 if action
== "error":
246 oncekey
= (text
, category
)
247 if onceregistry
.get(oncekey
):
249 onceregistry
[oncekey
] = 1
250 elif action
== "always":
252 elif action
== "module":
254 altkey
= (text
, category
, 0)
255 if registry
.get(altkey
):
258 elif action
== "default":
261 # Unrecognized actions are errors
263 "Unrecognized action (%r) in warnings.filters:\n %s" %
265 # Warn if showwarning() does not support the 'line' argument.
266 # Don't use 'inspect' as it relies on an extension module, which break the
267 # build thanks to 'warnings' being imported by setup.py.
269 if hasattr(showwarning
, 'func_code'):
270 fxn_code
= showwarning
.func_code
271 elif hasattr(showwarning
, '__func__'):
272 fxn_code
= showwarning
.__func
__.func_code
274 args
= fxn_code
.co_varnames
[:fxn_code
.co_argcount
]
276 if 'line' not in args
and not fxn_code
.co_flags
& CO_VARARGS
:
277 showwarning_msg
= ("functions overriding warnings.showwarning() "
278 "must support the 'line' argument")
279 if message
== showwarning_msg
:
280 _show_warning(message
, category
, filename
, lineno
)
282 warn(showwarning_msg
, DeprecationWarning)
283 # Print message and context
284 showwarning(message
, category
, filename
, lineno
)
287 class WarningMessage(object):
289 """Holds the result of a single showwarning() call."""
291 _WARNING_DETAILS
= ("message", "category", "filename", "lineno", "file",
294 def __init__(self
, message
, category
, filename
, lineno
, file=None,
296 local_values
= locals()
297 for attr
in self
._WARNING
_DETAILS
:
298 setattr(self
, attr
, local_values
[attr
])
299 self
._category
_name
= category
.__name
__ if category
else None
302 return ("{message : %r, category : %r, filename : %r, lineno : %s, "
303 "line : %r}" % (self
.message
, self
._category
_name
,
304 self
.filename
, self
.lineno
, self
.line
))
307 class catch_warnings(object):
309 """A context manager that copies and restores the warnings filter upon
312 The 'record' argument specifies whether warnings should be captured by a
313 custom implementation of warnings.showwarning() and be appended to a list
314 returned by the context manager. Otherwise None is returned by the context
315 manager. The objects appended to the list are arguments whose attributes
316 mirror the arguments to showwarning().
318 The 'module' argument is to specify an alternative module to the module
319 named 'warnings' and imported under that name. This argument is only useful
320 when testing the warnings module itself.
324 def __init__(self
, record
=False, module
=None):
325 """Specify whether to record warnings and if an alternative module
326 should be used other than sys.modules['warnings'].
328 For compatibility with Python 3.0, please consider all arguments to be
332 self
._record
= record
333 self
._module
= sys
.modules
['warnings'] if module
is None else module
334 self
._entered
= False
339 args
.append("record=True")
340 if self
._module
is not sys
.modules
['warnings']:
341 args
.append("module=%r" % self
._module
)
342 name
= type(self
).__name
__
343 return "%s(%s)" % (name
, ", ".join(args
))
347 raise RuntimeError("Cannot enter %r twice" % self
)
349 self
._filters
= self
._module
.filters
350 self
._module
.filters
= self
._filters
[:]
351 self
._showwarning
= self
._module
.showwarning
354 def showwarning(*args
, **kwargs
):
355 log
.append(WarningMessage(*args
, **kwargs
))
356 self
._module
.showwarning
= showwarning
361 def __exit__(self
, *exc_info
):
362 if not self
._entered
:
363 raise RuntimeError("Cannot exit %r without entering first" % self
)
364 self
._module
.filters
= self
._filters
365 self
._module
.showwarning
= self
._showwarning
368 # filters contains a sequence of filter 5-tuples
369 # The components of the 5-tuple are:
370 # - an action: error, ignore, always, default, module, or once
371 # - a compiled regex that must match the warning message
372 # - a class representing the warning category
373 # - a compiled regex that must match the module that is being warned
374 # - a line number for the line being warning, or 0 to mean any line
375 # If either if the compiled regexs are None, match anything.
376 _warnings_defaults
= False
378 from _warnings
import (filters
, default_action
, once_registry
,
380 defaultaction
= default_action
381 onceregistry
= once_registry
382 _warnings_defaults
= True
385 defaultaction
= "default"
389 # Module initialization
390 _processoptions(sys
.warnoptions
)
391 if not _warnings_defaults
:
392 simplefilter("ignore", category
=PendingDeprecationWarning
, append
=1)
393 simplefilter("ignore", category
=ImportWarning
, append
=1)
394 bytes_warning
= sys
.flags
.bytes_warning
395 if bytes_warning
> 1:
396 bytes_action
= "error"
398 bytes_action
= "default"
400 bytes_action
= "ignore"
401 simplefilter(bytes_action
, category
=BytesWarning
, append
=1)
402 del _warnings_defaults