HypothesisWorks / hypothesis

Hypothesis is a powerful, flexible, and easy to use library for property-based testing.
https://hypothesis.works
Other
7.39k stars 578 forks source link

`floats()` not returns floats! #106

Closed ckaran closed 8 years ago

ckaran commented 8 years ago

I just discovered that under some cases floats() don't actually return floats. My test case is below, and the output is at the bottom.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import pytest
from hypothesis import assume
from hypothesis import example
from hypothesis import given
from hypothesis import Settings
from hypothesis import Verbosity
from hypothesis.strategies import basic
from hypothesis.strategies import binary
from hypothesis.strategies import booleans
from hypothesis.strategies import builds
from hypothesis.strategies import complex_numbers
from hypothesis.strategies import decimals
from hypothesis.strategies import dictionaries
from hypothesis.strategies import fixed_dictionaries
from hypothesis.strategies import floats
from hypothesis.strategies import fractions
from hypothesis.strategies import frozensets
from hypothesis.strategies import integers
from hypothesis.strategies import just
from hypothesis.strategies import lists
from hypothesis.strategies import one_of
from hypothesis.strategies import sampled_from
from hypothesis.strategies import sets
from hypothesis.strategies import streaming
from hypothesis.strategies import text
from hypothesis.strategies import tuples

__docformat__ = "restructuredtext en"

##############################################################################
##############################################################################
# Minimal test that fails
##############################################################################
##############################################################################

class Test_Hypothesis(object):
    @given(floats())
    def test_one(self, arg):
        assert isinstance(arg, float)
    # End of test_one

    @given(floats(min_value=0, max_value=2**64-1))
    def test_two(self, arg):
        assert isinstance(arg, float)
    # End of test_two

    @given(floats(min_value=0, max_value=float(2**64-1)))
    def test_three(self, arg):
        assert isinstance(arg, float)
    # End of test_three

    @given(floats(min_value=float(0), max_value=2**64-1))
    def test_four(self, arg):
        assert isinstance(arg, float)
    # End of test_four

    @given(floats(min_value=float(0), max_value=float(2**64-1)))
    def test_five(self, arg):
        assert isinstance(arg, float)
    # End of test_five
# End of class Test_Hypothesis

##############################################################################
##############################################################################
# Main
##############################################################################
##############################################################################

if __name__ == "__main__":
    pass

Output

Cems-Mac-Pro:Desktop crushed$ py.test -vvvvvvv -s test_Hypothesis.py 
=========================================================================== test session starts ============================================================================
platform darwin -- Python 3.4.3 -- py-1.4.30 -- pytest-2.7.2 -- /opt/local/Library/Frameworks/Python.framework/Versions/3.4/bin/python3.4
rootdir: /Users/crushed/Desktop, inifile: 
plugins: xdist
collected 5 items 

test_Hypothesis.py::Test_Hypothesis::test_two <- .hypothesis/eval_source/hypothesis_temporary_module_636374a0a05d74fa9f54384c57b113af0f8243ee.py Falsifying example: test_two(self=<test_Hypothesis.Test_Hypothesis object at 0x10c07bcf8>, arg=0)
FAILED
test_Hypothesis.py::Test_Hypothesis::test_five <- .hypothesis/eval_source/hypothesis_temporary_module_98cd879b6ade60301b64f1fe33a6adace0ab525b.py PASSED
test_Hypothesis.py::Test_Hypothesis::test_four <- .hypothesis/eval_source/hypothesis_temporary_module_bd6b31e7bac6b3633e447132d6743fe98fe78c99.py Falsifying example: test_four(self=<test_Hypothesis.Test_Hypothesis object at 0x10c06e208>, arg=18446744073709551615)
FAILED
test_Hypothesis.py::Test_Hypothesis::test_three <- .hypothesis/eval_source/hypothesis_temporary_module_ca4da0a6d9c8044801a9b2299fe52e09c597c314.py Falsifying example: test_three(self=<test_Hypothesis.Test_Hypothesis object at 0x10cfa0550>, arg=0)
FAILED
test_Hypothesis.py::Test_Hypothesis::test_one <- .hypothesis/eval_source/hypothesis_temporary_module_e9b843d7b502b3042ac36151f9eb8ac839be6893.py PASSED

================================================================================= FAILURES =================================================================================
_________________________________________________________________________ Test_Hypothesis.test_two _________________________________________________________________________

self = <test_Hypothesis.Test_Hypothesis object at 0x10c07bcf8>, arg = HypothesisProvided(value=floats(min_value=0, max_value=18446744073709551615))

    def test_two(self, arg=not_set):
>       return f(self, arg)

.hypothesis/eval_source/hypothesis_temporary_module_636374a0a05d74fa9f54384c57b113af0f8243ee.py:5: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/hypothesis/core.py:532: in wrapped_test
    print_example=True
/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/hypothesis/executors/executors.py:26: in default_executor
    return function()
/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/hypothesis/core.py:343: in run
    return test(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <test_Hypothesis.Test_Hypothesis object at 0x10c07bcf8>, arg = 0

    @given(floats(min_value=0, max_value=2**64-1))
    def test_two(self, arg):
>       assert isinstance(arg, float)
E       assert isinstance(0, float)

test_Hypothesis.py:47: AssertionError
________________________________________________________________________ Test_Hypothesis.test_four _________________________________________________________________________

self = <test_Hypothesis.Test_Hypothesis object at 0x10c06e208>, arg = HypothesisProvided(value=floats(min_value=0.0, max_value=18446744073709551615))

    def test_four(self, arg=not_set):
>       return f(self, arg)

.hypothesis/eval_source/hypothesis_temporary_module_bd6b31e7bac6b3633e447132d6743fe98fe78c99.py:5: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/hypothesis/core.py:532: in wrapped_test
    print_example=True
/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/hypothesis/executors/executors.py:26: in default_executor
    return function()
/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/hypothesis/core.py:343: in run
    return test(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <test_Hypothesis.Test_Hypothesis object at 0x10c06e208>, arg = 18446744073709551615

    @given(floats(min_value=float(0), max_value=2**64-1))
    def test_four(self, arg):
>       assert isinstance(arg, float)
E       assert isinstance(18446744073709551615, float)

test_Hypothesis.py:57: AssertionError
________________________________________________________________________ Test_Hypothesis.test_three ________________________________________________________________________

self = <test_Hypothesis.Test_Hypothesis object at 0x10cfa0550>, arg = HypothesisProvided(value=floats(min_value=0, max_value=1.8446744073709552e+19))

    def test_three(self, arg=not_set):
>       return f(self, arg)

.hypothesis/eval_source/hypothesis_temporary_module_ca4da0a6d9c8044801a9b2299fe52e09c597c314.py:5: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/hypothesis/core.py:532: in wrapped_test
    print_example=True
/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/hypothesis/executors/executors.py:26: in default_executor
    return function()
/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/hypothesis/core.py:343: in run
    return test(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <test_Hypothesis.Test_Hypothesis object at 0x10cfa0550>, arg = 0

    @given(floats(min_value=0, max_value=float(2**64-1)))
    def test_three(self, arg):
>       assert isinstance(arg, float)
E       assert isinstance(0, float)

test_Hypothesis.py:52: AssertionError
==================================================================== 3 failed, 2 passed in 2.76 seconds ====================================================================
Cems-Mac-Pro:Desktop crushed$ 
DRMacIver commented 8 years ago

Oops. That's embarrassing.

What's going on is that as of 1.8 the bounded float strategies try to produce the endpoints, but I forgot that the end points might be non-floats.

As you've already spotted, yo can work around this for now by passing the endpoints as floats. I'll have a proper fix out soon.

ckaran commented 8 years ago

Sounds good. Thanks!

DRMacIver commented 8 years ago

This should be fixed in 1.8.4 (just released).