]> git.proxmox.com Git - mirror_edk2.git/blob - AppPkg/Applications/Python/Python-2.7.10/Lib/warnings.py
AppPkg/Applications/Python/Python-2.7.10: Initial Checkin part 4/5.
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.10 / Lib / warnings.py
1 """Python part of the warnings subsystem."""
2
3 # Note: function level imports should *not* be used
4 # in this module as it may cause import lock deadlock.
5 # See bug 683658.
6 import linecache
7 import sys
8 import types
9
10 __all__ = ["warn", "warn_explicit", "showwarning",
11 "formatwarning", "filterwarnings", "simplefilter",
12 "resetwarnings", "catch_warnings"]
13
14
15 def warnpy3k(message, category=None, stacklevel=1):
16 """Issue a deprecation warning for Python 3.x related changes.
17
18 Warnings are omitted unless Python is started with the -3 option.
19 """
20 if sys.py3kwarning:
21 if category is None:
22 category = DeprecationWarning
23 warn(message, category, stacklevel+1)
24
25 def _show_warning(message, category, filename, lineno, file=None, line=None):
26 """Hook to write a warning to a file; replace if you like."""
27 if file is None:
28 file = sys.stderr
29 if file is None:
30 # sys.stderr is None - warnings get lost
31 return
32 try:
33 file.write(formatwarning(message, category, filename, lineno, line))
34 except IOError:
35 pass # the file (probably stderr) is invalid - this warning gets lost.
36 # Keep a working version around in case the deprecation of the old API is
37 # triggered.
38 showwarning = _show_warning
39
40 def formatwarning(message, category, filename, lineno, line=None):
41 """Function to format a warning the standard way."""
42 s = "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message)
43 line = linecache.getline(filename, lineno) if line is None else line
44 if line:
45 line = line.strip()
46 s += " %s\n" % line
47 return s
48
49 def filterwarnings(action, message="", category=Warning, module="", lineno=0,
50 append=0):
51 """Insert an entry into the list of warnings filters (at the front).
52
53 'action' -- one of "error", "ignore", "always", "default", "module",
54 or "once"
55 'message' -- a regex that the warning message must match
56 'category' -- a class that the warning must be a subclass of
57 'module' -- a regex that the module name must match
58 'lineno' -- an integer line number, 0 matches all warnings
59 'append' -- if true, append to the list of filters
60 """
61 import re
62 assert action in ("error", "ignore", "always", "default", "module",
63 "once"), "invalid action: %r" % (action,)
64 assert isinstance(message, basestring), "message must be a string"
65 assert isinstance(category, (type, types.ClassType)), \
66 "category must be a class"
67 assert issubclass(category, Warning), "category must be a Warning subclass"
68 assert isinstance(module, basestring), "module must be a string"
69 assert isinstance(lineno, int) and lineno >= 0, \
70 "lineno must be an int >= 0"
71 item = (action, re.compile(message, re.I), category,
72 re.compile(module), lineno)
73 if append:
74 filters.append(item)
75 else:
76 filters.insert(0, item)
77
78 def simplefilter(action, category=Warning, lineno=0, append=0):
79 """Insert a simple entry into the list of warnings filters (at the front).
80
81 A simple filter matches all modules and messages.
82 'action' -- one of "error", "ignore", "always", "default", "module",
83 or "once"
84 'category' -- a class that the warning must be a subclass of
85 'lineno' -- an integer line number, 0 matches all warnings
86 'append' -- if true, append to the list of filters
87 """
88 assert action in ("error", "ignore", "always", "default", "module",
89 "once"), "invalid action: %r" % (action,)
90 assert isinstance(lineno, int) and lineno >= 0, \
91 "lineno must be an int >= 0"
92 item = (action, None, category, None, lineno)
93 if append:
94 filters.append(item)
95 else:
96 filters.insert(0, item)
97
98 def resetwarnings():
99 """Clear the list of warning filters, so that no filters are active."""
100 filters[:] = []
101
102 class _OptionError(Exception):
103 """Exception used by option processing helpers."""
104 pass
105
106 # Helper to process -W options passed via sys.warnoptions
107 def _processoptions(args):
108 for arg in args:
109 try:
110 _setoption(arg)
111 except _OptionError, msg:
112 print >>sys.stderr, "Invalid -W option ignored:", msg
113
114 # Helper for _processoptions()
115 def _setoption(arg):
116 import re
117 parts = arg.split(':')
118 if len(parts) > 5:
119 raise _OptionError("too many fields (max 5): %r" % (arg,))
120 while len(parts) < 5:
121 parts.append('')
122 action, message, category, module, lineno = [s.strip()
123 for s in parts]
124 action = _getaction(action)
125 message = re.escape(message)
126 category = _getcategory(category)
127 module = re.escape(module)
128 if module:
129 module = module + '$'
130 if lineno:
131 try:
132 lineno = int(lineno)
133 if lineno < 0:
134 raise ValueError
135 except (ValueError, OverflowError):
136 raise _OptionError("invalid lineno %r" % (lineno,))
137 else:
138 lineno = 0
139 filterwarnings(action, message, category, module, lineno)
140
141 # Helper for _setoption()
142 def _getaction(action):
143 if not action:
144 return "default"
145 if action == "all": return "always" # Alias
146 for a in ('default', 'always', 'ignore', 'module', 'once', 'error'):
147 if a.startswith(action):
148 return a
149 raise _OptionError("invalid action: %r" % (action,))
150
151 # Helper for _setoption()
152 def _getcategory(category):
153 import re
154 if not category:
155 return Warning
156 if re.match("^[a-zA-Z0-9_]+$", category):
157 try:
158 cat = eval(category)
159 except NameError:
160 raise _OptionError("unknown warning category: %r" % (category,))
161 else:
162 i = category.rfind(".")
163 module = category[:i]
164 klass = category[i+1:]
165 try:
166 m = __import__(module, None, None, [klass])
167 except ImportError:
168 raise _OptionError("invalid module name: %r" % (module,))
169 try:
170 cat = getattr(m, klass)
171 except AttributeError:
172 raise _OptionError("unknown warning category: %r" % (category,))
173 if not issubclass(cat, Warning):
174 raise _OptionError("invalid warning category: %r" % (category,))
175 return cat
176
177
178 # Code typically replaced by _warnings
179 def warn(message, category=None, stacklevel=1):
180 """Issue a warning, or maybe ignore it or raise an exception."""
181 # Check if message is already a Warning object
182 if isinstance(message, Warning):
183 category = message.__class__
184 # Check category argument
185 if category is None:
186 category = UserWarning
187 assert issubclass(category, Warning)
188 # Get context information
189 try:
190 caller = sys._getframe(stacklevel)
191 except ValueError:
192 globals = sys.__dict__
193 lineno = 1
194 else:
195 globals = caller.f_globals
196 lineno = caller.f_lineno
197 if '__name__' in globals:
198 module = globals['__name__']
199 else:
200 module = "<string>"
201 filename = globals.get('__file__')
202 if filename:
203 fnl = filename.lower()
204 if fnl.endswith((".pyc", ".pyo")):
205 filename = filename[:-1]
206 else:
207 if module == "__main__":
208 try:
209 filename = sys.argv[0]
210 except AttributeError:
211 # embedded interpreters don't have sys.argv, see bug #839151
212 filename = '__main__'
213 if not filename:
214 filename = module
215 registry = globals.setdefault("__warningregistry__", {})
216 warn_explicit(message, category, filename, lineno, module, registry,
217 globals)
218
219 def warn_explicit(message, category, filename, lineno,
220 module=None, registry=None, module_globals=None):
221 lineno = int(lineno)
222 if module is None:
223 module = filename or "<unknown>"
224 if module[-3:].lower() == ".py":
225 module = module[:-3] # XXX What about leading pathname?
226 if registry is None:
227 registry = {}
228 if isinstance(message, Warning):
229 text = str(message)
230 category = message.__class__
231 else:
232 text = message
233 message = category(message)
234 key = (text, category, lineno)
235 # Quick test for common case
236 if registry.get(key):
237 return
238 # Search the filters
239 for item in filters:
240 action, msg, cat, mod, ln = item
241 if ((msg is None or msg.match(text)) and
242 issubclass(category, cat) and
243 (mod is None or mod.match(module)) and
244 (ln == 0 or lineno == ln)):
245 break
246 else:
247 action = defaultaction
248 # Early exit actions
249 if action == "ignore":
250 registry[key] = 1
251 return
252
253 # Prime the linecache for formatting, in case the
254 # "file" is actually in a zipfile or something.
255 linecache.getlines(filename, module_globals)
256
257 if action == "error":
258 raise message
259 # Other actions
260 if action == "once":
261 registry[key] = 1
262 oncekey = (text, category)
263 if onceregistry.get(oncekey):
264 return
265 onceregistry[oncekey] = 1
266 elif action == "always":
267 pass
268 elif action == "module":
269 registry[key] = 1
270 altkey = (text, category, 0)
271 if registry.get(altkey):
272 return
273 registry[altkey] = 1
274 elif action == "default":
275 registry[key] = 1
276 else:
277 # Unrecognized actions are errors
278 raise RuntimeError(
279 "Unrecognized action (%r) in warnings.filters:\n %s" %
280 (action, item))
281 # Print message and context
282 showwarning(message, category, filename, lineno)
283
284
285 class WarningMessage(object):
286
287 """Holds the result of a single showwarning() call."""
288
289 _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file",
290 "line")
291
292 def __init__(self, message, category, filename, lineno, file=None,
293 line=None):
294 local_values = locals()
295 for attr in self._WARNING_DETAILS:
296 setattr(self, attr, local_values[attr])
297 self._category_name = category.__name__ if category else None
298
299 def __str__(self):
300 return ("{message : %r, category : %r, filename : %r, lineno : %s, "
301 "line : %r}" % (self.message, self._category_name,
302 self.filename, self.lineno, self.line))
303
304
305 class catch_warnings(object):
306
307 """A context manager that copies and restores the warnings filter upon
308 exiting the context.
309
310 The 'record' argument specifies whether warnings should be captured by a
311 custom implementation of warnings.showwarning() and be appended to a list
312 returned by the context manager. Otherwise None is returned by the context
313 manager. The objects appended to the list are arguments whose attributes
314 mirror the arguments to showwarning().
315
316 The 'module' argument is to specify an alternative module to the module
317 named 'warnings' and imported under that name. This argument is only useful
318 when testing the warnings module itself.
319
320 """
321
322 def __init__(self, record=False, module=None):
323 """Specify whether to record warnings and if an alternative module
324 should be used other than sys.modules['warnings'].
325
326 For compatibility with Python 3.0, please consider all arguments to be
327 keyword-only.
328
329 """
330 self._record = record
331 self._module = sys.modules['warnings'] if module is None else module
332 self._entered = False
333
334 def __repr__(self):
335 args = []
336 if self._record:
337 args.append("record=True")
338 if self._module is not sys.modules['warnings']:
339 args.append("module=%r" % self._module)
340 name = type(self).__name__
341 return "%s(%s)" % (name, ", ".join(args))
342
343 def __enter__(self):
344 if self._entered:
345 raise RuntimeError("Cannot enter %r twice" % self)
346 self._entered = True
347 self._filters = self._module.filters
348 self._module.filters = self._filters[:]
349 self._showwarning = self._module.showwarning
350 if self._record:
351 log = []
352 def showwarning(*args, **kwargs):
353 log.append(WarningMessage(*args, **kwargs))
354 self._module.showwarning = showwarning
355 return log
356 else:
357 return None
358
359 def __exit__(self, *exc_info):
360 if not self._entered:
361 raise RuntimeError("Cannot exit %r without entering first" % self)
362 self._module.filters = self._filters
363 self._module.showwarning = self._showwarning
364
365
366 # filters contains a sequence of filter 5-tuples
367 # The components of the 5-tuple are:
368 # - an action: error, ignore, always, default, module, or once
369 # - a compiled regex that must match the warning message
370 # - a class representing the warning category
371 # - a compiled regex that must match the module that is being warned
372 # - a line number for the line being warning, or 0 to mean any line
373 # If either if the compiled regexs are None, match anything.
374 _warnings_defaults = False
375 try:
376 from _warnings import (filters, default_action, once_registry,
377 warn, warn_explicit)
378 defaultaction = default_action
379 onceregistry = once_registry
380 _warnings_defaults = True
381 except ImportError:
382 filters = []
383 defaultaction = "default"
384 onceregistry = {}
385
386
387 # Module initialization
388 _processoptions(sys.warnoptions)
389 if not _warnings_defaults:
390 silence = [ImportWarning, PendingDeprecationWarning]
391 # Don't silence DeprecationWarning if -3 or -Q was used.
392 if not sys.py3kwarning and not sys.flags.division_warning:
393 silence.append(DeprecationWarning)
394 for cls in silence:
395 simplefilter("ignore", category=cls)
396 bytes_warning = sys.flags.bytes_warning
397 if bytes_warning > 1:
398 bytes_action = "error"
399 elif bytes_warning:
400 bytes_action = "default"
401 else:
402 bytes_action = "ignore"
403 simplefilter(bytes_action, category=BytesWarning, append=1)
404 del _warnings_defaults