Beispiel #1
0
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)
Beispiel #2
0
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)
Beispiel #3
0
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)
Beispiel #4
0
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)
Beispiel #5
0
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)
Beispiel #6
0
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)
Beispiel #7
0
    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
Beispiel #8
0
    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
Beispiel #9
0
    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
Beispiel #10
0
 def __call__(self, function):
     if isclass(function):
         raise ValueError(
                 "class fixtures not supported (may be in the future)")
     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
Beispiel #12
0
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)