[Python-modules-commits] [python-hypothesis] 02/06: Import python-hypothesis_3.0.0.orig.tar.gz
Tristan Seligmann
mithrandi at moszumanska.debian.org
Wed Feb 17 16:11:26 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 29758f95279f63292e3731c73d1383abd44e55a5
Author: Tristan Seligmann <mithrandi at debian.org>
Date: Wed Feb 17 17:44:04 2016 +0200
Import python-hypothesis_3.0.0.orig.tar.gz
---
README.rst | 3 -
appveyor.yml | 16 +-
benchmarks/test_strategies.py | 151 +++++
docs/changes.rst | 61 +-
docs/data.rst | 127 +---
docs/database.rst | 2 +-
docs/details.rst | 43 --
docs/django.rst | 104 +---
docs/examples.rst | 12 +-
docs/extras.rst | 2 +-
docs/index.rst | 1 -
docs/internals.rst | 287 ---------
docs/manifesto.rst | 6 +-
docs/settings.rst | 100 ++-
docs/stateful.rst | 6 +-
docs/supported.rst | 10 +-
docs/usage.rst | 7 +-
examples/README.rst | 10 +
examples/test_binary_search.py | 143 +++++
examples/test_rle.py | 104 ++++
scripts/basic-test.sh | 36 +-
setup.py | 7 +-
src/hypothesis/__init__.py | 3 +-
src/hypothesis/_settings.py | 53 +-
src/hypothesis/configuration.py | 4 +-
src/hypothesis/control.py | 19 +-
src/hypothesis/core.py | 653 +++++++------------
src/hypothesis/database.py | 255 ++++++++
src/hypothesis/database/__init__.py | 89 ---
src/hypothesis/database/backend.py | 156 -----
src/hypothesis/database/formats.py | 75 ---
src/hypothesis/errors.py | 31 +-
src/hypothesis/{executors => }/executors.py | 36 +-
src/hypothesis/executors/__init__.py | 42 --
src/hypothesis/extra/datetime.py | 189 +-----
src/hypothesis/extra/django/fixtures.py | 110 ----
src/hypothesis/extra/django/models.py | 18 +-
src/hypothesis/extra/fakefactory.py | 45 +-
src/hypothesis/extra/numpy.py | 140 +----
src/hypothesis/internal/charmap.py | 158 +++++
src/hypothesis/internal/charstree.py | 310 ----------
src/hypothesis/internal/chooser.py | 46 --
src/hypothesis/internal/compat.py | 125 ++++
.../conjecture}/__init__.py | 0
src/hypothesis/internal/conjecture/data.py | 167 +++++
src/hypothesis/internal/conjecture/engine.py | 435 +++++++++++++
src/hypothesis/internal/conjecture/minimizer.py | 139 +++++
src/hypothesis/internal/conjecture/utils.py | 130 ++++
src/hypothesis/internal/debug.py | 73 ---
src/hypothesis/internal/distributions.py | 65 --
src/hypothesis/internal/examplesource.py | 107 ----
src/hypothesis/internal/extmethod.py | 64 --
src/hypothesis/internal/floats.py | 57 ++
src/hypothesis/internal/intervalsets.py | 83 +++
src/hypothesis/internal/tracker.py | 80 ---
src/hypothesis/searchstrategy/collections.py | 687 ++------------------
src/hypothesis/searchstrategy/deferred.py | 35 +-
src/hypothesis/searchstrategy/fixed.py | 63 ++
src/hypothesis/searchstrategy/flatmapped.py | 16 +-
src/hypothesis/searchstrategy/misc.py | 91 +--
src/hypothesis/searchstrategy/morphers.py | 204 ------
src/hypothesis/searchstrategy/numbers.py | 688 ++++-----------------
src/hypothesis/searchstrategy/recursive.py | 48 +-
src/hypothesis/searchstrategy/reprwrapper.py | 21 -
src/hypothesis/searchstrategy/shared.py | 65 +-
src/hypothesis/searchstrategy/strategies.py | 417 ++-----------
src/hypothesis/searchstrategy/streams.py | 186 +-----
src/hypothesis/searchstrategy/strings.py | 207 ++-----
src/hypothesis/searchstrategy/wrappers.py | 27 +-
src/hypothesis/stateful.py | 335 +---------
src/hypothesis/strategies.py | 337 +++++-----
src/hypothesis/strategytests.py | 261 +-------
src/hypothesis/testrunners/forking.py | 105 ----
src/hypothesis/types.py | 13 -
src/hypothesis/version.py | 2 +-
tests/common/__init__.py | 12 +-
tests/{conftest.py => common/setup.py} | 40 +-
tests/conftest.py | 28 +-
tests/cover/test_arbitrary_data.py | 86 +++
tests/cover/test_charmap.py | 119 ++++
tests/cover/test_charstree.py | 90 ---
tests/cover/test_choices.py | 47 +-
tests/cover/test_conjecture_engine.py | 475 ++++++++++++++
.../test_conjecture_minimizer.py} | 16 +-
tests/cover/test_conjecture_test_data.py | 117 ++++
.../cover/test_conjecture_utils.py | 8 +-
tests/cover/test_control.py | 7 +-
tests/cover/test_converter.py | 56 --
tests/cover/test_core.py | 13 +-
tests/cover/test_database.py | 259 --------
tests/cover/test_database_agreement.py | 77 +++
tests/cover/test_database_backend.py | 132 +++-
tests/cover/test_database_usage.py | 109 ++++
tests/cover/test_direct_strategies.py | 11 -
tests/cover/test_distributions.py | 46 --
tests/cover/test_example.py | 7 +
tests/cover/test_examplesource.py | 91 ---
tests/cover/test_executors.py | 8 +
tests/cover/test_exhaustion.py | 57 --
tests/cover/test_explicit_examples.py | 10 +
tests/cover/test_extmethod.py | 69 ---
tests/cover/test_find.py | 18 +-
tests/cover/test_fixed_strategies.py | 79 +++
tests/cover/test_flakiness.py | 81 +--
tests/cover/test_flatmap.py | 32 +-
tests/cover/test_float_nastiness.py | 24 +-
tests/cover/test_forking.py | 126 ----
tests/cover/test_given_error_conditions.py | 6 +-
tests/cover/test_health_checks.py | 100 +--
tests/cover/test_integer_ranges.py | 72 +++
.../{test_chooser.py => test_interleaving.py} | 44 +-
.../cover/test_internal_helpers.py | 12 +-
tests/cover/test_intervalset.py | 87 +++
tests/cover/{test_example.py => test_limits.py} | 17 +-
tests/{django/manage.py => cover/test_map.py} | 19 +-
tests/cover/test_minimal.py | 38 --
tests/cover/test_morpher.py | 119 ----
tests/cover/test_one_of.py | 40 --
tests/cover/test_recursive.py | 163 +----
tests/cover/test_reporting.py | 13 +-
tests/cover/test_searchstrategy.py | 92 +--
tests/cover/test_sets.py | 87 +--
tests/cover/test_simple_collections.py | 32 +-
tests/cover/test_simple_numbers.py | 97 +--
tests/cover/test_simple_strings.py | 48 +-
tests/cover/test_sizes.py | 28 -
tests/cover/test_stateful.py | 195 +-----
tests/cover/test_streams.py | 92 +--
tests/cover/test_testdecorators.py | 23 +-
tests/cover/test_timeout.py | 13 +-
tests/cover/test_tracker.py | 99 ---
tests/cover/test_validation.py | 23 +-
tests/cover/test_verbosity.py | 15 +-
tests/cover/test_via_the_database.py | 115 ----
tests/datetime/test_dates.py | 24 -
tests/datetime/test_datetime.py | 53 +-
tests/datetime/test_times.py | 13 -
tests/django/manage.py | 3 +
tests/django/toystore/test_basic_configuration.py | 12 +-
tests/django/toystore/test_fixtures.py | 88 ---
tests/{cover => nocover}/test_choices.py | 39 +-
.../test_collective_minimization.py | 5 +-
tests/nocover/test_compat.py | 29 +-
tests/nocover/test_debug.py | 37 --
tests/nocover/test_descriptortests.py | 31 +-
tests/nocover/test_example_quality.py | 167 +++--
tests/nocover/test_floating.py | 18 +-
tests/nocover/test_git_merge.py | 13 +-
tests/nocover/test_pretty_repr.py | 4 +-
tests/{cover => nocover}/test_recursive.py | 90 ++-
tests/nocover/test_statistical_distribution.py | 105 ++--
tests/nocover/test_strategy_state.py | 150 +----
tests/nocover/test_streams.py | 8 +-
tests/numpy/test_gen_data.py | 8 +-
tox.ini | 10 +-
155 files changed, 5091 insertions(+), 8858 deletions(-)
diff --git a/README.rst b/README.rst
index 6ba75b2..9314db9 100644
--- a/README.rst
+++ b/README.rst
@@ -34,9 +34,6 @@ If you want to receive occasional updates about Hypothesis, including useful tip
If you want to contribute to Hypothesis, `instructions are here <https://github.com/DRMacIver/hypothesis/blob/master/CONTRIBUTING.rst>`_.
-If you're looking for inspiration for writing your own QuickCheck clone,
-`here's a list of ideas you might want to borrow <https://hypothesis.readthedocs.org/en/latest/internals.html>`_.
-
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>`_.
diff --git a/appveyor.yml b/appveyor.yml
index 60a421e..85ff3c6 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -14,22 +14,14 @@ environment:
PYTHON_VERSION: "2.7.8"
PYTHON_ARCH: "64"
- - PYTHON: "C:\\Python33"
- PYTHON_VERSION: "3.3.5"
+ - PYTHON: "C:\\Python34"
+ PYTHON_VERSION: "3.4.1"
PYTHON_ARCH: "32"
- - PYTHON: "C:\\Python33-x64"
- PYTHON_VERSION: "3.3.5"
+ - PYTHON: "C:\\Python34-x64"
+ PYTHON_VERSION: "3.4.1"
PYTHON_ARCH: "64"
-# - PYTHON: "C:\\Python34"
-# PYTHON_VERSION: "3.4.1"
-# PYTHON_ARCH: "32"
-
-# - PYTHON: "C:\\Python34-x64"
-# PYTHON_VERSION: "3.4.1"
-# PYTHON_ARCH: "64"
-
install:
- ECHO "Filesystem root:"
- ps: "ls \"C:/\""
diff --git a/benchmarks/test_strategies.py b/benchmarks/test_strategies.py
new file mode 100644
index 0000000..9c7749d
--- /dev/null
+++ b/benchmarks/test_strategies.py
@@ -0,0 +1,151 @@
+# 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
+
+from __future__ import division, print_function, absolute_import
+
+import os
+import hypothesis.strategies as st
+from hypothesis import find, settings, given
+
+settings.register_profile('benchmarking', settings(
+ database=None,
+))
+
+
+import pytest
+import random
+
+
+def setup_module():
+ settings.load_profile('benchmarking')
+
+
+def teardown_module():
+ settings.load_profile(os.getenv('HYPOTHESIS_PROFILE', 'default'))
+
+
+ at st.composite
+def sorted_three(draw):
+ x = draw(st.integers())
+ y = draw(st.integers(min_value=x))
+ z = draw(st.integers(min_value=y))
+ return (x, y, z)
+
+
+strategies = [
+ st.integers(),
+ st.text(),
+ st.binary(),
+ st.floats(),
+ st.integers().flatmap(lambda x: st.lists(st.integers(max_value=x))),
+ st.integers().filter(lambda x: x % 3 == 1),
+ st.tuples(st.integers(), st.integers(), st.integers(), st.integers()),
+ st.text() | st.integers(),
+ sorted_three(),
+ st.text(average_size=20)
+]
+
+strategies.extend(list(map(st.lists, strategies)))
+
+# Nothing special, just want a fixed seed list.
+seeds = [
+ 17449917217797177955,
+ 10900658426497387440,
+ 3678508287585343099,
+ 11902419052042326073,
+ 8648395390016624135
+]
+
+counter = 0
+ids = []
+for strat in strategies:
+ for seed in range(1, 1 + len(seeds)):
+ counter += 1
+ ids.append('example%d-%r-seed%d' % (counter, strat, seed))
+
+bench = pytest.mark.parametrize(
+ ('strategy', 'seed'), [
+ (strat, seed) for strat in strategies for seed in seeds
+ ],
+ ids=ids
+)
+
+
+ at bench
+def test_empty_given(benchmark, strategy, seed):
+
+ @benchmark
+ def run():
+ random.seed(seed)
+
+ @given(strategy)
+ def test(s):
+ pass
+ test()
+
+
+ at bench
+def test_failing_given(benchmark, strategy, seed):
+
+ @benchmark
+ def run():
+ random.seed(seed)
+
+ @given(strategy)
+ def test(s):
+ raise ValueError()
+
+ with pytest.raises(ValueError):
+ test()
+
+
+ at bench
+def test_one_off_generation(benchmark, strategy, seed):
+ @benchmark
+ def run():
+ strategy.example(random.Random(seed))
+
+
+ at bench
+def test_minimize_to_minimal(benchmark, strategy, seed):
+ @benchmark
+ def run():
+ find(strategy, lambda x: True, random=random.Random(seed))
+
+
+ at bench
+def test_minimize_to_not_minimal(benchmark, strategy, seed):
+ @benchmark
+ def run():
+ rnd = random.Random(seed)
+ minimal = find(strategy, lambda x: True, random=rnd)
+ find(strategy, lambda x: x != minimal, random=rnd)
+
+
+ at bench
+def test_total_failure_to_minimize(benchmark, strategy, seed):
+ @benchmark
+ def run():
+ rnd = random.Random(seed)
+ ex = []
+
+ def is_first(x):
+ if ex:
+ return x == ex[0]
+ else:
+ ex.append(x)
+ return True
+ find(strategy, lambda x: True, random=rnd)
diff --git a/docs/changes.rst b/docs/changes.rst
index 2f4c98e..234ab0b 100644
--- a/docs/changes.rst
+++ b/docs/changes.rst
@@ -22,6 +22,61 @@ You should generally assume that an API is internal unless you have specific
information to the contrary.
------------------
+3.0.0 - 2016-02-17
+------------------
+
+Codename: This really should have been 2.1.
+
+Externally this looks like a very small release. It has one small breaking change
+that probably doesn't affect anyone at all (some behaviour that never really worked
+correctly is now outright forbidden) but necessitated a major version bump and one
+visible new feature.
+
+Internally this is a complete rewrite. Almost nothing other than the public API is
+the same.
+
+New features:
+
+* Addition of data() strategy which allows you to draw arbitrary data interactively
+ within the test.
+* New "exploded" database format which allows you to more easily check the example
+ database into a source repository while supporting merging.
+* Better management of how examples are saved in the database.
+
+New limitations:
+
+* choices and streaming strategies may no longer be used with find(). Neither may
+ data() (this is the change that necessitated a major version bump).
+
+Performance improvements:
+
+* A new model which allows flatmap, composite strategies and stateful testing to
+ perform *much* better. They should also be more reliable.
+* Filtering may in some circumstances have improved significantly. This will
+ help especially in cases where you have lots of values with individual filters
+ on them, such as lists(x.filter(...)).
+* Modest performance improvements to the general test runner by avoiding expensive
+ operations
+
+In general your tests should have got faster. If they've instead got significantly
+slower, I'm interested in hearing about it.
+
+Data distribution:
+
+The data distribution should have changed significantly. This may uncover bugs the
+previous version missed. It may also miss bugs the previous version could have
+uncovered. Hypothesis is now producing less strongly correlated data than it used
+to, but the correlations are extended over more of the structure.
+
+Shrinking:
+
+Shrinking quality should have improved. In particular Hypothesis can now perform
+simultaneous shrinking of separate examples within a single test (previously it
+was only able to do this for elements of a single collection). In some cases
+performance will have improved, in some cases it will have got worse but generally
+shouldn't have by much.
+
+------------------
2.0.0 - 2016-01-10
------------------
@@ -44,8 +99,12 @@ In particular:
in the argspec at all.
* the basic() strategy no longer exists.
* the n_ary_tree strategy no longer exists.
-* the average_list_length setting no longer exists.
+* the average_list_length setting no longer exists. Note: If you're using
+ using recursive() this will cause you a significant slow down. You should
+ pass explicit average_size parameters to collections in recursive calls.
* @rule can no longer be applied to the same method twice.
+* Python 2.6 and 3.3 are no longer officially supported, although in practice
+ they still work fine.
This also includes two non-deprecation changes:
diff --git a/docs/data.rst b/docs/data.rst
index ca67e20..f3b1216 100644
--- a/docs/data.rst
+++ b/docs/data.rst
@@ -308,16 +308,8 @@ Composite strategies
~~~~~~~~~~~~~~~~~~~~
The @composite decorator lets you combine other strategies in more or less
-arbitrary ways.
-
-Advance warning: You're going to end up wanting to use this API for a lot of
-things, and it's not that you *shouldn't* do that, but it has certain
-intrinsic limitations which mean that overuse of it can hurt performance and
-example quality.
-
-If it's convenient to do so you should use builds instead. Otherwise feel free
-to use this, and if you end up with bad examples or poor performance then you
-should look here first as the culprit.
+arbitrary ways. It's probably the main thing you'll want to use for
+complicated custom strategies.
The composite decorator works by giving you a function as the first argument
that you can use to draw examples from other strategies. For example, the
@@ -366,109 +358,32 @@ You can use assume inside composite functions:
This works as assume normally would, filtering out any examples for which the
passed in argument is falsey.
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Defining entirely new strategies
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The full SearchStrategy API is only "semi-public", in that it may (but usually
-won't) break between minor versions but won't break between patch releases.
-
-However Hypothesis exposes a simplified version of the interface that you can
-use to build pretty good strategies. In general it's pretty strongly recommended
-that you don't use this if you can build your strategy out of existing ones,
-but it works perfectly well.
-
-Here is an example of using the simplified interface:
-
-.. code:: python
-
- from hypothesis.searchstrategy import BasicStrategy
-
- class Bitfields(BasicStrategy):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Drawing interactively in tests
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- """A BasicStrategy for generating 128 bit integers to be treated as if they
- were bitfields."""
+There is also the ``data()`` strategy, which gives you a means of using
+strategies interactively. Rather than having to specify everything up front in
+``@given`` you can draw from strategies in the body of your test:
- def generate_parameter(self, random):
- # This controls the shape of the data that can be generated by
- # randomly screening off some bits.
- return random.getrandbits(128)
-
- def generate(self, random, parameter_value):
- # This generates a random value subject to a parameter we have
- # previously generated
- return parameter_value & random.getrandbits(128)
-
- def simplify(self, random, value):
- # Simplify by settings bits to zero.
- for i in range(128):
- k = 1 << i
- # It's important to test this because otherwise it would create a
- # cycle where value simplifies to value. This would cause
- # Hypothesis to get stuck on that value and not be able to simplify
- # it further.
- if value & k:
- yield value & (~k)
-
- def copy(self, value):
- # integers are immutable so there's no need to copy them
- return value
-
-
-Only generate is strictly necessary to implement. copy will default to using
-deepcopy, generate_parameter will default to returning None, and simplify will
-default to not simplifying.
-
-The reason why the parameters are important is that they let you "shape" the
-data so that it works with adaptive assumptions, which work by being more likely
-to reuse parameter values that don't cause assumptions to be violated.
+.. code-block:: python
-Simplify is of course what Hypothesis uses to produce simpler examples. It will
-greedily apply it to your data to produce the simplest example it possible can.
-You should avoid having cycles or unbounded paths in the graph, as this will tend
-to hurt example quality and performance.
+ @given(data())
+ def test_draw_sequentially(data):
+ x = data.draw(integers())
+ y = data.draw(integers(min_value=x))
+ assert x < y
-Instances of BasicStrategy are not actually strategies and must be converted
-to them using the basic function from hypothesis.strategies. You can convert
-either a class or an instance:
+If the test fails, each draw will be printed with the falsifying example. e.g.
+the above is wrong (it has a boundary condition error), so will print:
-.. code:: python
- >>> basic(Bitfields).example()
- 70449389301502165026254673882738917538
- >>> basic(Bitfields()).example()
- 180947746395888412520415493036267606532
+::
-You can also skip the class definition if you prefer and just pass functions to
-basic. e.g.
+ Falsifying example: test_draw_sequentially(data=data(...))
+ Draw 1: 0
+ Draw 2: 0
-.. code:: python
- >>> basic(generate=lambda random, _: random.getrandbits(8)).example()
- 88
-
-The arguments to basic have the same names as the methods you would define on
-BasicStrategy.
-
-Caveats:
-
-* Remember that BasicStrategy is not a subclass of SearchStrategy, only
- convertible to one.
-* The values produced by BasicStrategy are opaque to Hypothesis in a way that
- ones it is more intimately familiar with are not, because it's impossible
- to safely and sensibly deduplicate arbitrary Python objects. This is mostly
- fine but it blocks certain heuristics and optimisations Hypothesis uses for
- improving the simplification process. As such implementations using
- BasicStrategy might get slightly worse examples than the equivalent native
- ones.
-* You should not use BasicData for anything which you need control over the
- life cycle of, e.g. ORM objects. Hypothesis will keep instances of these
- values around for a potentially arbitrarily long time and will not do any
- clean up for disposing of them other than letting them be GCed as normal.
-
-However if it's genuinely the best way for you to do it, you should feel free to
-use BasicStrategy. These caveats should be read in the light of the fact that
-the full Hypothesis SearchStrategy interface is really very powerful, and the
-ones using BasicStrategy are merely a bit better than the normal quickcheck
-interface.
+As you can see, data drawn this way is simplified as usual.
diff --git a/docs/database.rst b/docs/database.rst
index f42c8fd..333008f 100644
--- a/docs/database.rst
+++ b/docs/database.rst
@@ -24,7 +24,7 @@ File locations
The default (and currently only) storage format is as rather weirdly unidiomatic JSON saved
in an sqlite3 database. The standard location for that is .hypothesis/examples.db in your current
working directory. You can override this, either by setting either the database\_file property on
-a Settings object (you probably want to specify it on Settings.default) or by setting the
+a settings object (you probably want to specify it on settings.default) or by setting the
HYPOTHESIS\_DATABASE\_FILE environment variable.
Note: There are other files in .hypothesis but everything other than the examples.db will be
diff --git a/docs/details.rst b/docs/details.rst
index 8315cbb..a987497 100644
--- a/docs/details.rst
+++ b/docs/details.rst
@@ -382,49 +382,6 @@ Methods of a BasicStrategy however will typically be called whenever. This may
happen inside your executor or outside. This is why they have a "Warning you
have no control over the lifecycle of these values" attached.
-~~~~~~~~~~~~~~~~~~~~~
-Fork before each test
-~~~~~~~~~~~~~~~~~~~~~
-
-An obstacle you can run into if you want to use Hypothesis to test native code
-is that your C code segfaults, or fails a C level assertion, and it causes the
-whole process to exit hard and Hypothesis just cries a little and doesn't know
-what is going on, so can't minimize an example for you.
-
-The solution to this is to run your tests in a subprocess. The process can die
-as messily as it likes and Hypothesis will be sitting happily in the
-controlling process unaffected by the crash. Hypothesis provides a custom
-executor for this:
-
-.. code:: python
-
- from hypothesis.testrunners.forking import ForkingTestCase
-
- class TestForking(ForkingTestCase):
-
- @given(integers())
- def test_handles_abnormal_exit(self, i):
- os._exit(1)
-
- @given(integers())
- def test_normal_exceptions_work_too(self, i):
- assert False
-
-
-Exceptions that occur in the child process will be seamlessly passed back to
-the parent. Abnormal exits that do not throw an exception in the child process
-will be turned into an AbnormalExit exception.
-
-There are currently some limitations to this approach:
-
-1. Exceptions which are not pickleable will be turned into abnormal exits.
-2. Tracebacks from exceptions are not properly recreated in the parent process.
-3. Code called in the child process will not be recorded by coverage.
-4. This is only supported on platforms with os.fork. e.g. it will not work on
- Windows.
-
-Some of these limitations should be resolvable in time.
-
-------------------------------
Using Hypothesis to find values
-------------------------------
diff --git a/docs/django.rst b/docs/django.rst
index c55976f..90c8f6f 100644
--- a/docs/django.rst
+++ b/docs/django.rst
@@ -5,7 +5,7 @@ Hypothesis for Django users
===========================
Hypothesis offers a number of features specific for Django testing, available
-in the :mod:`hypothesis-django` extra package.
+in the :mod:`hypothesis[django]` :doc:`extra </extras>`.
Using it is quite straightforward: All you need to do is subclass
:class:`hypothesis.extra.django.TestCase` or
@@ -75,108 +75,6 @@ for it as:
shop_strategy = models(Shop, company=models(Company))
-
---------
-Fixtures
---------
-
-The other way you can use Hypothesis for testing your Django project is to
-replace your fixtures. This feature is a bit new and experimental but seems
-to work pretty well.
-
-Hypothesis offers a function *fixture* which lets you specify a single example
-to use in your tests by what properties it should satisfy. For example, suppose
-we want a Company with a long name (I have no idea why) you could specify:
-
-
-.. code:: python
-
- from hypothesis.extra.django.models import models
- from hypothesis.extra.django.fixtures import fixture
-
- from toystore.models import Company
-
- a_company = fixture(
- models(Company),
- lambda c: len(c.name) >= 10,
- )
-
-This gives you a function that you can call from within your tests to get a
-value of the desired type matching these conditions:
-
-.. code:: python
-
- from hypothesis.extra.django.models import models
- from hypothesis.extra.django.fixtures import fixture
-
- from toystore.models import Company
-
- class TestCompany(TestCase):
- def test_can_find_unique_name(self):
- assert len(a_company().name) >= 10
-
-Unlike normal tests with Hypothesis this doesn't randomize your test, and you
-only run it once: Hypothesis has built and minimized an example before the test
-ever runs, then it just provides you with that example each time. This lacks
-much of the power of normal Hypothesis, but may be a lot more convenient to use
-in some cases and lets you still get many of the benefits of using its data
-generation while writing a more classic style of test. It's also a lot less
-annoying than writing your fixtures by hand.
-
-Each time you call a single fixture in your test will give you the same
-example back, so e.g. the following test will pass:
-
-.. code:: python
-
- def test_two_calls_to_fixture_are_the_same(self):
- assert a_company().pk == a_company().pk
-
-You can also use multiple fixtures in the same test. These will always give
-different results, even if their definitions are the same:
-
-.. code:: python
-
- from hypothesis.extra.django.models import models
- from hypothesis.extra.django.fixtures import fixture
-
- from toystore.models import Company
-
- company1 = fixture(models(Company))
- company2 = fixture(models(Company))
-
- class TestCompany(TestCase):
- def test_two_fixtures(self):
- assert company1().pk != company2().pk
-
-Note that fixtures don't have to define models. They can define any type you
-like. e.g. the following gives us a list containing at least 3 distinct companies:
-
-
-.. code:: python
-
- some_companies = fixture(
- models(Company), lambda cs: len({c.pk for c in cs}) >= 3
- )
-
-(Note we ask for three distinct primary keys rather than just the length of
-the company: Otherwise we'd probably have got the same company 3 times)
-
-Some caveats:
-
-1. If you have unique constraints then you should call fixture functions
- before instantiating any models yourself, or you may get integrity errors
- when Hypothesis tries to create the fixture.
-2. Fixtures can make startup quite slow the first time as Hypothesis has to work
- out the example to use. Values are cached in the Hypothesis example
- database (which has nothing to do with your Django test database), stored
- by default in .hypothesis/examples.db. You might wish to cache this
- between test runs on your CI server, as it will significantly improve startup
- performance.
-3. Hypothesis creates and destroys test databases during fixture definition.
- This is normal and you shouldn't be concerned if you notice it. It would be
- nice if this weren't necessary and if anyone has a better idea about how to
- do it, please talk to me...
-
---------------
Tips and tricks
---------------
diff --git a/docs/examples.rst b/docs/examples.rst
index 8f9b25a..f9e7249 100644
--- a/docs/examples.rst
+++ b/docs/examples.rst
@@ -94,7 +94,7 @@ First we need to define a strategy for Node:
.. code:: python
- from hypothesis import Settings, strategy
+ from hypothesis import settings, strategy
import hypothesis.strategies as s
NodeStrategy = s.builds(
@@ -200,7 +200,7 @@ Hypothesis, and how the hypothesis-datetime extra package works.
.. code:: python
- from hypothesis import given, Settings
+ from hypothesis import given, settings
from hypothesis.extra.datetime import datetimes
from hypothesis.strategies import sampled_from
import pytz
@@ -210,7 +210,7 @@ Hypothesis, and how the hypothesis-datetime extra package works.
# There are a lot of fiddly edge cases in dates, so we run a larger number of
# examples just to be sure
- with Settings(max_examples=1000):
+ with settings(max_examples=1000):
@given(
datetimes(), # datetimes generated are non-naive by default
sampled_from(ALL_TIMEZONES), sampled_from(ALL_TIMEZONES),
@@ -387,7 +387,7 @@ then use the result and go on to do other things are definitely also possible.
.. code:: python
import unittest
- from hypothesis import given, assume, Settings
+ from hypothesis import given, assume, settings
from collections import namedtuple
import requests
import os
@@ -399,8 +399,8 @@ then use the result and go on to do other things are definitely also possible.
# These tests will be quite slow because we have to talk to an external
# service. Also we'll put in a sleep between calls so as to not hammer it.
# As a result we reduce the number of test cases and turn off the timeout.
- Settings.default.max_examples = 100
- Settings.default.timeout = -1
+ settings.default.max_examples = 100
+ settings.default.timeout = -1
Goal = namedtuple("Goal", ("slug",))
diff --git a/docs/extras.rst b/docs/extras.rst
index d5fc348..7745d19 100644
--- a/docs/extras.rst
+++ b/docs/extras.rst
@@ -194,4 +194,4 @@ 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>`.
+It can also load :ref:`settings Profiles <settings_profiles>`.
diff --git a/docs/index.rst b/docs/index.rst
index dcbb980..6e2c06d 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -65,7 +65,6 @@ of the things you need to know to begin testing your code with it.
stateful
supported
examples
- internals
community
manifesto
endorsements
diff --git a/docs/internals.rst b/docs/internals.rst
deleted file mode 100644
index 73e5eb7..0000000
--- a/docs/internals.rst
+++ /dev/null
@@ -1,287 +0,0 @@
-=================================
-Innovative features of Hypothesis
-=================================
-
-This document is a guide to Hypothesis internals, mostly with a goal to porting
-to other implementations of Quickcheck that want to benefit from some of the
-more unusual/interesting ideas in it, but it's probably of general interest. It
-assumes you have some familiarity with the general ideas of property based testing
-and Quickcheck.
-
-Nothing here is stable public API and might all be prone to change between
-minor releases. The purpose of this document is to share the ideas, not to
-specify the behaviour.
-
-If you want to see all of these how most of these pieces fit together, there
-is also `a worked example available here <https://github.com/DRMacIver/hypothesis/blob/master/examples/bintree.py>`_.
-
-This is sorted roughly in order of most interesting to least technically interesting.
-
-----------
-Templating
-----------
-
-Templating is the single most important innovation in Hypothesis. If you're
-going to take any ideas out of Hypothesis you should take this one.
-
-The idea is as follows: Rather than generating data of the required type
-directly, value generation is split into two parts. We first generate a *template*
-and we then have a function which can reify that template, turning it into a
-value of the desired type. Importantly, simplification happens on templates and
-not on reified data.
-
-This has several major advantages:
-
-1. The templates can be of a much more restricted type than the desired output
- - you can require them to be immutable, serializable, hashable, etc without
- in any way restricting the range of data that you can generate.
-2. Seamless support for mutable data: Because the mutable object you produce
- is the result of reifying the template, any mutation done by the function
- you call does not affect the underlying template.
-3. Generation strategies are monads (more or less. The generation is monadic,
- the simplification rules don't strictly follow the monad laws but this isn't
- a problem in practice).
-
-The latter is worth elaborating on: Hypothesis SearchStrategy has methods map and
-flatmap, which lets you do e.g. integers().map(lambda x: Decimal(x) / 100).
-
-This gives you a new strategy for decimals, which still supports minimization.
-The normal obstacle here is that you can't minimize the result because you'd
-need a way to map back to the original data type, but that isn't an issue here
-because you can just keep using the previous template type, minimize that, and
-only convert to the new data type at the point of reification.
-
-Making generation monadic is trickier because of the way it has to interact with
-reification (you can't know what the strategy you need to draw from is until you've
-reified the intermediate argument, which you can't do). The way this is solved is
-pretty fiddly and involves some tricks that wouldn't work in a pure language unless
-reify was also pure (and it's quite useful to allow reify to be monadic).
-
---------------------------
-Multi-stage simplification
---------------------------
-
-Hypothesis generally seems to try harder than classic quickcheck to produce
-simple examples. Unfortunately this meant historically that simplification was
-potentially *very* slow. Multi-stage simplification helps with this a lot by
-avoiding large categories of behaviours that waste time.
-
-The core idea is that there are different categories of simplification, and
-once a category of simplification has stopped working you should stop trying
-it even if you've changed other things. For example, if we have something like:
-
-.. code:: python
-
- @given([int])
- def test_lists_are_short(xs):
- assert len(xs) < 100
-
-then in the classic mode of quickcheck simplification, once we've found an
-example which is only 100 elements long and are trying to simplify the elements
-to find out if they are essential, each recursive simplification will nevertheless
-try to shrink the size of the list, wasting a lot of time after each successful
-shrink of an element.
-
-The way Hypothesis solves this is to split simplification into stages: Instead
-of a single function simplify, we have a list (well, generator) of simplify
-functions.
-
-This gives us the following algorithm (somewhere between python and pseudocode):
-
-.. code:: python
-
- def minimize_with_shrinker(x, f, shrinker):
- """
- Greedily apply a single shrinker function to find a smaller version
- of x which satisfies f.
- """
- for s in shrinker(x):
- if f(s):
- return minimize_with_shrinker(s, f, shrinker)
- return x
-
- def shrink_pass(x, f):
- """
- Apply each shrinker in turn to minimizing an example from x
- """
- for shrinker in shrinkers:
- x = minimize_with_shrinker(x, f, shrinker)
- return x
-
- def minimize(x, f):
- """
- Repeatedly do minimization passes on x until we hit a fixed point
- """
- while True:
- shrunk = shrink_pass(x, f)
- if shrunk == x:
- return shrunk
- x = shrunk
-
-So in the list example we have two simplification passes: The first attempts
-to remove elements, the second attempts to simplify elements in place without
-changing the size of the list.
-
-We do multiple passes because sometimes a later pass can unblock a condition
-that was making a previous pass make progress by e.g. changing relations between
-elements.
-
-In order to avoid combinatorial explosions when recursively applying simplification
-one will frequently flatten down the simplification passes for elements into a
-single pass, using the function
-
-
-.. code:: python
-
... 17062 lines suppressed ...
--
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