def pytest_pycollect_makeitem(collector, name, obj): outcome = yield res = outcome.get_result() if res is not None: return # nothing was collected elsewhere, let's do it here if isclass(obj): if collector.istestclass(obj, name): Class = collector._getcustomclass("Class") outcome.force_result(Class(name, parent=collector)) elif collector.istestfunction(obj, name): # mock seems to store unbound methods (issue473), normalize it obj = getattr(obj, "__func__", obj) # We need to try and unwrap the function if it's a functools.partial # or a funtools.wrapped. # We musn't if it's been wrapped with mock.patch (python 2 only) if not (isfunction(obj) or isfunction(get_real_func(obj))): collector.warn( code="C2", message="cannot collect %r because it is not a function." % name, ) elif getattr(obj, "__test__", True): if is_generator(obj): res = Generator(name, parent=collector) else: res = list(collector._genfunctions(name, obj)) outcome.force_result(res)
def pytest_pycollect_makeitem(collector, name, obj): outcome = yield res = outcome.get_result() if res is not None: return # nothing was collected elsewhere, let's do it here if isclass(obj): if collector.istestclass(obj, name): Class = collector._getcustomclass("Class") outcome.force_result(Class(name, parent=collector)) elif collector.istestfunction(obj, name): # mock seems to store unbound methods (issue473), normalize it obj = getattr(obj, "__func__", obj) # We need to try and unwrap the function if it's a functools.partial # or a funtools.wrapped. # We musn't if it's been wrapped with mock.patch (python 2 only) if not (isfunction(obj) or isfunction(get_real_func(obj))): collector.warn(code="C2", message="cannot collect %r because it is not a function." % name, ) elif getattr(obj, "__test__", True): if is_generator(obj): res = Generator(name, parent=collector) else: res = list(collector._genfunctions(name, obj)) outcome.force_result(res)
def _idval(val, argname, idx, idfn, config=None): if idfn: s = None try: s = idfn(val) except Exception: # See issue https://github.com/pytest-dev/pytest/issues/2169 import warnings msg = "Raised while trying to determine id of parameter %s at position %d." % (argname, idx) msg += '\nUpdate your code as this will raise an error in pytest-4.0.' warnings.warn(msg, DeprecationWarning) if s: return ascii_escaped(s) if config: hook_id = config.hook.pytest_make_parametrize_id( config=config, val=val, argname=argname) if hook_id: return hook_id if isinstance(val, STRING_TYPES): return ascii_escaped(val) elif isinstance(val, (float, int, bool, NoneType)): return str(val) elif isinstance(val, REGEX_TYPE): return ascii_escaped(val.pattern) elif enum is not None and isinstance(val, enum.Enum): return str(val) elif isclass(val) and hasattr(val, '__name__'): return val.__name__ return str(argname) + str(idx)
def _idval(val, argname, idx, idfn, item, config): if idfn: s = None try: s = idfn(val) except Exception as e: # See issue https://github.com/pytest-dev/pytest/issues/2169 msg = "{}: error raised while trying to determine id of parameter '{}' at position {}\n" msg = msg.format(item.nodeid, argname, idx) # we only append the exception type and message because on Python 2 reraise does nothing msg += " {}: {}\n".format(type(e).__name__, e) six.raise_from(ValueError(msg), e) if s: return ascii_escaped(s) if config: hook_id = config.hook.pytest_make_parametrize_id( config=config, val=val, argname=argname ) if hook_id: return hook_id if isinstance(val, STRING_TYPES): return ascii_escaped(val) elif isinstance(val, (float, int, bool, NoneType)): return str(val) elif isinstance(val, REGEX_TYPE): return ascii_escaped(val.pattern) elif enum is not None and isinstance(val, enum.Enum): return str(val) elif (isclass(val) or isfunction(val)) and hasattr(val, "__name__"): return val.__name__ return str(argname) + str(idx)
def _idval(val, argname, idx, idfn, config=None): if idfn: s = None try: s = idfn(val) except Exception: # See issue https://github.com/pytest-dev/pytest/issues/2169 import warnings msg = "Raised while trying to determine id of parameter %s at position %d." % ( argname, idx) msg += '\nUpdate your code as this will raise an error in pytest-4.0.' warnings.warn(msg, DeprecationWarning) if s: return ascii_escaped(s) if config: hook_id = config.hook.pytest_make_parametrize_id(config=config, val=val, argname=argname) if hook_id: return hook_id if isinstance(val, STRING_TYPES): return ascii_escaped(val) elif isinstance(val, (float, int, bool, NoneType)): return str(val) elif isinstance(val, REGEX_TYPE): return ascii_escaped(val.pattern) elif enum is not None and isinstance(val, enum.Enum): return str(val) elif isclass(val) and hasattr(val, '__name__'): return val.__name__ return str(argname) + str(idx)
def __call__(self, function): if isclass(function): raise ValueError( "class fixtures not supported (may be in the future)") if getattr(function, "_pytestfixturefunction", False): raise ValueError( "fixture is being applied more than once to the same function") function._pytestfixturefunction = self return function
def __call__(self, function): if isclass(function): raise ValueError("class fixtures not supported (may be in the future)") if getattr(function, "_pytestfixturefunction", False): raise ValueError( "fixture is being applied more than once to the same function" ) function._pytestfixturefunction = self return function
def __call__(self, function): if isclass(function): raise ValueError("class fixtures not supported (maybe in the future)") if getattr(function, "_pytestfixturefunction", False): raise ValueError( "fixture is being applied more than once to the same function" ) function = wrap_function_to_error_out_if_called_directly(function, self) name = self.name or function.__name__ if name == "request": warnings.warn(FIXTURE_NAMED_REQUEST) function._pytestfixturefunction = self return function
def __call__(self, function): if isclass(function): raise ValueError( "class fixtures not supported (may be in the future)") function._pytestfixturefunction = self return function
def raises(expected_exception, *args, **kwargs): """ Assert that a code block/function call raises ``expected_exception`` and raise a failure exception otherwise. This helper produces a ``ExceptionInfo()`` object (see below). If using Python 2.5 or above, you may use this function as a context manager:: >>> with raises(ZeroDivisionError): ... 1/0 .. versionchanged:: 2.10 In the context manager form you may use the keyword argument ``message`` to specify a custom failure message:: >>> with raises(ZeroDivisionError, message="Expecting ZeroDivisionError"): ... pass Traceback (most recent call last): ... Failed: Expecting ZeroDivisionError .. note:: When using ``pytest.raises`` as a context manager, it's worthwhile to note that normal context manager rules apply and that the exception raised *must* be the final line in the scope of the context manager. Lines of code after that, within the scope of the context manager will not be executed. For example:: >>> value = 15 >>> with raises(ValueError) as exc_info: ... if value > 10: ... raise ValueError("value must be <= 10") ... assert exc_info.type == ValueError # this will not execute Instead, the following approach must be taken (note the difference in scope):: >>> with raises(ValueError) as exc_info: ... if value > 10: ... raise ValueError("value must be <= 10") ... >>> assert exc_info.type == ValueError Since version ``3.1`` you can use the keyword argument ``match`` to assert that the exception matches a text or regex:: >>> with raises(ValueError, match='must be 0 or None'): ... raise ValueError("value must be 0 or None") >>> with raises(ValueError, match=r'must be \d+$'): ... raise ValueError("value must be 42") **Legacy forms** The forms below are fully supported but are discouraged for new code because the context manager form is regarded as more readable and less error-prone. It is possible to specify a callable by passing a to-be-called lambda:: >>> raises(ZeroDivisionError, lambda: 1/0) <ExceptionInfo ...> or you can specify an arbitrary callable with arguments:: >>> def f(x): return 1/x ... >>> raises(ZeroDivisionError, f, 0) <ExceptionInfo ...> >>> raises(ZeroDivisionError, f, x=0) <ExceptionInfo ...> It is also possible to pass a string to be evaluated at runtime:: >>> raises(ZeroDivisionError, "f(0)") <ExceptionInfo ...> The string will be evaluated using the same ``locals()`` and ``globals()`` at the moment of the ``raises`` call. .. autoclass:: _pytest._code.ExceptionInfo :members: .. note:: Similar to caught exception objects in Python, explicitly clearing local references to returned ``ExceptionInfo`` objects can help the Python interpreter speed up its garbage collection. Clearing those references breaks a reference cycle (``ExceptionInfo`` --> caught exception --> frame stack raising the exception --> current frame stack --> local variables --> ``ExceptionInfo``) which makes Python keep all objects referenced from that cycle (including all local variables in the current frame) alive until the next cyclic garbage collection run. See the official Python ``try`` statement documentation for more detailed information. """ __tracebackhide__ = True msg = ("exceptions must be old-style classes or" " derived from BaseException, not %s") if isinstance(expected_exception, tuple): for exc in expected_exception: if not isclass(exc): raise TypeError(msg % type(exc)) elif not isclass(expected_exception): raise TypeError(msg % type(expected_exception)) message = "DID NOT RAISE {0}".format(expected_exception) match_expr = None if not args: if "message" in kwargs: message = kwargs.pop("message") if "match" in kwargs: match_expr = kwargs.pop("match") message += " matching '{0}'".format(match_expr) return RaisesContext(expected_exception, message, match_expr) elif isinstance(args[0], str): code, = args assert isinstance(code, str) frame = sys._getframe(1) loc = frame.f_locals.copy() loc.update(kwargs) # print "raises frame scope: %r" % frame.f_locals try: code = _pytest._code.Source(code).compile() py.builtin.exec_(code, frame.f_globals, loc) # XXX didn'T mean f_globals == f_locals something special? # this is destroyed here ... except expected_exception: return _pytest._code.ExceptionInfo() else: func = args[0] try: func(*args[1:], **kwargs) except expected_exception: return _pytest._code.ExceptionInfo() fail(message)