def always_iterable(item): """ Given an object, always return an iterable. If the item is not already iterable, return a tuple containing only the item. If item is None, an empty iterable is returned. >>> always_iterable([1,2,3]) [1, 2, 3] >>> always_iterable('foo') ('foo',) >>> always_iterable(None) () >>> always_iterable(range(10)) range(0, 10) >>> def _test_func(): yield "I'm iterable" >>> print(next(always_iterable(_test_func()))) I'm iterable Although mappings are iterable, treat each like a singleton, as it's more like an object than a sequence. >>> always_iterable(dict(a=1)) ({'a': 1},) """ return ( (item,) if isinstance(item, collections.Mapping) else more.always_iterable(item) )
def merge_styles(self, offline: bool) -> Iterator[Fuss]: """Merge one or multiple style files.""" config = self.read_configuration() # pylint: disable=import-outside-toplevel from nitpick.style import StyleManager style = StyleManager(self, offline, config.cache) base = config.file.expanduser().resolve().as_uri( ) if config.file else None style_errors = list( style.find_initial_styles(peekable(always_iterable(config.styles)), base)) if style_errors: raise QuitComplainingError(style_errors) self.style_dict = style.merge_toml_dict() from nitpick.flake8 import NitpickFlake8Extension minimum_version = search_json(self.style_dict, NITPICK_MINIMUM_VERSION_JMEX, None) logger.debug(f"Minimum version: {minimum_version}") if minimum_version and version_to_tuple( NitpickFlake8Extension.version) < version_to_tuple( minimum_version): yield Reporter().make_fuss( ProjectViolations.MINIMUM_VERSION, project=PROJECT_NAME, expected=minimum_version, actual=NitpickFlake8Extension.version, ) self.nitpick_section = self.style_dict.get("nitpick", {}) self.nitpick_files_section = self.nitpick_section.get("files", {})
def always_iterable(item): """ Given an object, always return an iterable. If the item is not already iterable, return a tuple containing only the item. If item is None, an empty iterable is returned. >>> always_iterable([1,2,3]) <list_iterator...> >>> always_iterable('foo') <tuple_iterator...> >>> always_iterable(None) <tuple_iterator...> >>> always_iterable(range(10)) <range_iterator...> >>> def _test_func(): yield "I'm iterable" >>> print(next(always_iterable(_test_func()))) I'm iterable Although mappings are iterable, treat each like a singleton, as it's more like an object than a sequence. >>> next(always_iterable(dict(a=1))) {'a': 1} """ base_types = six.text_type, bytes, collections.abc.Mapping return more.always_iterable(item, base_type=base_types)
def default_from_config(keys, defaults): _keys = list(always_iterable(keys)) _defaults = list(always_iterable(defaults)) def getter(field): ftype, fname = self.data_source._determine_fields(field)[0] ret = [ ytcfg.get_most_specific("plot", ftype, fname, key, fallback=default) for key, default in zip(_keys, _defaults) ] if len(ret) == 1: return ret[0] return ret return getter
def assertStatus(self, status, msg=None): """Fail if self.status != status. status may be integer code, exact string status, or iterable of allowed possibilities. """ if any(map(self.status_matches, always_iterable(status))): return tmpl = 'Status {self.status} does not match {status}' msg = msg or tmpl.format(**locals()) self._handlewebError(msg)
def assertStatus(self, status, msg=None): """Fail if self.status != status. status may be integer code, exact string status, or iterable of allowed possibilities. """ if any(map(self.status_matches, always_iterable(status))): return tmpl = 'Status {self.status} does not match {status}' msg = msg or tmpl.format(**locals()) self._handlewebError(msg)
def radar2mat(radars, axis=1, as_dict=False, **kwargs): '''Render one or more radar files as a 4d array''' #from IPython.core.debugger import set_trace; set_trace() radars = always_iterable(radars) results = [radar2mat_single(r, **kwargs) for r in radars] data = np.concatenate([r[0] for r in results], axis=axis) coords = [r[1:] for r in results] # coords[i] = (fields, elev, y, x) or (fields, elev, range, azimuth) combined_coords = list(coords[0]) combined_coords[axis] = np.concatenate([r[axis] for r in coords]) if as_dict: fields = coords[1] data = {f: v for f, v in zip(fields, data)} return (data, ) + tuple(combined_coords)
def _simulate_cli(self, command: str, expected_str_or_lines: StrOrList = None, *args: str, exit_code: int = None): """Simulate the CLI by invoking a click command. 1. If the command raised an exception that was not a common "system exit", this method will re-raise it, so the test can be fixed. """ result = CliRunner().invoke(nitpick_cli, ["--project", str(self.root_dir), command, *args]) # 1. if result.exception and not isinstance(result.exception, SystemExit): raise result.exception actual: list[str] = result.output.splitlines() if isinstance(expected_str_or_lines, str): expected = dedent(expected_str_or_lines).strip().splitlines() else: expected = list(always_iterable(expected_str_or_lines)) compare(actual=result.exit_code, expected=exit_code or 0) return result, actual, expected
def raises(expected_exception, *args, **kwargs): r""" Assert that a code block/function call raises ``expected_exception`` and raise a failure exception otherwise. :arg message: if specified, provides a custom failure message if the exception is not raised :arg match: if specified, asserts that the exception matches a text or regex This helper produces a ``ExceptionInfo()`` object (see below). 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. .. currentmodule:: _pytest._code Consult the API of ``excinfo`` objects: :class:`ExceptionInfo`. .. 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 for exc in filterfalse(isclass, always_iterable(expected_exception, BASE_TYPE)): msg = ( "exceptions must be old-style classes or" " derived from BaseException, not %s" ) raise TypeError(msg % type(exc)) message = "DID NOT RAISE {}".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") if kwargs: msg = "Unexpected keyword arguments passed to pytest.raises: " msg += ", ".join(kwargs.keys()) raise TypeError(msg) 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)
def raises(expected_exception, *args, **kwargs): r""" Assert that a code block/function call raises ``expected_exception`` and raise a failure exception otherwise. :arg message: if specified, provides a custom failure message if the exception is not raised :arg match: if specified, asserts that the exception matches a text or regex This helper produces a ``ExceptionInfo()`` object (see below). 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. .. currentmodule:: _pytest._code Consult the API of ``excinfo`` objects: :class:`ExceptionInfo`. .. 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 for exc in filterfalse(isclass, always_iterable(expected_exception, BASE_TYPE)): msg = ("exceptions must be old-style classes or" " derived from BaseException, not %s") raise TypeError(msg % type(exc)) message = "DID NOT RAISE {}".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") if kwargs: msg = "Unexpected keyword arguments passed to pytest.raises: " msg += ", ".join(kwargs.keys()) raise TypeError(msg) 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() six.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)
def raises( # noqa: F811 expected_exception: Union["Type[_E]", Tuple["Type[_E]", ...]], *args: Any, match: Optional[Union[str, "Pattern"]] = None, **kwargs: Any ) -> Union["RaisesContext[_E]", Optional[_pytest._code.ExceptionInfo[_E]]]: r""" Assert that a code block/function call raises ``expected_exception`` or raise a failure exception otherwise. :kwparam match: if specified, a string containing a regular expression, or a regular expression object, that is tested against the string representation of the exception using ``re.search``. To match a literal string that may contain `special characters`__, the pattern can first be escaped with ``re.escape``. __ https://docs.python.org/3/library/re.html#regular-expression-syntax .. currentmodule:: _pytest._code Use ``pytest.raises`` as a context manager, which will capture the exception of the given type:: >>> with raises(ZeroDivisionError): ... 1/0 If the code block does not raise the expected exception (``ZeroDivisionError`` in the example above), or no exception at all, the check will fail instead. You can also 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") The context manager produces an :class:`ExceptionInfo` object which can be used to inspect the details of the captured exception:: >>> with raises(ValueError) as exc_info: ... raise ValueError("value must be 42") >>> assert exc_info.type is ValueError >>> assert exc_info.value.args[0] == "value must be 42" .. deprecated:: 4.1 In the context manager form you may use the keyword argument ``message`` to specify a custom failure message that will be displayed in case the ``pytest.raises`` check fails. This has been deprecated as it is considered error prone as users often mean to use ``match`` instead. See :ref:`the deprecation docs <raises message deprecated>` for a workaround. .. 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 is 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 is ValueError **Using with** ``pytest.mark.parametrize`` When using :ref:`pytest.mark.parametrize ref` it is possible to parametrize tests such that some runs raise an exception and others do not. See :ref:`parametrizing_conditional_raising` for an example. **Legacy form** 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 ...> The form above is fully supported but discouraged for new code because the context manager form is regarded as more readable and less error-prone. .. 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 for exc in filterfalse(inspect.isclass, always_iterable(expected_exception, BASE_TYPE)): msg = "exceptions must be derived from BaseException, not %s" raise TypeError(msg % type(exc)) message = "DID NOT RAISE {}".format(expected_exception) if not args: if kwargs: msg = "Unexpected keyword arguments passed to pytest.raises: " msg += ", ".join(sorted(kwargs)) msg += "\nUse context-manager form instead?" raise TypeError(msg) return RaisesContext(expected_exception, message, match) else: func = args[0] if not callable(func): raise TypeError("{!r} object (type: {}) must be callable".format( func, type(func))) try: func(*args[1:], **kwargs) except expected_exception as e: # We just caught the exception - there is a traceback. assert e.__traceback__ is not None return _pytest._code.ExceptionInfo.from_exc_info( (type(e), e, e.__traceback__)) fail(message)
def raises(expected_exception, *args, **kwargs): r""" Assert that a code block/function call raises ``expected_exception`` or raise a failure exception otherwise. :kwparam match: if specified, asserts that the exception matches a text or regex :kwparam message: **(deprecated since 4.1)** if specified, provides a custom failure message if the exception is not raised .. currentmodule:: _pytest._code Use ``pytest.raises`` as a context manager, which will capture the exception of the given type:: >>> with raises(ZeroDivisionError): ... 1/0 If the code block does not raise the expected exception (``ZeroDivisionError`` in the example above), or no exception at all, the check will fail instead. You can also 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") The context manager produces an :class:`ExceptionInfo` object which can be used to inspect the details of the captured exception:: >>> with raises(ValueError) as exc_info: ... raise ValueError("value must be 42") >>> assert exc_info.type is ValueError >>> assert exc_info.value.args[0] == "value must be 42" .. deprecated:: 4.1 In the context manager form you may use the keyword argument ``message`` to specify a custom failure message that will be displayed in case the ``pytest.raises`` check fails. This has been deprecated as it is considered error prone as users often mean to use ``match`` instead. .. 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 is 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 is ValueError **Using with** ``pytest.mark.parametrize`` When using :ref:`pytest.mark.parametrize ref` it is possible to parametrize tests such that some runs raise an exception and others do not. See :ref:`parametrizing_conditional_raising` for an example. **Legacy form** 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 ...> The form above is fully supported but discouraged for new code because the context manager form is regarded as more readable and less error-prone. .. 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 for exc in filterfalse(isclass, always_iterable(expected_exception, BASE_TYPE)): msg = ( "exceptions must be old-style classes or" " derived from BaseException, not %s" ) raise TypeError(msg % type(exc)) message = "DID NOT RAISE {}".format(expected_exception) match_expr = None if not args: if "message" in kwargs: message = kwargs.pop("message") warnings.warn(deprecated.RAISES_MESSAGE_PARAMETER, stacklevel=2) if "match" in kwargs: match_expr = kwargs.pop("match") if kwargs: msg = "Unexpected keyword arguments passed to pytest.raises: " msg += ", ".join(kwargs.keys()) raise TypeError(msg) return RaisesContext(expected_exception, message, match_expr) elif isinstance(args[0], str): warnings.warn(deprecated.RAISES_EXEC, stacklevel=2) 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(_genframe=frame) six.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.from_current() else: func = args[0] try: func(*args[1:], **kwargs) except expected_exception: return _pytest._code.ExceptionInfo.from_current() fail(message)
def raises(expected_exception, *args, **kwargs): r""" Assert that a code block/function call raises ``expected_exception`` or raise a failure exception otherwise. :kwparam match: if specified, a string containing a regular expression, or a regular expression object, that is tested against the string representation of the exception using ``re.search``. To match a literal string that may contain `special characters`__, the pattern can first be escaped with ``re.escape``. __ https://docs.python.org/3/library/re.html#regular-expression-syntax :kwparam message: **(deprecated since 4.1)** if specified, provides a custom failure message if the exception is not raised. See :ref:`the deprecation docs <raises message deprecated>` for a workaround. .. currentmodule:: _pytest._code Use ``pytest.raises`` as a context manager, which will capture the exception of the given type:: >>> with raises(ZeroDivisionError): ... 1/0 If the code block does not raise the expected exception (``ZeroDivisionError`` in the example above), or no exception at all, the check will fail instead. You can also 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") The context manager produces an :class:`ExceptionInfo` object which can be used to inspect the details of the captured exception:: >>> with raises(ValueError) as exc_info: ... raise ValueError("value must be 42") >>> assert exc_info.type is ValueError >>> assert exc_info.value.args[0] == "value must be 42" .. deprecated:: 4.1 In the context manager form you may use the keyword argument ``message`` to specify a custom failure message that will be displayed in case the ``pytest.raises`` check fails. This has been deprecated as it is considered error prone as users often mean to use ``match`` instead. See :ref:`the deprecation docs <raises message deprecated>` for a workaround. .. 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 is 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 is ValueError **Using with** ``pytest.mark.parametrize`` When using :ref:`pytest.mark.parametrize ref` it is possible to parametrize tests such that some runs raise an exception and others do not. See :ref:`parametrizing_conditional_raising` for an example. **Legacy form** 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 ...> The form above is fully supported but discouraged for new code because the context manager form is regarded as more readable and less error-prone. .. 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 for exc in filterfalse(isclass, always_iterable(expected_exception, BASE_TYPE)): msg = ("exceptions must be old-style classes or" " derived from BaseException, not %s") raise TypeError(msg % type(exc)) message = "DID NOT RAISE {}".format(expected_exception) match_expr = None if not args: if "message" in kwargs: message = kwargs.pop("message") warnings.warn(deprecated.RAISES_MESSAGE_PARAMETER, stacklevel=2) if "match" in kwargs: match_expr = kwargs.pop("match") if kwargs: msg = "Unexpected keyword arguments passed to pytest.raises: " msg += ", ".join(sorted(kwargs)) raise TypeError(msg) return RaisesContext(expected_exception, message, match_expr) elif isinstance(args[0], str): warnings.warn(deprecated.RAISES_EXEC, stacklevel=2) 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(_genframe=frame) 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.from_current() else: func = args[0] try: func(*args[1:], **kwargs) except expected_exception: return _pytest._code.ExceptionInfo.from_current() fail(message)