97 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Python
		
	
	
	
| from __future__ import absolute_import, division, print_function
 | |
| 
 | |
| import warnings
 | |
| from contextlib import contextmanager
 | |
| 
 | |
| import pytest
 | |
| 
 | |
| from _pytest import compat
 | |
| 
 | |
| 
 | |
| def _setoption(wmod, arg):
 | |
|     """
 | |
|     Copy of the warning._setoption function but does not escape arguments.
 | |
|     """
 | |
|     parts = arg.split(':')
 | |
|     if len(parts) > 5:
 | |
|         raise wmod._OptionError("too many fields (max 5): %r" % (arg,))
 | |
|     while len(parts) < 5:
 | |
|         parts.append('')
 | |
|     action, message, category, module, lineno = [s.strip()
 | |
|                                                  for s in parts]
 | |
|     action = wmod._getaction(action)
 | |
|     category = wmod._getcategory(category)
 | |
|     if lineno:
 | |
|         try:
 | |
|             lineno = int(lineno)
 | |
|             if lineno < 0:
 | |
|                 raise ValueError
 | |
|         except (ValueError, OverflowError):
 | |
|             raise wmod._OptionError("invalid lineno %r" % (lineno,))
 | |
|     else:
 | |
|         lineno = 0
 | |
|     wmod.filterwarnings(action, message, category, module, lineno)
 | |
| 
 | |
| 
 | |
| def pytest_addoption(parser):
 | |
|     group = parser.getgroup("pytest-warnings")
 | |
|     group.addoption(
 | |
|         '-W', '--pythonwarnings', action='append',
 | |
|         help="set which warnings to report, see -W option of python itself.")
 | |
|     parser.addini("filterwarnings", type="linelist",
 | |
|                   help="Each line specifies a pattern for "
 | |
|                   "warnings.filterwarnings. "
 | |
|                   "Processed after -W and --pythonwarnings.")
 | |
| 
 | |
| 
 | |
| @contextmanager
 | |
| def catch_warnings_for_item(item):
 | |
|     """
 | |
|     catches the warnings generated during setup/call/teardown execution
 | |
|     of the given item and after it is done posts them as warnings to this
 | |
|     item.
 | |
|     """
 | |
|     args = item.config.getoption('pythonwarnings') or []
 | |
|     inifilters = item.config.getini("filterwarnings")
 | |
|     with warnings.catch_warnings(record=True) as log:
 | |
|         for arg in args:
 | |
|             warnings._setoption(arg)
 | |
| 
 | |
|         for arg in inifilters:
 | |
|             _setoption(warnings, arg)
 | |
| 
 | |
|         mark = item.get_marker('filterwarnings')
 | |
|         if mark:
 | |
|             for arg in mark.args:
 | |
|                 warnings._setoption(arg)
 | |
| 
 | |
|         yield
 | |
| 
 | |
|         for warning in log:
 | |
|             warn_msg = warning.message
 | |
|             unicode_warning = False
 | |
| 
 | |
|             if compat._PY2 and any(isinstance(m, compat.UNICODE_TYPES) for m in warn_msg.args):
 | |
|                 new_args = []
 | |
|                 for m in warn_msg.args:
 | |
|                     new_args.append(compat.ascii_escaped(m) if isinstance(m, compat.UNICODE_TYPES) else m)
 | |
|                 unicode_warning = list(warn_msg.args) != new_args
 | |
|                 warn_msg.args = new_args
 | |
| 
 | |
|             msg = warnings.formatwarning(
 | |
|                 warn_msg, warning.category,
 | |
|                 warning.filename, warning.lineno, warning.line)
 | |
|             item.warn("unused", msg)
 | |
| 
 | |
|             if unicode_warning:
 | |
|                 warnings.warn(
 | |
|                     "Warning is using unicode non convertible to ascii, "
 | |
|                     "converting to a safe representation:\n  %s" % msg,
 | |
|                     UnicodeWarning)
 | |
| 
 | |
| 
 | |
| @pytest.hookimpl(hookwrapper=True)
 | |
| def pytest_runtest_protocol(item):
 | |
|     with catch_warnings_for_item(item):
 | |
|         yield
 |