# Buggy code
def floats(
    min_value=None,  # type: Real
    max_value=None,  # type: Real
    allow_nan=None,  # type: bool
    allow_infinity=None,  # type: bool
    width=64,  # type: int
    exclude_min=False,  # type: bool
    exclude_max=False,  # type: bool
):
    # type: (...) -> SearchStrategy[float]
    """Returns a strategy which generates floats.

    - If min_value is not None, all values will be >= min_value.
    - If max_value is not None, all values will be <= max_value.
    - If min_value or max_value is not None, it is an error to enable
      allow_nan.
    - If both min_value and max_value are not None, it is an error to enable
      allow_infinity.

    Where not explicitly ruled out by the bounds, all of infinity, -infinity
    and NaN are possible values generated by this strategy.

    The width argument specifies the maximum number of bits of precision
    required to represent the generated float. Valid values are 16, 32, or 64.
    Passing ``width=32`` will still use the builtin 64-bit ``float`` class,
    but always for values which can be exactly represented as a 32-bit float.
    Half-precision floats (``width=16``) are only supported on Python 3.6, or
    if :pypi:`Numpy` is installed.

    The exclude_min and exclude_max argument can be used to generate numbers
    from open or half-open intervals, by excluding the respective endpoints.
    Attempting to exclude an endpoint which is None will raise an error;
    use ``allow_infinity=False`` to generate finite floats.  You can however
    use e.g. ``min_value=float("-inf"), exclude_min=True`` to exclude only
    one infinite endpoint.

    Examples from this strategy have a complicated and hard to explain
    shrinking behaviour, but it tries to improve "human readability". Finite
    numbers will be preferred to infinity and infinity will be preferred to
    NaN.
    """
    check_type(bool, exclude_min, "exclude_min")
    check_type(bool, exclude_max, "exclude_max")

    if allow_nan is None:
        allow_nan = bool(min_value is None and max_value is None)
    elif allow_nan:
        if min_value is not None or max_value is not None:
            raise InvalidArgument(
                "Cannot have allow_nan=%r, with min_value or max_value" % (allow_nan)
            )

    if width not in (16, 32, 64):
        raise InvalidArgument(
            "Got width=%r, but the only valid values are the integers 16, "
            "32, and 64." % (width,)
        )
    if width == 16 and sys.version_info[:2] < (3, 6) and numpy is None:
        raise InvalidArgument(  # pragma: no cover
            "width=16 requires either Numpy, or Python >= 3.6"
        )

    check_valid_bound(min_value, "min_value")
    check_valid_bound(max_value, "max_value")

    min_arg, max_arg = min_value, max_value
    if min_value is not None:
        min_value = float_of(min_value, width)
        assert isinstance(min_value, float)
    if max_value is not None:
        max_value = float_of(max_value, width)
        assert isinstance(max_value, float)

    if min_value != min_arg:
        note_deprecation(
            "min_value=%r cannot be exactly represented as a float of width "
            "%d, which will be an error in a future version. Use min_value=%r "
            "instead." % (min_arg, width, min_value),
            since="2018-10-10",
        )
    if max_value != max_arg:
        note_deprecation(
            "max_value=%r cannot be exactly represented as a float of width "
            "%d, which will be an error in a future version. Use max_value=%r "
            "instead" % (max_arg, width, max_value),
            since="2018-10-10",
        )

    if exclude_min:
        if min_value is None:
            raise InvalidArgument("Cannot exclude min_value=None")
        min_value = next_up(min_value, width=width)
    if exclude_max:
        if max_value is None:
            raise InvalidArgument("Cannot exclude max_value=None")
        max_value = next_down(max_value, width=width)

    check_valid_interval(min_value, max_value, "min_value", "max_value")
    if min_value == float("-inf"):
        min_value = None
    if max_value == float("inf"):
        max_value = None

    if min_value is not None and min_arg is not None and min_value < min_arg:
        min_value = next_up(min_value, width)
        assert min_value > min_arg  # type: ignore
    if max_value is not None and max_arg is not None and max_value > max_arg:
        max_value = next_down(max_value, width)
        assert max_value < max_arg  # type: ignore
    if min_value is not None and max_value is not None and min_value > max_value:
        raise InvalidArgument(
            "There are no %s-bit floating-point values between min_value=%r "
            "and max_value=%r" % (width, min_arg, max_arg)
        )

    if allow_infinity is None:
        allow_infinity = bool(min_value is None or max_value is None)
    elif allow_infinity:
        if min_value is not None and max_value is not None:
            raise InvalidArgument(
                "Cannot have allow_infinity=%r, with both min_value and "
                "max_value" % (allow_infinity)
            )
    elif min_value == float("inf"):
        raise InvalidArgument("allow_infinity=False excludes min_value=inf")
    elif max_value == float("-inf"):
        raise InvalidArgument("allow_infinity=False excludes max_value=-inf")

    if min_value is None and max_value is None:
        result = FloatStrategy(allow_infinity=allow_infinity, allow_nan=allow_nan)  # type: SearchStrategy[float]
    elif min_value is not None and max_value is not None:
        if min_value == max_value:
            assert isinstance(min_value, float)
            result = just(min_value)
        elif is_negative(min_value):
            if is_negative(max_value):
                result = floats(min_value=-max_value, max_value=-min_value).map(
                    operator.neg
                )
            else:
                result = floats(min_value=0.0, max_value=max_value) | floats(
                    min_value=0.0, max_value=-min_value
                ).map(operator.neg)
        elif count_between_floats(min_value, max_value) > 1000:
            result = FixedBoundedFloatStrategy(
                lower_bound=min_value, upper_bound=max_value
            )
        else:
            ub_int = float_to_int(max_value, width)
            lb_int = float_to_int(min_value, width)
            assert lb_int <= ub_int
            result = integers(min_value=lb_int, max_value=ub_int).map(
                lambda x: int_to_float(x, width)
            )
    elif min_value is not None:
        assert isinstance(min_value, float)
        if min_value < 0:
            result = floats(min_value=0.0, allow_infinity=allow_infinity) | floats(
                min_value=min_value, max_value=-0.0
            )
        else:
            result = floats(allow_infinity=allow_infinity, allow_nan=False).map(
                lambda x: min_value + abs(x)  # type: ignore
            )
            if not allow_infinity:
                result = result.filter(lambda x: not math.isinf(x))
        if min_value == 0 and not is_negative(min_value):
            result = result.filter(lambda x: math.copysign(1.0, x) == 1)
    else:
        assert isinstance(max_value, float)
        if max_value > 0:
            result = floats(min_value=0.0, max_value=max_value) | floats(
                max_value=-0.0, allow_infinity=allow_infinity
            )
        else:
            result = floats(allow_infinity=allow_infinity, allow_nan=False).map(
                lambda x: max_value - abs(x)  # type: ignore
            )
            if not allow_infinity:
                result = result.filter(lambda x: not math.isinf(x))
        if max_value == 0 and is_negative(max_value):
            result = result.filter(is_negative)

    if width < 64:

        def downcast(x):
            try:
                return float_of(x, width)
            except OverflowError:
                reject()

        return result.map(downcast)
    return result


# Traceback (AssertionError)
================================================================================================================================= FAILURES =================================================================================================================================
________________________________________________________________________________________________________________________ test_should_be_always_true ________________________________________________________________________________________________________________________

@given(val=floats(max_value=float('-inf'), allow_nan=False, exclude_max=True))
@settings(verbosity=Verbosity.verbose)
def test_should_be_always_true(val):

float_inf_strat.py:6:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

val = -inf

@given(val=floats(max_value=float('-inf'), allow_nan=False, exclude_max=True))
@settings(verbosity=Verbosity.verbose)
def test_should_be_always_true(val):
assert val != float('-inf')
E       AssertionError: assert -inf != -inf
E        +  where -inf = float('-inf')

float_inf_strat.py:8: AssertionError
-------------------------------------------------------------------------------------------------------------------------------- Hypothesis --------------------------------------------------------------------------------------------------------------------------------
Trying example: test_should_be_always_true(val=-inf)
Traceback (most recent call last):
File "/home/alexv/Projects/tmp/float_inf_strat.py", line 8, in test_should_be_always_true
assert val != float('-inf')
AssertionError: assert -inf != -inf
+  where -inf = float('-inf')

Trying example: test_should_be_always_true(val=-inf)
Traceback (most recent call last):
File "/home/alexv/Projects/tmp/float_inf_strat.py", line 8, in test_should_be_always_true
assert val != float('-inf')
AssertionError: assert -inf != -inf
+  where -inf = float('-inf')

Falsifying example: test_should_be_always_true(val=-inf)
____________________________________________________________________________________________________________________ test_should_be_always_true_aswell _____________________________________________________________________________________________________________________

@given(val=floats(min_value=float('inf'), allow_nan=False, exclude_min=True))
@settings(verbosity=Verbosity.verbose)
def test_should_be_always_true_aswell(val):

float_inf_strat.py:11:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

val = inf

@given(val=floats(min_value=float('inf'), allow_nan=False, exclude_min=True))
@settings(verbosity=Verbosity.verbose)
def test_should_be_always_true_aswell(val):
assert val != float('inf')
E       AssertionError: assert inf != inf
E        +  where inf = float('inf')

float_inf_strat.py:13: AssertionError
-------------------------------------------------------------------------------------------------------------------------------- Hypothesis --------------------------------------------------------------------------------------------------------------------------------
Trying example: test_should_be_always_true_aswell(val=inf)
Traceback (most recent call last):
File "/home/alexv/Projects/tmp/float_inf_strat.py", line 13, in test_should_be_always_true_aswell
assert val != float('inf')
AssertionError: assert inf != inf
+  where inf = float('inf')

Trying example: test_should_be_always_true_aswell(val=inf)
Traceback (most recent call last):
File "/home/alexv/Projects/tmp/float_inf_strat.py", line 13, in test_should_be_always_true_aswell
assert val != float('inf')
AssertionError: assert inf != inf
+  where inf = float('inf')

Falsifying example: test_should_be_always_true_aswell(val=inf)
============================================================================================================================= warnings summary =============================================================================================================================
/home/alexv/.virtualenvs/tmptesthyp/lib/python3.6/site-packages/_pytest/config/__init__.py:752
/home/alexv/.virtualenvs/tmptesthyp/lib/python3.6/site-packages/_pytest/config/__init__.py:752: PytestWarning: Module already imported so cannot be rewritten: hypothesis
self._mark_plugins_for_rewrite(hook)

-- Docs: https://docs.pytest.org/en/latest/warnings.html
=================================================================================================================== 2 failed, 1 warnings in 0.08 seconds ===================================================================================================================

# Fixed code
def floats(
    min_value=None,  # type: Real
    max_value=None,  # type: Real
    allow_nan=None,  # type: bool
    allow_infinity=None,  # type: bool
    width=64,  # type: int
    exclude_min=False,  # type: bool
    exclude_max=False,  # type: bool
):
    # type: (...) -> SearchStrategy[float]
    """Returns a strategy which generates floats.

    - If min_value is not None, all values will be >= min_value.
    - If max_value is not None, all values will be <= max_value.
    - If min_value or max_value is not None, it is an error to enable
      allow_nan.
    - If both min_value and max_value are not None, it is an error to enable
      allow_infinity.

    Where not explicitly ruled out by the bounds, all of infinity, -infinity
    and NaN are possible values generated by this strategy.

    The width argument specifies the maximum number of bits of precision
    required to represent the generated float. Valid values are 16, 32, or 64.
    Passing ``width=32`` will still use the builtin 64-bit ``float`` class,
    but always for values which can be exactly represented as a 32-bit float.
    Half-precision floats (``width=16``) are only supported on Python 3.6, or
    if :pypi:`Numpy` is installed.

    The exclude_min and exclude_max argument can be used to generate numbers
    from open or half-open intervals, by excluding the respective endpoints.
    Attempting to exclude an endpoint which is None will raise an error;
    use ``allow_infinity=False`` to generate finite floats.  You can however
    use e.g. ``min_value=float("-inf"), exclude_min=True`` to exclude only
    one infinite endpoint.

    Examples from this strategy have a complicated and hard to explain
    shrinking behaviour, but it tries to improve "human readability". Finite
    numbers will be preferred to infinity and infinity will be preferred to
    NaN.
    """
    check_type(bool, exclude_min, "exclude_min")
    check_type(bool, exclude_max, "exclude_max")

    if allow_nan is None:
        allow_nan = bool(min_value is None and max_value is None)
    elif allow_nan:
        if min_value is not None or max_value is not None:
            raise InvalidArgument(
                "Cannot have allow_nan=%r, with min_value or max_value" % (allow_nan)
            )

    if width not in (16, 32, 64):
        raise InvalidArgument(
            "Got width=%r, but the only valid values are the integers 16, "
            "32, and 64." % (width,)
        )
    if width == 16 and sys.version_info[:2] < (3, 6) and numpy is None:
        raise InvalidArgument(  # pragma: no cover
            "width=16 requires either Numpy, or Python >= 3.6"
        )

    check_valid_bound(min_value, "min_value")
    check_valid_bound(max_value, "max_value")

    min_arg, max_arg = min_value, max_value
    if min_value is not None:
        min_value = float_of(min_value, width)
        assert isinstance(min_value, float)
    if max_value is not None:
        max_value = float_of(max_value, width)
        assert isinstance(max_value, float)

    if min_value != min_arg:
        note_deprecation(
            "min_value=%r cannot be exactly represented as a float of width "
            "%d, which will be an error in a future version. Use min_value=%r "
            "instead." % (min_arg, width, min_value),
            since="2018-10-10",
        )
    if max_value != max_arg:
        note_deprecation(
            "max_value=%r cannot be exactly represented as a float of width "
            "%d, which will be an error in a future version. Use max_value=%r "
            "instead" % (max_arg, width, max_value),
            since="2018-10-10",
        )

    if exclude_min and (min_value is None or min_value == float("inf")):
        raise InvalidArgument("Cannot exclude min_value=%r" % (min_value,))
    if exclude_max and (max_value is None or max_value == float("-inf")):
        raise InvalidArgument("Cannot exclude max_value=%r" % (max_value,))

    if min_value is not None and (
        exclude_min or (min_arg is not None and min_value < min_arg)
    ):
        min_value = next_up(min_value, width)
        assert min_value > min_arg or min_value == min_arg == 0  # type: ignore
    if max_value is not None and (
        exclude_max or (max_arg is not None and max_value > max_arg)
    ):
        max_value = next_down(max_value, width)
        assert max_value < max_arg or max_value == max_arg == 0  # type: ignore

    if min_value == float("-inf"):
        min_value = None
    if max_value == float("inf"):
        max_value = None

    bad_zero_bounds = (
        min_value == max_value == 0
        and is_negative(max_value)
        and not is_negative(min_value)
    )
    if (
        min_value is not None
        and max_value is not None
        and (min_value > max_value or bad_zero_bounds)
    ):
        # This is a custom alternative to check_valid_interval, because we want
        # to include the bit-width and exclusion information in the message.
        msg = (
            "There are no %s-bit floating-point values between min_value=%r "
            "and max_value=%r" % (width, min_arg, max_arg)
        )
        if exclude_min or exclude_max:
            msg += ", exclude_min=%r and exclude_max=%r" % (exclude_min, exclude_max)
        if bad_zero_bounds:
            note_deprecation(msg, since="RELEASEDAY")
        else:
            raise InvalidArgument(msg)

    if allow_infinity is None:
        allow_infinity = bool(min_value is None or max_value is None)
    elif allow_infinity:
        if min_value is not None and max_value is not None:
            raise InvalidArgument(
                "Cannot have allow_infinity=%r, with both min_value and "
                "max_value" % (allow_infinity)
            )
    elif min_value == float("inf"):
        raise InvalidArgument("allow_infinity=False excludes min_value=inf")
    elif max_value == float("-inf"):
        raise InvalidArgument("allow_infinity=False excludes max_value=-inf")

    if min_value is None and max_value is None:
        result = FloatStrategy(allow_infinity=allow_infinity, allow_nan=allow_nan)  # type: SearchStrategy[float]
    elif min_value is not None and max_value is not None:
        if min_value == max_value:
            assert isinstance(min_value, float)
            result = just(min_value)
        elif is_negative(min_value):
            if is_negative(max_value):
                result = floats(min_value=-max_value, max_value=-min_value).map(
                    operator.neg
                )
            else:
                result = floats(min_value=0.0, max_value=max_value) | floats(
                    min_value=0.0, max_value=-min_value
                ).map(operator.neg)
        elif count_between_floats(min_value, max_value) > 1000:
            result = FixedBoundedFloatStrategy(
                lower_bound=min_value, upper_bound=max_value
            )
        else:
            ub_int = float_to_int(max_value, width)
            lb_int = float_to_int(min_value, width)
            assert lb_int <= ub_int
            result = integers(min_value=lb_int, max_value=ub_int).map(
                lambda x: int_to_float(x, width)
            )
    elif min_value is not None:
        assert isinstance(min_value, float)
        if min_value < 0:
            result = floats(min_value=0.0, allow_infinity=allow_infinity) | floats(
                min_value=min_value, max_value=-0.0
            )
        else:
            result = floats(allow_infinity=allow_infinity, allow_nan=False).map(
                lambda x: min_value + abs(x)  # type: ignore
            )
            if not allow_infinity:
                result = result.filter(lambda x: not math.isinf(x))
        if min_value == 0 and not is_negative(min_value):
            result = result.filter(lambda x: math.copysign(1.0, x) == 1)
    else:
        assert isinstance(max_value, float)
        if max_value > 0:
            result = floats(min_value=0.0, max_value=max_value) | floats(
                max_value=-0.0, allow_infinity=allow_infinity
            )
        else:
            result = floats(allow_infinity=allow_infinity, allow_nan=False).map(
                lambda x: max_value - abs(x)  # type: ignore
            )
            if not allow_infinity:
                result = result.filter(lambda x: not math.isinf(x))
        if max_value == 0 and is_negative(max_value):
            result = result.filter(is_negative)

    if width < 64:

        def downcast(x):
            try:
                return float_of(x, width)
            except OverflowError:
                reject()

        return result.map(downcast)
    return result