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."""
133 assert action
in ("error", "ignore", "always", "default", "module",
134 "once"), "invalid action: %s" % `action`
135 assert isinstance(message
, basestring
), "message must be a string"
136 assert isinstance(category
, types
.ClassType
), "category must be a class"
137 assert issubclass(category
, Warning), "category must be a Warning subclass"
138 assert isinstance(module
, basestring
), "module must be a string"
139 assert isinstance(lineno
, int) and lineno
>= 0, \
140 "lineno must be an int >= 0"
141 item
= (action
, re
.compile(message
, re
.I
), category
,
142 re
.compile(module
), lineno
)
146 filters
.insert(0, item
)
149 """Clear the list of warning filters, so that no filters are active."""
152 class _OptionError(Exception):
153 """Exception used by option processing helpers."""
156 # Helper to process -W options passed via sys.warnoptions
157 def _processoptions(args
):
161 except _OptionError
, msg
:
162 print >>sys
.stderr
, "Invalid -W option ignored:", msg
164 # Helper for _processoptions()
167 parts
= arg
.split(':')
169 raise _OptionError("too many fields (max 5): %s" % `arg`
)
170 while len(parts
) < 5:
172 action
, message
, category
, module
, lineno
= [s
.strip()
174 action
= _getaction(action
)
175 message
= re
.escape(message
)
176 category
= _getcategory(category
)
177 module
= re
.escape(module
)
179 module
= module
+ '$'
185 except (ValueError, OverflowError):
186 raise _OptionError("invalid lineno %s" % `lineno`
)
189 filterwarnings(action
, message
, category
, module
, lineno
)
191 # Helper for _setoption()
192 def _getaction(action
):
195 if action
== "all": return "always" # Alias
196 for a
in ['default', 'always', 'ignore', 'module', 'once', 'error']:
197 if a
.startswith(action
):
199 raise _OptionError("invalid action: %s" % `action`
)
201 # Helper for _setoption()
202 def _getcategory(category
):
206 if re
.match("^[a-zA-Z0-9_]+$", category
):
210 raise _OptionError("unknown warning category: %s" % `category`
)
212 i
= category
.rfind(".")
213 module
= category
[:i
]
214 klass
= category
[i
+1:]
216 m
= __import__(module
, None, None, [klass
])
218 raise _OptionError("invalid module name: %s" % `module`
)
220 cat
= getattr(m
, klass
)
221 except AttributeError:
222 raise _OptionError("unknown warning category: %s" % `category`
)
223 if (not isinstance(cat
, types
.ClassType
) or
224 not issubclass(cat
, Warning)):
225 raise _OptionError("invalid warning category: %s" % `category`
)
233 opts
, args
= getopt
.getopt(sys
.argv
[1:], "W:")
234 except getopt
.error
, msg
:
235 print >>sys
.stderr
, msg
238 testoptions
.append(a
)
240 _processoptions(testoptions
)
241 except _OptionError
, msg
:
242 print >>sys
.stderr
, msg
244 for item
in filters
: print item
245 hello
= "hello world"
246 warn(hello
); warn(hello
); warn(hello
); warn(hello
)
247 warn(hello
, UserWarning)
248 warn(hello
, DeprecationWarning)
251 filterwarnings("error", "", Warning, "", 0)
254 except Exception, msg
:
255 print "Caught", msg
.__class
__.__name
__ + ":", msg
260 filterwarnings("booh", "", Warning, "", 0)
261 except Exception, msg
:
262 print "Caught", msg
.__class
__.__name
__ + ":", msg
266 # Module initialization
267 if __name__
== "__main__":
269 sys
.modules
['warnings'] = __main__
272 _processoptions(sys
.warnoptions
)
273 filterwarnings("ignore", category
=OverflowWarning, append
=1)
274 filterwarnings("ignore", category
=PendingDeprecationWarning
, append
=1)