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
, (type, types
.ClassType
)), \
149 "category must be a class"
150 assert issubclass(category
, Warning), "category must be a Warning subclass"
151 assert isinstance(module
, basestring
), "module must be a string"
152 assert isinstance(lineno
, int) and lineno
>= 0, \
153 "lineno must be an int >= 0"
154 item
= (action
, re
.compile(message
, re
.I
), category
,
155 re
.compile(module
), lineno
)
159 filters
.insert(0, item
)
161 def simplefilter(action
, category
=Warning, lineno
=0, append
=0):
162 """Insert a simple entry into the list of warnings filters (at the front).
164 A simple filter matches all modules and messages.
166 assert action
in ("error", "ignore", "always", "default", "module",
167 "once"), "invalid action: %r" % (action
,)
168 assert isinstance(lineno
, int) and lineno
>= 0, \
169 "lineno must be an int >= 0"
170 item
= (action
, None, category
, None, lineno
)
174 filters
.insert(0, item
)
177 """Clear the list of warning filters, so that no filters are active."""
180 class _OptionError(Exception):
181 """Exception used by option processing helpers."""
184 # Helper to process -W options passed via sys.warnoptions
185 def _processoptions(args
):
189 except _OptionError
, msg
:
190 print >>sys
.stderr
, "Invalid -W option ignored:", msg
192 # Helper for _processoptions()
195 parts
= arg
.split(':')
197 raise _OptionError("too many fields (max 5): %r" % (arg
,))
198 while len(parts
) < 5:
200 action
, message
, category
, module
, lineno
= [s
.strip()
202 action
= _getaction(action
)
203 message
= re
.escape(message
)
204 category
= _getcategory(category
)
205 module
= re
.escape(module
)
207 module
= module
+ '$'
213 except (ValueError, OverflowError):
214 raise _OptionError("invalid lineno %r" % (lineno
,))
217 filterwarnings(action
, message
, category
, module
, lineno
)
219 # Helper for _setoption()
220 def _getaction(action
):
223 if action
== "all": return "always" # Alias
224 for a
in ('default', 'always', 'ignore', 'module', 'once', 'error'):
225 if a
.startswith(action
):
227 raise _OptionError("invalid action: %r" % (action
,))
229 # Helper for _setoption()
230 def _getcategory(category
):
234 if re
.match("^[a-zA-Z0-9_]+$", category
):
238 raise _OptionError("unknown warning category: %r" % (category
,))
240 i
= category
.rfind(".")
241 module
= category
[:i
]
242 klass
= category
[i
+1:]
244 m
= __import__(module
, None, None, [klass
])
246 raise _OptionError("invalid module name: %r" % (module
,))
248 cat
= getattr(m
, klass
)
249 except AttributeError:
250 raise _OptionError("unknown warning category: %r" % (category
,))
251 if (not isinstance(cat
, types
.ClassType
) or
252 not issubclass(cat
, Warning)):
253 raise _OptionError("invalid warning category: %r" % (category
,))
256 # Module initialization
257 _processoptions(sys
.warnoptions
)
258 # XXX OverflowWarning should go away for Python 2.5.
259 simplefilter("ignore", category
=OverflowWarning, append
=1)
260 simplefilter("ignore", category
=PendingDeprecationWarning
, append
=1)