[Python-modules-commits] [python-hypothesis] 01/05: Import python-hypothesis_1.17.0.orig.tar.gz
Tristan Seligmann
mithrandi at moszumanska.debian.org
Wed Dec 16 15:18:23 UTC 2015
This is an automated email from the git hooks/post-receive script.
mithrandi pushed a commit to branch master
in repository python-hypothesis.
commit 917e33d40e98591ff160f4a41b17239b513c1f61
Author: Tristan Seligmann <mithrandi at debian.org>
Date: Wed Dec 16 17:11:07 2015 +0200
Import python-hypothesis_1.17.0.orig.tar.gz
---
PKG-INFO | 3 +-
README.rst | 1 +
setup.cfg | 2 +-
src/hypothesis.egg-info/PKG-INFO | 3 +-
src/hypothesis.egg-info/SOURCES.txt | 1 -
src/hypothesis.egg-info/requires.txt | 6 +-
src/hypothesis/core.py | 166 ++++++++++++++++++++++++++++--
src/hypothesis/errors.py | 14 +++
src/hypothesis/extra/fakefactory.py | 10 +-
src/hypothesis/internal/compat.py | 20 ++--
src/hypothesis/internal/compat3.py | 23 -----
src/hypothesis/searchstrategy/deferred.py | 11 +-
src/hypothesis/settings.py | 27 +++--
src/hypothesis/version.py | 2 +-
14 files changed, 227 insertions(+), 62 deletions(-)
diff --git a/PKG-INFO b/PKG-INFO
index 1db1069..c89d9a7 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: hypothesis
-Version: 1.16.0
+Version: 1.17.0
Summary: A library for property based testing
Home-page: https://github.com/DRMacIver/hypothesis
Author: David R. MacIver
@@ -42,6 +42,7 @@ Description: ==========
If you want to hear from people who are already using Hypothesis, some of them `have written
about it <https://hypothesis.readthedocs.org/en/latest/endorsements.html>`_.
+ If you want to create a downstream package of Hypothesis, please read `these guidelines for packagers <http://hypothesis.readthedocs.org/en/latest/packaging.html>`_
-------------------
Ongoing Development
diff --git a/README.rst b/README.rst
index 7293f9c..ab6bb37 100644
--- a/README.rst
+++ b/README.rst
@@ -34,6 +34,7 @@ If you're looking for inspiration for writing your own QuickCheck clone,
If you want to hear from people who are already using Hypothesis, some of them `have written
about it <https://hypothesis.readthedocs.org/en/latest/endorsements.html>`_.
+If you want to create a downstream package of Hypothesis, please read `these guidelines for packagers <http://hypothesis.readthedocs.org/en/latest/packaging.html>`_
-------------------
Ongoing Development
diff --git a/setup.cfg b/setup.cfg
index a669c45..ebbec92 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,5 @@
[egg_info]
-tag_svn_revision = 0
tag_build =
+tag_svn_revision = 0
tag_date = 0
diff --git a/src/hypothesis.egg-info/PKG-INFO b/src/hypothesis.egg-info/PKG-INFO
index 1db1069..c89d9a7 100644
--- a/src/hypothesis.egg-info/PKG-INFO
+++ b/src/hypothesis.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: hypothesis
-Version: 1.16.0
+Version: 1.17.0
Summary: A library for property based testing
Home-page: https://github.com/DRMacIver/hypothesis
Author: David R. MacIver
@@ -42,6 +42,7 @@ Description: ==========
If you want to hear from people who are already using Hypothesis, some of them `have written
about it <https://hypothesis.readthedocs.org/en/latest/endorsements.html>`_.
+ If you want to create a downstream package of Hypothesis, please read `these guidelines for packagers <http://hypothesis.readthedocs.org/en/latest/packaging.html>`_
-------------------
Ongoing Development
diff --git a/src/hypothesis.egg-info/SOURCES.txt b/src/hypothesis.egg-info/SOURCES.txt
index 482bff0..bcbc5a5 100644
--- a/src/hypothesis.egg-info/SOURCES.txt
+++ b/src/hypothesis.egg-info/SOURCES.txt
@@ -38,7 +38,6 @@ src/hypothesis/internal/charstree.py
src/hypothesis/internal/chooser.py
src/hypothesis/internal/classmap.py
src/hypothesis/internal/compat.py
-src/hypothesis/internal/compat3.py
src/hypothesis/internal/debug.py
src/hypothesis/internal/distributions.py
src/hypothesis/internal/examplesource.py
diff --git a/src/hypothesis.egg-info/requires.txt b/src/hypothesis.egg-info/requires.txt
index f85733e..285a5dc 100644
--- a/src/hypothesis.egg-info/requires.txt
+++ b/src/hypothesis.egg-info/requires.txt
@@ -5,12 +5,12 @@ ordereddict
Counter
[all]
-pytz
-django>=1.7
+fake-factory>=0.5.2,<=0.5.3
pytest>=2.7.0
pytz
numpy>=1.9.0
-fake-factory>=0.5.2,<=0.5.3
+pytz
+django>=1.7
[datetime]
pytz
diff --git a/src/hypothesis/core.py b/src/hypothesis/core.py
index 2d6637f..09bd773 100644
--- a/src/hypothesis/core.py
+++ b/src/hypothesis/core.py
@@ -23,21 +23,24 @@ import math
import time
import inspect
import binascii
+import warnings
import functools
import traceback
+from random import getstate as getglobalrandomstate
from random import Random
from itertools import islice
from collections import namedtuple
from hypothesis.errors import Flaky, Timeout, NoSuchExample, \
- Unsatisfiable, BadTemplateDraw, InvalidArgument, \
- UnsatisfiedAssumption, DefinitelyNoSuchExample
+ Unsatisfiable, BadTemplateDraw, InvalidArgument, FailedHealthCheck, \
+ UnsatisfiedAssumption, DefinitelyNoSuchExample, \
+ HypothesisDeprecationWarning
from hypothesis.control import BuildContext
from hypothesis.settings import Settings, Verbosity, note_deprecation
-from hypothesis.executors import executor
+from hypothesis.executors import executor, default_executor
from hypothesis.reporting import report, debug_report, verbose_report, \
current_verbosity
-from hypothesis.internal.compat import qualname, getargspec, \
+from hypothesis.internal.compat import hrange, qualname, getargspec, \
unicode_safe_repr
from hypothesis.internal.tracker import Tracker
from hypothesis.internal.reflection import arg_string, impersonate, \
@@ -194,6 +197,10 @@ def simplify_template_such_that(
assert isinstance(random, Random)
yield t
+
+ if settings.max_shrinks <= 0 or not f(t):
+ return
+
successful_shrinks = 0
changed = True
@@ -259,7 +266,7 @@ def simplify_template_such_that(
def best_satisfying_template(
search_strategy, random, condition, settings, storage, tracker=None,
- max_parameter_tries=None,
+ max_parameter_tries=None, start_time=None,
):
"""Find and then minimize a satisfying template.
@@ -270,7 +277,8 @@ def best_satisfying_template(
"""
if tracker is None:
tracker = Tracker()
- start_time = time.time()
+ if start_time is None:
+ start_time = time.time()
successful_shrinks = -1
with settings:
@@ -461,6 +469,10 @@ def given(*generator_arguments, **generator_kwargs):
for k in extra_kwargs:
unused_kwargs[k] = HypothesisProvided(generator_kwargs[k])
+ hypothesis_owned_arguments = [
+ argspec.args[-1 - i] for i in hrange(len(argspec.defaults))
+ ] + list(unused_kwargs)
+
@impersonate(test)
@copy_argspec(
test.__name__, argspec
@@ -472,6 +484,21 @@ def given(*generator_arguments, **generator_kwargs):
selfy = None
arguments, kwargs = convert_positional_arguments(
wrapped_test, arguments, kwargs)
+
+ for arg in hypothesis_owned_arguments:
+ try:
+ value = kwargs[arg]
+ except KeyError:
+ continue
+ if not isinstance(value, HypothesisProvided):
+ note_deprecation(
+ 'Passing in explicit values to override Hypothesis '
+ 'provided values is deprecated and will no longer '
+ 'work in Hypothesis 2.0. If you need to do this, '
+ 'extract a common function and call that from a '
+ 'Hypothesis based test.', settings
+ )
+
# Anything in unused_kwargs hasn't been injected through
# argspec.defaults, so we need to add them.
for k in unused_kwargs:
@@ -537,6 +564,16 @@ def given(*generator_arguments, **generator_kwargs):
(k, convert_to_specifier(v)) for (k, v) in kwargs.items()))
)
+ def fail_health_check(message):
+ message += (
+ '\nSee http://hypothesis.readthedocs.org/en/latest/health'
+ 'checks.html for more information about this.'
+ )
+ if settings.strict:
+ raise FailedHealthCheck(message)
+ else:
+ warnings.warn(FailedHealthCheck(message))
+
search_strategy = strategy(given_specifier, settings)
search_strategy.validate()
@@ -546,17 +583,116 @@ def given(*generator_arguments, **generator_kwargs):
else:
storage = None
+ start = time.time()
+ warned_random = [False]
+ perform_health_check = settings.perform_health_check
+ if Settings.default is not None:
+ perform_health_check &= Settings.default.perform_health_check
+
+ if perform_health_check:
+ initial_state = getglobalrandomstate()
+ with Settings(settings, verbosity=Verbosity.quiet):
+ count = 0
+ bad_draws = 0
+ filtered_draws = 0
+ while (
+ count < 10 and time.time() < start + 1 and
+ filtered_draws < 50 and bad_draws < 50
+ ):
+ try:
+ test_runner(reify_and_execute(
+ search_strategy,
+ search_strategy.draw_template(
+ random,
+ search_strategy.draw_parameter(random)),
+ lambda *args, **kwargs: None,
+ ))
+ count += 1
+ except BadTemplateDraw:
+ bad_draws += 1
+ except UnsatisfiedAssumption:
+ filtered_draws += 1
+ except Exception:
+ traceback.print_exc()
+ if test_runner is default_executor:
+ fail_health_check(
+ 'An exception occurred during data '
+ 'generation in initial health check. '
+ 'This indicates a bug in the strategy. '
+ 'This could either be a Hypothesis bug or '
+ "an error in a function you've passed to "
+ 'it to construct your data.'
+ )
+ else:
+ fail_health_check(
+ 'An exception occurred during data '
+ 'generation in initial health check. '
+ 'This indicates a bug in the strategy. '
+ 'This could either be a Hypothesis bug or '
+ 'an error in a function you\'ve passed to '
+ 'it to construct your data. Additionally, '
+ 'you have a custom executor, which means '
+ 'that this could be your executor failing '
+ 'to handle a function which returns None. '
+ )
+ if filtered_draws >= 50:
+ fail_health_check((
+ 'It looks like your strategy is filtering out a lot '
+ 'of data. Health check found %d filtered examples but '
+ 'only %d good ones. This will make your tests much '
+ 'slower, and also will probably distort the data '
+ 'generation quite a lot. You should adapt your '
+ 'strategy to filter less.') % (
+ filtered_draws, count
+ ))
+ if bad_draws >= 50:
+ fail_health_check(
+ 'Hypothesis is struggling to generate examples. '
+ 'This is often a sign of a recursive strategy which '
+ 'fans out too broadly. If you\'re using recursive, '
+ 'try to reduce the size of the recursive step or '
+ 'increase the maximum permitted number of leaves.'
+ )
+ runtime = time.time() - start
+ if runtime > 1.0 or count < 10:
+ fail_health_check((
+ 'Data generation is extremely slow: Only produced '
+ '%d valid examples in %.2f seconds. Try decreasing '
+ "size of the data you're generating (with e.g."
+ 'average_size or max_leaves parameters).'
+ ) % (count, runtime))
+ if getglobalrandomstate() != initial_state:
+ warned_random[0] = True
+ 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.'
+ )
+
last_exception = [None]
repr_for_last_exception = [None]
def is_template_example(xs):
+ if perform_health_check and not warned_random[0]:
+ initial_state = getglobalrandomstate()
record_repr = [None]
try:
- test_runner(reify_and_execute(
+ result = test_runner(reify_and_execute(
search_strategy, xs, test,
record_repr=record_repr,
))
+ if result is not None:
+ note_deprecation((
+ 'Tests run under @given should return None, but '
+ '%s returned %r instead.'
+ 'In Hypothesis 2.0 this will become an error.'
+ ) % (test.__name__, result), settings)
return False
+ except HypothesisDeprecationWarning:
+ raise
except UnsatisfiedAssumption as e:
raise e
except Exception as e:
@@ -564,7 +700,19 @@ def given(*generator_arguments, **generator_kwargs):
repr_for_last_exception[0] = record_repr[0]
verbose_report(last_exception[0])
return True
-
+ finally:
+ if (
+ not warned_random[0] and
+ perform_health_check and
+ getglobalrandomstate() != initial_state
+ ):
+ warned_random[0] = True
+ 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.'
+ )
is_template_example.__name__ = test.__name__
is_template_example.__qualname__ = qualname(test)
@@ -572,7 +720,7 @@ def given(*generator_arguments, **generator_kwargs):
try:
falsifying_template = best_satisfying_template(
search_strategy, random, is_template_example,
- settings, storage
+ settings, storage, start_time=start,
)
except NoSuchExample:
return
diff --git a/src/hypothesis/errors.py b/src/hypothesis/errors.py
index 4780852..d2b4e64 100644
--- a/src/hypothesis/errors.py
+++ b/src/hypothesis/errors.py
@@ -16,6 +16,8 @@
from __future__ import division, print_function, absolute_import
+import warnings
+
class HypothesisException(Exception):
@@ -162,3 +164,15 @@ class AbnormalExit(HypothesisException):
"""Raised when a test running in a child process exits without returning or
raising an exception."""
+
+
+class FailedHealthCheck(HypothesisException, Warning):
+ """Raised when a test fails a preliminary healthcheck that occurs before
+ execution."""
+
+
+class HypothesisDeprecationWarning(HypothesisException, DeprecationWarning):
+ pass
+
+
+warnings.simplefilter(u'once', HypothesisDeprecationWarning)
diff --git a/src/hypothesis/extra/fakefactory.py b/src/hypothesis/extra/fakefactory.py
index d557c50..618548c 100644
--- a/src/hypothesis/extra/fakefactory.py
+++ b/src/hypothesis/extra/fakefactory.py
@@ -16,6 +16,7 @@
from __future__ import division, print_function, absolute_import
+import random as globalrandom
from random import Random
import faker
@@ -94,8 +95,13 @@ class FakeFactoryStrategy(SearchStrategy):
def gen_example(self, random, locales):
factory = self.factory_for(random.choice(locales))
- factory.seed(random.getrandbits(128))
- return text_type(getattr(factory, self.source)())
+ original = globalrandom.getstate()
+ seed = random.getrandbits(128)
+ try:
+ factory.seed(seed)
+ return text_type(getattr(factory, self.source)())
+ finally:
+ globalrandom.setstate(original)
def basic_simplify(self, random, template):
for _ in hrange(10):
diff --git a/src/hypothesis/internal/compat.py b/src/hypothesis/internal/compat.py
index 36064dc..115dc6c 100644
--- a/src/hypothesis/internal/compat.py
+++ b/src/hypothesis/internal/compat.py
@@ -89,9 +89,10 @@ if PY3:
def escape_unicode_characters(s):
return codecs.encode(s, 'unicode_escape').decode('ascii')
- def quiet_raise(exc):
- from hypothesis.internal.compat3 import quiet_raise as q
- q(exc)
+ exec("""
+def quiet_raise(exc):
+ raise exc from None
+""")
else:
VALID_PYTHON_IDENTIFIER = re.compile(
r"^[a-zA-Z_][a-zA-Z0-9_]*$"
@@ -102,10 +103,17 @@ else:
def unicode_safe_repr(x):
try:
- r = type(x).__repr__(x)
- except TypeError:
- # Workaround for https://bitbucket.org/pypy/pypy/issues/2083/
r = repr(x)
+ except UnicodeEncodeError:
+ r = type(x).__repr__(x)
+ from hypothesis.settings import note_deprecation
+ note_deprecation((
+ 'Type %s has a broken repr implementation. Calling __repr__ '
+ 'on it returned %r, which cannot be represented as ASCII '
+ 'text. This is not permitted in Python 2. Hypothesis is '
+ 'currently working around this, but will stop doing so in '
+ 'Hypothesis 2.0. You should fix your code.'
+ ) % (type(x).__name__, r))
if isinstance(r, unicode):
return r
else:
diff --git a/src/hypothesis/internal/compat3.py b/src/hypothesis/internal/compat3.py
deleted file mode 100644
index e301277..0000000
--- a/src/hypothesis/internal/compat3.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# coding=utf-8
-#
-# This file is part of Hypothesis (https://github.com/DRMacIver/hypothesis)
-#
-# Most of this work is copyright (C) 2013-2015 David R. MacIver
-# (david at drmaciver.com), but it contains contributions by others. See
-# https://github.com/DRMacIver/hypothesis/blob/master/CONTRIBUTING.rst for a
-# full list of people who may hold copyright, and consult the git log if you
-# need to determine who owns an individual contribution.
-#
-# 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 http://mozilla.org/MPL/2.0/.
-#
-# END HEADER
-
-# pylint: skip-file
-
-from __future__ import division, print_function, absolute_import
-
-
-def quiet_raise(exc):
- raise exc from None
diff --git a/src/hypothesis/searchstrategy/deferred.py b/src/hypothesis/searchstrategy/deferred.py
index 9bdb83f..ef4f5d1 100644
--- a/src/hypothesis/searchstrategy/deferred.py
+++ b/src/hypothesis/searchstrategy/deferred.py
@@ -16,6 +16,7 @@
from __future__ import division, print_function, absolute_import
+from hypothesis import Settings
from hypothesis.internal.compat import hrange, getargspec, \
unicode_safe_repr
from hypothesis.internal.reflection import arg_string, \
@@ -62,14 +63,16 @@ class DeferredStrategy(SearchStrategy):
self.__kwargs = dict(
(k, tupleize(v)) for k, v in kwargs.items()
)
+ self.__settings = Settings.default or Settings()
@property
def wrapped_strategy(self):
if self.__wrapped_strategy is None:
- self.__wrapped_strategy = self.__function(
- *self.__args,
- **self.__kwargs
- )
+ with self.__settings:
+ self.__wrapped_strategy = self.__function(
+ *self.__args,
+ **self.__kwargs
+ )
return self.__wrapped_strategy
def validate(self):
diff --git a/src/hypothesis/settings.py b/src/hypothesis/settings.py
index 7789ccc..6e7b720 100644
--- a/src/hypothesis/settings.py
+++ b/src/hypothesis/settings.py
@@ -29,7 +29,7 @@ import warnings
import threading
from collections import namedtuple
-from hypothesis.errors import InvalidArgument
+from hypothesis.errors import InvalidArgument, HypothesisDeprecationWarning
from hypothesis.utils.conventions import not_set
from hypothesis.utils.dynamicvariables import DynamicVariable
@@ -415,7 +415,12 @@ Settings.define_setting(
default=os.getenv(u'HYPOTHESIS_STRICT_MODE') == u'true',
description="""
If set to True, anything that would cause Hypothesis to issue a warning will
-instead raise an error.
+instead raise an error. Note that new warnings may be added at any time, so
+running with strict set to True means that new Hypothesis releases may validly
+break your code.
+
+You can enable this setting temporarily by setting the HYPOTHESIS_STRICT_MODE
+environment variable to the string 'true'.
"""
)
@@ -509,20 +514,22 @@ Settings.define_setting(
description=u'Average length of lists to use'
)
+Settings.define_setting(
+ u'perform_health_check',
+ default=True,
+ description=u"""
+If set to True, Hypothesis will run a preliminary health check before
+attempting to actually execute your test.
+"""
+)
+
Settings.lock_further_definitions()
Settings.register_profile('default', Settings())
Settings.load_profile('default')
-class HypothesisDeprecationWarning(DeprecationWarning):
- pass
-
-
-warnings.simplefilter(u'once', HypothesisDeprecationWarning)
-
-
-def note_deprecation(message, settings):
+def note_deprecation(message, settings=None):
# If *either* self or the current default are non-strict
# then this should be an error. This is to handle e.g. the case
# where defining a new setting while non-strict updates a
diff --git a/src/hypothesis/version.py b/src/hypothesis/version.py
index f4a1011..b74ae75 100644
--- a/src/hypothesis/version.py
+++ b/src/hypothesis/version.py
@@ -16,5 +16,5 @@
from __future__ import division, print_function, absolute_import
-__version_info__ = (1, 16, 0)
+__version_info__ = (1, 17, 0)
__version__ = u'.'.join(map(str, __version_info__))
--
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