File: test_subnormal_floats.py

package info (click to toggle)
python-hypothesis 6.138.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 15,272 kB
  • sloc: python: 62,853; ruby: 1,107; sh: 253; makefile: 41; javascript: 6
file content (98 lines) | stat: -rw-r--r-- 3,431 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
# 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 sys import float_info

import pytest

from hypothesis.errors import InvalidArgument
from hypothesis.internal.floats import next_down, next_up
from hypothesis.strategies import floats
from hypothesis.strategies._internal.numbers import next_down_normal, next_up_normal

from tests.common.debug import assert_no_examples, check_can_generate_examples, find_any
from tests.common.utils import PYTHON_FTZ

pytestmark = [pytest.mark.skipif(PYTHON_FTZ, reason="broken by unsafe compiler flags")]


def kw(marks=(), **kwargs):
    id_ = ", ".join(f"{k}={v!r}" for k, v in kwargs.items())
    return pytest.param(kwargs, id=id_, marks=marks)


@pytest.mark.parametrize(
    "kwargs",
    [
        kw(min_value=1),
        kw(max_value=-1),
        kw(min_value=float_info.min),
        kw(min_value=next_down(float_info.min), exclude_min=True),
        kw(max_value=-float_info.min),
        kw(min_value=next_up(-float_info.min), exclude_max=True),
    ],
)
def test_subnormal_validation(kwargs):
    strat = floats(**kwargs, allow_subnormal=True)
    with pytest.raises(InvalidArgument):
        check_can_generate_examples(strat)


@pytest.mark.parametrize(
    "kwargs",
    [
        # min value
        kw(allow_subnormal=False, min_value=1),
        kw(allow_subnormal=False, min_value=float_info.min),
        kw(allow_subnormal=True, min_value=-1),
        kw(allow_subnormal=True, min_value=next_down(float_info.min)),
        # max value
        kw(allow_subnormal=False, max_value=-1),
        kw(allow_subnormal=False, max_value=-float_info.min),
        kw(allow_subnormal=True, max_value=1),
        kw(allow_subnormal=True, max_value=next_up(-float_info.min)),
        # min/max values
        kw(allow_subnormal=True, min_value=-1, max_value=1),
        kw(
            allow_subnormal=True,
            min_value=next_down(float_info.min),
            max_value=float_info.min,
        ),
        kw(
            allow_subnormal=True,
            min_value=-float_info.min,
            max_value=next_up(-float_info.min),
        ),
        kw(allow_subnormal=False, min_value=-1, max_value=-float_info.min),
        kw(allow_subnormal=False, min_value=float_info.min, max_value=1),
    ],
)
def test_allow_subnormal_defaults_correctly(kwargs):
    # copy to support our threading CI tests
    kwargs = kwargs.copy()
    allow_subnormal = kwargs.pop("allow_subnormal")
    strat = floats(**kwargs).filter(lambda x: x != 0)
    if allow_subnormal:
        find_any(strat, lambda x: -float_info.min < x < float_info.min)
    else:
        assert_no_examples(strat, lambda x: -float_info.min < x < float_info.min)


@pytest.mark.parametrize(
    "func, val, expected",
    [
        (next_up_normal, -float_info.min, -0.0),
        (next_up_normal, +0.0, float_info.min),
        (next_down_normal, float_info.min, +0.0),
        (next_down_normal, -0.0, -float_info.min),
    ],
)
def test_next_float_normal(func, val, expected):
    assert func(value=val, width=64, allow_subnormal=False) == expected