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__":
54 filename
= sys
.argv
[0]
55 except AttributeError:
56 # embedded interpreters don't have sys.argv, see bug #839151
60 registry
= globals.setdefault("__warningregistry__", {})
61 warn_explicit(message
, category
, filename
, lineno
, module
, registry
)
63 def warn_explicit(message
, category
, filename
, lineno
,
64 module
=None, registry
=None):
66 module
= filename
or "<unknown>"
67 if module
[-3:].lower() == ".py":
68 module
= module
[:-3] # XXX What about leading pathname?
71 if isinstance(message
, Warning):
73 category
= message
.__class
__
76 message
= category(message
)
77 key
= (text
, category
, lineno
)
78 # Quick test for common case
83 action
, msg
, cat
, mod
, ln
= item
84 if ((msg
is None or msg
.match(text
)) and
85 issubclass(category
, cat
) and
86 (mod
is None or mod
.match(module
)) and
87 (ln
== 0 or lineno
== ln
)):
90 action
= defaultaction
92 if action
== "ignore":
100 oncekey
= (text
, category
)
101 if onceregistry
.get(oncekey
):
103 onceregistry
[oncekey
] = 1
104 elif action
== "always":
106 elif action
== "module":
108 altkey
= (text
, category
, 0)
109 if registry
.get(altkey
):
112 elif action
== "default":
115 # Unrecognized actions are errors
117 "Unrecognized action (%r) in warnings.filters:\n %s" %
119 # Print message and context
120 showwarning(message
, category
, filename
, lineno
)
122 def showwarning(message
, category
, filename
, lineno
, file=None):
123 """Hook to write a warning to a file; replace if you like."""
127 file.write(formatwarning(message
, category
, filename
, lineno
))
129 pass # the file (probably stderr) is invalid - this warning gets lost.
131 def formatwarning(message
, category
, filename
, lineno
):
132 """Function to format a warning the standard way."""
133 s
= "%s:%s: %s: %s\n" % (filename
, lineno
, category
.__name
__, message
)
134 line
= linecache
.getline(filename
, lineno
).strip()
136 s
= s
+ " " + line
+ "\n"
139 def filterwarnings(action
, message
="", category
=Warning, module
="", lineno
=0,
141 """Insert an entry into the list of warnings filters (at the front).
143 Use assertions to check that all arguments have the right type."""
145 assert action
in ("error", "ignore", "always", "default", "module",
146 "once"), "invalid action: %r" % (action
,)
147 assert isinstance(message
, basestring
), "message must be a string"
148 assert isinstance(category
, types
.ClassType
), "category must be a class"
149 assert issubclass(category
, Warning), "category must be a Warning subclass"
150 assert isinstance(module
, basestring
), "module must be a string"
151 assert isinstance(lineno
, int) and lineno
>= 0, \
152 "lineno must be an int >= 0"
153 item
= (action
, re
.compile(message
, re
.I
), category
,
154 re
.compile(module
), lineno
)
158 filters
.insert(0, item
)
160 def simplefilter(action
, category
=Warning, lineno
=0, append
=0):
161 """Insert a simple entry into the list of warnings filters (at the front).
163 A simple filter matches all modules and messages.
165 assert action
in ("error", "ignore", "always", "default", "module",
166 "once"), "invalid action: %r" % (action
,)
167 assert isinstance(lineno
, int) and lineno
>= 0, \
168 "lineno must be an int >= 0"
169 item
= (action
, None, category
, None, lineno
)
173 filters
.insert(0, item
)
176 """Clear the list of warning filters, so that no filters are active."""
179 class _OptionError(Exception):
180 """Exception used by option processing helpers."""
183 # Helper to process -W options passed via sys.warnoptions
184 def _processoptions(args
):
188 except _OptionError
, msg
:
189 print >>sys
.stderr
, "Invalid -W option ignored:", msg
191 # Helper for _processoptions()
194 parts
= arg
.split(':')
196 raise _OptionError("too many fields (max 5): %r" % (arg
,))
197 while len(parts
) < 5:
199 action
, message
, category
, module
, lineno
= [s
.strip()
201 action
= _getaction(action
)
202 message
= re
.escape(message
)
203 category
= _getcategory(category
)
204 module
= re
.escape(module
)
206 module
= module
+ '$'
212 except (ValueError, OverflowError):
213 raise _OptionError("invalid lineno %r" % (lineno
,))
216 filterwarnings(action
, message
, category
, module
, lineno
)
218 # Helper for _setoption()
219 def _getaction(action
):
222 if action
== "all": return "always" # Alias
223 for a
in ('default', 'always', 'ignore', 'module', 'once', 'error'):
224 if a
.startswith(action
):
226 raise _OptionError("invalid action: %r" % (action
,))
228 # Helper for _setoption()
229 def _getcategory(category
):
233 if re
.match("^[a-zA-Z0-9_]+$", category
):
237 raise _OptionError("unknown warning category: %r" % (category
,))
239 i
= category
.rfind(".")
240 module
= category
[:i
]
241 klass
= category
[i
+1:]
243 m
= __import__(module
, None, None, [klass
])
245 raise _OptionError("invalid module name: %r" % (module
,))
247 cat
= getattr(m
, klass
)
248 except AttributeError:
249 raise _OptionError("unknown warning category: %r" % (category
,))
250 if (not isinstance(cat
, types
.ClassType
) or
251 not issubclass(cat
, Warning)):
252 raise _OptionError("invalid warning category: %r" % (category
,))
255 # Module initialization
256 _processoptions(sys
.warnoptions
)
257 # XXX OverflowWarning should go away for Python 2.5.
258 simplefilter("ignore", category
=OverflowWarning, append
=1)
259 simplefilter("ignore", category
=PendingDeprecationWarning
, append
=1)