[pypy-commit] pypy hypothesis-apptest: support AppTest methods using hypothesis

cfbolz pypy.commits at gmail.com
Fri Jun 10 08:46:28 EDT 2016


Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: hypothesis-apptest
Changeset: r85076:1da0d5d67e2f
Date: 2016-06-10 14:41 +0200
http://bitbucket.org/pypy/pypy/changeset/1da0d5d67e2f/

Log:	support AppTest methods using hypothesis

	(a lot of hackery :-( )

diff --git a/pypy/tool/pytest/appsupport.py b/pypy/tool/pytest/appsupport.py
--- a/pypy/tool/pytest/appsupport.py
+++ b/pypy/tool/pytest/appsupport.py
@@ -15,7 +15,11 @@
     from hypothesis import given
     from hypothesis import strategies
     def decorator(func):
+        # this is a bit of a mess, because @given does not work on functions
+        # with *args
         tuple_stategy = strategies.tuples(*args)
+
+        # two versions of the function, one for applevel, one appdirect
         @given(tuple_stategy)
         def inner(space, original, arg_tuple):
             args_w = [space.wrap(arg) for arg in arg_tuple]
@@ -24,8 +28,20 @@
         @given(tuple_stategy)
         def appdirect(arg_tuple):
             return func(*arg_tuple)
+
+        # two versions that work on methods
+        @given(tuple_stategy)
+        def inner_method(space, w_instance, original, arg_tuple):
+            args_w = [space.wrap(arg) for arg in arg_tuple]
+            return original(space, w_instance, *args_w)
+
+        @given(tuple_stategy)
+        def appdirect_method(instance, arg_tuple):
+            return func(instance, *arg_tuple)
         appdirect.hypothesis_inner = inner
         appdirect.original_function = func
+        appdirect.hypothesis_method = inner_method
+        appdirect.appdirect_method = appdirect_method
         return appdirect
     return decorator
 
diff --git a/pypy/tool/pytest/apptest.py b/pypy/tool/pytest/apptest.py
--- a/pypy/tool/pytest/apptest.py
+++ b/pypy/tool/pytest/apptest.py
@@ -107,12 +107,22 @@
     def runtest(self):
         target = self.obj
         if self.config.option.runappdirect:
+            if hasattr(target.im_func, 'appdirect_method'):
+                return target.im_func.appdirect_method(target.im_self)
             return target()
         space = target.im_self.space
-        filename = self._getdynfilename(target)
-        func = app2interp_temp(target.im_func, filename=filename)
+        func = target.im_func
         w_instance = self.parent.w_instance
-        self.execute_appex(space, func, space, w_instance)
+        if hasattr(func, 'hypothesis_inner'):
+            filename = self._getdynfilename(func.original_function)
+            original = app2interp_temp(func.original_function, filename=filename)
+            func = func.hypothesis_method
+            args = (space, w_instance, original)
+        else:
+            filename = self._getdynfilename(target)
+            func = app2interp_temp(func, filename=filename)
+            args = (space, w_instance)
+        self.execute_appex(space, func, *args)
 
 
 class AppClassInstance(py.test.collect.Instance):
diff --git a/pypy/tool/pytest/test/test_hypothesis.py b/pypy/tool/pytest/test/test_hypothesis.py
--- a/pypy/tool/pytest/test/test_hypothesis.py
+++ b/pypy/tool/pytest/test/test_hypothesis.py
@@ -16,4 +16,8 @@
     assert f == f # not a NaN
     assert g == g # not a NaN
 
-
+class AppTest(object):
+    @app_hypothesis_given(strategies.floats(min_value=1.0, max_value=2.0))
+    def test_floats(self, f):
+        assert 1.0 <= f <= 2.0
+        assert f == f # not a NaN


More information about the pypy-commit mailing list