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 category argument
16 category
= UserWarning
17 assert issubclass(category
, Warning)
18 # Get context information
20 caller
= sys
._getframe
(stacklevel
)
22 globals = sys
.__dict
__
25 globals = caller
.f_globals
26 lineno
= caller
.f_lineno
27 if globals.has_key('__name__'):
28 module
= globals['__name__']
31 filename
= globals.get('__file__')
33 fnl
= filename
.lower()
34 if fnl
.endswith(".pyc") or fnl
.endswith(".pyo"):
35 filename
= filename
[:-1]
37 if module
== "__main__":
38 filename
= sys
.argv
[0]
41 registry
= globals.setdefault("__warningregistry__", {})
42 warn_explicit(message
, category
, filename
, lineno
, module
, registry
)
44 def warn_explicit(message
, category
, filename
, lineno
,
45 module
=None, registry
=None):
48 if module
[-3:].lower() == ".py":
49 module
= module
[:-3] # XXX What about leading pathname?
52 key
= (message
, category
, lineno
)
53 # Quick test for common case
58 action
, msg
, cat
, mod
, ln
= item
59 if (msg
.match(message
) and
60 issubclass(category
, cat
) and
62 (ln
== 0 or lineno
== ln
)):
65 action
= defaultaction
67 if action
== "ignore":
71 raise category(message
)
75 oncekey
= (message
, category
)
76 if onceregistry
.get(oncekey
):
78 onceregistry
[oncekey
] = 1
79 elif action
== "always":
81 elif action
== "module":
83 altkey
= (message
, category
, 0)
84 if registry
.get(altkey
):
87 elif action
== "default":
90 # Unrecognized actions are errors
92 "Unrecognized action (%s) in warnings.filters:\n %s" %
93 (`action`
, str(item
)))
94 # Print message and context
95 showwarning(message
, category
, filename
, lineno
)
97 def showwarning(message
, category
, filename
, lineno
, file=None):
98 """Hook to write a warning to a file; replace if you like."""
101 file.write(formatwarning(message
, category
, filename
, lineno
))
103 def formatwarning(message
, category
, filename
, lineno
):
104 """Function to format a warning the standard way."""
106 s
= "%s:%s: %s: %s\n" % (filename
, lineno
, category
.__name
__, message
)
107 line
= linecache
.getline(filename
, lineno
).strip()
109 s
= s
+ " " + line
+ "\n"
112 def filterwarnings(action
, message
="", category
=Warning, module
="", lineno
=0,
114 """Insert an entry into the list of warnings filters (at the front).
116 Use assertions to check that all arguments have the right type."""
117 assert action
in ("error", "ignore", "always", "default", "module",
118 "once"), "invalid action: %s" % `action`
119 assert isinstance(message
, types
.StringType
), "message must be a string"
120 assert isinstance(category
, types
.ClassType
), "category must be a class"
121 assert issubclass(category
, Warning), "category must be a Warning subclass"
122 assert type(module
) is types
.StringType
, "module must be a string"
123 assert type(lineno
) is types
.IntType
and lineno
>= 0, \
124 "lineno must be an int >= 0"
125 item
= (action
, re
.compile(message
, re
.I
), category
,
126 re
.compile(module
), lineno
)
130 filters
.insert(0, item
)
133 """Reset the list of warnings filters to its default state."""
136 class _OptionError(Exception):
137 """Exception used by option processing helpers."""
140 # Helper to process -W options passed via sys.warnoptions
141 def _processoptions(args
):
145 except _OptionError
, msg
:
146 print >>sys
.stderr
, "Invalid -W option ignored:", msg
148 # Helper for _processoptions()
150 parts
= arg
.split(':')
152 raise _OptionError("too many fields (max 5): %s" % `arg`
)
153 while len(parts
) < 5:
155 action
, message
, category
, module
, lineno
= [s
.strip()
157 action
= _getaction(action
)
158 message
= re
.escape(message
)
159 category
= _getcategory(category
)
160 module
= re
.escape(module
)
162 module
= module
+ '$'
168 except (ValueError, OverflowError):
169 raise _OptionError("invalid lineno %s" % `lineno`
)
172 filterwarnings(action
, message
, category
, module
, lineno
)
174 # Helper for _setoption()
175 def _getaction(action
):
178 if action
== "all": return "always" # Alias
179 for a
in ['default', 'always', 'ignore', 'module', 'once', 'error']:
180 if a
.startswith(action
):
182 raise _OptionError("invalid action: %s" % `action`
)
184 # Helper for _setoption()
185 def _getcategory(category
):
188 if re
.match("^[a-zA-Z0-9_]+$", category
):
192 raise _OptionError("unknown warning category: %s" % `category`
)
194 i
= category
.rfind(".")
195 module
= category
[:i
]
196 klass
= category
[i
+1:]
198 m
= __import__(module
, None, None, [klass
])
200 raise _OptionError("invalid module name: %s" % `module`
)
202 cat
= getattr(m
, klass
)
203 except AttributeError:
204 raise _OptionError("unknown warning category: %s" % `category`
)
205 if (not isinstance(cat
, types
.ClassType
) or
206 not issubclass(cat
, Warning)):
207 raise _OptionError("invalid warning category: %s" % `category`
)
215 opts
, args
= getopt
.getopt(sys
.argv
[1:], "W:")
216 except getopt
.error
, msg
:
217 print >>sys
.stderr
, msg
220 testoptions
.append(a
)
222 _processoptions(testoptions
)
223 except _OptionError
, msg
:
224 print >>sys
.stderr
, msg
226 for item
in filters
: print item
227 hello
= "hello world"
228 warn(hello
); warn(hello
); warn(hello
); warn(hello
)
229 warn(hello
, UserWarning)
230 warn(hello
, DeprecationWarning)
233 filterwarnings("error", "", Warning, "", 0)
236 except Exception, msg
:
237 print "Caught", msg
.__class
__.__name
__ + ":", msg
242 filterwarnings("booh", "", Warning, "", 0)
243 except Exception, msg
:
244 print "Caught", msg
.__class
__.__name
__ + ":", msg
248 # Module initialization
249 if __name__
== "__main__":
251 sys
.modules
['warnings'] = __main__
254 _processoptions(sys
.warnoptions
)
255 filterwarnings("ignore", category
=OverflowWarning, append
=1)