[Python-modules-commits] [python-hypothesis] 01/03: Import python-hypothesis_3.4.0.orig.tar.gz

Tristan Seligmann mithrandi at moszumanska.debian.org
Sat Jun 25 01:01:41 UTC 2016


This is an automated email from the git hooks/post-receive script.

mithrandi pushed a commit to branch master
in repository python-hypothesis.

commit 3f1e2cddf7ec412a29d70c93174f2dab92238f3e
Author: Tristan Seligmann <mithrandi at debian.org>
Date:   Sat Jun 25 02:00:35 2016 +0200

    Import python-hypothesis_3.4.0.orig.tar.gz
---
 .coveragerc                                        |  4 +-
 .gitattributes                                     |  1 +
 .gitignore                                         |  2 +
 CITATION                                           |  4 +-
 Makefile                                           |  7 +-
 Vagrantfile                                        | 33 ++++++++
 docs/changes.rst                                   | 37 ++++++++-
 docs/details.rst                                   |  2 +-
 docs/development.rst                               |  8 +-
 docs/endorsements.rst                              |  2 +-
 docs/extras.rst                                    | 14 ----
 docs/index.rst                                     |  2 +-
 docs/packaging.rst                                 |  2 +-
 docs/support.rst                                   |  2 +-
 hypothesislegacysupport/setup.py                   |  2 +-
 .../src/hypothesislegacysupport/version.py         |  2 +-
 scripts/install.sh                                 |  2 +-
 setup.py                                           |  2 +-
 src/hypothesis/core.py                             | 45 +++-------
 src/hypothesis/extra/django/models.py              | 74 ++++++++++++++---
 src/hypothesis/version.py                          |  2 +-
 tests/cover/test_health_checks.py                  | 96 ++++++++++------------
 tests/cover/test_random_module.py                  | 30 +++++++
 tests/cover/test_testdecorators.py                 |  3 +-
 tests/django/toystore/models.py                    | 29 ++++++-
 tests/django/toystore/test_given_models.py         | 21 ++++-
 tox.ini                                            |  2 +
 27 files changed, 291 insertions(+), 139 deletions(-)

diff --git a/.coveragerc b/.coveragerc
index 0c4a163..5e67a9f 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -1,8 +1,8 @@
 [run]
 branch = True
 include =
-    .tox/*/lib/*/site-packages/hypothesis/*.py
-    .tox/*/lib/*/site-packages/hypothesis/**/*.py
+    **/.tox/*/lib/*/site-packages/hypothesis/*.py
+    **/.tox/*/lib/*/site-packages/hypothesis/**/*.py
 omit =
     **/_settings.py
     **/pytestplugin.py
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..70a9d75
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+*    text eol=lf
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index cf521b1..b3fc281 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,5 @@ _build
 .tox
 .coverage
 .runtimes
+.idea
+.vagrant
diff --git a/CITATION b/CITATION
index 6ac50a5..6c0364b 100644
--- a/CITATION
+++ b/CITATION
@@ -4,7 +4,7 @@ x.y) from this installation
 Text:
 
 [Hypothesis]  Hypothesis x.y, 2016
-David R. MacIver, https://github.com/DRMacIver/hypothesis
+David R. MacIver, https://github.com/HypothesisWorks/hypothesis-python
 
 BibTeX:
 
@@ -12,7 +12,7 @@ BibTeX:
   title =            {{H}ypothesis x.y},
   author =     {David R. MacIver},
   year =             {2016},
-  howpublished = {\href{https://github.com/DRMacIver/hypothesis}{\texttt{https://github.com/DRMacIver/hypothesis}}},
+  howpublished = {\href{https://github.com/HypothesisWorks/hypothesis-python}{\texttt{https://github.com/HypothesisWorks/hypothesis-python}}},
 }
 
 If you are unsure about which version of hypothesis you are using run: `pip show
diff --git a/Makefile b/Makefile
index e3da186..ef1f921 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,9 @@ SPHINXBUILD   = $(DEV_PYTHON) -m sphinx
 SPHINX_BUILDDIR      = docs/_build
 ALLSPHINXOPTS   = -d $(SPHINX_BUILDDIR)/doctrees docs -W
 
-BUILD_RUNTIMES?=$(PWD)/.runtimes
+export BUILD_RUNTIMES?=$(HOME)/.cache/hypothesis-build-runtimes
+export TOX_WORK_DIR=$(BUILD_RUNTIMES)/.tox
+export COVERAGE_FILE=$(BUILD_RUNTIMES)/.coverage
 
 PY26=$(BUILD_RUNTIMES)/snakepit/python2.6
 PY27=$(BUILD_RUNTIMES)/snakepit/python2.7
@@ -62,6 +64,8 @@ $(TOOL_VIRTUALENV): $(PY34)
 
 $(TOOLS): $(TOOL_VIRTUALENV)
 
+install-tools: $(TOOLS)
+
 $(ISORT_VIRTUALENV): $(PY34)
 	$(PY34) -m virtualenv $(ISORT_VIRTUALENV)
 
@@ -160,7 +164,6 @@ check-fast: lint $(PY26) $(PY35) $(PYPY) $(TOX)
 $(TOX): $(PY35) tox.ini $(TOOLS)
 	rm -f $(TOX)
 	$(TOOL_INSTALL) tox
-	rm -rf .tox
 	ln -sf $(TOOL_VIRTUALENV)/bin/tox $(TOX)
 	touch $(TOOL_VIRTUALENV)/bin/tox $(TOX)
 
diff --git a/Vagrantfile b/Vagrantfile
new file mode 100644
index 0000000..99be1c6
--- /dev/null
+++ b/Vagrantfile
@@ -0,0 +1,33 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+# This is a trivial Vagrantfile designed to simplify development of Hypothesis on Windows,
+# where the normal make based build system doesn't work, or anywhere else where you would
+# prefer a clean environment for Hypothesis development. It doesn't do anything more than spin
+# up a suitable local VM for use with vagrant ssh. You should then use the Makefile from within
+# that VM.
+
+PROVISION = <<PROVISION
+
+sudo apt-get install -y git libreadline-dev libssl-dev zlib1g-dev build-essential libbz2-dev libsqlite3-dev
+
+if [ ! $(grep -q 'cd /vagrant' $HOME/.bashrc) ]; then
+    echo 'cd /vagrant' >> $HOME/.bashrc
+fi
+
+cd /vagrant/
+
+make install-tools
+
+PROVISION
+
+Vagrant.configure(2) do |config|
+
+  config.vm.provider "virtualbox" do |v|
+    v.memory = 1024
+  end
+
+  config.vm.box = "ubuntu/trusty64"
+
+  config.vm.provision "shell", inline: PROVISION, privileged: false
+end
diff --git a/docs/changes.rst b/docs/changes.rst
index 1e38e06..cb9adfd 100644
--- a/docs/changes.rst
+++ b/docs/changes.rst
@@ -22,6 +22,41 @@ You should generally assume that an API is internal unless you have specific
 information to the contrary.
 
 ------------------
+3.4.0 - 2016-05-27
+------------------
+
+This release is entirely provided by `Lucas Wiman <https://github.com/lucaswiman>`_:
+
+models() strategies from hypothesis.extra.django will now respect much more of
+Django's validations out of the box. Wherever possible full_clean() should
+succeed.
+
+In particular:
+
+* The max_length, blank and choices kwargs are now respected.
+* Add support for DecimalField.
+* If a field includes validators, the list of validators are used to filter the field strategy.
+
+------------------
+3.3.0 - 2016-05-27
+------------------
+
+This release went wrong and is functionally equivalent to 3.2.0. Ignore it.
+
+------------------
+3.2.0 - 2016-05-19
+------------------
+
+This is a small single-feature release:
+
+* All tests using @given now fix the global random seed. This removes the health
+  check for that. If a non-zero seed is required for the final falsifying
+  example, it will be reported. Otherwise Hypothesis will assume randomization
+  was not a significant factor for the test and be silent on the subject. If you
+  use the random_module() strategy this will continue to work and will always
+  display the seed.
+
+------------------
 3.1.3 - 2016-05-01
 ------------------
 
@@ -548,7 +583,7 @@ Bug fixes:
   instead of its contexts. This is obviously silly. It now works with any sequence
   of things convertible to unicode strings.
 * @given will now work on methods whose definitions contains no explicit positional
-  arguments, only varargs (`bug #118 <https://github.com/DRMacIver/hypothesis/issues/118>`_).
+  arguments, only varargs (`bug #118 <https://github.com/HypothesisWorks/hypothesis-python/issues/118>`_).
   This may have some knock on effects because it means that @given no longer changes the
   argspec of functions other than by adding defaults.
 * Introduction of new @composite feature for more natural definition of strategies you'd
diff --git a/docs/details.rst b/docs/details.rst
index a987497..c516d61 100644
--- a/docs/details.rst
+++ b/docs/details.rst
@@ -418,7 +418,7 @@ example to a condition that is always false it will raise an error:
   >>> find(booleans(), lambda x: False)
   Traceback (most recent call last):
   ...
-  hypothesis.errors.DefinitelyNoSuchExample: No examples of condition lambda x: <unknown> (all 2 considered)
+  hypothesis.errors.NoSuchExample: No examples of condition lambda x: <unknown>
 
 
 
diff --git a/docs/development.rst b/docs/development.rst
index 361ca81..387a2f9 100644
--- a/docs/development.rst
+++ b/docs/development.rst
@@ -16,13 +16,13 @@ I am the primary author of Hypothesis.
 
 So all new features must either be sponsored or implemented by someone else. That being said, I take a fairly active
 role in shepherding pull requests and helping people write a new feature (see `the
-contributing guidelines <https://github.com/DRMacIver/hypothesis/blob/master/CONTRIBUTING.rst>`_ for
+contributing guidelines <https://github.com/HypothesisWorks/hypothesis-python/blob/master/CONTRIBUTING.rst>`_ for
 details and `this pull request
-<https://github.com/DRMacIver/hypothesis/pull/154>`_ for an example of how the process goes). This isn't
+<https://github.com/HypothesisWorks/hypothesis-python/pull/154>`_ for an example of how the process goes). This isn't
 "patches welcome", it's "I will help you write a patch".
 
-All enhancement tickets on GitHub are tagged with either `help-wanted <https://github.com/DRMacIver/hypothesis/labels/help-wanted>`_
-if I think they're viable for someone else to pick up or `for-a-modest-fee <https://github.com/DRMacIver/hypothesis/labels/for-a-modest-fee>`_ if
+All enhancement tickets on GitHub are tagged with either `help-wanted <https://github.com/HypothesisWorks/hypothesis-python/labels/help-wanted>`_
+if I think they're viable for someone else to pick up or `for-a-modest-fee <https://github.com/HypothesisWorks/hypothesis-python/labels/for-a-modest-fee>`_ if
 I think they are not and that if you want them you should probably talk to me about paid development.
 
 You are of course entirely welcome to ask for paid development on something that is marked help-wanted,
diff --git a/docs/endorsements.rst b/docs/endorsements.rst
index 91b3895..0989d94 100644
--- a/docs/endorsements.rst
+++ b/docs/endorsements.rst
@@ -4,7 +4,7 @@ Who is using Hypothesis?
 
 This is a page for listing people who are using Hypothesis and how excited they
 are about that. If that's you and your name is not on the list, `this file is in
-Git <https://github.com/DRMacIver/hypothesis/blob/master/docs/endorsements.rst>`_
+Git <https://github.com/HypothesisWorks/hypothesis-python/blob/master/docs/endorsements.rst>`_
 and I'd love it if you sent me a pull request to fix that.
 
 
diff --git a/docs/extras.rst b/docs/extras.rst
index dcc0aa2..a58806a 100644
--- a/docs/extras.rst
+++ b/docs/extras.rst
@@ -184,20 +184,6 @@ against 1.8.
 
 It's large enough that it is :doc:`documented elsewhere <django>`.
 
------------------
-hypothesis-pytest
------------------
-
-hypothesis-pytest is actually available as a separate package that is installed as
-hypothesis-pytest rather than hypothesis[pytest]. This may change in future but the
-package will remain for compatibility reasons if it does.
-
-hypothesis-pytest is the world's most basic pytest plugin. Install it to get
-slightly better integrated example reporting when using @given and running
-under pytest.
-
-It can also load :ref:`settings Profiles <settings_profiles>`.
-
 ------------------
 hypothesis[numpy]
 ------------------
diff --git a/docs/index.rst b/docs/index.rst
index 1f0e3fd..7d08ab9 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -2,7 +2,7 @@
 Welcome to Hypothesis!
 ======================
 
-`Hypothesis <https://github.com/DRMacIver/hypothesis>`_ is a Python library for
+`Hypothesis <http://hypothesis.works>`_ is a Python library for
 creating unit tests which are simpler to write and more powerful when run,
 finding edge cases in your code you wouldn't have thought to look for. It is
 stable, powerful and easy to add to any existing test suite.
diff --git a/docs/packaging.rst b/docs/packaging.rst
index 6d7696a..39e6cdc 100644
--- a/docs/packaging.rst
+++ b/docs/packaging.rst
@@ -21,7 +21,7 @@ some information you might find useful.
 Release tarballs
 ----------------
 
-These are available from `the GitHub releases page <https://github.com/DRMacIver/hypothesis/releases>`_. The
+These are available from `the GitHub releases page <https://github.com/HypothesisWorks/hypothesis-python/releases>`_. The
 tarballs on pypi are intended for installation from a Python tool such as pip or easy_install and should not
 be considered complete releases. Requests to include additional files in them will not be granted. Their absence
 is not a bug.
diff --git a/docs/support.rst b/docs/support.rst
index e700508..9b579dc 100644
--- a/docs/support.rst
+++ b/docs/support.rst
@@ -7,7 +7,7 @@ friendly place where I or others will be more than happy to help you out. You're
 ask questions on Stack Overflow. If you do, please tag them with 'python-hypothesis' so someone
 sees them.
 
-For bugs and enhancements, please file an issue on the `GitHub issue tracker <https://github.com/DRMacIver/hypothesis/issues>`_.
+For bugs and enhancements, please file an issue on the `GitHub issue tracker <https://github.com/HypothesisWorks/hypothesis-python/issues>`_.
 Note that as per the :doc:`development policy <development>`, enhancements will probably not get
 implemented unless you're willing to pay for development or implement them yourself (with assistance from me). Bugs
 will tend to get fixed reasonably promptly, though it is of course on a best effort basis.
diff --git a/hypothesislegacysupport/setup.py b/hypothesislegacysupport/setup.py
index 607dd7b..bbbfa26 100644
--- a/hypothesislegacysupport/setup.py
+++ b/hypothesislegacysupport/setup.py
@@ -37,7 +37,7 @@ setup(
     author_email='david at drmaciver.com',
     packages=find_packages(SOURCE),
     package_dir={'': SOURCE},
-    url='https://github.com/DRMacIver/hypothesis',
+    url='https://github.com/HypothesisWorks/hypothesis-python',
     license='AGPL',
     install_requires=install_requires,
     extras_require={
diff --git a/hypothesislegacysupport/src/hypothesislegacysupport/version.py b/hypothesislegacysupport/src/hypothesislegacysupport/version.py
index d3ede55..9a5c67e 100644
--- a/hypothesislegacysupport/src/hypothesislegacysupport/version.py
+++ b/hypothesislegacysupport/src/hypothesislegacysupport/version.py
@@ -20,5 +20,5 @@
 
 from __future__ import division, print_function, absolute_import
 
-__version_info__ = (3, 1, 3)
+__version_info__ = (3, 4, 0)
 __version__ = '.'.join(map(str, __version_info__))
diff --git a/scripts/install.sh b/scripts/install.sh
index 95c0d04..f29fdf4 100755
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -26,7 +26,7 @@ env | grep UTF
 # ever not being acquired. 
 
 BASE=${BUILD_RUNTIMES-$PWD/.runtimes}
-echo $BASE
+
 mkdir -p $BASE
 
 LOCKFILE="$BASE/.install-lockfile"
diff --git a/setup.py b/setup.py
index c35a1ad..26cc83c 100644
--- a/setup.py
+++ b/setup.py
@@ -63,7 +63,7 @@ setup(
     author_email='david at drmaciver.com',
     packages=find_packages(SOURCE),
     package_dir={"": SOURCE},
-    url='https://github.com/DRMacIver/hypothesis',
+    url='https://github.com/HypothesisWorks/hypothesis-python',
     license='MPL v2',
     description='A library for property based testing',
     zip_safe=False,
diff --git a/src/hypothesis/core.py b/src/hypothesis/core.py
index 821ccd1..1f889d8 100644
--- a/src/hypothesis/core.py
+++ b/src/hypothesis/core.py
@@ -24,7 +24,6 @@ import time
 import inspect
 import functools
 import traceback
-from random import getstate as getglobalrandomstate
 from random import Random
 from collections import namedtuple
 
@@ -89,8 +88,15 @@ def reify_and_execute(
     print_example=False,
     is_final=False,
 ):
+    from hypothesis.strategies import random_module
+
     def run(data):
+        from hypothesis.control import note
+
         with BuildContext(is_final=is_final):
+            seed = data.draw(random_module()).seed
+            if seed != 0:
+                note('random.seed(%d)' % (seed,))
             args, kwargs = data.draw(search_strategy)
 
             if print_example:
@@ -314,7 +320,6 @@ def given(*generator_arguments, **generator_kwargs):
                 return
 
             if perform_health_check:
-                initial_state = getglobalrandomstate()
                 health_check_random = Random(random.getrandbits(128))
                 # We "pre warm" the health check with one draw to give it some
                 # time to calculate any cached data. This prevents the case
@@ -364,6 +369,11 @@ def given(*generator_arguments, **generator_kwargs):
                     except InvalidArgument:
                         raise
                     except Exception:
+                        if (
+                            HealthCheck.exception_in_generation in
+                            settings.suppress_health_check
+                        ):
+                            raise
                         report(traceback.format_exc())
                         if test_runner is default_new_style_executor:
                             fail_health_check(
@@ -424,27 +434,10 @@ def given(*generator_arguments, **generator_kwargs):
                     ) % (count, runtime, filtered_draws, overruns),
                         HealthCheck.too_slow,
                     )
-                if getglobalrandomstate() != initial_state:
-                    fail_health_check(
-                        'Data generation depends on global random module. '
-                        'This makes results impossible to replay, which '
-                        'prevents Hypothesis from working correctly. '
-                        'If you want to use methods from random, use '
-                        'randoms() from hypothesis.strategies to get an '
-                        'instance of Random you can use. Alternatively, you '
-                        'can use the random_module() strategy to explicitly '
-                        'seed the random module.', HealthCheck.random_module,
-                    )
             last_exception = [None]
             repr_for_last_exception = [None]
-            performed_random_check = [False]
 
             def evaluate_test_data(data):
-                if perform_health_check and not performed_random_check[0]:
-                    initial_state = getglobalrandomstate()
-                    performed_random_check[0] = True
-                else:
-                    initial_state = None
                 try:
                     result = test_runner(data, reify_and_execute(
                         search_strategy, test,
@@ -466,20 +459,6 @@ def given(*generator_arguments, **generator_kwargs):
                     last_exception[0] = traceback.format_exc()
                     verbose_report(last_exception[0])
                     data.mark_interesting()
-                finally:
-                    if (
-                        initial_state is not None and
-                        getglobalrandomstate() != initial_state
-                    ):
-                        fail_health_check(
-                            'Your test used the global random module. '
-                            'This is unlikely to work correctly. You should '
-                            'consider using the randoms() strategy from '
-                            'hypothesis.strategies instead. Alternatively, '
-                            'you can use the random_module() strategy to '
-                            'explicitly seed the random module.',
-                            HealthCheck.random_module,
-                        )
 
             from hypothesis.internal.conjecture.engine import TestRunner
 
diff --git a/src/hypothesis/extra/django/models.py b/src/hypothesis/extra/django/models.py
index ad3d68b..b8267e4 100644
--- a/src/hypothesis/extra/django/models.py
+++ b/src/hypothesis/extra/django/models.py
@@ -17,8 +17,11 @@
 
 from __future__ import division, print_function, absolute_import
 
+from decimal import Decimal
+
 import django.db.models as dm
 from django.db import IntegrityError
+from django.core.exceptions import ValidationError
 
 import hypothesis.strategies as st
 import hypothesis.extra.fakefactory as ff
@@ -60,10 +63,7 @@ def field_mappings():
             dm.PositiveSmallIntegerField: st.integers(0, 32767),
             dm.BinaryField: st.binary(),
             dm.BooleanField: st.booleans(),
-            dm.CharField: st.text(),
-            dm.TextField: st.text(),
             dm.DateTimeField: datetimes(allow_naive=False),
-            dm.EmailField: ff.fake_factory(u'email'),
             dm.FloatField: st.floats(),
             dm.NullBooleanField: st.one_of(st.none(), st.booleans()),
         }
@@ -77,22 +77,70 @@ def add_default_field_mapping(field_type, strategy):
 default_value = UniqueIdentifier(u'default_value')
 
 
+class UnmappedFieldError(Exception):
+    pass
+
+
+def validator_to_filter(f):
+    """Converts the field run_validators method to something suitable for use
+    in filter."""
+
+    def validate(value):
+        try:
+            f.run_validators(value)
+            return True
+        except ValidationError:
+            return False
+
+    return validate
+
+
+def _get_strategy_for_field(f):
+    if isinstance(f, dm.AutoField):
+        return default_value
+    elif f.choices:
+        choices = [value for (value, name) in f.choices]
+        if isinstance(f, (dm.CharField, dm.TextField)) and f.blank:
+            choices.append(u'')
+        strategy = st.sampled_from(choices)
+    elif isinstance(f, dm.EmailField):
+        return ff.fake_factory(u'email')
+    elif type(f) in (dm.TextField, dm.CharField):
+        strategy = st.text(min_size=(None if f.blank else 1),
+                           max_size=f.max_length)
+    elif type(f) == dm.DecimalField:
+        m = 10 ** f.max_digits - 1
+        div = 10 ** f.decimal_places
+        q = Decimal('1.' + ('0' * f.decimal_places))
+        strategy = (
+            st.integers(min_value=-m, max_value=m)
+            .map(lambda n: (Decimal(n) / div).quantize(q)))
+    else:
+        try:
+            strategy = field_mappings()[type(f)]
+        except KeyError:
+            if f.null:
+                return None
+            else:
+                raise UnmappedFieldError(f)
+    if f.validators:
+        strategy = strategy.filter(validator_to_filter(f))
+    if f.null:
+        strategy = st.one_of(st.none(), strategy)
+    return strategy
+
+
 def models(model, **extra):
     result = {}
-    mappings = field_mappings()
     mandatory = set()
     for f in model._meta.concrete_fields:
-        if isinstance(f, dm.AutoField):
-            continue
         try:
-            mapped = mappings[type(f)]
-        except KeyError:
-            if not f.null:
-                mandatory.add(f.name)
+            strategy = _get_strategy_for_field(f)
+        except UnmappedFieldError:
+            mandatory.add(f.name)
             continue
-        if f.null:
-            mapped = st.one_of(st.none(), mapped)
-        result[f.name] = mapped
+        if strategy is not None:
+            result[f.name] = strategy
     missed = {x for x in mandatory if x not in extra}
     if missed:
         raise InvalidArgument((
diff --git a/src/hypothesis/version.py b/src/hypothesis/version.py
index 41be08a..1b68ae6 100644
--- a/src/hypothesis/version.py
+++ b/src/hypothesis/version.py
@@ -17,5 +17,5 @@
 
 from __future__ import division, print_function, absolute_import
 
-__version_info__ = (3, 1, 3)
+__version_info__ = (3, 4, 0)
 __version__ = '.'.join(map(str, __version_info__))
diff --git a/tests/cover/test_health_checks.py b/tests/cover/test_health_checks.py
index e74f67c..dce5a06 100644
--- a/tests/cover/test_health_checks.py
+++ b/tests/cover/test_health_checks.py
@@ -26,6 +26,7 @@ import hypothesis.strategies as st
 from hypothesis import given, settings, HealthCheck
 from hypothesis.errors import FailedHealthCheck
 from hypothesis.control import assume
+from tests.common.utils import capture_out
 from hypothesis.internal.compat import int_from_bytes
 from hypothesis.searchstrategy.strategies import SearchStrategy
 
@@ -39,28 +40,6 @@ def test_slow_generation_fails_a_health_check():
         test()
 
 
-def test_global_random_in_strategy_fails_a_health_check():
-    import random
-
-    @given(st.lists(st.integers(), min_size=1).map(random.choice))
-    def test(x):
-        pass
-
-    with raises(FailedHealthCheck):
-        test()
-
-
-def test_global_random_in_test_fails_a_health_check():
-    import random
-
-    @given(st.lists(st.integers(), min_size=1))
-    def test(x):
-        random.choice(x)
-
-    with raises(FailedHealthCheck):
-        test()
-
-
 def test_default_health_check_can_weaken_specific():
     import random
 
@@ -86,6 +65,48 @@ def test_error_in_strategy_produces_health_check_error():
     assert 'executor' not in e.value.args[0]
 
 
+def test_suppressing_error_in_value_generation():
+    def boom(x):
+        raise ValueError()
+
+    @settings(suppress_health_check=[HealthCheck.exception_in_generation])
+    @given(st.integers().map(boom))
+    def test(x):
+        pass
+
+    with capture_out() as out:
+        with reporting.with_reporter(reporting.default):
+            with raises(ValueError):
+                test()
+    assert 'ValueError' not in out.getvalue()
+
+
+def test_suppressing_filtering_health_check():
+    count = [0]
+
+    def too_soon(x):
+        count[0] += 1
+        return count[0] >= 200
+
+    @given(st.integers().filter(too_soon))
+    def test1(x):
+        raise ValueError()
+
+    with raises(FailedHealthCheck):
+        test1()
+
+    count[0] = 0
+
+    @settings(suppress_health_check=[
+        HealthCheck.filter_too_much, HealthCheck.too_slow])
+    @given(st.integers().filter(too_soon))
+    def test2(x):
+        raise ValueError()
+
+    with raises(ValueError):
+        test2()
+
+
 def test_error_in_strategy_with_custom_executor():
     def boom(x):
         raise ValueError()
@@ -147,18 +168,6 @@ def test_large_data_will_fail_a_health_check():
     assert 'allowable size' in e.value.args[0]
 
 
-def test_nesting_without_control_fails_health_check():
-    @given(st.integers())
-    def test_blah(x):
-        @given(st.integers())
-        def test_nest(y):
-            assert y < x
-        with raises(AssertionError):
-            test_nest()
-    with raises(FailedHealthCheck):
-        test_blah()
-
-
 def test_returning_non_none_is_forbidden():
     @given(st.integers())
     def a(x):
@@ -175,22 +184,3 @@ def test_returning_non_none_does_not_fail_if_health_check_disabled():
         return 1
 
     a()
-
-
- at given(st.integers())
- at settings(suppress_health_check=[HealthCheck.random_module])
-def test_can_suppress_a_single_health_check(i):
-    import random
-    random.seed(i)
-
-
-def test_suppressing_health_check_does_not_suppress_others():
-    import random
-
-    @given(st.integers().filter(lambda x: random.randint(0, 1) and False))
-    @settings(suppress_health_check=[HealthCheck.random_module])
-    def test(i):
-        pass
-
-    with raises(FailedHealthCheck):
-        test()
diff --git a/tests/cover/test_random_module.py b/tests/cover/test_random_module.py
index 6a95a96..7da8098 100644
--- a/tests/cover/test_random_module.py
+++ b/tests/cover/test_random_module.py
@@ -17,6 +17,8 @@
 
 from __future__ import division, print_function, absolute_import
 
+import random
+
 import pytest
 
 import hypothesis.strategies as st
@@ -44,3 +46,31 @@ def test_seed_random_twice(r, r2):
 def test_does_not_fail_health_check_if_randomness_is_used(r):
     import random
     random.getrandbits(128)
+
+
+def test_reports_non_zero_seed():
+    random.seed(0)
+    zero_value = random.randint(0, 10)
+
+    with capture_out() as out:
+        with reporting.with_reporter(reporting.default):
+            with pytest.raises(AssertionError):
+                @given(st.integers())
+                def test(r):
+                    assert random.randint(0, 10) == zero_value
+                test()
+    assert 'random.seed' in out.getvalue()
+
+
+def test_does_not_report_zero_seed():
+    random.seed(0)
+    zero_value = random.randint(0, 3)
+
+    with capture_out() as out:
+        with reporting.with_reporter(reporting.default):
+            with pytest.raises(AssertionError):
+                @given(st.integers())
+                def test(r):
+                    assert random.randint(0, 3) != zero_value
+                test()
+    assert 'random.seed' not in out.getvalue()
diff --git a/tests/cover/test_testdecorators.py b/tests/cover/test_testdecorators.py
index b2519f1..41bbd25 100644
--- a/tests/cover/test_testdecorators.py
+++ b/tests/cover/test_testdecorators.py
@@ -454,7 +454,8 @@ def test_can_run_with_database_in_thread():
 
 @given(integers())
 def test_can_call_an_argument_f(f):
-    # See issue https://github.com/DRMacIver/hypothesis/issues/38 for details
+    # See issue https://github.com/HypothesisWorks/hypothesis-python/issues/38
+    # for details
     pass
 
 
diff --git a/tests/django/toystore/models.py b/tests/django/toystore/models.py
index 2b70347..050e76f 100644
--- a/tests/django/toystore/models.py
+++ b/tests/django/toystore/models.py
@@ -18,6 +18,7 @@
 from __future__ import division, print_function, absolute_import
 
 from django.db import models
+from django.core.exceptions import ValidationError
 
 
 class Company(models.Model):
@@ -73,7 +74,7 @@ class LoopB(models.Model):
     a = models.ForeignKey(u'LoopA', null=True)
 
 
-class ManyInts(models.Model):
+class ManyNumerics(models.Model):
     i1 = models.IntegerField()
     i2 = models.SmallIntegerField()
     i3 = models.BigIntegerField()
@@ -81,6 +82,8 @@ class ManyInts(models.Model):
     p1 = models.PositiveIntegerField()
     p2 = models.PositiveSmallIntegerField()
 
+    d = models.DecimalField(decimal_places=2, max_digits=5)
+
 
 class CustomishDefault(models.Model):
     customish = CustomishField(default=u'b')
@@ -96,3 +99,27 @@ class MandatoryComputed(models.Model):
         cname = kw[u'name'] + u'_company'
         kw[u'company'] = Company.objects.create(name=cname)
         super(MandatoryComputed, self).__init__(**kw)
+
+
+def validate_even(value):
+    if value % 2 != 0:
+        raise ValidationError('')
+
+
+class RestrictedFields(models.Model):
+    text_field_4 = models.TextField(max_length=4, blank=True)
+    char_field_4 = models.CharField(max_length=4, blank=True)
+    choice_field_text = models.TextField(
+        choices=(('foo', 'Foo'), ('bar', 'Bar'))
+    )
+    choice_field_int = models.IntegerField(
+        choices=((1, 'First'), (2, 'Second'))
+    )
+    null_choice_field_int = models.IntegerField(
+        choices=((1, 'First'), (2, 'Second')),
+        null=True, blank=True
+    )
+    even_number_field = models.IntegerField(
+        validators=[validate_even]
+    )
+    non_blank_text_field = models.TextField(blank=False)
diff --git a/tests/django/toystore/test_given_models.py b/tests/django/toystore/test_given_models.py
index 6dd0f0a..2273550 100644
--- a/tests/django/toystore/test_given_models.py
+++ b/tests/django/toystore/test_given_models.py
@@ -22,8 +22,8 @@ from hypothesis.errors import InvalidArgument
 from hypothesis.strategies import just, lists
 from hypothesis.extra.django import TestCase, TransactionTestCase
 from tests.django.toystore.models import Store, Company, Customer, \
-    ManyInts, SelfLoop, Customish, CustomishField, CouldBeCharming, \
-    CustomishDefault, MandatoryComputed
+    SelfLoop, Customish, ManyNumerics, CustomishField, CouldBeCharming, \
+    CustomishDefault, RestrictedFields, MandatoryComputed
 from hypothesis.extra.django.models import models, default_value, \
     add_default_field_mapping
 
@@ -66,7 +66,7 @@ class TestGetsBasicModels(TestCase):
     def test_sl(self, sl):
         self.assertIsNone(sl.me)
 
-    @given(lists(models(ManyInts)))
+    @given(lists(models(ManyNumerics)))
     def test_no_overflow_in_integer(self, manyints):
         pass
 
@@ -102,3 +102,18 @@ class TestsNeedingRollback(TransactionTestCase):
     def test_can_get_examples(self):
         for _ in range(200):
             models(Company).example()
+
+
+class TestRestrictedFields(TestCase):
+
+    @given(models(RestrictedFields))
+    def test_constructs_valid_instance(self, instance):
+        self.assertTrue(isinstance(instance, RestrictedFields))
+        instance.full_clean()
+        self.assertLessEqual(len(instance.text_field_4), 4)
+        self.assertLessEqual(len(instance.char_field_4), 4)
+        self.assertIn(instance.choice_field_text, ('foo', 'bar'))
+        self.assertIn(instance.choice_field_int, (1, 2))
+        self.assertIn(instance.null_choice_field_int, (1, 2, None))
+        self.assertEqual(instance.even_number_field % 2, 0)
+        self.assertTrue(instance.non_blank_text_field)
diff --git a/tox.ini b/tox.ini
index 1452d2d..9810c17 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,9 +1,11 @@
 [tox]
 envlist = py{26,27,33,34,35,py}-{brief,prettyquick,full,custom,benchmark}
+toxworkdir={env:TOX_WORK_DIR:.tox}
 
 passenv=
   HOME
   LC_ALL
+  COVERAGE_FILE
 
 [testenv]
 deps =

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-hypothesis.git



More information about the Python-modules-commits mailing list