def test_integral_floats_order_as_integers(x, y):
    assume(x != y)
    x, y = sorted((x, y))
    assume(y < 0 or x > 0)
    if y < 0:
        assert flt.float_to_lex(y) < flt.float_to_lex(x)
    else:
        assert flt.float_to_lex(x) < flt.float_to_lex(y)
def test_integral_floats_order_as_integers(x, y):
    assume(x != y)
    x, y = sorted((x, y))
    assume(y < 0 or x > 0)
    if y < 0:
        assert flt.float_to_lex(y) < flt.float_to_lex(x)
    else:
        assert flt.float_to_lex(x) < flt.float_to_lex(y)
def test_floats_order_worse_than_their_integral_part(f):
    assume(f != int(f))
    assume(int(f) != 0)
    i = flt.float_to_lex(f)
    if f < 0:
        g = ceil(f)
    else:
        g = floor(f)

    assert flt.float_to_lex(float(g)) < i
def test_floats_order_worse_than_their_integral_part(f):
    assume(f != int(f))
    assume(int(f) != 0)
    i = flt.float_to_lex(f)
    if f < 0:
        g = ceil(f)
    else:
        g = floor(f)

    assert flt.float_to_lex(float(g)) < i
def minimal_from(start, condition):
    buf = int_to_bytes(flt.float_to_lex(start), 8)

    def parse_buf(b):
        return flt.lex_to_float(int_from_bytes(b))

    shrunk = minimize(
        buf, lambda b: condition(parse_buf(b)),
        full=True, random=Random(0)
    )
    return parse_buf(shrunk)
Beispiel #6
0
def minimal_from(start, condition):
    buf = int_to_bytes(flt.float_to_lex(start), 8)

    def parse_buf(b):
        return flt.lex_to_float(int_from_bytes(b))

    shrunk = minimize(buf,
                      lambda b: condition(parse_buf(b)),
                      full=True,
                      random=Random(0))
    return parse_buf(shrunk)
def float_runner(start, condition):
    def parse_buf(b):
        return flt.lex_to_float(int_from_bytes(b))

    def test_function(data):
        f = flt.draw_float(data)
        if condition(f):
            data.mark_interesting()

    runner = ConjectureRunner(test_function)
    runner.cached_test_function(int_to_bytes(flt.float_to_lex(start), 8) + hbytes(1))
    assert runner.interesting_examples
    return runner
Beispiel #8
0
    def float_hack(self):
        """Our encoding of floating point numbers does the right thing when you
        lexically shrink it, but there are some highly non-obvious lexical
        shrinks corresponding to natural floating point operations.

        We can't actually tell when the floating point encoding is being used
        (that would break the assumptions that Hypothesis doesn't inspect
        the generated values), but we can cheat: We just guess when it might be
        being used and perform shrinks that are valid regardless of our guess
        is correct.

        So that's what this method does. It's a cheat to give us good shrinking
        of floating at low cost in runtime and only moderate cost in elegance.
        """
        # If the block is of the wrong size then we're certainly not using the
        # float encoding.
        if self.size != 8:
            return

        # If the high bit is zero then we're in the integer representation of
        # floats so we don't need these hacks because it will shrink normally.
        if self.current[0] >> 7 == 0:
            return

        i = self.current_int
        f = lex_to_float(i)

        # This floating point number can be represented in our simple format.
        # So we try converting it to that (which will give the same float, but
        # a different encoding of it). If that doesn't work then the float
        # value of this doesn't unambiguously give the desired predicate, so
        # this approach isn't useful. If it *does* work, then we're now in a
        # situation where we don't need it, so either way we return here.
        if is_simple(f):
            self.incorporate_float(f)
            return

        self.delegate(
            Float,
            convert_to=lambda b: lex_to_float(int_from_bytes(b)),
            convert_from=lambda f: int_to_bytes(float_to_lex(f), self.size),
        )
Beispiel #9
0
    def float_hack(self):
        """Our encoding of floating point numbers does the right thing when you
        lexically shrink it, but there are some highly non-obvious lexical
        shrinks corresponding to natural floating point operations.

        We can't actually tell when the floating point encoding is being used
        (that would break the assumptions that Hypothesis doesn't inspect
        the generated values), but we can cheat: We just guess when it might be
        being used and perform shrinks that are valid regardless of our guess
        is correct.

        So that's what this method does. It's a cheat to give us good shrinking
        of floating at low cost in runtime and only moderate cost in elegance.
        """
        # If the block is of the wrong size then we're certainly not using the
        # float encoding.
        if self.size != 8:
            return

        # If the high bit is zero then we're in the integer representation of
        # floats so we don't need these hacks because it will shrink normally.
        if self.current[0] >> 7 == 0:
            return

        i = self.current_int
        f = lex_to_float(i)

        # This floating point number can be represented in our simple format.
        # So we try converting it to that (which will give the same float, but
        # a different encoding of it). If that doesn't work then the float
        # value of this doesn't unambiguously give the desired predicate, so
        # this approach isn't useful. If it *does* work, then we're now in a
        # situation where we don't need it, so either way we return here.
        if is_simple(f):
            self.incorporate_float(f)
            return

        self.delegate(
            Float,
            convert_to=lambda b: lex_to_float(int_from_bytes(b)),
            convert_from=lambda f: int_to_bytes(float_to_lex(f), self.size),
        )
    result = flt.draw_float(ConjectureData.for_buffer(v.buffer))
    assert condition(result)
    return result


INTERESTING_FLOATS = [
    0.0, 1.0, 2.0, sys.float_info.max,
    float("inf"),
    float("nan")
]


@pytest.mark.parametrize(
    ("start", "end"),
    [(a, b) for a in INTERESTING_FLOATS
     for b in INTERESTING_FLOATS if flt.float_to_lex(a) > flt.float_to_lex(b)],
)
def test_can_shrink_downwards(start, end):
    assert minimal_from(start, lambda x: not (x < end)) == end


@pytest.mark.parametrize(
    "f", [1, 2, 4, 8, 10, 16, 32, 64, 100, 128, 256, 500, 512, 1000, 1024])
@pytest.mark.parametrize("mul", [1.1, 1.5, 9.99, 10])
def test_shrinks_downwards_to_integers(f, mul):
    g = minimal_from(f * mul, lambda x: x >= f)
    assert g == f


def test_shrink_to_integer_upper_bound():
    assert minimal_from(1.1, lambda x: 1 < x <= 2) == 2
Beispiel #11
0
    def float_hack(self):
        """Our encoding of floating point numbers does the right thing when you
        lexically shrink it, but there are some highly non-obvious lexical
        shrinks corresponding to natural floating point operations.

        We can't actually tell when the floating point encoding is being used
        (that would break the assumptions that Hypothesis doesn't inspect
        the generated values), but we can cheat: We just guess when it might be
        being used and perform shrinks that are valid regardless of our guess
        is correct.

        So that's what this method does. It's a cheat to give us good shrinking
        of floating at low cost in runtime and only moderate cost in elegance.
        """
        # If the block is of the wrong size then we're certainly not using the
        # float encoding.
        if self.size != 8:
            return

        # If the high bit is zero then we're in the integer representation of
        # floats so we don't need these hacks because it will shrink normally.
        if self.current[0] >> 7 == 0:
            return

        i = self.current_int
        f = lex_to_float(i)

        # This floating point number can be represented in our simple format.
        # So we try converting it to that (which will give the same float, but
        # a different encoding of it). If that doesn't work then the float
        # value of this doesn't unambiguously give the desired predicate, so
        # this approach isn't useful. If it *does* work, then we're now in a
        # situation where we don't need it, so either way we return here.
        if is_simple(f):
            self.incorporate_float(f)
            return

        # We check for a bunch of standard "large" floats. If we're currently
        # worse than them and the shrink downwards doesn't help, abort early
        # because there's not much useful we can do here.
        for g in [
            float('nan'), float('inf'), sys.float_info.max,
        ]:
            j = float_to_lex(g)
            if j < i:
                if self.incorporate_int(j):
                    f = g
                    i = j

        if math.isinf(f) or math.isnan(f):
            return

        # Finally we get to the important bit: Each of these is a small change
        # to the floating point number that corresponds to a large change in
        # the lexical representation. Trying these ensures that our floating
        # point shrink can always move past these obstacles. In particular it
        # ensures we can always move to integer boundaries and shrink past a
        # change that would require shifting the exponent while not changing
        # the float value much.
        for g in [floor(f), ceil(f)]:
            if self.incorporate_float(g):
                return

        if f > 2:
            self.incorporate_float(f - 1)
Beispiel #12
0
 def incorporate_float(self, f):
     assert self.size == 8
     return self.incorporate_int(float_to_lex(f))
Beispiel #13
0
    def float_hack(self):
        """Our encoding of floating point numbers does the right thing when you
        lexically shrink it, but there are some highly non-obvious lexical
        shrinks corresponding to natural floating point operations.

        We can't actually tell when the floating point encoding is being used
        (that would break the assumptions that Hypothesis doesn't inspect
        the generated values), but we can cheat: We just guess when it might be
        being used and perform shrinks that are valid regardless of our guess
        is correct.

        So that's what this method does. It's a cheat to give us good shrinking
        of floating at low cost in runtime and only moderate cost in elegance.

        """

        # If the block is of the wrong size then we're certainly not using the
        # float encoding.
        if self.size != 8:
            return

        # If the high bit is zero then we're in the integer representation of
        # floats so we don't need these hacks because it will shrink normally.
        if self.current[0] >> 7 == 0:
            return

        i = int_from_bytes(self.current)
        f = lex_to_float(i)

        # This floating point number can be represented in our simple format.
        # So we try converting it to that (which will give the same float, but
        # a different encoding of it). If that doesn't work then the float
        # value of this doesn't unambiguously give the desired predicate, so
        # this approach isn't useful. If it *does* work, then we're now in a
        # situation where we don't need it, so either way we return here.
        if is_simple(f):
            self.incorporate_float(f)
            return

        # We check for a bunch of standard "large" floats. If we're currently
        # worse than them and the shrink downwards doesn't help, abort early
        # because there's not much useful we can do here.
        for g in [
            float('nan'), float('inf'), sys.float_info.max,
        ]:
            j = float_to_lex(g)
            if j < i:
                if self.incorporate_int(j):
                    f = g
                    i = j

        if math.isinf(f) or math.isnan(f):
            return

        # Finally we get to the important bit: Each of these is a small change
        # to the floating point number that corresponds to a large change in
        # the lexical representation. Trying these ensures that our floating
        # point shrink can always move past these obstacles. In particular it
        # ensures we can always move to integer boundaries and shrink past a
        # change that would require shifting the exponent while not changing
        # the float value much.
        for g in [
            floor(f), ceil(f),
        ]:
            if self.incorporate_float(g):
                return

        if f > 2:
            self.incorporate_float(f - 1)
Beispiel #14
0
 def incorporate_float(self, f):
     assert self.size == 8
     return self.incorporate_int(float_to_lex(f))
Beispiel #15
0
 def left_is_better(self, left, right):
     lex1 = float_to_lex(left)
     lex2 = float_to_lex(right)
     return lex1 < lex2
Beispiel #16
0
        buf, lambda b: condition(parse_buf(b)),
        full=True, random=Random(0)
    )
    return parse_buf(shrunk)


INTERESTING_FLOATS = [
    0.0, 1.0, 2.0, sys.float_info.max, float('inf'), float('nan')
]


@pytest.mark.parametrize(('start', 'end'), [
    (a, b)
    for a in INTERESTING_FLOATS
    for b in INTERESTING_FLOATS
    if flt.float_to_lex(a) > flt.float_to_lex(b)
])
def test_can_shrink_downwards(start, end):
    assert minimal_from(start, lambda x: not (x < end)) == end


@pytest.mark.parametrize(
    'f', [1, 2, 4, 8, 10, 16, 32, 64, 100, 128, 256, 500, 512, 1000, 1024]
)
@pytest.mark.parametrize(
    'mul', [1.1, 1.5, 9.99, 10]
)
def test_shrinks_downwards_to_integers(f, mul):
    g = minimal_from(f * mul, lambda x: x >= f)
    assert g == f
def test_fractional_floats_are_worse_than_one(f):
    assume(0 < f < 1)
    assert flt.float_to_lex(f) > flt.float_to_lex(1)
        buf, lambda b: condition(parse_buf(b)),
        full=True, random=Random(0)
    )
    return parse_buf(shrunk)


INTERESTING_FLOATS = [
    0.0, 1.0, 2.0, sys.float_info.max, float('inf'), float('nan')
]


@pytest.mark.parametrize(('start', 'end'), [
    (a, b)
    for a in INTERESTING_FLOATS
    for b in INTERESTING_FLOATS
    if flt.float_to_lex(a) > flt.float_to_lex(b)
])
def test_can_shrink_downwards(start, end):
    assert minimal_from(start, lambda x: not (x < end)) == end


@pytest.mark.parametrize(
    'f', [1, 2, 4, 8, 10, 16, 32, 64, 100, 128, 256, 500, 512, 1000, 1024]
)
@pytest.mark.parametrize(
    'mul', [1.1, 1.5, 9.99, 10]
)
def test_shrinks_downwards_to_integers(f, mul):
    g = minimal_from(f * mul, lambda x: x >= f)
    assert g == f
def test_floats_round_trip(f):
    i = flt.float_to_lex(f)
    g = flt.lex_to_float(i)

    assert float_to_int(f) == float_to_int(g)
def test_fractional_floats_are_worse_than_one(f):
    assume(0 < f < 1)
    assert flt.float_to_lex(f) > flt.float_to_lex(1)
def test_floats_round_trip(f):
    i = flt.float_to_lex(f)
    g = flt.lex_to_float(i)

    assert float_to_int(f) == float_to_int(g)
 def left_is_better(self, left, right):
     lex1 = float_to_lex(left)
     lex2 = float_to_lex(right)
     return lex1 < lex2