Beispiel #1
0
    def fail(self, message, path=None):
        from _pytest.outcomes import Failed

        __tracebackhide__ = True
        self.success = self.FAIL
        log.error(message)
        raise Failed(message) from None
Beispiel #2
0
    def warns(warningcls, **kwargs):
        '''Like raises but tests that warnings are emitted.

        >>> from sympy.utilities.pytest import warns
        >>> import warnings

        >>> with warns(UserWarning):
        ...     warnings.warn('deprecated', UserWarning)

        >>> with warns(UserWarning):
        ...     pass
        Traceback (most recent call last):
        ...
        Failed: DID NOT WARN. No warnings of type UserWarning\
        was emitted. The list of emitted warnings is: [].
        '''
        match = kwargs.pop('match', '')
        if kwargs:
            raise TypeError('Invalid keyword arguments: %s' % kwargs)

        # Absorbs all warnings in warnrec
        with warnings.catch_warnings(record=True) as warnrec:
            # Hide all warnings but make sure that our warning is emitted
            warnings.simplefilter("ignore")
            warnings.filterwarnings("always", match, warningcls)
            # Now run the test
            yield

        # Raise if expected warning not found
        if not any(issubclass(w.category, warningcls) for w in warnrec):
            msg = ('Failed: DID NOT WARN.'
                   ' No warnings of type %s was emitted.'
                   ' The list of emitted warnings is: %s.'
                   ) % (warningcls, [w.message for w in warnrec])
            raise Failed(msg)
Beispiel #3
0
    def fail(self, message, path=None):
        from _pytest.outcomes import Failed

        __tracebackhide__ = True
        self.success = self.FAIL
        if path:
            message += " at " + format_path(path)
        log.error(message)
        raise Failed(message) from None
    def runner(fspath, context: dict = None):
        __tracebackhide__ = True

        fspath = request.fspath.dirpath(fspath)

        for item in get_request_items(fspath,
                                      parent=request.node,
                                      context=context):
            try:
                item.runtest()
            except Exception as err:
                msg = "File: {}\nFail: {.name}{}".format(fspath, item, err)
                raise Failed(msg=msg, pytrace=False)
Beispiel #5
0
    def raises(expectedException, code=None):
        """
        Tests that ``code`` raises the exception ``expectedException``.

        ``code`` may be a callable, such as a lambda expression or function
        name.

        If ``code`` is not given or None, ``raises`` will return a context
        manager for use in ``with`` statements; the code to execute then
        comes from the scope of the ``with``.

        ``raises()`` does nothing if the callable raises the expected exception,
        otherwise it raises an AssertionError.

        Examples
        ========

        >>> from sympy.utilities.pytest import raises

        >>> raises(ZeroDivisionError, lambda: 1/0)
        >>> raises(ZeroDivisionError, lambda: 1/2)
        Traceback (most recent call last):
        ...
        Failed: DID NOT RAISE

        >>> with raises(ZeroDivisionError):
        ...     n = 1/0
        >>> with raises(ZeroDivisionError):
        ...     n = 1/2
        Traceback (most recent call last):
        ...
        Failed: DID NOT RAISE

        Note that you cannot test multiple statements via
        ``with raises``:

        >>> with raises(ZeroDivisionError):
        ...     n = 1/0    # will execute and raise, aborting the ``with``
        ...     n = 9999/0 # never executed

        This is just what ``with`` is supposed to do: abort the
        contained statement sequence at the first exception and let
        the context manager deal with the exception.

        To test multiple statements, you'll need a separate ``with``
        for each:

        >>> with raises(ZeroDivisionError):
        ...     n = 1/0    # will execute and raise
        >>> with raises(ZeroDivisionError):
        ...     n = 9999/0 # will also execute and raise

        """
        if code is None:
            return RaisesContext(expectedException)
        elif callable(code):
            try:
                code()
            except expectedException:
                return
            raise Failed("DID NOT RAISE")
        elif isinstance(code, str):
            raise TypeError(
                '\'raises(xxx, "code")\' has been phased out; '
                'change \'raises(xxx, "expression")\' '
                'to \'raises(xxx, lambda: expression)\', '
                '\'raises(xxx, "statement")\' '
                'to \'with raises(xxx): statement\'')
        else:
            raise TypeError(
                'raises() expects a callable for the 2nd argument.')
Beispiel #6
0
 def __exit__(self, exc_type, exc_value, traceback):
     if exc_type is None:
         raise Failed("DID NOT RAISE")
     return issubclass(exc_type, self.expectedException)
Beispiel #7
0
def warns(warningcls, *, match='', test_stacklevel=True):
    '''
    Like raises but tests that warnings are emitted.

    >>> from sympy.testing.pytest import warns
    >>> import warnings

    >>> with warns(UserWarning):
    ...     warnings.warn('deprecated', UserWarning, stacklevel=2)

    >>> with warns(UserWarning):
    ...     pass
    Traceback (most recent call last):
    ...
    Failed: DID NOT WARN. No warnings of type UserWarning\
    was emitted. The list of emitted warnings is: [].

    ``test_stacklevel`` makes it check that the ``stacklevel`` parameter to
    ``warn()`` is set so that the warning shows the user line of code (the
    code under the warns() context manager). Set this to False if this is
    ambiguous or if the context manager does not test the direct user code
    that emits the warning.

    If the warning is a ``SymPyDeprecationWarning``, this additionally tests
    that the ``active_deprecations_target`` is a real target in the
    ``active-deprecations.md`` file.

    '''
    # Absorbs all warnings in warnrec
    with warnings.catch_warnings(record=True) as warnrec:
        # Any warning other than the one we are looking for is an error
        warnings.simplefilter("error")
        warnings.filterwarnings("always", category=warningcls)
        # Now run the test
        yield warnrec

    # Raise if expected warning not found
    if not any(issubclass(w.category, warningcls) for w in warnrec):
        msg = ('Failed: DID NOT WARN.'
               ' No warnings of type %s was emitted.'
               ' The list of emitted warnings is: %s.') % (
                   warningcls, [w.message for w in warnrec])
        raise Failed(msg)

    # We don't include the match in the filter above because it would then
    # fall to the error filter, so we instead manually check that it matches
    # here
    for w in warnrec:
        # Should always be true due to the filters above
        assert issubclass(w.category, warningcls)
        if not re.compile(match, re.I).match(str(w.message)):
            raise Failed(
                f"Failed: WRONG MESSAGE. A warning with of the correct category ({warningcls.__name__}) was issued, but it did not match the given match regex ({match!r})"
            )

    if test_stacklevel:
        for f in inspect.stack():
            thisfile = f.filename
            file = os.path.split(thisfile)[1]
            if file.startswith('test_'):
                break
            elif file == 'doctest.py':
                # skip the stacklevel testing in the doctests of this
                # function
                return
        else:
            raise RuntimeError(
                "Could not find the file for the given warning to test the stacklevel"
            )
        for w in warnrec:
            if w.filename != thisfile:
                msg = f'''\
Failed: Warning has the wrong stacklevel. The warning stacklevel needs to be
set so that the line of code shown in the warning message is user code that
calls the deprecated code (the current stacklevel is showing code from
{w.filename} (line {w.lineno}), expected {thisfile})'''.replace('\n', ' ')
                raise Failed(msg)

    if warningcls == SymPyDeprecationWarning:
        this_file = pathlib.Path(__file__)
        active_deprecations_file = (this_file.parent.parent.parent / 'doc' /
                                    'src' / 'explanation' /
                                    'active-deprecations.md')
        if not active_deprecations_file.exists():
            # We can only test that the active_deprecations_target works if we are
            # in the git repo.
            return
        targets = []
        for w in warnrec:
            targets.append(w.message.active_deprecations_target)
        with open(active_deprecations_file) as f:
            text = f.read()
        for target in targets:
            if f'({target})=' not in text:
                raise Failed(
                    f"The active deprecations target {target!r} does not appear to be a valid target in the active-deprecations.md file ({active_deprecations_file})."
                )
Beispiel #8
0
 def verify(self, provider_url, provider_setup):
     try:
         self.interaction.verify_with_callable_setup(provider_url, provider_setup)
     except (Failed, AssertionError) as e:
         raise Failed(str(e)) from None