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", ".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
,
64 def warn_explicit(message
, category
, filename
, lineno
,
65 module
=None, registry
=None, module_globals
=None):
67 module
= filename
or "<unknown>"
68 if module
[-3:].lower() == ".py":
69 module
= module
[:-3] # XXX What about leading pathname?
72 if isinstance(message
, Warning):
74 category
= message
.__class
__
77 message
= category(message
)
78 key
= (text
, category
, lineno
)
79 # Quick test for common case
84 action
, msg
, cat
, mod
, ln
= item
85 if ((msg
is None or msg
.match(text
)) and
86 issubclass(category
, cat
) and
87 (mod
is None or mod
.match(module
)) and
88 (ln
== 0 or lineno
== ln
)):
91 action
= defaultaction
93 if action
== "ignore":
97 # Prime the linecache for formatting, in case the
98 # "file" is actually in a zipfile or something.
99 linecache
.getlines(filename
, module_globals
)
101 if action
== "error":
106 oncekey
= (text
, category
)
107 if onceregistry
.get(oncekey
):
109 onceregistry
[oncekey
] = 1
110 elif action
== "always":
112 elif action
== "module":
114 altkey
= (text
, category
, 0)
115 if registry
.get(altkey
):
118 elif action
== "default":
121 # Unrecognized actions are errors
123 "Unrecognized action (%r) in warnings.filters:\n %s" %
125 # Print message and context
126 showwarning(message
, category
, filename
, lineno
)
128 def showwarning(message
, category
, filename
, lineno
, file=None):
129 """Hook to write a warning to a file; replace if you like."""
133 file.write(formatwarning(message
, category
, filename
, lineno
))
135 pass # the file (probably stderr) is invalid - this warning gets lost.
137 def formatwarning(message
, category
, filename
, lineno
):
138 """Function to format a warning the standard way."""
139 s
= "%s:%s: %s: %s\n" % (filename
, lineno
, category
.__name
__, message
)
140 line
= linecache
.getline(filename
, lineno
).strip()
142 s
= s
+ " " + line
+ "\n"
145 def filterwarnings(action
, message
="", category
=Warning, module
="", lineno
=0,
147 """Insert an entry into the list of warnings filters (at the front).
149 Use assertions to check that all arguments have the right type."""
151 assert action
in ("error", "ignore", "always", "default", "module",
152 "once"), "invalid action: %r" % (action
,)
153 assert isinstance(message
, basestring
), "message must be a string"
154 assert isinstance(category
, (type, types
.ClassType
)), \
155 "category must be a class"
156 assert issubclass(category
, Warning), "category must be a Warning subclass"
157 assert isinstance(module
, basestring
), "module must be a string"
158 assert isinstance(lineno
, int) and lineno
>= 0, \
159 "lineno must be an int >= 0"
160 item
= (action
, re
.compile(message
, re
.I
), category
,
161 re
.compile(module
), lineno
)
165 filters
.insert(0, item
)
167 def simplefilter(action
, category
=Warning, lineno
=0, append
=0):
168 """Insert a simple entry into the list of warnings filters (at the front).
170 A simple filter matches all modules and messages.
172 assert action
in ("error", "ignore", "always", "default", "module",
173 "once"), "invalid action: %r" % (action
,)
174 assert isinstance(lineno
, int) and lineno
>= 0, \
175 "lineno must be an int >= 0"
176 item
= (action
, None, category
, None, lineno
)
180 filters
.insert(0, item
)
183 """Clear the list of warning filters, so that no filters are active."""
186 class _OptionError(Exception):
187 """Exception used by option processing helpers."""
190 # Helper to process -W options passed via sys.warnoptions
191 def _processoptions(args
):
195 except _OptionError
, msg
:
196 print >>sys
.stderr
, "Invalid -W option ignored:", msg
198 # Helper for _processoptions()
201 parts
= arg
.split(':')
203 raise _OptionError("too many fields (max 5): %r" % (arg
,))
204 while len(parts
) < 5:
206 action
, message
, category
, module
, lineno
= [s
.strip()
208 action
= _getaction(action
)
209 message
= re
.escape(message
)
210 category
= _getcategory(category
)
211 module
= re
.escape(module
)
213 module
= module
+ '$'
219 except (ValueError, OverflowError):
220 raise _OptionError("invalid lineno %r" % (lineno
,))
223 filterwarnings(action
, message
, category
, module
, lineno
)
225 # Helper for _setoption()
226 def _getaction(action
):
229 if action
== "all": return "always" # Alias
230 for a
in ('default', 'always', 'ignore', 'module', 'once', 'error'):
231 if a
.startswith(action
):
233 raise _OptionError("invalid action: %r" % (action
,))
235 # Helper for _setoption()
236 def _getcategory(category
):
240 if re
.match("^[a-zA-Z0-9_]+$", category
):
244 raise _OptionError("unknown warning category: %r" % (category
,))
246 i
= category
.rfind(".")
247 module
= category
[:i
]
248 klass
= category
[i
+1:]
250 m
= __import__(module
, None, None, [klass
])
252 raise _OptionError("invalid module name: %r" % (module
,))
254 cat
= getattr(m
, klass
)
255 except AttributeError:
256 raise _OptionError("unknown warning category: %r" % (category
,))
257 if (not isinstance(cat
, types
.ClassType
) or
258 not issubclass(cat
, Warning)):
259 raise _OptionError("invalid warning category: %r" % (category
,))
262 # Module initialization
263 _processoptions(sys
.warnoptions
)
264 simplefilter("ignore", category
=PendingDeprecationWarning
, append
=1)