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 defaultaction
= "default"
16 def warn(message
, category
=None, stacklevel
=1):
17 """Issue a warning, or maybe ignore it or raise an exception."""
18 # Check if message is already a Warning object
19 if isinstance(message
, Warning):
20 category
= message
.__class
__
21 # Check category argument
23 category
= UserWarning
24 assert issubclass(category
, Warning)
25 # Get context information
27 caller
= sys
._getframe
(stacklevel
)
29 globals = sys
.__dict
__
32 globals = caller
.f_globals
33 lineno
= caller
.f_lineno
34 if '__name__' in globals:
35 module
= globals['__name__']
38 filename
= globals.get('__file__')
40 fnl
= filename
.lower()
41 if fnl
.endswith(".pyc") or fnl
.endswith(".pyo"):
42 filename
= filename
[:-1]
44 if module
== "__main__":
45 filename
= sys
.argv
[0]
48 registry
= globals.setdefault("__warningregistry__", {})
49 warn_explicit(message
, category
, filename
, lineno
, module
, registry
)
51 def warn_explicit(message
, category
, filename
, lineno
,
52 module
=None, registry
=None):
55 if module
[-3:].lower() == ".py":
56 module
= module
[:-3] # XXX What about leading pathname?
59 if isinstance(message
, Warning):
61 category
= message
.__class
__
64 message
= category(message
)
65 key
= (text
, category
, lineno
)
66 # Quick test for common case
71 action
, msg
, cat
, mod
, ln
= item
72 if (msg
.match(text
) and
73 issubclass(category
, cat
) and
75 (ln
== 0 or lineno
== ln
)):
78 action
= defaultaction
80 if action
== "ignore":
88 oncekey
= (text
, category
)
89 if onceregistry
.get(oncekey
):
91 onceregistry
[oncekey
] = 1
92 elif action
== "always":
94 elif action
== "module":
96 altkey
= (text
, category
, 0)
97 if registry
.get(altkey
):
100 elif action
== "default":
103 # Unrecognized actions are errors
105 "Unrecognized action (%s) in warnings.filters:\n %s" %
106 (`action`
, str(item
)))
107 # Print message and context
108 showwarning(message
, category
, filename
, lineno
)
110 def showwarning(message
, category
, filename
, lineno
, file=None):
111 """Hook to write a warning to a file; replace if you like."""
115 file.write(formatwarning(message
, category
, filename
, lineno
))
117 pass # the file (probably stderr) is invalid - this warning gets lost.
119 def formatwarning(message
, category
, filename
, lineno
):
120 """Function to format a warning the standard way."""
121 s
= "%s:%s: %s: %s\n" % (filename
, lineno
, category
.__name
__, message
)
122 line
= linecache
.getline(filename
, lineno
).strip()
124 s
= s
+ " " + line
+ "\n"
127 def filterwarnings(action
, message
="", category
=Warning, module
="", lineno
=0,
129 """Insert an entry into the list of warnings filters (at the front).
131 Use assertions to check that all arguments have the right type."""
132 assert action
in ("error", "ignore", "always", "default", "module",
133 "once"), "invalid action: %s" % `action`
134 assert isinstance(message
, basestring
), "message must be a string"
135 assert isinstance(category
, types
.ClassType
), "category must be a class"
136 assert issubclass(category
, Warning), "category must be a Warning subclass"
137 assert isinstance(module
, basestring
), "module must be a string"
138 assert isinstance(lineno
, int) and lineno
>= 0, \
139 "lineno must be an int >= 0"
140 item
= (action
, re
.compile(message
, re
.I
), category
,
141 re
.compile(module
), lineno
)
145 filters
.insert(0, item
)
148 """Clear the list of warning filters, so that no filters are active."""
151 class _OptionError(Exception):
152 """Exception used by option processing helpers."""
155 # Helper to process -W options passed via sys.warnoptions
156 def _processoptions(args
):
160 except _OptionError
, msg
:
161 print >>sys
.stderr
, "Invalid -W option ignored:", msg
163 # Helper for _processoptions()
165 parts
= arg
.split(':')
167 raise _OptionError("too many fields (max 5): %s" % `arg`
)
168 while len(parts
) < 5:
170 action
, message
, category
, module
, lineno
= [s
.strip()
172 action
= _getaction(action
)
173 message
= re
.escape(message
)
174 category
= _getcategory(category
)
175 module
= re
.escape(module
)
177 module
= module
+ '$'
183 except (ValueError, OverflowError):
184 raise _OptionError("invalid lineno %s" % `lineno`
)
187 filterwarnings(action
, message
, category
, module
, lineno
)
189 # Helper for _setoption()
190 def _getaction(action
):
193 if action
== "all": return "always" # Alias
194 for a
in ['default', 'always', 'ignore', 'module', 'once', 'error']:
195 if a
.startswith(action
):
197 raise _OptionError("invalid action: %s" % `action`
)
199 # Helper for _setoption()
200 def _getcategory(category
):
203 if re
.match("^[a-zA-Z0-9_]+$", category
):
207 raise _OptionError("unknown warning category: %s" % `category`
)
209 i
= category
.rfind(".")
210 module
= category
[:i
]
211 klass
= category
[i
+1:]
213 m
= __import__(module
, None, None, [klass
])
215 raise _OptionError("invalid module name: %s" % `module`
)
217 cat
= getattr(m
, klass
)
218 except AttributeError:
219 raise _OptionError("unknown warning category: %s" % `category`
)
220 if (not isinstance(cat
, types
.ClassType
) or
221 not issubclass(cat
, Warning)):
222 raise _OptionError("invalid warning category: %s" % `category`
)
230 opts
, args
= getopt
.getopt(sys
.argv
[1:], "W:")
231 except getopt
.error
, msg
:
232 print >>sys
.stderr
, msg
235 testoptions
.append(a
)
237 _processoptions(testoptions
)
238 except _OptionError
, msg
:
239 print >>sys
.stderr
, msg
241 for item
in filters
: print item
242 hello
= "hello world"
243 warn(hello
); warn(hello
); warn(hello
); warn(hello
)
244 warn(hello
, UserWarning)
245 warn(hello
, DeprecationWarning)
248 filterwarnings("error", "", Warning, "", 0)
251 except Exception, msg
:
252 print "Caught", msg
.__class
__.__name
__ + ":", msg
257 filterwarnings("booh", "", Warning, "", 0)
258 except Exception, msg
:
259 print "Caught", msg
.__class
__.__name
__ + ":", msg
263 # Module initialization
264 if __name__
== "__main__":
266 sys
.modules
['warnings'] = __main__
269 _processoptions(sys
.warnoptions
)
270 filterwarnings("ignore", category
=OverflowWarning, append
=1)
271 filterwarnings("ignore", category
=PendingDeprecationWarning
, append
=1)