File: debug.py

package info (click to toggle)
python-hypothesis 6.67.1-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 14,220 kB
  • sloc: python: 46,711; ruby: 1,107; sh: 255; xml: 140; makefile: 49; javascript: 12
file content (120 lines) | stat: -rw-r--r-- 3,376 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# This file is part of Hypothesis, which may be found at
# https://github.com/HypothesisWorks/hypothesis/
#
# Copyright the Hypothesis Authors.
# Individual contributors are listed in AUTHORS.rst and the git log.
#
# This Source Code Form is subject to the terms of the Mozilla Public License,
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at https://mozilla.org/MPL/2.0/.

from hypothesis import (
    HealthCheck,
    Verbosity,
    given,
    settings as Settings,
    strategies as st,
)
from hypothesis.errors import Found, NoSuchExample, Unsatisfiable
from hypothesis.internal.conjecture.data import ConjectureData, StopTest
from hypothesis.internal.reflection import get_pretty_function_description

from tests.common.utils import no_shrink

TIME_INCREMENT = 0.01


class Timeout(BaseException):
    pass


def minimal(definition, condition=lambda x: True, settings=None, timeout_after=10):
    def wrapped_condition(x):
        if timeout_after is not None:
            if runtime:
                runtime[0] += TIME_INCREMENT
                if runtime[0] >= timeout_after:
                    raise Timeout()
        result = condition(x)
        if result and not runtime:
            runtime.append(0.0)
        return result

    if settings is None:
        settings = Settings(max_examples=50000)

    verbosity = settings.verbosity
    if verbosity == Verbosity.normal:
        verbosity = Verbosity.quiet

    @given(definition)
    @Settings(
        parent=settings,
        suppress_health_check=HealthCheck.all(),
        report_multiple_bugs=False,
        derandomize=True,
        database=None,
        verbosity=verbosity,
    )
    def inner(x):
        if wrapped_condition(x):
            result[:] = [x]
            raise Found

    definition.validate()
    runtime = []
    result = []
    try:
        inner()
    except Found:
        return result[0]
    raise Unsatisfiable(
        "Could not find any examples from %r that satisfied %s"
        % (definition, get_pretty_function_description(condition))
    )


def find_any(definition, condition=lambda _: True, settings=None):
    settings = settings or Settings.default
    return minimal(
        definition,
        condition,
        settings=Settings(
            settings, phases=no_shrink, max_examples=max(1000, settings.max_examples)
        ),
    )


def assert_no_examples(strategy, condition=lambda _: True):
    try:
        result = find_any(strategy, condition)
        raise AssertionError(f"Expected no results but found {result!r}")
    except (Unsatisfiable, NoSuchExample):
        pass


def assert_all_examples(strategy, predicate):
    """Asserts that all examples of the given strategy match the predicate.

    :param strategy: Hypothesis strategy to check
    :param predicate: (callable) Predicate that takes example and returns bool
    """

    @given(strategy)
    def assert_examples(s):
        msg = f"Found {s!r} using strategy {strategy} which does not match"
        assert predicate(s), msg

    assert_examples()


def assert_can_trigger_event(strategy, predicate):
    def test(buf):
        data = ConjectureData.for_buffer(buf)
        try:
            data.draw(strategy)
        except StopTest:
            pass
        return any(predicate(e) for e in data.events)

    find_any(st.binary(), test)