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.
9 __all__
= ["warn", "showwarning", "formatwarning", "filterwarnings",
12 # filters contains a sequence of filter 5-tuples
13 # The components of the 5-tuple are:
14 # - an action: error, ignore, always, default, module, or once
15 # - a compiled regex that must match the warning message
16 # - a class representing the warning category
17 # - a compiled regex that must match the module that is being warned
18 # - a line number for the line being warning, or 0 to mean any line
19 # If either if the compiled regexs are None, match anything.
21 defaultaction
= "default"
24 def warn(message
, category
=None, stacklevel
=1):
25 """Issue a warning, or maybe ignore it or raise an exception."""
26 # Check if message is already a Warning object
27 if isinstance(message
, Warning):
28 category
= message
.__class
__
29 # Check category argument
31 category
= UserWarning
32 assert issubclass(category
, Warning)
33 # Get context information
35 caller
= sys
._getframe
(stacklevel
)
37 globals = sys
.__dict
__
40 globals = caller
.f_globals
41 lineno
= caller
.f_lineno
42 if '__name__' in globals:
43 module
= globals['__name__']
46 filename
= globals.get('__file__')
48 fnl
= filename
.lower()
49 if fnl
.endswith(".pyc") or fnl
.endswith(".pyo"):
50 filename
= filename
[:-1]
52 if module
== "__main__":
53 filename
= sys
.argv
[0]
56 registry
= globals.setdefault("__warningregistry__", {})
57 warn_explicit(message
, category
, filename
, lineno
, module
, registry
)
59 def warn_explicit(message
, category
, filename
, lineno
,
60 module
=None, registry
=None):
63 if module
[-3:].lower() == ".py":
64 module
= module
[:-3] # XXX What about leading pathname?
67 if isinstance(message
, Warning):
69 category
= message
.__class
__
72 message
= category(message
)
73 key
= (text
, category
, lineno
)
74 # Quick test for common case
79 action
, msg
, cat
, mod
, ln
= item
80 if ((msg
is None or msg
.match(text
)) and
81 issubclass(category
, cat
) and
82 (mod
is None or mod
.match(module
)) and
83 (ln
== 0 or lineno
== ln
)):
86 action
= defaultaction
88 if action
== "ignore":
96 oncekey
= (text
, category
)
97 if onceregistry
.get(oncekey
):
99 onceregistry
[oncekey
] = 1
100 elif action
== "always":
102 elif action
== "module":
104 altkey
= (text
, category
, 0)
105 if registry
.get(altkey
):
108 elif action
== "default":
111 # Unrecognized actions are errors
113 "Unrecognized action (%r) in warnings.filters:\n %s" %
115 # Print message and context
116 showwarning(message
, category
, filename
, lineno
)
118 def showwarning(message
, category
, filename
, lineno
, file=None):
119 """Hook to write a warning to a file; replace if you like."""
123 file.write(formatwarning(message
, category
, filename
, lineno
))
125 pass # the file (probably stderr) is invalid - this warning gets lost.
127 def formatwarning(message
, category
, filename
, lineno
):
128 """Function to format a warning the standard way."""
129 s
= "%s:%s: %s: %s\n" % (filename
, lineno
, category
.__name
__, message
)
130 line
= linecache
.getline(filename
, lineno
).strip()
132 s
= s
+ " " + line
+ "\n"
135 def filterwarnings(action
, message
="", category
=Warning, module
="", lineno
=0,
137 """Insert an entry into the list of warnings filters (at the front).
139 Use assertions to check that all arguments have the right type."""
141 assert action
in ("error", "ignore", "always", "default", "module",
142 "once"), "invalid action: %r" % (action
,)
143 assert isinstance(message
, basestring
), "message must be a string"
144 assert isinstance(category
, types
.ClassType
), "category must be a class"
145 assert issubclass(category
, Warning), "category must be a Warning subclass"
146 assert isinstance(module
, basestring
), "module must be a string"
147 assert isinstance(lineno
, int) and lineno
>= 0, \
148 "lineno must be an int >= 0"
149 item
= (action
, re
.compile(message
, re
.I
), category
,
150 re
.compile(module
), lineno
)
154 filters
.insert(0, item
)
156 def simplefilter(action
, category
=Warning, lineno
=0, append
=0):
157 """Insert a simple entry into the list of warnings filters (at the front).
159 A simple filter matches all modules and messages.
161 assert action
in ("error", "ignore", "always", "default", "module",
162 "once"), "invalid action: %r" % (action
,)
163 assert isinstance(lineno
, int) and lineno
>= 0, \
164 "lineno must be an int >= 0"
165 item
= (action
, None, category
, None, lineno
)
169 filters
.insert(0, item
)
172 """Clear the list of warning filters, so that no filters are active."""
175 class _OptionError(Exception):
176 """Exception used by option processing helpers."""
179 # Helper to process -W options passed via sys.warnoptions
180 def _processoptions(args
):
184 except _OptionError
, msg
:
185 print >>sys
.stderr
, "Invalid -W option ignored:", msg
187 # Helper for _processoptions()
190 parts
= arg
.split(':')
192 raise _OptionError("too many fields (max 5): %r" % (arg
,))
193 while len(parts
) < 5:
195 action
, message
, category
, module
, lineno
= [s
.strip()
197 action
= _getaction(action
)
198 message
= re
.escape(message
)
199 category
= _getcategory(category
)
200 module
= re
.escape(module
)
202 module
= module
+ '$'
208 except (ValueError, OverflowError):
209 raise _OptionError("invalid lineno %r" % (lineno
,))
212 filterwarnings(action
, message
, category
, module
, lineno
)
214 # Helper for _setoption()
215 def _getaction(action
):
218 if action
== "all": return "always" # Alias
219 for a
in ['default', 'always', 'ignore', 'module', 'once', 'error']:
220 if a
.startswith(action
):
222 raise _OptionError("invalid action: %r" % (action
,))
224 # Helper for _setoption()
225 def _getcategory(category
):
229 if re
.match("^[a-zA-Z0-9_]+$", category
):
233 raise _OptionError("unknown warning category: %r" % (category
,))
235 i
= category
.rfind(".")
236 module
= category
[:i
]
237 klass
= category
[i
+1:]
239 m
= __import__(module
, None, None, [klass
])
241 raise _OptionError("invalid module name: %r" % (module
,))
243 cat
= getattr(m
, klass
)
244 except AttributeError:
245 raise _OptionError("unknown warning category: %r" % (category
,))
246 if (not isinstance(cat
, types
.ClassType
) or
247 not issubclass(cat
, Warning)):
248 raise _OptionError("invalid warning category: %r" % (category
,))
251 # Module initialization
252 _processoptions(sys
.warnoptions
)
253 # XXX OverflowWarning should go away for Python 2.5.
254 simplefilter("ignore", category
=OverflowWarning, append
=1)
255 simplefilter("ignore", category
=PendingDeprecationWarning
, append
=1)