Пример #1
0
def check_valid_size(value, name):
    """Checks that value is either unspecified, or a valid non-negative size
    expressed as an integer/float.

    Otherwise raises InvalidArgument.
    """
    if value is None:
        if name == "min_size":
            from hypothesis._settings import note_deprecation

            note_deprecation(
                "min_size=None is deprecated; use min_size=0 instead.",
                since="2018-10-06",
            )
        return
    if isinstance(value, float):
        if math.isnan(value):
            raise InvalidArgument(u"Invalid size %s=%r" % (name, value))
        from hypothesis._settings import note_deprecation

        note_deprecation(
            "Float size are deprecated: "
            "%s should be an integer, got %r" % (name, value),
            since="2018-10-11",
        )
    else:
        check_type(integer_types, value)
    if value < 0:
        raise InvalidArgument(u"Invalid size %s=%r < 0" % (name, value))
Пример #2
0
def test_deprecate_uses_default():
    with settings(strict=False):
        note_deprecation('Hi')

    with settings(strict=True):
        with pytest.raises(DeprecationWarning):
            note_deprecation('Hi')
Пример #3
0
def unicode_string_dtypes(endianness="?", min_len=1, max_len=16):
    # type: (str, int, int) -> st.SearchStrategy[np.dtype]
    """Return a strategy for generating unicode string dtypes, of various
    lengths and byteorder.

    While Hypothesis' string strategies can generate empty strings, string
    dtypes with length 0 indicate that size is still to be determined, so
    the minimum length for string dtypes is 1.
    """
    if min_len == 0:
        note_deprecation(
            "generating unicode string dtypes for unspecified length ('U0') "
            "is deprecated. min_len will be 1 instead.",
            since="2019-09-09",
        )
        min_len = 1
    if max_len == 0:
        note_deprecation(
            "generating unicode string dtypes for unspecified length ('U0') "
            "is deprecated. max_len will be 1 instead.",
            since="2019-09-09",
        )
        max_len = 1

    order_check("len", 1, min_len, max_len)
    return dtype_factory("U", list(range(min_len, max_len + 1)), None, endianness)
Пример #4
0
def test_deprecate_uses_default():
    with settings(strict=False):
        note_deprecation('Hi')

    with settings(strict=True):
        with pytest.raises(DeprecationWarning):
            note_deprecation('Hi')
Пример #5
0
def check_sample(values):
    if isinstance(values, ndarray):
        if values.ndim != 1:
            note_deprecation(
                ('Only one-dimensional arrays are supported for sampling, '
                 'and the given value has {ndim} dimensions (shape '
                 '{shape}).  This array would give samples of array slices '
                 'instead of elements!  Use np.ravel(values) to convert '
                 'to a one-dimensional array, or tuple(values) if you '
                 'want to sample slices.  Sampling a multi-dimensional '
                 'array will be an error in a future version of Hypothesis.'
                 ).format(ndim=values.ndim, shape=values.shape))
    elif not isinstance(values, (OrderedDict, Sequence, enum.EnumMeta)):
        note_deprecation(
            ('Cannot sample from %r, not a sequence.  ' % (values, )) +
            'Hypothesis goes to some length to ensure that sampling an '
            'element from a collection (with `sampled_from` or `choices`) is '
            'replayable and can be minimised.  To replay a saved example, '
            'the sampled values must have the same iteration order on every '
            'run - ruling out sets, dicts, etc due to hash randomisation.  '
            'Most cases can simply use `sorted(values)`, but mixed types or '
            'special values such as math.nan require careful handling - and '
            'note that when simplifying an example, Hypothesis treats '
            'earlier values as simpler.')
    return tuple(values)
Пример #6
0
def as_general_categories(cats, name='cats'):
    """Return a tuple of Unicode categories in a normalised order.

    This function expands one-letter designations of a major class to include
    all subclasses:

    >>> as_general_categories(['N'])
    ('Nd', 'Nl', 'No')

    See section 4.5 of the Unicode standard for more on classes:
    https://www.unicode.org/versions/Unicode10.0.0/ch04.pdf

    If the collection ``cats`` includes any elements that do not represent a
    major class or a class with subclass, a deprecation warning is raised.
    """
    if cats is None:
        return None
    major_classes = ('L', 'M', 'N', 'P', 'S', 'Z', 'C')
    cs = categories()
    out = set(cats)
    for c in cats:
        if c in major_classes:
            out.discard(c)
            out.update(x for x in cs if x.startswith(c))
        elif c not in cs:
            note_deprecation(
                'In %s=%r, %r is not a valid Unicode category.  This will '
                'be an error in a future version.' % (name, cats, c))
    return tuple(c for c in cs if c in out)
Пример #7
0
 def test(*args, **kwargs):
     self.__test_runtime = None
     initial_draws = len(data.draw_times)
     start = benchmark_time()
     result = self.test(*args, **kwargs)
     finish = benchmark_time()
     internal_draw_time = sum(data.draw_times[initial_draws:])
     runtime = (finish - start - internal_draw_time) * 1000
     self.__test_runtime = runtime
     if self.settings.deadline is not_set:
         if (
             not self.__warned_deadline and
             runtime >= 200
         ):
             self.__warned_deadline = True
             note_deprecation((
                 'Test: %s took %.2fms to run. In future the '
                 'default deadline setting will be 200ms, which '
                 'will make this an error. You can set deadline to '
                 'an explicit value of e.g. %d to turn tests '
                 'slower than this into an error, or you can set '
                 'it to None to disable this check entirely.') % (
                     self.test.__name__, runtime,
                     ceil(runtime / 100) * 100,
             ))
     else:
         current_deadline = self.settings.deadline
         if not is_final:
             current_deadline *= 1.25
         if runtime >= current_deadline:
             raise DeadlineExceeded(runtime, self.settings.deadline)
     return result
Пример #8
0
def check_sample(values, strategy_name):
    if isinstance(values, ndarray):
        if values.ndim != 1:
            note_deprecation((
                'Only one-dimensional arrays are supported for sampling, '
                'and the given value has {ndim} dimensions (shape '
                '{shape}).  This array would give samples of array slices '
                'instead of elements!  Use np.ravel(values) to convert '
                'to a one-dimensional array, or tuple(values) if you '
                'want to sample slices.  Sampling a multi-dimensional '
                'array will be an error in a future version of Hypothesis.'
            ).format(ndim=values.ndim, shape=values.shape))
    elif not isinstance(values, (OrderedDict, abc.Sequence, enum.EnumMeta)):
        note_deprecation(
            'Cannot sample from {values}, not an ordered collection. '
            'Hypothesis goes to some length to ensure that the {strategy} '
            'strategy has stable results between runs. To replay a saved '
            'example, the sampled values must have the same iteration order '
            'on every run - ruling out sets, dicts, etc due to hash '
            'randomisation. Most cases can simply use `sorted(values)`, but '
            'mixed types or special values such as math.nan require careful '
            'handling - and note that when simplifying an example, '
            'Hypothesis treats earlier values as simpler.'.format(
                values=repr(values), strategy=strategy_name))
    return tuple(values)
Пример #9
0
def _convert_targets(targets, target):
    """Single validator and convertor for target arguments."""
    if target is not None:
        if targets:
            note_deprecation(
                'Passing both targets=%r and target=%r is redundant, and '
                'will become an error in a future version of Hypothesis.  '
                'Pass targets=%r instead.'
                % (targets, target, tuple(targets) + (target,))
            )
        targets = tuple(targets) + (target,)

    converted_targets = []
    for t in targets:
        if isinstance(t, string_types):
            note_deprecation(
                'Got %r as a target, but passing the name of a Bundle is '
                'deprecated - please pass the Bundle directly.' % (t,)
            )
        elif not isinstance(t, Bundle):
            msg = 'Got invalid target %r of type %r, but all targets must ' \
                'be either a Bundle or the name of a Bundle.'
            if isinstance(t, OneOfStrategy):
                msg += (
                    '\nIt looks like you passed `one_of(a, b)` or `a | b` as '
                    'a target.  You should instead pass `targets=(a, b)` to '
                    'add the return value of this rule to both the `a` and '
                    '`b` bundles, or define a rule for each target if it '
                    'should be added to exactly one.'
                )
            raise InvalidArgument(msg % (t, type(t)))
        while isinstance(t, Bundle):
            t = t.name
        converted_targets.append(t)
    return tuple(converted_targets)
Пример #10
0
def ip6_addr_strings() -> SearchStrategy[str]:
    note_deprecation(
        "Use `ip_addresses(v=6).map(str)` instead of `ip6_addr_strings()`; "
        "the provisional strategy is less flexible and will be removed.",
        since="2020-01-21",
    )
    return ip_addresses(v=6).map(str)
Пример #11
0
def _convert_targets(targets, target):
    """Single validator and converter for target arguments."""
    if target is not None:
        if targets:
            raise InvalidArgument(
                "Passing both targets=%r and target=%r is redundant - pass "
                "targets=%r instead." % (targets, target, tuple(targets) +
                                         (target, )))
        targets = (target, )

    converted_targets = []
    for t in targets:
        if not isinstance(t, Bundle):
            msg = "Got invalid target %r of type %r, but all targets must be Bundles."
            if isinstance(t, OneOfStrategy):
                msg += (
                    "\nIt looks like you passed `one_of(a, b)` or `a | b` as "
                    "a target.  You should instead pass `targets=(a, b)` to "
                    "add the return value of this rule to both the `a` and "
                    "`b` bundles, or define a rule for each target if it "
                    "should be added to exactly one.")
            raise InvalidArgument(msg % (t, type(t)))
        while isinstance(t, Bundle):
            if isinstance(t, BundleConsumer):
                note_deprecation(
                    f"Using consumes({t.name}) doesn't makes sense in this context.  "
                    "This will be an error in a future version of Hypothesis.",
                    since="2021-09-08",
                    has_codemod=False,
                )
            t = t.name
        converted_targets.append(t)
    return tuple(converted_targets)
def check_valid_size(value, name):
    """Checks that value is either unspecified, or a valid non-negative size
    expressed as an integer/float.

    Otherwise raises InvalidArgument.
    """
    if value is None:
        if name == "min_size":
            from hypothesis._settings import note_deprecation

            note_deprecation(
                "min_size=None is deprecated; use min_size=0 instead.",
                since="2018-10-06",
            )
        return
    if isinstance(value, float):
        if math.isnan(value):
            raise InvalidArgument(u"Invalid size %s=%r" % (name, value))
        from hypothesis._settings import note_deprecation

        note_deprecation(
            "Float size are deprecated: "
            "%s should be an integer, got %r" % (name, value),
            since="2018-10-11",
        )
    else:
        check_type(integer_types, value)
    if value < 0:
        raise InvalidArgument(u"Invalid size %s=%r < 0" % (name, value))
Пример #13
0
def check_sample(values, strategy_name):
    if isinstance(values, ndarray):
        if values.ndim != 1:
            note_deprecation(
                ('Only one-dimensional arrays are supported for sampling, '
                 'and the given value has {ndim} dimensions (shape '
                 '{shape}).  This array would give samples of array slices '
                 'instead of elements!  Use np.ravel(values) to convert '
                 'to a one-dimensional array, or tuple(values) if you '
                 'want to sample slices.  Sampling a multi-dimensional '
                 'array will be an error in a future version of Hypothesis.'
                 ).format(ndim=values.ndim, shape=values.shape))
    elif not isinstance(values, (OrderedDict, Sequence, enum.EnumMeta)):
        note_deprecation(
            'Cannot sample from {values}, not an ordered collection. '
            'Hypothesis goes to some length to ensure that the {strategy} '
            'strategy has stable results between runs. To replay a saved '
            'example, the sampled values must have the same iteration order '
            'on every run - ruling out sets, dicts, etc due to hash '
            'randomisation. Most cases can simply use `sorted(values)`, but '
            'mixed types or special values such as math.nan require careful '
            'handling - and note that when simplifying an example, '
            'Hypothesis treats earlier values as simpler.'.format(
                values=repr(values), strategy=strategy_name))
    return tuple(values)
Пример #14
0
    def accept(*args, **kwargs):
        bound = func.__signature__.bind_partial(*args, **kwargs)
        bad_posargs = bound.arguments.pop("__deprecated_posargs", None) or ()
        if len(bad_posargs) > len(deprecated):
            # We have more positional arguments than the wrapped func has parameters,
            # so there's no way this ever worked.  We know that this bind will fail
            # but attempting it will raise a nice descriptive TypeError.
            signature.bind_partial(*args, **kwargs)
        for param, pos in zip(deprecated, bad_posargs):
            # Unfortunately, another layer of our function-wrapping logic passes in
            # all the default arguments as explicit arguments.  This means that if
            # someone explicitly passes some value for a parameter as a positional
            # argument and *the default value* as a keyword argument, we'll emit a
            # deprecation warning but not an immediate error.  Ah well...
            if bound.arguments.get(param.name, param.default) != param.default:
                raise TypeError(
                    "Cannot pass {name}={p} positionally and {name}={n} by name!"
                    .format(name=param.name,
                            p=pos,
                            n=bound.arguments[param.name]))
            from hypothesis._settings import note_deprecation

            note_deprecation(
                "%s was passed %s=%r as a positional argument, which will be a "
                "keyword-only argument in a future version." %
                (qualname(func), param.name, pos),
                since="2020-02-07",
            )
            bound.arguments[param.name] = pos
        return func(*bound.args, **bound.kwargs)
Пример #15
0
def _convert_targets(targets, target):
    """Single validator and convertor for target arguments."""
    if target is not None:
        if targets:
            note_deprecation(
                'Passing both targets=%r and target=%r is redundant, and '
                'will become an error in a future version of Hypothesis.  '
                'Pass targets=%r instead.' % (targets, target, tuple(targets) +
                                              (target, )))
        targets = tuple(targets) + (target, )

    converted_targets = []
    for t in targets:
        if isinstance(t, string_types):
            note_deprecation(
                'Got %r as a target, but passing the name of a Bundle is '
                'deprecated - please pass the Bundle directly.' % (t, ))
        elif not isinstance(t, Bundle):
            msg = 'Got invalid target %r of type %r, but all targets must ' \
                'be either a Bundle or the name of a Bundle.'
            if isinstance(t, OneOfStrategy):
                msg += (
                    '\nIt looks like you passed `one_of(a, b)` or `a | b` as '
                    'a target.  You should instead pass `targets=(a, b)` to '
                    'add the return value of this rule to both the `a` and '
                    '`b` bundles, or define a rule for each target if it '
                    'should be added to exactly one.')
            raise InvalidArgument(msg % (t, type(t)))
        while isinstance(t, Bundle):
            t = t.name
        converted_targets.append(t)
    return tuple(converted_targets)
Пример #16
0
 def test(*args, **kwargs):
     self.__test_runtime = None
     initial_draws = len(data.draw_times)
     start = benchmark_time()
     result = self.test(*args, **kwargs)
     finish = benchmark_time()
     internal_draw_time = sum(data.draw_times[initial_draws:])
     runtime = (finish - start - internal_draw_time) * 1000
     self.__test_runtime = runtime
     if self.settings.deadline is not_set:
         if (not self.__warned_deadline and runtime >= 200):
             self.__warned_deadline = True
             note_deprecation(
                 ('Test took %.2fms to run. In future the default '
                  'deadline setting will be 200ms, which will '
                  'make this an error. You can set deadline to '
                  'an explicit value of e.g. %d to turn tests '
                  'slower than this into an error, or you can set '
                  'it to None to disable this check entirely.') % (
                      runtime,
                      ceil(runtime / 100) * 100,
                  ))
     else:
         current_deadline = self.settings.deadline
         if not is_final:
             current_deadline *= 1.25
         if runtime >= current_deadline:
             raise DeadlineExceeded(runtime, self.settings.deadline)
     return result
Пример #17
0
def test_note_deprecation_checks_date():
    with pytest.warns(None) as rec:
        note_deprecation("This is bad", since="RELEASEDAY", has_codemod=False)
    assert len(rec) == 1
    with pytest.raises(AssertionError):
        note_deprecation("This is way too old",
                         since="1999-12-31",
                         has_codemod=False)
Пример #18
0
def add_default_field_mapping(field_type, strategy):
    # type: (Type[dm.Field], st.SearchStrategy[Any]) -> None
    note_deprecation(
        "`hypothesis.extra.django.models.add_default_field_mapping` is deprecated; use `hypothesis.extra.django."
        "register_field_strategy` instead.",
        since="2019-01-10",
    )
    register_field_strategy(field_type, strategy)
Пример #19
0
def add_default_field_mapping(field_type, strategy):
    # type: (Type[dm.Field], st.SearchStrategy[Any]) -> None
    note_deprecation(
        "This function is deprecated; use `hypothesis.extra.django."
        "register_field_strategy` instead.",
        since="2019-01-10",
    )
    register_field_strategy(field_type, strategy)
 def note_strategy_is_not_test(*args, **kwargs):
     note_deprecation(
         "%s is a function that returns a Hypothesis strategy, "
         "but pytest has collected it as a test function.  This "
         "is useless as the function body will never be executed.  "
         "To define a test function, use @given instead of "
         "@composite." % (item.nodeid,),
         since="2018-11-02",
     )
Пример #21
0
 def note_strategy_is_not_test(*args, **kwargs):
     note_deprecation(
         "%s is a function that returns a Hypothesis strategy, "
         "but pytest has collected it as a test function.  This "
         "is useless as the function body will never be executed.  "
         "To define a test function, use @given instead of "
         "@composite." % (item.nodeid, ),
         since="2018-11-02",
     )
Пример #22
0
    def example(self, random=None):
        """Provide an example of the sort of value that this strategy
        generates. This is biased to be slightly simpler than is typical for
        values from this strategy, for clarity purposes.

        This method shouldn't be taken too seriously. It's here for interactive
        exploration of the API, not for any sort of real testing.

        This method is part of the public API.

        """
        context = _current_build_context.value
        if context is not None:
            if context.data is not None and context.data.depth > 0:
                note_deprecation(
                    'Using example() inside a strategy definition is a bad '
                    'idea. It will become an error in a future version of '
                    "Hypothesis, but it's unlikely that it's doing what you "
                    'intend even now. Instead consider using '
                    'hypothesis.strategies.builds() or '
                    '@hypothesis.strategies.composite to define your strategy.'
                    ' See '
                    'https://hypothesis.readthedocs.io/en/latest/data.html'
                    '#hypothesis.strategies.builds or '
                    'https://hypothesis.readthedocs.io/en/latest/data.html'
                    '#composite-strategies for more details.'
                )
            else:
                note_deprecation(
                    'Using example() inside a test function is a bad '
                    'idea. It will become an error in a future version of '
                    "Hypothesis, but it's unlikely that it's doing what you "
                    'intend even now. Instead consider using '
                    'hypothesis.strategies.data() to draw '
                    'more examples during testing. See '
                    'https://hypothesis.readthedocs.io/en/latest/data.html'
                    '#drawing-interactively-in-tests for more details.'
                )

        from hypothesis import find, settings, Verbosity
        try:
            return find(
                self,
                lambda x: True,
                random=random,
                settings=settings(
                    max_shrinks=0,
                    max_iterations=1000,
                    database=None,
                    verbosity=Verbosity.quiet,
                )
            )
        except (NoSuchExample, Unsatisfiable):
            raise NoExamples(
                u'Could not find any valid examples in 100 tries'
            )
Пример #23
0
 def with_name_check(**kwargs):
     for k, v in list(kwargs.items()):
         if k in rename_mapping and v is not None:
             t = rename_mapping[k]
             note_deprecation(
                 ('The argument %s has been renamed to %s. The old '
                  'name will go away in a future version of '
                  'Hypothesis.') % (k, t))
             kwargs[t] = kwargs.pop(k)
     return f(**kwargs)
Пример #24
0
 def with_name_check(**kwargs):
     for k, v in list(kwargs.items()):
         if k in rename_mapping and v is not None:
             t = rename_mapping[k]
             note_deprecation((
                 'The argument %s has been renamed to %s. The old '
                 'name will go away in a future version of '
                 'Hypothesis.') % (k, t))
             kwargs[t] = kwargs.pop(k)
     return f(**kwargs)
Пример #25
0
def elements_and_dtype(elements, dtype, source=None):

    if source is None:
        prefix = ""
    else:
        prefix = f"{source}."

    if elements is not None:
        check_strategy(elements, f"{prefix}elements")
    else:
        with check("dtype is not None"):
            if dtype is None:
                raise InvalidArgument(
                    f"At least one of {prefix}elements or {prefix}dtype must be provided."
                )

    with check("is_categorical_dtype"):
        if is_categorical_dtype(dtype):
            raise InvalidArgument(
                f"{prefix}dtype is categorical, which is currently unsupported"
            )

    if isinstance(
            dtype,
            type) and np.dtype(dtype).kind == "O" and dtype is not object:
        note_deprecation(
            f"Passed dtype={dtype!r} is not a valid Pandas dtype.  We'll treat it as "
            "dtype=object for now, but this will be an error in a future version.",
            since="2021-12-31",
            has_codemod=False,
        )

    dtype = try_convert(np.dtype, dtype, "dtype")

    if elements is None:
        elements = npst.from_dtype(dtype)
    elif dtype is not None:

        def convert_element(value):
            name = f"draw({prefix}elements)"
            try:
                return np.array([value], dtype=dtype)[0]
            except TypeError:
                raise InvalidArgument(
                    "Cannot convert %s=%r of type %s to dtype %s" %
                    (name, value, type(value).__name__, dtype.str)) from None
            except ValueError:
                raise InvalidArgument(
                    f"Cannot convert {name}={value!r} to type {dtype.str}"
                ) from None

        elements = elements.map(convert_element)
    assert elements is not None

    return elements, dtype
Пример #26
0
    def example(self, random=not_set):
        # type: (UniqueIdentifier) -> Ex
        """Provide an example of the sort of value that this strategy
        generates. This is biased to be slightly simpler than is typical for
        values from this strategy, for clarity purposes.

        This method shouldn't be taken too seriously. It's here for interactive
        exploration of the API, not for any sort of real testing.

        This method is part of the public API.
        """
        if random is not not_set:
            note_deprecation("The random argument does nothing", since="2019-07-08")

        context = _current_build_context.value
        if context is not None:
            if context.data is not None and context.data.depth > 0:
                raise HypothesisException(
                    "Using example() inside a strategy definition is a bad "
                    "idea. Instead consider using hypothesis.strategies.builds() "
                    "or @hypothesis.strategies.composite to define your strategy."
                    " See https://hypothesis.readthedocs.io/en/latest/data.html"
                    "#hypothesis.strategies.builds or "
                    "https://hypothesis.readthedocs.io/en/latest/data.html"
                    "#composite-strategies for more details."
                )
            else:
                raise HypothesisException(
                    "Using example() inside a test function is a bad "
                    "idea. Instead consider using hypothesis.strategies.data() "
                    "to draw more examples during testing. See "
                    "https://hypothesis.readthedocs.io/en/latest/data.html"
                    "#drawing-interactively-in-tests for more details."
                )

        from hypothesis.core import given

        # Note: this function has a weird name because it might appear in
        # tracebacks, and we want users to know that they can ignore it.
        @given(self)
        @settings(
            database=None,
            max_examples=10,
            deadline=None,
            verbosity=Verbosity.quiet,
            phases=(Phase.generate,),
            suppress_health_check=HealthCheck.all(),
        )
        def example_generating_inner_function(ex):
            examples.append(ex)

        examples = []  # type: List[Ex]
        example_generating_inner_function()
        return random_choice(examples)
Пример #27
0
def check_valid_sizes(min_size, average_size, max_size):
    if average_size is not None:
        from hypothesis._settings import note_deprecation
        note_deprecation(
            'You should remove the average_size argument, because it is '
            'deprecated and no longer has any effect.  Please open an issue '
            'if the default distribution of examples does not work for you.')

    check_valid_size(min_size, 'min_size')
    check_valid_size(max_size, 'max_size')
    check_valid_interval(min_size, max_size, 'min_size', 'max_size')
Пример #28
0
def times(allow_naive=None, timezones=None):
    """Return a strategy for generating times.

    .. deprecated:: 3.9.0
        use :py:func:`hypothesis.strategies.times` instead.

    The allow_naive and timezones arguments act the same as the datetimes
    strategy above.
    """
    note_deprecation('Use hypothesis.strategies.times, which supports '
                     'min_time and max_time arguments.')
    return st.times(timezones=tz_args_strat(allow_naive, timezones, 'times'))
Пример #29
0
def check_valid_sizes(min_size, average_size, max_size):
    if average_size is not None:
        from hypothesis._settings import note_deprecation
        note_deprecation(
            'You should remove the average_size argument, because it is '
            'deprecated and no longer has any effect.  Please open an issue '
            'if the default distribution of examples does not work for you.'
        )

    check_valid_size(min_size, 'min_size')
    check_valid_size(max_size, 'max_size')
    check_valid_interval(min_size, max_size, 'min_size', 'max_size')
Пример #30
0
def dates(min_year=None, max_year=None):
    """Return a strategy for generating dates.

    .. deprecated:: 3.9.0
        use :py:func:`hypothesis.strategies.dates` instead.

    All generated dates will be between min_year and max_year, inclusive.
    """
    note_deprecation('Use hypothesis.strategies.dates, which supports bounds '
                     'given as date objects for single-day resolution.')
    return st.dates(convert_year_bound(min_year, dt.date.min),
                    convert_year_bound(max_year, dt.date.max))
Пример #31
0
def times(allow_naive=None, timezones=None):
    """Return a strategy for generating times.

    .. deprecated:: 3.9.0
        use :py:func:`hypothesis.strategies.times` instead.

    The allow_naive and timezones arguments act the same as the datetimes
    strategy above.
    """
    note_deprecation('Use hypothesis.strategies.times, which supports '
                     'min_time and max_time arguments.')
    return st.times(timezones=tz_args_strat(allow_naive, timezones, 'times'))
Пример #32
0
def dates(min_year=None, max_year=None):
    """Return a strategy for generating dates.

    .. deprecated:: 3.9.0
        use :py:func:`hypothesis.strategies.dates` instead.

    All generated dates will be between min_year and max_year, inclusive.
    """
    note_deprecation('Use hypothesis.strategies.dates, which supports bounds '
                     'given as date objects for single-day resolution.')
    return st.dates(convert_year_bound(min_year, dt.date.min),
                    convert_year_bound(max_year, dt.date.max))
Пример #33
0
 def do_validate(self):
     self.element_strategy.validate()
     if self.is_empty:
         raise InvalidArgument(
             ('Cannot create non-empty lists with elements drawn from '
              'strategy %r because it has no values.') %
             (self.element_strategy, ))
     if self.element_strategy.is_empty and 0 < self.max_size < float('inf'):
         from hypothesis._settings import note_deprecation
         note_deprecation(
             'Cannot create a collection of max_size=%r, because no '
             'elements can be drawn from the element strategy %r' %
             (self.max_size, self.element_strategy))
Пример #34
0
def check_sample(values):
    if not isinstance(values, (OrderedDict, Sequence, enum.EnumMeta)):
        note_deprecation(
            ('Cannot sample from %r, not a sequence.  ' % (values,)) +
            'Hypothesis goes to some length to ensure that sampling an '
            'element from a collection (with `sampled_from` or `choices`) is '
            'replayable and can be minimised.  To replay a saved example, '
            'the sampled values must have the same iteration order on every '
            'run - ruling out sets, dicts, etc due to hash randomisation.  '
            'Most cases can simply use `sorted(values)`, but mixed types or '
            'special values such as math.nan require careful handling - and '
            'note that when simplifying an example, Hypothesis treats '
            'earlier values as simpler.')
    return tuple(values)
Пример #35
0
def check_sample(values):
    if not isinstance(values, (OrderedDict, Sequence, enum.EnumMeta)):
        note_deprecation(
            ('Cannot sample from %r, not a sequence.  ' % (values, )) +
            'Hypothesis goes to some length to ensure that sampling an '
            'element from a collection (with `sampled_from` or `choices`) is '
            'replayable and can be minimised.  To replay a saved example, '
            'the sampled values must have the same iteration order on every '
            'run - ruling out sets, dicts, etc due to hash randomisation.  '
            'Most cases can simply use `sorted(values)`, but mixed types or '
            'special values such as math.nan require careful handling - and '
            'note that when simplifying an example, Hypothesis treats '
            'earlier values as simpler.')
    return tuple(values)
Пример #36
0
 def do_validate(self):
     self.element_strategy.validate()
     if self.is_empty:
         raise InvalidArgument((
             'Cannot create non-empty lists with elements drawn from '
             'strategy %r because it has no values.') % (
             self.element_strategy,))
     if self.element_strategy.is_empty and 0 < self.max_size < float('inf'):
         from hypothesis._settings import note_deprecation
         note_deprecation(
             'Cannot create a collection of max_size=%r, because no '
             'elements can be drawn from the element strategy %r'
             % (self.max_size, self.element_strategy)
         )
Пример #37
0
 def set_element(self, data, result, idx, strategy=None):
     strategy = strategy or self.element_strategy
     val = data.draw(strategy)
     result[idx] = val
     if self._report_overflow and not self.check_cast(val):
         note_deprecation(
             'Generated array element %r from %r cannot be represented as '
             'dtype %r - instead it becomes %r .  Consider using a more '
             'precise strategy, as this will be an error in a future '
             'version.' % (val, strategy, self.dtype, result[idx]))
         # Because the message includes the value of the generated element,
         # it would be easy to spam users with thousands of warnings.
         # We therefore only warn once per draw, unless in verbose mode.
         self._report_overflow = current_verbosity() >= Verbosity.verbose
Пример #38
0
 def set_element(self, data, result, idx, strategy=None):
     strategy = strategy or self.element_strategy
     val = data.draw(strategy)
     if self._report_overflow and not self.check_cast(val):
         note_deprecation(
             'Generated array element %r from %r cannot be represented as '
             'dtype %r without overflow or underflow.  Consider using a '
             'more precise strategy, as this will be an error in a future '
             'version of Hypothesis.' % (val, strategy, self.dtype)
         )
         # Because the message includes the value of the generated element,
         # it would be easy to spam users with thousands of warnings.
         # We therefore only warn once per draw, unless in verbose mode.
         self._report_overflow = current_verbosity() >= Verbosity.verbose
     result[idx] = val
Пример #39
0
def check_valid_size(value, name):
    """Checks that value is either unspecified, or a valid non-negative size
    expressed as an integer/float.

    Otherwise raises InvalidArgument.
    """
    if value is None:
        if name == 'min_size':
            from hypothesis._settings import note_deprecation
            note_deprecation(
                'min_size=None is deprecated; use min_size=0 instead.')
        return
    check_type(integer_types + (float, ), value)
    if value < 0:
        raise InvalidArgument(u'Invalid size %s=%r < 0' % (name, value))
    if isinstance(value, float) and math.isnan(value):
        raise InvalidArgument(u'Invalid size %s=%r' % (name, value))
Пример #40
0
    def pytest_runtest_call(item):
        if not hasattr(item, "obj"):
            yield
        elif not is_hypothesis_test(item.obj):
            # If @given was not applied, check whether other hypothesis
            # decorators were applied, and raise an error if they were.
            message = "Using `@%s` on a test without `@given` is completely pointless."
            if getattr(item.obj, "_hypothesis_internal_settings_applied",
                       False):
                raise InvalidArgument(message % ("settings", ))
            if getattr(item.obj, "is_hypothesis_strategy_function", False):
                note_deprecation(
                    "%s is a function that returns a Hypothesis strategy, but pytest "
                    "has collected it as a test function.  This is useless as the "
                    "function body will never be executed.  To define a test "
                    "function, use @given instead of @composite." %
                    (item.nodeid, ),
                    since="2018-11-02",
                )
            for name, attribute in [
                ("example", "hypothesis_explicit_examples"),
                ("seed", "_hypothesis_internal_use_seed"),
                ("reproduce_example",
                 "_hypothesis_internal_use_reproduce_failure"),
            ]:
                if hasattr(item.obj, attribute):
                    note_deprecation(message % (name, ), since="2019-12-07")
            yield
        else:
            if item.get_closest_marker("parametrize") is not None:
                # Give every parametrized test invocation a unique database key
                key = item.nodeid.encode("utf-8")
                item.obj.hypothesis.inner_test._hypothesis_internal_add_digest = key

            store = StoringReporter(item.config)

            def note_statistics(stats):
                lines = [item.nodeid + ":", ""
                         ] + stats.get_description() + [""]
                item.hypothesis_statistics = lines

            with collector.with_value(note_statistics):
                with with_reporter(store):
                    yield
            if store.results:
                item.hypothesis_report_information = list(store.results)
Пример #41
0
 def set_element(self, data, result, idx, strategy=None):
     strategy = strategy or self.element_strategy
     val = data.draw(strategy)
     result[idx] = val
     if self._report_overflow and val != result[idx] and val == val:
         note_deprecation(
             "Generated array element %r from %r cannot be represented as "
             "dtype %r - instead it becomes %r (type %r).  Consider using a more "
             "precise strategy, for example passing the `width` argument to "
             "`floats()`, as this will be an error in a future version."
             % (val, strategy, self.dtype, result[idx], type(result[idx])),
             since="2019-07-28",
         )
         # Because the message includes the value of the generated element,
         # it would be easy to spam users with thousands of warnings.
         # We therefore only warn once per draw, unless in verbose mode.
         self._report_overflow = current_verbosity() >= Verbosity.verbose
Пример #42
0
def check_valid_magnitude(value, name):
    """Checks that value is either unspecified, or a non-negative valid
    interval bound.

    Otherwise raises InvalidArgument.
    """
    check_valid_bound(value, name)
    if value is not None and value < 0:
        raise InvalidArgument("%s=%r must not be negative." % (name, value))
    if value is None and name == "min_magnitude":
        from hypothesis._settings import note_deprecation

        note_deprecation(
            "min_magnitude=None is deprecated; use min_magnitude=0 "
            "or omit the argument entirely.",
            since="2020-05-13",
        )
Пример #43
0
    def run_state_machine(factory, data):
        machine = factory()
        if isinstance(machine, GenericStateMachine) and not isinstance(
                machine, RuleBasedStateMachine):
            note_deprecation(
                "%s inherits from GenericStateMachine, which is deprecated.  Use a "
                "RuleBasedStateMachine, or a test function with st.data(), instead."
                % (type(machine).__name__, ),
                since="2019-05-29",
            )
        else:
            check_type(RuleBasedStateMachine, machine,
                       "state_machine_factory()")
        data.conjecture_data.hypothesis_runner = machine

        n_steps = settings.stateful_step_count
        should_continue = cu.many(data.conjecture_data,
                                  min_size=1,
                                  max_size=n_steps,
                                  average_size=n_steps)

        print_steps = (current_build_context().is_final
                       or current_verbosity() >= Verbosity.debug)
        try:
            if print_steps:
                machine.print_start()
            machine.check_invariants()

            while should_continue.more():
                value = data.conjecture_data.draw(machine.steps())
                # Assign 'result' here in case 'execute_step' fails below
                result = multiple()
                try:
                    result = machine.execute_step(value)
                finally:
                    if print_steps:
                        # 'result' is only used if the step has target bundles.
                        # If it does, and the result is a 'MultipleResult',
                        # then 'print_step' prints a multi-variable assignment.
                        machine.print_step(value, result)
                machine.check_invariants()
        finally:
            if print_steps:
                machine.print_end()
            machine.teardown()
Пример #44
0
    def __init__(self, path=u':memory:'):
        self.path = path
        self.db_created = False
        self.current_connection = threading.local()
        global sqlite3
        import sqlite3

        if path == u':memory:':
            note_deprecation(
                'The SQLite database backend has been deprecated. '
                'Use InMemoryExampleDatabase or set database_file=":memory:" '
                'instead.')
        else:
            note_deprecation(
                'The SQLite database backend has been deprecated. '
                'Set database_file to some path name not ending in .db, '
                '.sqlite or .sqlite3 to get the new directory based database '
                'backend instead.')
Пример #45
0
def datetimes(allow_naive=None, timezones=None, min_year=None, max_year=None):
    """Return a strategy for generating datetimes.

    .. deprecated:: 3.9.0
        use :py:func:`hypothesis.strategies.datetimes` instead.

    allow_naive=True will cause the values to sometimes be naive.
    timezones is the set of permissible timezones. If set to an empty
    collection all datetimes will be naive. If set to None all timezones
    available via pytz will be used.

    All generated datetimes will be between min_year and max_year, inclusive.
    """
    note_deprecation('Use hypothesis.strategies.datetimes, which supports '
                     'full-precision bounds and has a simpler API.')
    min_dt = convert_year_bound(min_year, dt.datetime.min)
    max_dt = convert_year_bound(max_year, dt.datetime.max)
    tzs = tz_args_strat(allow_naive, timezones, 'datetimes')
    return st.datetimes(min_dt, max_dt, tzs)
Пример #46
0
    def __init__(self, path=u':memory:'):
        self.path = path
        self.db_created = False
        self.current_connection = threading.local()
        global sqlite3
        import sqlite3

        if path == u':memory:':
            note_deprecation(
                'The SQLite database backend has been deprecated. '
                'Use InMemoryExampleDatabase or set database_file=":memory:" '
                'instead.'
            )
        else:
            note_deprecation(
                'The SQLite database backend has been deprecated. '
                'Set database_file to some path name not ending in .db, '
                '.sqlite or .sqlite3 to get the new directory based database '
                'backend instead.'
            )
Пример #47
0
def fake_factory(source, locale=None, locales=None, providers=()):
    note_deprecation(
        'hypothesis.extra.fakefactory has been deprecated, because it does '
        'not support example discovery or shrinking.  Consider using a lower-'
        'level strategy (such as st.text()) instead.'
    )
    check_valid_identifier(source)
    if source[0] == u'_':
        raise ValueError(u'Bad source name %s' % (source,))

    if locale is not None and locales is not None:
        raise ValueError(u'Cannot specify both single and multiple locales')
    if locale:
        locales = (locale,)
    elif locales:
        locales = tuple(locales)
    else:
        locales = None
    for l in (locales or ()):
        if l not in AVAILABLE_LOCALES:
            raise ValueError(u'Unsupported locale %r' % (l,))

    def supports_source(locale):
        test_faker = faker.Faker(locale)
        for provider in providers:
            test_faker.add_provider(provider)
        return hasattr(test_faker, source)

    if locales is None:
        locales = list(filter(supports_source, AVAILABLE_LOCALES))
        if not locales:
            raise ValueError(u'No such source %r' % (source,))
    else:
        for l in locales:
            if not supports_source(locale):
                raise ValueError(u'Unsupported source %s for locale %s' % (
                    source, l
                ))
    return FakeFactoryStrategy(source, providers, locales)
Пример #48
0
def _db_for_path(path=None):
    if path is not_set:
        path = os.getenv('HYPOTHESIS_DATABASE_FILE')
        if path is not None:  # pragma: no cover
            # Note: we should retain an explicit deprecation warning for a
            # further period after this is removed, to ease debugging for
            # anyone migrating to a new version.
            note_deprecation(
                'The $HYPOTHESIS_DATABASE_FILE environment variable is '
                'deprecated, and will be ignored by a future version of '
                'Hypothesis.  Configure your database location via a '
                'settings profile instead.'
            )
            return _db_for_path(path)
        # Note: storage_directory attempts to create the dir in question, so
        # if os.access fails there *must* be a fatal permissions issue.
        path = storage_directory('examples')
        if os.access(path, os.R_OK | os.W_OK | os.X_OK):
            return _db_for_path(path)
        else:  # pragma: no cover
            warnings.warn(HypothesisWarning(
                'The database setting is not configured, and the default '
                'location is unusable - falling back to an in-memory '
                'database for this session.  path=%r' % (path,)
            ))
            return InMemoryExampleDatabase()
    if path in (None, ':memory:'):
        return InMemoryExampleDatabase()
    path = str(path)
    if os.path.isdir(path):
        return DirectoryBasedExampleDatabase(path)
    if os.path.exists(path):
        return SQLiteExampleDatabase(path)
    if SQLITE_PATH.search(path):
        return SQLiteExampleDatabase(path)
    else:
        return DirectoryBasedExampleDatabase(path)
Пример #49
0
 def timed_test(*args, **kwargs):
     self.__test_runtime = None
     start = time.time()
     result = test(*args, **kwargs)
     runtime = (time.time() - start) * 1000
     self.__test_runtime = runtime
     if self.settings.deadline is not_set:
         if (
             not self.__warned_deadline and
             runtime >= 200
         ):
             self.__warned_deadline = True
             note_deprecation((
                 'Test took %.2fms to run. In future the default '
                 'deadline setting will be 200ms, which will '
                 'make this an error. You can set deadline to '
                 'an explicit value of e.g. %d to turn tests '
                 'slower than this into an error, or you can set '
                 'it to None to disable this check entirely.') % (
                     runtime, ceil(runtime / 100) * 100,
             ))
     elif runtime >= self.current_deadline:
         raise DeadlineExceeded(runtime, self.settings.deadline)
     return result
Пример #50
0
def models(
    model,  # type: Type[dm.Model]
    **field_strategies  # type: Union[st.SearchStrategy[Any], DefaultValueType]
):
    # type: (...) -> st.SearchStrategy[Any]
    """Return a strategy for examples of ``model``.

    .. warning::
        Hypothesis creates saved models. This will run inside your testing
        transaction when using the test runner, but if you use the dev console
        this will leave debris in your database.

    ``model`` must be an subclass of :class:`~django:django.db.models.Model`.
    Strategies for fields may be passed as keyword arguments, for example
    ``is_staff=st.just(False)``.

    Hypothesis can often infer a strategy based the field type and validators
    - for best results, make sure your validators are derived from Django's
    and therefore have the known types and attributes.
    Passing a keyword argument skips inference for that field; pass a strategy
    or pass ``hypothesis.extra.django.models.default_value`` to skip
    inference for that field.

    Foreign keys are not automatically derived. If they're nullable they will
    default to always being null, otherwise you always have to specify them.
    For example, examples of a Shop type with a foreign key to Company could
    be generated with::

      shop_strategy = models(Shop, company=models(Company))
    """
    note_deprecation(
        "This function is deprecated; use `hypothesis.extra.django."
        "from_model` instead.",
        since="2019-01-10",
    )
    result = {}
    for k, v in field_strategies.items():
        if not isinstance(v, DefaultValueType):
            result[k] = v
    missed = []  # type: List[Text]
    for f in model._meta.concrete_fields:
        if not (f.name in field_strategies or isinstance(f, dm.AutoField)):
            result[f.name] = from_field(f)
            if result[f.name].is_empty:
                missed.append(f.name)
    if missed:
        raise InvalidArgument(
            u"Missing arguments for mandatory field%s %s for model %s"
            % (u"s" if len(missed) > 1 else u"", u", ".join(missed), model.__name__)
        )

    for field in result:
        if model._meta.get_field(field).primary_key:
            # The primary key is generated as part of the strategy. We
            # want to find any existing row with this primary key and
            # overwrite its contents.
            kwargs = {field: result.pop(field)}
            kwargs["defaults"] = st.fixed_dictionaries(result)
            return _models_impl(st.builds(model.objects.update_or_create, **kwargs))

    # The primary key is not generated as part of the strategy, so we
    # just match against any row that has the same value for all
    # fields.
    return _models_impl(st.builds(model.objects.get_or_create, **result))
 def deprecated_strategy(draw):
     draw(integers())
     note_deprecation(msg, since="RELEASEDAY")
Пример #52
0
    def run(self):
        # Tell pytest to omit the body of this function from tracebacks
        __tracebackhide__ = True
        database_key = str_to_bytes(fully_qualified_name(self.test))
        self.start_time = time.time()
        global in_given
        runner = ConjectureRunner(
            self.evaluate_test_data,
            settings=self.settings, random=self.random,
            database_key=database_key,
        )

        if in_given or self.collector is None:
            runner.run()
        else:  # pragma: no cover
            in_given = True
            original_trace = sys.gettrace()
            try:
                sys.settrace(None)
                runner.run()
            finally:
                in_given = False
                sys.settrace(original_trace)
        note_engine_for_statistics(runner)
        run_time = time.time() - self.start_time
        timed_out = runner.exit_reason == ExitReason.timeout
        if runner.last_data is None:
            return
        if runner.interesting_examples:
            self.falsifying_examples = sorted(
                [d for d in runner.interesting_examples.values()],
                key=lambda d: sort_key(d.buffer), reverse=True
            )
        else:
            if timed_out:
                note_deprecation((
                    'Your tests are hitting the settings timeout (%.2fs). '
                    'This functionality will go away in a future release '
                    'and you should not rely on it. Instead, try setting '
                    'max_examples to be some value lower than %d (the number '
                    'of examples your test successfully ran here). Or, if you '
                    'would prefer your tests to run to completion, regardless '
                    'of how long they take, you can set the timeout value to '
                    'hypothesis.unlimited.'
                ) % (
                    self.settings.timeout, runner.valid_examples),
                    self.settings)
            if runner.valid_examples < min(
                self.settings.min_satisfying_examples,
                self.settings.max_examples,
            ) and not (
                runner.exit_reason == ExitReason.finished and
                self.at_least_one_success
            ):
                if timed_out:
                    raise Timeout((
                        'Ran out of time before finding a satisfying '
                        'example for '
                        '%s. Only found %d examples in ' +
                        '%.2fs.'
                    ) % (
                        get_pretty_function_description(self.test),
                        runner.valid_examples, run_time
                    ))
                else:
                    raise Unsatisfiable((
                        'Unable to satisfy assumptions of hypothesis '
                        '%s. Only %d examples considered '
                        'satisfied assumptions'
                    ) % (
                        get_pretty_function_description(self.test),
                        runner.valid_examples,))

        if not self.falsifying_examples:
            return

        flaky = 0

        self.__in_final_replay = True

        for falsifying_example in self.falsifying_examples:
            self.__was_flaky = False
            raised_exception = False
            try:
                with self.settings:
                    self.test_runner(
                        ConjectureData.for_buffer(falsifying_example.buffer),
                        reify_and_execute(
                            self.search_strategy, self.test,
                            print_example=True, is_final=True
                        ))
            except (UnsatisfiedAssumption, StopTest):
                report(traceback.format_exc())
                self.__flaky(
                    'Unreliable assumption: An example which satisfied '
                    'assumptions on the first run now fails it.'
                )
            except:
                if len(self.falsifying_examples) <= 1:
                    raise
                raised_exception = True
                report(traceback.format_exc())

            if not raised_exception:
                if (
                    isinstance(
                        falsifying_example.__expected_exception,
                        DeadlineExceeded
                    ) and self.__test_runtime is not None
                ):
                    report((
                        'Unreliable test timings! On an initial run, this '
                        'test took %.2fms, which exceeded the deadline of '
                        '%.2fms, but on a subsequent run it took %.2f ms, '
                        'which did not. If you expect this sort of '
                        'variability in your test timings, consider turning '
                        'deadlines off for this test by setting deadline=None.'
                    ) % (
                        falsifying_example.__expected_exception.runtime,
                        self.settings.deadline, self.__test_runtime
                    ))
                else:
                    report(
                        'Failed to reproduce exception. Expected: \n' +
                        falsifying_example.__expected_traceback,
                    )

                filter_message = (
                    'Unreliable test data: Failed to reproduce a failure '
                    'and then when it came to recreating the example in '
                    'order to print the test data with a flaky result '
                    'the example was filtered out (by e.g. a '
                    'call to filter in your strategy) when we didn\'t '
                    'expect it to be.'
                )

                try:
                    self.test_runner(
                        ConjectureData.for_buffer(falsifying_example.buffer),
                        reify_and_execute(
                            self.search_strategy,
                            test_is_flaky(
                                self.test, self.repr_for_last_exception),
                            print_example=True, is_final=True
                        ))
                except (UnsatisfiedAssumption, StopTest):
                    self.__flaky(filter_message)
                except Flaky as e:
                    if len(self.falsifying_examples) > 1:
                        self.__flaky(e.args[0])
                    else:
                        raise

            if self.__was_flaky:
                flaky += 1

        # If we only have one example then we should have raised an error or
        # flaky prior to this point.
        assert len(self.falsifying_examples) > 1

        if flaky > 0:
            raise Flaky((
                'Hypothesis found %d distinct failures, but %d of them '
                'exhibited some sort of flaky behaviour.') % (
                    len(self.falsifying_examples), flaky))
        else:
            raise MultipleFailures((
                'Hypothesis found %d distinct failures.') % (
                    len(self.falsifying_examples,)))
Пример #53
0
        def wrapped_test(*arguments, **kwargs):
            # Tell pytest to omit the body of this function from tracebacks
            __tracebackhide__ = True

            test = wrapped_test.hypothesis.inner_test

            if getattr(test, 'is_hypothesis_test', False):
                note_deprecation((
                    'You have applied @given to test: %s more than once. In '
                    'future this will be an error. Applying @given twice '
                    'wraps the test twice, which can be extremely slow. A '
                    'similar effect can be gained by combining the arguments '
                    'of the two calls to given. For example, instead of '
                    '@given(booleans()) @given(integers()), you could write '
                    '@given(booleans(), integers())') % (test.__name__, )
                )

            settings = wrapped_test._hypothesis_internal_use_settings

            random = get_random_for_wrapped_test(test, wrapped_test)

            if infer in generator_kwargs.values():
                hints = get_type_hints(test)
            for name in [name for name, value in generator_kwargs.items()
                         if value is infer]:
                if name not in hints:
                    raise InvalidArgument(
                        'passed %s=infer for %s, but %s has no type annotation'
                        % (name, test.__name__, name))
                generator_kwargs[name] = st.from_type(hints[name])

            processed_args = process_arguments_to_given(
                wrapped_test, arguments, kwargs, generator_arguments,
                generator_kwargs, argspec, test, settings
            )
            arguments, kwargs, test_runner, search_strategy = processed_args

            runner = getattr(search_strategy, 'runner', None)
            if isinstance(runner, TestCase) and test.__name__ in dir(TestCase):
                msg = ('You have applied @given to the method %s, which is '
                       'used by the unittest runner but is not itself a test.'
                       '  This is not useful in any way.' % test.__name__)
                fail_health_check(settings, msg, HealthCheck.not_a_test_method)
            if bad_django_TestCase(runner):  # pragma: no cover
                # Covered by the Django tests, but not the pytest coverage task
                raise InvalidArgument(
                    'You have applied @given to a method on %s, but this '
                    'class does not inherit from the supported versions in '
                    '`hypothesis.extra.django`.  Use the Hypothesis variants '
                    'to ensure that each example is run in a separate '
                    'database transaction.' % qualname(type(runner))
                )

            state = StateForActualGivenExecution(
                test_runner, search_strategy, test, settings, random,
                had_seed=wrapped_test._hypothesis_internal_use_seed
            )

            reproduce_failure = \
                wrapped_test._hypothesis_internal_use_reproduce_failure

            if reproduce_failure is not None:
                expected_version, failure = reproduce_failure
                if expected_version != __version__:
                    raise InvalidArgument((
                        'Attempting to reproduce a failure from a different '
                        'version of Hypothesis. This failure is from %s, but '
                        'you are currently running %r. Please change your '
                        'Hypothesis version to a matching one.'
                    ) % (expected_version, __version__))
                try:
                    state.execute(ConjectureData.for_buffer(
                        decode_failure(failure)),
                        print_example=True, is_final=True,
                    )
                    raise DidNotReproduce(
                        'Expected the test to raise an error, but it '
                        'completed successfully.'
                    )
                except StopTest:
                    raise DidNotReproduce(
                        'The shape of the test data has changed in some way '
                        'from where this blob was defined. Are you sure '
                        "you're running the same test?"
                    )
                except UnsatisfiedAssumption:
                    raise DidNotReproduce(
                        'The test data failed to satisfy an assumption in the '
                        'test. Have you added it since this blob was '
                        'generated?'
                    )

            execute_explicit_examples(
                test_runner, test, wrapped_test, settings, arguments, kwargs
            )

            if settings.max_examples <= 0:
                return

            if not (
                Phase.reuse in settings.phases or
                Phase.generate in settings.phases
            ):
                return

            try:
                if isinstance(runner, TestCase) and hasattr(runner, 'subTest'):
                    subTest = runner.subTest
                    try:
                        setattr(runner, 'subTest', fake_subTest)
                        state.run()
                    finally:
                        setattr(runner, 'subTest', subTest)
                else:
                    state.run()
            except BaseException:
                generated_seed = \
                    wrapped_test._hypothesis_internal_use_generated_seed
                if generated_seed is not None and not state.failed_normally:
                    with local_settings(settings):
                        if running_under_pytest:
                            report(
                                'You can add @seed(%(seed)d) to this test or '
                                'run pytest with --hypothesis-seed=%(seed)d '
                                'to reproduce this failure.' % {
                                    'seed': generated_seed})
                        else:
                            report(
                                'You can add @seed(%d) to this test to '
                                'reproduce this failure.' % (generated_seed,))
                raise
Пример #54
0
    def run(self):
        # Tell pytest to omit the body of this function from tracebacks
        __tracebackhide__ = True
        if global_force_seed is None:
            database_key = str_to_bytes(fully_qualified_name(self.test))
        else:
            database_key = None
        self.start_time = benchmark_time()
        runner = ConjectureRunner(
            self.evaluate_test_data,
            settings=self.settings, random=self.random,
            database_key=database_key,
        )
        try:
            runner.run()
        finally:
            self.used_examples_from_database = \
                runner.used_examples_from_database
        note_engine_for_statistics(runner)
        run_time = benchmark_time() - self.start_time

        self.used_examples_from_database = runner.used_examples_from_database

        if runner.used_examples_from_database:
            if self.settings.derandomize:
                note_deprecation((
                    'In future derandomize will imply database=None, but your '
                    'test: %s is currently using examples from the database. '
                    'To get the future behaviour, update your settings to '
                    'include database=None.') % (self.test.__name__, )
                )
            if self.__had_seed:
                note_deprecation((
                    'In future use of @seed will imply database=None in your '
                    'settings, but your test: %s is currently using examples '
                    'from the database. To get the future behaviour, update '
                    'your settings for this test to include database=None.')
                    % (self.test.__name__,)
                )

        timed_out = runner.exit_reason == ExitReason.timeout
        if runner.call_count == 0:
            return
        if runner.interesting_examples:
            self.falsifying_examples = sorted(
                [d for d in runner.interesting_examples.values()],
                key=lambda d: sort_key(d.buffer), reverse=True
            )
        else:
            if runner.valid_examples == 0:
                if timed_out:
                    raise Timeout((
                        'Ran out of time before finding a satisfying '
                        'example for %s. Only found %d examples in %.2fs.'
                    ) % (
                        get_pretty_function_description(self.test),
                        runner.valid_examples, run_time
                    ))
                else:
                    raise Unsatisfiable(
                        'Unable to satisfy assumptions of hypothesis %s.' %
                        (get_pretty_function_description(self.test),)
                    )

        if not self.falsifying_examples:
            return

        self.failed_normally = True

        flaky = 0

        for falsifying_example in self.falsifying_examples:
            ran_example = ConjectureData.for_buffer(falsifying_example.buffer)
            self.__was_flaky = False
            assert falsifying_example.__expected_exception is not None
            try:
                self.execute(
                    ran_example,
                    print_example=True, is_final=True,
                    expected_failure=(
                        falsifying_example.__expected_exception,
                        falsifying_example.__expected_traceback,
                    )
                )
            except (UnsatisfiedAssumption, StopTest):
                report(traceback.format_exc())
                self.__flaky(
                    'Unreliable assumption: An example which satisfied '
                    'assumptions on the first run now fails it.'
                )
            except BaseException:
                if len(self.falsifying_examples) <= 1:
                    raise
                report(traceback.format_exc())
            finally:  # pragma: no cover
                # This section is in fact entirely covered by the tests in
                # test_reproduce_failure, but it seems to trigger a lovely set
                # of coverage bugs: The branches show up as uncovered (despite
                # definitely being covered - you can add an assert False else
                # branch to verify this and see it fail - and additionally the
                # second branch still complains about lack of coverage even if
                # you add a pragma: no cover to it!
                # See https://bitbucket.org/ned/coveragepy/issues/623/
                if self.settings.print_blob is not PrintSettings.NEVER:
                    failure_blob = encode_failure(falsifying_example.buffer)
                    # Have to use the example we actually ran, not the original
                    # falsifying example! Otherwise we won't catch problems
                    # where the repr of the generated example doesn't parse.
                    can_use_repr = ran_example.can_reproduce_example_from_repr
                    if (
                        self.settings.print_blob is PrintSettings.ALWAYS or (
                            self.settings.print_blob is PrintSettings.INFER and
                            self.settings.verbosity >= Verbosity.normal and
                            not can_use_repr and
                            len(failure_blob) < 200
                        )
                    ):
                        report((
                            '\n'
                            'You can reproduce this example by temporarily '
                            'adding @reproduce_failure(%r, %r) as a decorator '
                            'on your test case') % (
                                __version__, failure_blob,))
            if self.__was_flaky:
                flaky += 1

        # If we only have one example then we should have raised an error or
        # flaky prior to this point.
        assert len(self.falsifying_examples) > 1

        if flaky > 0:
            raise Flaky((
                'Hypothesis found %d distinct failures, but %d of them '
                'exhibited some sort of flaky behaviour.') % (
                    len(self.falsifying_examples), flaky))
        else:
            raise MultipleFailures((
                'Hypothesis found %d distinct failures.') % (
                    len(self.falsifying_examples,)))
def test_does_not_warn_if_quiet():
    with pytest.warns(None) as rec:
        note_deprecation("This is bad", since="RELEASEDAY", verbosity=Verbosity.quiet)
    assert len(rec) == 0
Пример #56
0
 def deprecated_strategy(draw):
     draw(integers())
     note_deprecation(msg)
Пример #57
0
    def example(self, random=None):
        """Provide an example of the sort of value that this strategy
        generates. This is biased to be slightly simpler than is typical for
        values from this strategy, for clarity purposes.

        This method shouldn't be taken too seriously. It's here for interactive
        exploration of the API, not for any sort of real testing.

        This method is part of the public API.

        """
        context = _current_build_context.value
        if context is not None:
            if context.data is not None and context.data.depth > 0:
                note_deprecation(
                    'Using example() inside a strategy definition is a bad '
                    'idea. It will become an error in a future version of '
                    "Hypothesis, but it's unlikely that it's doing what you "
                    'intend even now. Instead consider using '
                    'hypothesis.strategies.builds() or '
                    '@hypothesis.strategies.composite to define your strategy.'
                    ' See '
                    'https://hypothesis.readthedocs.io/en/latest/data.html'
                    '#hypothesis.strategies.builds or '
                    'https://hypothesis.readthedocs.io/en/latest/data.html'
                    '#composite-strategies for more details.'
                )
            else:
                note_deprecation(
                    'Using example() inside a test function is a bad '
                    'idea. It will become an error in a future version of '
                    "Hypothesis, but it's unlikely that it's doing what you "
                    'intend even now. Instead consider using '
                    'hypothesis.strategies.data() to draw '
                    'more examples during testing. See '
                    'https://hypothesis.readthedocs.io/en/latest/data.html'
                    '#drawing-interactively-in-tests for more details.'
                )

        from hypothesis import find, settings, Verbosity

        # Conjecture will always try the zero example first. This would result
        # in us producing the same example each time, which is boring, so we
        # deliberately skip the first example it feeds us.
        first = []

        def condition(x):
            if first:
                return True
            else:
                first.append(x)
                return False
        try:
            return find(
                self,
                condition,
                random=random,
                settings=settings(
                    max_shrinks=0,
                    max_iterations=1000,
                    database=None,
                    verbosity=Verbosity.quiet,
                )
            )
        except (NoSuchExample, Unsatisfiable):
            # This can happen when a strategy has only one example. e.g.
            # st.just(x). In that case we wanted the first example after all.
            if first:
                return first[0]
            raise NoExamples(
                u'Could not find any valid examples in 100 tries'
            )
Пример #58
0
def test_does_not_warn_if_quiet():
    with pytest.warns(None) as rec:
        note_deprecation('This is bad', settings(
            strict=False, verbosity=Verbosity.quiet))
    assert len(rec) == 0