1 """Python part of the warnings subsystem."""
5 __all__
= ["warn", "showwarning", "formatwarning", "filterwarnings",
8 defaultaction
= "default"
12 def warn(message
, category
=None, stacklevel
=1):
13 """Issue a warning, or maybe ignore it or raise an exception."""
14 # Check if message is already a Warning object
15 if isinstance(message
, Warning):
16 category
= message
.__class
__
17 # Check category argument
19 category
= UserWarning
20 assert issubclass(category
, Warning)
21 # Get context information
23 caller
= sys
._getframe
(stacklevel
)
25 globals = sys
.__dict
__
28 globals = caller
.f_globals
29 lineno
= caller
.f_lineno
30 if '__name__' in globals:
31 module
= globals['__name__']
34 filename
= globals.get('__file__')
36 fnl
= filename
.lower()
37 if fnl
.endswith(".pyc") or fnl
.endswith(".pyo"):
38 filename
= filename
[:-1]
40 if module
== "__main__":
41 filename
= sys
.argv
[0]
44 registry
= globals.setdefault("__warningregistry__", {})
45 warn_explicit(message
, category
, filename
, lineno
, module
, registry
)
47 def warn_explicit(message
, category
, filename
, lineno
,
48 module
=None, registry
=None):
51 if module
[-3:].lower() == ".py":
52 module
= module
[:-3] # XXX What about leading pathname?
55 if isinstance(message
, Warning):
57 category
= message
.__class
__
60 message
= category(message
)
61 key
= (text
, category
, lineno
)
62 # Quick test for common case
67 action
, msg
, cat
, mod
, ln
= item
68 if (msg
.match(text
) and
69 issubclass(category
, cat
) and
71 (ln
== 0 or lineno
== ln
)):
74 action
= defaultaction
76 if action
== "ignore":
84 oncekey
= (text
, category
)
85 if onceregistry
.get(oncekey
):
87 onceregistry
[oncekey
] = 1
88 elif action
== "always":
90 elif action
== "module":
92 altkey
= (text
, category
, 0)
93 if registry
.get(altkey
):
96 elif action
== "default":
99 # Unrecognized actions are errors
101 "Unrecognized action (%s) in warnings.filters:\n %s" %
102 (`action`
, str(item
)))
103 # Print message and context
104 showwarning(message
, category
, filename
, lineno
)
106 def showwarning(message
, category
, filename
, lineno
, file=None):
107 """Hook to write a warning to a file; replace if you like."""
111 file.write(formatwarning(message
, category
, filename
, lineno
))
113 pass # the file (probably stderr) is invalid - this warning gets lost.
115 def formatwarning(message
, category
, filename
, lineno
):
116 """Function to format a warning the standard way."""
118 s
= "%s:%s: %s: %s\n" % (filename
, lineno
, category
.__name
__, message
)
119 line
= linecache
.getline(filename
, lineno
).strip()
121 s
= s
+ " " + line
+ "\n"
124 def filterwarnings(action
, message
="", category
=Warning, module
="", lineno
=0,
126 """Insert an entry into the list of warnings filters (at the front).
128 Use assertions to check that all arguments have the right type."""
129 assert action
in ("error", "ignore", "always", "default", "module",
130 "once"), "invalid action: %s" % `action`
131 assert isinstance(message
, str), "message must be a string"
132 assert isinstance(category
, types
.ClassType
), "category must be a class"
133 assert issubclass(category
, Warning), "category must be a Warning subclass"
134 assert isinstance(module
, str), "module must be a string"
135 assert isinstance(lineno
, int) and lineno
>= 0, \
136 "lineno must be an int >= 0"
137 item
= (action
, re
.compile(message
, re
.I
), category
,
138 re
.compile(module
), lineno
)
142 filters
.insert(0, item
)
145 """Clear the list of warning filters, so that no filters are active."""
148 class _OptionError(Exception):
149 """Exception used by option processing helpers."""
152 # Helper to process -W options passed via sys.warnoptions
153 def _processoptions(args
):
157 except _OptionError
, msg
:
158 print >>sys
.stderr
, "Invalid -W option ignored:", msg
160 # Helper for _processoptions()
162 parts
= arg
.split(':')
164 raise _OptionError("too many fields (max 5): %s" % `arg`
)
165 while len(parts
) < 5:
167 action
, message
, category
, module
, lineno
= [s
.strip()
169 action
= _getaction(action
)
170 message
= re
.escape(message
)
171 category
= _getcategory(category
)
172 module
= re
.escape(module
)
174 module
= module
+ '$'
180 except (ValueError, OverflowError):
181 raise _OptionError("invalid lineno %s" % `lineno`
)
184 filterwarnings(action
, message
, category
, module
, lineno
)
186 # Helper for _setoption()
187 def _getaction(action
):
190 if action
== "all": return "always" # Alias
191 for a
in ['default', 'always', 'ignore', 'module', 'once', 'error']:
192 if a
.startswith(action
):
194 raise _OptionError("invalid action: %s" % `action`
)
196 # Helper for _setoption()
197 def _getcategory(category
):
200 if re
.match("^[a-zA-Z0-9_]+$", category
):
204 raise _OptionError("unknown warning category: %s" % `category`
)
206 i
= category
.rfind(".")
207 module
= category
[:i
]
208 klass
= category
[i
+1:]
210 m
= __import__(module
, None, None, [klass
])
212 raise _OptionError("invalid module name: %s" % `module`
)
214 cat
= getattr(m
, klass
)
215 except AttributeError:
216 raise _OptionError("unknown warning category: %s" % `category`
)
217 if (not isinstance(cat
, types
.ClassType
) or
218 not issubclass(cat
, Warning)):
219 raise _OptionError("invalid warning category: %s" % `category`
)
227 opts
, args
= getopt
.getopt(sys
.argv
[1:], "W:")
228 except getopt
.error
, msg
:
229 print >>sys
.stderr
, msg
232 testoptions
.append(a
)
234 _processoptions(testoptions
)
235 except _OptionError
, msg
:
236 print >>sys
.stderr
, msg
238 for item
in filters
: print item
239 hello
= "hello world"
240 warn(hello
); warn(hello
); warn(hello
); warn(hello
)
241 warn(hello
, UserWarning)
242 warn(hello
, DeprecationWarning)
245 filterwarnings("error", "", Warning, "", 0)
248 except Exception, msg
:
249 print "Caught", msg
.__class
__.__name
__ + ":", msg
254 filterwarnings("booh", "", Warning, "", 0)
255 except Exception, msg
:
256 print "Caught", msg
.__class
__.__name
__ + ":", msg
260 # Module initialization
261 if __name__
== "__main__":
263 sys
.modules
['warnings'] = __main__
266 _processoptions(sys
.warnoptions
)
267 filterwarnings("ignore", category
=OverflowWarning, append
=1)
268 filterwarnings("ignore", category
=PendingDeprecationWarning
, append
=1)