Hello community,

here is the log from the commit of package python-hypothesis for 
openSUSE:Factory checked in at 2015-12-18 21:50:21
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-hypothesis (Old)
 and      /work/SRC/openSUSE:Factory/.python-hypothesis.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-hypothesis"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-hypothesis/python-hypothesis.changes      
2015-11-28 15:19:04.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.python-hypothesis.new/python-hypothesis.changes 
2015-12-18 21:50:23.000000000 +0100
@@ -1,0 +2,9 @@
+Wed Dec  9 10:06:43 UTC 2015 - [email protected]
+
+- update to 1.16.0:
+  * Functions from hypothesis.strategies will no longer raise InvalidArgument 
on bad arguments
+  * Errors caused by accidentally invoking the legacy API are now much less 
confusing
+  * hypothesis.extra.django is 1.9 compatible.
+  * When tests are run with max_shrinks=0 this will now still rerun the test 
on failure
+
+-------------------------------------------------------------------

Old:
----
  hypothesis-1.14.0.tar.gz

New:
----
  hypothesis-1.16.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-hypothesis.spec ++++++
--- /var/tmp/diff_new_pack.3gHzTr/_old  2015-12-18 21:50:23.000000000 +0100
+++ /var/tmp/diff_new_pack.3gHzTr/_new  2015-12-18 21:50:23.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-hypothesis
 #
-# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -13,23 +13,24 @@
 # published by the Open Source Initiative.
 
 # Please submit bugfixes or comments via http://bugs.opensuse.org/
+#
 
 
 Name:           python-hypothesis
-Version:        1.14.0
+Version:        1.16.0
 Release:        0
-License:        MPL-2.0
 Summary:        A library for property based testing
-Url:            https://github.com/DRMacIver/hypothesis
+License:        MPL-2.0
 Group:          Development/Languages/Python
+Url:            https://github.com/DRMacIver/hypothesis
 Source:         
https://pypi.python.org/packages/source/h/hypothesis/hypothesis-%{version}.tar.gz
 BuildRequires:  python-devel
 BuildRequires:  python-setuptools
-Requires:       python-pytest >= 2.7.0
-Requires:       python-numpy >= 1.9.0
+Requires:       python-Django >= 1.7
 Requires:       python-fake-factory >= 0.5.2
+Requires:       python-numpy >= 1.9.0
+Requires:       python-pytest >= 2.7.0
 Requires:       python-pytz
-Requires:       python-Django >= 1.7
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 %if 0%{?suse_version} && 0%{?suse_version} <= 1110
 %{!?python_sitelib: %global python_sitelib %(python -c "from 
distutils.sysconfig import get_python_lib; print get_python_lib()")}

++++++ hypothesis-1.14.0.tar.gz -> hypothesis-1.16.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hypothesis-1.14.0/PKG-INFO 
new/hypothesis-1.16.0/PKG-INFO
--- old/hypothesis-1.14.0/PKG-INFO      2015-11-01 15:01:59.000000000 +0100
+++ new/hypothesis-1.16.0/PKG-INFO      2015-12-08 19:06:20.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: hypothesis
-Version: 1.14.0
+Version: 1.16.0
 Summary: A library for property based testing
 Home-page: https://github.com/DRMacIver/hypothesis
 Author: David R. MacIver
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hypothesis-1.14.0/setup.cfg 
new/hypothesis-1.16.0/setup.cfg
--- old/hypothesis-1.14.0/setup.cfg     2015-11-01 15:01:59.000000000 +0100
+++ new/hypothesis-1.16.0/setup.cfg     2015-12-08 19:06:20.000000000 +0100
@@ -1,5 +1,5 @@
 [egg_info]
 tag_svn_revision = 0
-tag_date = 0
 tag_build = 
+tag_date = 0
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hypothesis-1.14.0/src/hypothesis/core.py 
new/hypothesis-1.16.0/src/hypothesis/core.py
--- old/hypothesis-1.14.0/src/hypothesis/core.py        2015-11-01 
14:04:01.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis/core.py        2015-12-08 
15:25:34.000000000 +0100
@@ -345,7 +345,7 @@
 
 def reify_and_execute(
     search_strategy, template, test,
-    print_example=False, always_print=False, record_repr=None,
+    print_example=False, record_repr=None,
     is_final=False,
 ):
     def run():
@@ -356,7 +356,7 @@
                 report(
                     lambda: u'Falsifying example: %s(%s)' % (
                         test.__name__, text_version,))
-            elif current_verbosity() >= Verbosity.verbose or always_print:
+            elif current_verbosity() >= Verbosity.verbose:
                 report(
                     lambda: u'Trying example: %s(%s)' % (
                         test.__name__, text_version))
@@ -380,15 +380,6 @@
     # if they were keyword specifiers for data to pass to the test.
     provided_random = generator_kwargs.pop(u'random', None)
     settings = generator_kwargs.pop(u'settings', None) or Settings.default
-
-    if (provided_random is not None) and settings.derandomize:
-        raise InvalidArgument(
-            u'Cannot both be derandomized and provide an explicit random')
-
-    if not (generator_arguments or generator_kwargs):
-        raise InvalidArgument(
-            u'given must be called with at least one argument')
-
     if generator_arguments and generator_kwargs:
         note_deprecation(
             u'Mixing positional and keyword arguments in a call to given is '
@@ -396,22 +387,35 @@
         )
 
     def run_test_with_generator(test):
+        original_argspec = getargspec(test)
+
+        def invalid(message):
+            def wrapped_test(*arguments, **kwargs):
+                raise InvalidArgument(message)
+            return wrapped_test
+
+        if (provided_random is not None) and settings.derandomize:
+            return invalid(
+                u'Cannot both be derandomized and provide an explicit random')
+
+        if not (generator_arguments or generator_kwargs):
+            return invalid(
+                u'given must be called with at least one argument')
+
         if settings.derandomize:
-            assert provided_random is None
             random = Random(function_digest(test))
         else:
             random = provided_random or Random()
 
-        original_argspec = getargspec(test)
         if generator_arguments and original_argspec.varargs:
-            raise InvalidArgument(
+            return invalid(
                 u'varargs are not supported with positional arguments to '
                 u'@given'
             )
         extra_kwargs = [
             k for k in generator_kwargs if k not in original_argspec.args]
         if extra_kwargs and not original_argspec.keywords:
-            raise InvalidArgument(
+            return invalid(
                 u'%s() got an unexpected keyword argument %r' % (
                     test.__name__,
                     extra_kwargs[0]
@@ -419,7 +423,7 @@
         if (
             len(generator_arguments) > len(original_argspec.args)
         ):
-            raise InvalidArgument((
+            return invalid((
                 u'Too many positional arguments for %s() (got %d but'
                 u' expected at most %d') % (
                     test.__name__, len(generator_arguments),
@@ -429,7 +433,7 @@
         seen_kwarg = None
         for a in arguments:
             if isinstance(a, list):  # pragma: no cover
-                raise InvalidArgument((
+                return invalid((
                     u'Cannot decorate function %s() because it has '
                     u'destructuring arguments') % (
                         test.__name__,
@@ -439,7 +443,7 @@
                 specifiers.append(generator_kwargs[a])
             else:
                 if seen_kwarg is not None:
-                    raise InvalidArgument((
+                    return invalid((
                         u'Argument %s comes after keyword %s which has been '
                         u'specified, but does not itself have a '
                         u'specification') % (
@@ -534,6 +538,7 @@
             )
 
             search_strategy = strategy(given_specifier, settings)
+            search_strategy.validate()
 
             if settings.database:
                 storage = settings.database.storage(
@@ -549,15 +554,12 @@
                 try:
                     test_runner(reify_and_execute(
                         search_strategy, xs, test,
-                        always_print=settings.max_shrinks <= 0,
                         record_repr=record_repr,
                     ))
                     return False
                 except UnsatisfiedAssumption as e:
                     raise e
                 except Exception as e:
-                    if settings.max_shrinks <= 0:
-                        raise e
                     last_exception[0] = traceback.format_exc()
                     repr_for_last_exception[0] = record_repr[0]
                     verbose_report(last_exception[0])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hypothesis-1.14.0/src/hypothesis/errors.py 
new/hypothesis-1.16.0/src/hypothesis/errors.py
--- old/hypothesis-1.14.0/src/hypothesis/errors.py      2015-11-01 
13:58:11.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis/errors.py      2015-12-08 
13:17:41.000000000 +0100
@@ -1,6 +1,3 @@
-from __future__ import division, print_function, absolute_import
-
-
 # coding=utf-8
 #
 # This file is part of Hypothesis (https://github.com/DRMacIver/hypothesis)
@@ -17,6 +14,9 @@
 #
 # END HEADER
 
+from __future__ import division, print_function, absolute_import
+
+
 class HypothesisException(Exception):
 
     """Generic parent class for exceptions thrown by Hypothesis."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hypothesis-1.14.0/src/hypothesis/extra/django/fixtures.py 
new/hypothesis-1.16.0/src/hypothesis/extra/django/fixtures.py
--- old/hypothesis-1.14.0/src/hypothesis/extra/django/fixtures.py       
2015-11-01 13:58:11.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis/extra/django/fixtures.py       
2015-12-08 13:50:10.000000000 +0100
@@ -19,6 +19,7 @@
 import weakref
 from random import Random
 
+import django
 from django.db import transaction
 from django.test.runner import setup_databases
 
@@ -90,10 +91,15 @@
                 max_parameter_tries=1
             )
         finally:
-            old_names, mirrors = old_config
+            if django.VERSION[:2] < (1, 9):
+                old_names, _ = old_config
+            else:
+                old_names = old_config
+
             for connection, old_name, destroy in old_names:
                 if destroy:
-                    connection.creation.destroy_test_db(old_name, verbosity)
+                    connection.creation.destroy_test_db(
+                        old_name, verbosity)
 
     def __call__(self):
         with BuildContext():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hypothesis-1.14.0/src/hypothesis/internal/charstree.py 
new/hypothesis-1.16.0/src/hypothesis/internal/charstree.py
--- old/hypothesis-1.14.0/src/hypothesis/internal/charstree.py  1970-01-01 
01:00:00.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis/internal/charstree.py  2015-12-08 
13:17:41.000000000 +0100
@@ -0,0 +1,310 @@
+# 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
+# ([email protected]), 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 sys
+import zlib
+import bisect
+import functools
+import itertools
+import unicodedata
+
+import marshal
+from hypothesis.errors import InvalidArgument
+from hypothesis.settings import hypothesis_home_dir
+from hypothesis.internal.compat import hrange, hunichr
+
+__all__ = (
+    'ascii_tree',
+    'unicode_tree',
+    'categories',
+    'category_by_codepoint',
+    'codepoints',
+    'codepoints_for_category',
+    'filter_tree',
+    'random_codepoint',
+)
+
+
+ASCII_TREE = {}
+UNICODE_TREE = {}
+
+
+def ascii_tree():
+    """Returns tree for ASCII characters."""
+    global ASCII_TREE
+    if not ASCII_TREE:
+        ASCII_TREE = filter_tree(unicode_tree(), max_codepoint=127)
+    return ASCII_TREE
+
+
+def unicode_tree():
+    """Returns tree of Unicode characters."""
+    global UNICODE_TREE
+    if not UNICODE_TREE:
+        try:
+            UNICODE_TREE = load_tree()
+        except:
+            UNICODE_TREE = make_tree()
+            try:
+                dump_tree(UNICODE_TREE)
+            except:  # pragma: no cover
+                pass
+    return UNICODE_TREE
+
+
+def categories(tree):
+    """Returns list of all categories in specified tree."""
+    return list(tree)
+
+
+def category_by_codepoint(tree, codepoint):
+    """Returns category by specified code point in the tree."""
+    categories = list(filter_tree(
+        tree, min_codepoint=codepoint, max_codepoint=codepoint))
+    if not categories:
+        return None
+    assert len(categories) == 1
+    return categories[0]
+
+
+def codepoints(tree):
+    """Iterates over all code points in specified tree.
+
+    Code points get yielded in single stream category by category.
+
+    """
+    by_category = functools.partial(codepoints_for_category, tree)
+    return itertools.chain.from_iterable(map(by_category, categories(tree)))
+
+
+def codepoints_for_category(tree, category):
+    """Iterates over all code points of the specified category in the tree."""
+    for value in iter_values(tree[category]):
+        for cp in hrange(value[0], value[1] + 1):
+            yield cp
+
+
+def random_codepoint(tree, category, random):
+    """Returns random code point for specified category in the tree."""
+    base, values = select_values(
+        tree, category, lambda ns: random.choice(list(ns)))
+    assert values, 'no values found'
+    value = random.choice(values)
+    if value[0] == value[1]:
+        return base + value[0]
+    return random.randint(base + value[0], base + value[1])
+
+
+def filter_tree(tree, whitelist_categories=None, blacklist_categories=None,
+                blacklist_characters=None, min_codepoint=0,
+                max_codepoint=sys.maxunicode):
+    """Filters tree by Unicode categories and code points range."""
+    if whitelist_categories and blacklist_categories:
+        raise InvalidArgument('cannot have both white and black list of'
+                              ' categories at the same time')
+
+    if min_codepoint > max_codepoint:
+        raise InvalidArgument('min code point is greater than max')
+
+    categories = set(tree)
+    if whitelist_categories:
+        categories &= set(whitelist_categories)
+    if blacklist_categories:
+        categories -= set(blacklist_categories)
+    if not blacklist_characters:
+        blacklist_characters = set([])
+
+    return do_filter_tree(tree, categories, blacklist_characters,
+                          min_codepoint, max_codepoint)
+
+
+def do_filter_tree(tree, categories, blacklist_characters,
+                   min_codepoint, max_codepoint):
+    new_tree = {}
+    for key, subtree in tree.items():
+        if key not in categories:
+            continue
+
+        subtree = do_filter_tree_by_codepoints(
+            subtree, min_codepoint, max_codepoint, {}, 0)
+
+        if not subtree:
+            continue
+
+        subtree = do_filter_tree_by_characters(
+            subtree, sorted(blacklist_characters), {}, 0)
+
+        if not subtree:
+            continue
+
+        new_tree[key] = subtree
+
+    return new_tree
+
+
+def do_filter_tree_by_codepoints(tree, min_codepoint, max_codepoint,
+                                 acc, base):
+    for key, value in tree.items():
+        this_base = base + key
+
+        if this_base > max_codepoint:
+            continue
+
+        if isinstance(value, dict):
+            subtree = do_filter_tree_by_codepoints(
+                value, min_codepoint, max_codepoint, {}, this_base)
+            if subtree:
+                acc[key] = subtree
+
+        else:
+            filtered_items = []
+
+            for item in value:
+                if item[0] + this_base > max_codepoint:
+                    continue
+                if item[1] + this_base < min_codepoint:
+                    continue
+                if item[0] + this_base < min_codepoint:
+                    item = (min_codepoint - this_base, item[1])
+                if item[1] + this_base > max_codepoint:
+                    item = (item[0], max_codepoint - this_base)
+                filtered_items.append(item)
+
+            if filtered_items:
+                acc[key] = tuple(filtered_items)
+
+    return acc
+
+
+def do_filter_tree_by_characters(tree, blacklist_characters, acc, base):
+    if not blacklist_characters:
+        return tree
+
+    for key, value in tree.items():
+        this_base = base + key
+
+        index = bisect.bisect(blacklist_characters, hunichr(this_base))
+        characters = blacklist_characters[index - 1 if index else 0:]
+
+        if isinstance(value, dict):
+            subtree = do_filter_tree_by_characters(
+                value, characters, {}, this_base)
+            if subtree:
+                acc[key] = subtree
+        else:
+            filtered_value = value
+            for character in characters:
+                codepoint = ord(character)
+                value_acc = []
+                for item in filtered_value:
+                    locp, hicp = item[0] + this_base, item[1] + this_base
+                    if locp == codepoint == hicp:
+                        continue
+                    elif not (locp <= codepoint <= hicp):
+                        value_acc.append(item)
+                    elif locp == codepoint:
+                        item = (codepoint + 1 - this_base, item[1])
+                        value_acc.append(item)
+                    elif hicp == codepoint:
+                        item = (item[0], codepoint - 1 - this_base)
+                        value_acc.append(item)
+                    else:
+                        value_acc.append((item[0], codepoint - 1 - this_base))
+                        value_acc.append((codepoint + 1 - this_base, item[1]))
+                filtered_value = value_acc
+            if filtered_value:
+                acc[key] = tuple(filtered_value)
+    return acc
+
+
+def select_values(tree, category, selector):
+    if category not in tree:
+        return 0, []
+    base = 0
+    namespace = tree[category]
+    while True:
+        key = selector(namespace)
+        namespace = namespace[key]
+        base += key
+        if isinstance(namespace, dict):
+            continue
+        return base, namespace
+
+
+def iter_values(namespace, base=0):
+    if isinstance(namespace, dict):
+        for key in namespace:
+            for value in iter_values(namespace[key], base + key):
+                yield value
+    else:
+        for value in namespace:
+            yield (base + value[0], base + value[1])
+
+
+def make_tree():
+    def new_tree():
+        tree = {}
+        for codepoint in hrange(0, sys.maxunicode + 1):
+            cat = unicodedata.category(hunichr(codepoint))
+            target = tree.setdefault(cat, [])
+            if target and codepoint == target[-1][-1] + 1:
+                target[-1][-1] += 1
+            else:
+                target.append([codepoint, codepoint])
+        return tree
+
+    def fold(tree, factor):
+        for key, values in tree.items():
+            if isinstance(values, dict):
+                fold(values, factor)
+            else:
+                tree[key] = fold_values(values, factor)
+
+    def fold_values(values, factor):
+        group = {}
+        by_factor = lambda i: i[0] & factor
+        for ns, items in itertools.groupby(values, key=by_factor):
+            namespace = group.setdefault(ns, [])
+            namespace.extend([[i[0] - ns, i[1] - ns] for i in items])
+        return group
+
+    tree = new_tree()
+    # Multi folding optimizes file size ~10-15% and improves algorithmic cost
+    # of code point lookup
+    fold(tree, 0xfff000)
+    fold(tree, 0xffff00)
+    fold(tree, 0xfffff0)
+    return tree
+
+
+def cache_file_path():
+    return os.path.join(hypothesis_home_dir(),
+                        os.path.basename(__file__) + '.cache')
+
+
+def dump_tree(tree):  # pragma: no cover
+    dump = marshal.dumps(tree, version=2)
+    with open(cache_file_path(), 'wb') as f:
+        f.write(zlib.compress(dump))
+
+
+def load_tree():  # pragma: no cover
+    with open(cache_file_path(), 'rb') as f:
+        dump = zlib.decompress(f.read())
+    return marshal.loads(dump)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hypothesis-1.14.0/src/hypothesis/internal/compat.py 
new/hypothesis-1.16.0/src/hypothesis/internal/compat.py
--- old/hypothesis-1.14.0/src/hypothesis/internal/compat.py     2015-11-01 
13:58:11.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis/internal/compat.py     2015-12-08 
13:50:10.000000000 +0100
@@ -88,6 +88,10 @@
 
     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)
 else:
     VALID_PYTHON_IDENTIFIER = re.compile(
         r"^[a-zA-Z_][a-zA-Z0-9_]*$"
@@ -152,6 +156,9 @@
     def escape_unicode_characters(s):
         return codecs.encode(s, 'string_escape')
 
+    def quiet_raise(exc):
+        raise exc
+
 
 def a_good_encoding():
     result = sys.getdefaultencoding()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hypothesis-1.14.0/src/hypothesis/internal/compat3.py 
new/hypothesis-1.16.0/src/hypothesis/internal/compat3.py
--- old/hypothesis-1.14.0/src/hypothesis/internal/compat3.py    1970-01-01 
01:00:00.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis/internal/compat3.py    2015-12-08 
13:50:10.000000000 +0100
@@ -0,0 +1,23 @@
+# 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
+# ([email protected]), 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hypothesis-1.14.0/src/hypothesis/internal/examplesource.py 
new/hypothesis-1.16.0/src/hypothesis/internal/examplesource.py
--- old/hypothesis-1.14.0/src/hypothesis/internal/examplesource.py      
2015-11-01 13:58:11.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis/internal/examplesource.py      
2015-12-08 13:17:41.000000000 +0100
@@ -1,6 +1,3 @@
-from __future__ import division, print_function, absolute_import
-
-
 # coding=utf-8
 #
 # This file is part of Hypothesis (https://github.com/DRMacIver/hypothesis)
@@ -17,6 +14,9 @@
 #
 # END HEADER
 
+from __future__ import division, print_function, absolute_import
+
+
 class ParameterSource(object):
 
     """An object that provides you with an a stream of parameters to work with.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hypothesis-1.14.0/src/hypothesis/internal/reflection.py 
new/hypothesis-1.16.0/src/hypothesis/internal/reflection.py
--- old/hypothesis-1.14.0/src/hypothesis/internal/reflection.py 2015-11-01 
13:58:11.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis/internal/reflection.py 2015-12-08 
13:50:10.000000000 +0100
@@ -305,8 +305,9 @@
         return unicode_safe_repr(v)
 
 
-def arg_string(f, args, kwargs):
-    args, kwargs = convert_positional_arguments(f, args, kwargs)
+def arg_string(f, args, kwargs, reorder=True):
+    if reorder:
+        args, kwargs = convert_positional_arguments(f, args, kwargs)
 
     argspec = getargspec(f)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hypothesis-1.14.0/src/hypothesis/internal/strategymethod.py 
new/hypothesis-1.16.0/src/hypothesis/internal/strategymethod.py
--- old/hypothesis-1.14.0/src/hypothesis/internal/strategymethod.py     
2015-11-01 13:58:11.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis/internal/strategymethod.py     
2015-12-08 13:50:10.000000000 +0100
@@ -17,6 +17,7 @@
 from __future__ import division, print_function, absolute_import
 
 from hypothesis.settings import Settings, note_deprecation
+from hypothesis.internal.compat import quiet_raise
 from hypothesis.utils.extmethod import ExtMethod
 
 
@@ -191,7 +192,15 @@
         if settings is None:
             settings = Settings()
 
-        result = super(StrategyExtMethod, self).__call__(specifier, settings)
+        try:
+            result = super(StrategyExtMethod, self).__call__(
+                specifier, settings)
+        except NotImplementedError:
+            quiet_raise(NotImplementedError((
+                'Expected a SearchStrategy but got %r of type %s. '
+                'Note: This is a NotImplementedError for legacy reasons and '
+                'will become an InvalidArgumentError in Hypothesis 2.0.'
+            ) % (specifier, type(specifier).__name__)))
         note_deprecation((
             'Conversion of %r to strategy is deprecated '
             'and will be removed in Hypothesis 2.0. Use %r instead.') % (
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hypothesis-1.14.0/src/hypothesis/searchstrategy/collections.py 
new/hypothesis-1.16.0/src/hypothesis/searchstrategy/collections.py
--- old/hypothesis-1.14.0/src/hypothesis/searchstrategy/collections.py  
2015-11-01 13:58:11.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis/searchstrategy/collections.py  
2015-12-08 13:50:10.000000000 +0100
@@ -59,6 +59,10 @@
             self.template_upper_bound = safe_mul(
                 e.template_upper_bound, self.template_upper_bound)
 
+    def validate(self):
+        for s in self.element_strategies:
+            s.validate()
+
     def reify(self, value):
         return self.newtuple([
             e.reify(v) for e, v in zip(self.element_strategies, value)
@@ -169,6 +173,10 @@
             self.element_strategy = None
             self.template_upper_bound = 1
 
+    def validate(self):
+        if self.element_strategy is not None:
+            self.element_strategy.validate()
+
     def reify(self, value):
         if self.element_strategy is not None:
             return list(map(self.element_strategy.reify, value))
@@ -538,6 +546,9 @@
         self.elements = elements
         self.key = key
 
+    def validate(self):
+        self.elements.validate()
+
     Parameter = namedtuple(
         u'Parameter', (u'parameter_seed', u'parameter')
     )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hypothesis-1.14.0/src/hypothesis/searchstrategy/deferred.py 
new/hypothesis-1.16.0/src/hypothesis/searchstrategy/deferred.py
--- old/hypothesis-1.14.0/src/hypothesis/searchstrategy/deferred.py     
1970-01-01 01:00:00.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis/searchstrategy/deferred.py     
2015-12-08 13:50:10.000000000 +0100
@@ -0,0 +1,127 @@
+# 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
+# ([email protected]), 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
+
+from hypothesis.internal.compat import hrange, getargspec, \
+    unicode_safe_repr
+from hypothesis.internal.reflection import arg_string, \
+    convert_keyword_arguments, convert_positional_arguments
+from hypothesis.searchstrategy.strategies import SearchStrategy
+
+
+class reprmangledtuple(tuple):
+
+    def __repr__(self):
+        try:
+            return super(reprmangledtuple, self).__repr__()
+        except UnicodeEncodeError:  # pragma: no cover
+            if len(self) == 1:
+                return u"(%s,)" % (unicode_safe_repr(self[0]),)
+            else:
+                return u"(%s)" % (u", ".join(
+                    map(unicode_safe_repr, self)
+                ))
+
+
+def tupleize(x):
+    if isinstance(x, (tuple, list)):
+        return reprmangledtuple(x)
+    else:
+        return x
+
+
+class DeferredStrategy(SearchStrategy):
+
+    """A strategy which is defined purely by conversion to and from another
+    strategy.
+
+    Its parameter and distribution come from that other strategy.
+
+    """
+
+    def __init__(self, function, args, kwargs):
+        SearchStrategy.__init__(self)
+        self.__wrapped_strategy = None
+        self.__representation = None
+        self.__function = function
+        self.__args = tuple(map(tupleize, args))
+        self.__kwargs = dict(
+            (k, tupleize(v)) for k, v in kwargs.items()
+        )
+
+    @property
+    def wrapped_strategy(self):
+        if self.__wrapped_strategy is None:
+            self.__wrapped_strategy = self.__function(
+                *self.__args,
+                **self.__kwargs
+            )
+        return self.__wrapped_strategy
+
+    def validate(self):
+        self.wrapped_strategy.validate()
+
+    @property
+    def template_upper_bound(self):
+        return self.wrapped_strategy.template_upper_bound
+
+    def __repr__(self):
+        if self.__representation is None:
+            _args = self.__args
+            _kwargs = self.__kwargs
+            argspec = getargspec(self.__function)
+            defaults = {}
+            if argspec.defaults is not None:
+                for k in hrange(1, len(argspec.defaults) + 1):
+                    defaults[argspec.args[-k]] = argspec.defaults[-k]
+            if len(argspec.args) > 1 or argspec.defaults:
+                _args, _kwargs = convert_positional_arguments(
+                    self.__function, _args, _kwargs)
+            else:
+                _args, _kwargs = convert_keyword_arguments(
+                    self.__function, _args, _kwargs)
+            kwargs_for_repr = dict(_kwargs)
+            for k, v in defaults.items():
+                if k in kwargs_for_repr and kwargs_for_repr[k] is defaults[k]:
+                    del kwargs_for_repr[k]
+            self.__representation = u'%s(%s)' % (
+                self.__function.__name__,
+                arg_string(
+                    self.__function, _args, kwargs_for_repr, reorder=False),
+            )
+        return self.__representation
+
+    def draw_parameter(self, random):
+        return self.wrapped_strategy.draw_parameter(random)
+
+    def draw_template(self, random, pv):
+        return self.wrapped_strategy.draw_template(random, pv)
+
+    def reify(self, value):
+        return self.wrapped_strategy.reify(value)
+
+    def simplifiers(self, random, template):
+        return self.wrapped_strategy.simplifiers(random, template)
+
+    def strictly_simpler(self, x, y):
+        return self.wrapped_strategy.strictly_simpler(x, y)
+
+    def to_basic(self, template):
+        return self.wrapped_strategy.to_basic(template)
+
+    def from_basic(self, data):
+        return self.wrapped_strategy.from_basic(data)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hypothesis-1.14.0/src/hypothesis/searchstrategy/strategies.py 
new/hypothesis-1.16.0/src/hypothesis/searchstrategy/strategies.py
--- old/hypothesis-1.14.0/src/hypothesis/searchstrategy/strategies.py   
2015-11-01 13:58:11.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis/searchstrategy/strategies.py   
2015-12-08 13:50:10.000000000 +0100
@@ -215,6 +215,14 @@
             raise ValueError(u'Cannot | a SearchStrategy with %r' % (other,))
         return one_of_strategies((self, other))
 
+    def validate(self):
+        """Through an exception if the strategy is not valid.
+
+        This can happen due to lazy construction
+
+        """
+        pass
+
     # HERE BE DRAGONS. All below is non-public API of varying degrees of
     # stability.
 
@@ -413,6 +421,10 @@
     def __repr__(self):
         return u' | '.join(map(repr, self.element_strategies))
 
+    def validate(self):
+        for e in self.element_strategies:
+            e.validate()
+
     def strictly_simpler(self, x, y):
         lx, vx = x
         ly, vy = y
@@ -529,6 +541,9 @@
             )
         return self._cached_repr
 
+    def validate(self):
+        self.mapped_strategy.validate()
+
     def draw_parameter(self, random):
         return self.mapped_strategy.draw_parameter(random)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hypothesis-1.14.0/src/hypothesis/searchstrategy/strings.py 
new/hypothesis-1.16.0/src/hypothesis/searchstrategy/strings.py
--- old/hypothesis-1.14.0/src/hypothesis/searchstrategy/strings.py      
2015-11-01 13:58:11.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis/searchstrategy/strings.py      
2015-12-08 13:17:41.000000000 +0100
@@ -20,61 +20,110 @@
 import unicodedata
 
 import hypothesis.internal.distributions as dist
-from hypothesis.internal.compat import hrange, hunichr, text_type, \
-    binary_type
+from hypothesis.errors import InvalidArgument
+from hypothesis.internal import charstree
+from hypothesis.internal.compat import hunichr, text_type, binary_type
 from hypothesis.searchstrategy.strategies import check_length, \
     SearchStrategy, check_data_type, MappedSearchStrategy
 
-_spaces = [
-    i for i in [
-        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
-        20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 127, 128, 129, 130,
-        131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
-        145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158,
-        159, 160, 5760, 8192, 8193, 8194, 8195, 8196, 8197, 8198, 8199, 8200,
-        8201, 8202, 8239, 8287, 12288] if i <= sys.maxunicode]
-
 
 class OneCharStringStrategy(SearchStrategy):
 
     """A strategy which generates single character strings of text type."""
     specifier = text_type
-    ascii_characters = u''.join(
-        chr(i) for i in hrange(128)
-    )
     zero_point = ord(u'0')
 
+    def __init__(self,
+                 whitelist_categories=None,
+                 blacklist_categories=None,
+                 blacklist_characters=None,
+                 min_codepoint=None,
+                 max_codepoint=None):
+        whitelist_categories = set(whitelist_categories or [])
+        blacklist_categories = set(blacklist_categories or [])
+        blacklist_characters = set(blacklist_characters or [])
+
+        min_codepoint = int(min_codepoint or 0)
+        max_codepoint = int(max_codepoint or sys.maxunicode)
+
+        self.ascii_tree = charstree.filter_tree(
+            charstree.ascii_tree(),
+            whitelist_categories,
+            blacklist_categories,
+            blacklist_characters,
+            min_codepoint,
+            max_codepoint,
+        )
+        self.unicode_tree = charstree.filter_tree(
+            charstree.unicode_tree(),
+            whitelist_categories,
+            blacklist_categories,
+            blacklist_characters,
+            min_codepoint,
+            max_codepoint,
+        )
+        self.spaces_tree = charstree.filter_tree(
+            self.unicode_tree,
+            whitelist_categories=set(['Zs', 'Cc']),
+            blacklist_characters=blacklist_characters,
+            min_codepoint=min_codepoint,
+            max_codepoint=max_codepoint,
+        )
+        self.blacklist_characters = blacklist_characters
+        self.min_codepoint = min_codepoint
+        self.max_codepoint = max_codepoint
+        if not self.unicode_tree:
+            raise InvalidArgument('No characters could be produced.'
+                                  ' Try to reduce white/black categories list'
+                                  ' or min/max allowed code points.')
+
     def draw_parameter(self, random):
+        ascii_categories = charstree.categories(self.ascii_tree)
+        unicode_categories = charstree.categories(self.unicode_tree)
+        spaces_categories = charstree.categories(self.spaces_tree)
+
         alphabet_size = 1 + dist.geometric(random, 0.1)
         alphabet = []
         buckets = 10
         ascii_chance = random.randint(1, buckets)
-        if ascii_chance < buckets:
+
+        if spaces_categories and ascii_chance < buckets:
             space_chance = random.randint(1, buckets - ascii_chance)
         else:
             space_chance = 0
+
         while len(alphabet) < alphabet_size:
             choice = random.randint(1, buckets)
-            if choice <= ascii_chance:
-                codepoint = dist.geometric(random, 1.0 / 127)
-            elif choice <= ascii_chance + space_chance:
-                while True:
-                    i = dist.geometric(random, 2 / len(_spaces))
-                    if i < len(_spaces):
-                        codepoint = _spaces[i]
-                        break
+
+            if ascii_categories and choice <= ascii_chance:
+                category = random.choice(ascii_categories)
+                tree = self.ascii_tree
+            elif spaces_categories and choice <= ascii_chance + space_chance:
+                category = random.choice(spaces_categories)
+                tree = self.spaces_tree
             else:
-                codepoint = random.randint(0, sys.maxunicode)
+                category = random.choice(unicode_categories)
+                tree = self.unicode_tree
+
+            codepoint = charstree.random_codepoint(tree, category, random)
+            alphabet.append(hunichr(codepoint))
+
+        if u'\n' not in alphabet and not random.randint(0, 6):
+            if self.is_good(u'\n'):
+                alphabet.append(u'\n')
 
-            char = hunichr(codepoint)
-            if self.is_good(char):
-                alphabet.append(char)
-        if u'\n' not in alphabet and not random.randint(0, 10):
-            alphabet.append(u'\n')
         return tuple(alphabet)
 
     def is_good(self, char):
-        return unicodedata.category(char) != u'Cs'
+        if char in self.blacklist_characters:
+            return False
+
+        categories = charstree.categories(self.unicode_tree)
+        if unicodedata.category(char) not in categories:
+            return False
+
+        codepoint = ord(char)
+        return self.min_codepoint <= codepoint <= self.max_codepoint
 
     def draw_template(self, random, p):
         return random.choice(p)
@@ -114,16 +163,26 @@
         return accept
 
     def try_ascii(self, random, template):
-        if template < u'0':
-            for i in hrange(ord(template) + 1, self.zero_point + 1):
-                yield hunichr(i)
-
-        for i in self.ascii_characters:
-            if i < u'0':
-                continue
-            if i >= template:
-                break
-            yield i
+        tree = self.ascii_tree
+
+        if not tree:
+            return
+
+        zero_point = self.zero_point
+        template = ord(template)
+
+        if template < zero_point:
+            min_codepoint, max_codepoint = template, zero_point
+        elif template > zero_point:
+            min_codepoint, max_codepoint = zero_point, template
+        else:
+            return
+
+        subtree = charstree.filter_tree(
+            tree, min_codepoint=min_codepoint, max_codepoint=max_codepoint)
+
+        for codepoint in charstree.codepoints(subtree):
+            yield hunichr(codepoint)
 
     def to_basic(self, template):
         return template
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hypothesis-1.14.0/src/hypothesis/searchstrategy/wrappers.py 
new/hypothesis-1.16.0/src/hypothesis/searchstrategy/wrappers.py
--- old/hypothesis-1.14.0/src/hypothesis/searchstrategy/wrappers.py     
2015-11-01 13:58:11.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis/searchstrategy/wrappers.py     
2015-12-08 13:50:10.000000000 +0100
@@ -36,6 +36,9 @@
     def __repr__(self):
         return u'%s(%r)' % (type(self).__name__, self.wrapped_strategy)
 
+    def validate(self):
+        self.wrapped_strategy.validate()
+
     def draw_parameter(self, random):
         return self.wrapped_strategy.draw_parameter(random)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hypothesis-1.14.0/src/hypothesis/settings.py 
new/hypothesis-1.16.0/src/hypothesis/settings.py
--- old/hypothesis-1.14.0/src/hypothesis/settings.py    2015-11-01 
13:58:11.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis/settings.py    2015-12-08 
13:17:41.000000000 +0100
@@ -388,7 +388,7 @@
     u'timeout',
     default=60,
     description="""
-Once this amount of time has passed, falsify will terminate even
+Once this many seconds have passed, falsify will terminate even
 if it has not found many examples. This is a soft rather than a hard
 limit - Hypothesis won't e.g. interrupt execution of the called
 function to stop it. If this value is <= 0 then no timeout will be
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hypothesis-1.14.0/src/hypothesis/stateful.py 
new/hypothesis-1.16.0/src/hypothesis/stateful.py
--- old/hypothesis-1.14.0/src/hypothesis/stateful.py    2015-11-01 
14:04:01.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis/stateful.py    2015-12-08 
13:17:41.000000000 +0100
@@ -36,9 +36,10 @@
 from hypothesis.errors import Flaky, NoSuchExample, InvalidDefinition, \
     UnsatisfiedAssumption
 from hypothesis.control import BuildContext
-from hypothesis.settings import Settings, Verbosity
+from hypothesis.settings import Settings, Verbosity, note_deprecation
 from hypothesis.reporting import report, verbose_report, current_verbosity
 from hypothesis.internal.compat import hrange, integer_types
+from hypothesis.internal.reflection import proxies
 from hypothesis.searchstrategy.misc import JustStrategy, \
     SampledFromStrategy
 from hypothesis.internal.strategymethod import strategy
@@ -141,7 +142,7 @@
 
     def execute_step(self, step):
         """Execute a step that has been previously drawn from self.steps()"""
-        raise NotImplementedError(u'%r.execute_steps()' % (self,))
+        raise NotImplementedError(u'%r.execute_step()' % (self,))
 
     def print_step(self, step):
         """Print a step to the current reporter.
@@ -498,7 +499,8 @@
 
 Rule = namedtuple(
     u'Rule',
-    (u'targets', u'function', u'arguments')
+    (u'targets', u'function', u'arguments', u'precondition',
+     u'parent_rule')
 
 )
 
@@ -506,6 +508,7 @@
 
 
 RULE_MARKER = u'hypothesis_stateful_rule'
+PRECONDITION_MARKER = u'hypothesis_stateful_precondition'
 
 
 def rule(targets=(), target=None, **kwargs):
@@ -531,20 +534,69 @@
         converted_targets.append(t)
 
     def accept(f):
-        if not hasattr(f, RULE_MARKER):
-            setattr(f, RULE_MARKER, [])
-        getattr(f, RULE_MARKER).append(
-            Rule(
-                targets=tuple(converted_targets), arguments=kwargs, function=f
+        parent_rule = getattr(f, RULE_MARKER, None)
+        if parent_rule is not None:
+            note_deprecation(
+                'Applying the rule decorator to a function that is already '
+                'decorated by rule is deprecated. Please assign the result '
+                'of the rule function to separate names in your class.',
+                Settings.default,
             )
-        )
-        return f
+        precondition = getattr(f, PRECONDITION_MARKER, None)
+        rule = Rule(targets=tuple(converted_targets), arguments=kwargs,
+                    function=f, precondition=precondition,
+                    parent_rule=parent_rule)
+
+        @proxies(f)
+        def rule_wrapper(*args, **kwargs):
+            return f(*args, **kwargs)
+
+        setattr(rule_wrapper, RULE_MARKER, rule)
+        return rule_wrapper
     return accept
 
 
 VarReference = namedtuple(u'VarReference', (u'name',))
 
 
+def precondition(precond):
+    """Decorator to apply a precondition for rules in a RuleBasedStateMachine.
+    Specifies a precondition for a rule to be considered as a valid step in the
+    state machine. The given function will be called with the instance of
+    RuleBasedStateMachine and should return True or False. Usually it will need
+    to look at attributes on that instance.
+
+    For example::
+
+        class MyTestMachine(RuleBasedStateMachine):
+            state = 1
+
+            @precondition(lambda self: self.state != 0)
+            @rule(numerator=integers())
+            def divide_with(self, numerator):
+                self.state = numerator / self.state
+
+    This is better than using assume in your rule since more valid rules
+    should be able to be run.
+
+    """
+    def decorator(f):
+        @proxies(f)
+        def precondition_wrapper(*args, **kwargs):
+            return f(*args, **kwargs)
+
+        rule = getattr(f, RULE_MARKER, None)
+        if rule is None:
+            setattr(precondition_wrapper, PRECONDITION_MARKER, precond)
+        else:
+            new_rule = Rule(targets=rule.targets, arguments=rule.arguments,
+                            function=rule.function, precondition=precond,
+                            parent_rule=rule.parent_rule)
+            setattr(precondition_wrapper, RULE_MARKER, new_rule)
+        return precondition_wrapper
+    return decorator
+
+
 class SimpleSampledFromStrategy(SampledFromStrategy):
 
     def draw_parameter(self, random):
@@ -603,15 +655,19 @@
             pass
 
         for k, v in inspect.getmembers(cls):
-            for r in getattr(v, RULE_MARKER, ()):
+            r = getattr(v, RULE_MARKER, None)
+            while r is not None:
                 cls.define_rule(
-                    r.targets, r.function, r.arguments
+                    r.targets, r.function, r.arguments, r.precondition,
+                    r.parent_rule
                 )
+                r = r.parent_rule
         cls._rules_per_class[cls] = cls._base_rules_per_class.pop(cls, [])
         return cls._rules_per_class[cls]
 
     @classmethod
-    def define_rule(cls, targets, function, arguments):
+    def define_rule(cls, targets, function, arguments, precondition=None,
+                    parent_rule=None):
         converted_arguments = {}
         for k, v in arguments.items():
             if not isinstance(v, Bundle):
@@ -623,7 +679,10 @@
             target = cls._base_rules_per_class.setdefault(cls, [])
 
         return target.append(
-            Rule(targets, function, converted_arguments)
+            Rule(
+                targets, function, converted_arguments, precondition,
+                parent_rule
+            )
         )
 
     def steps(self):
@@ -631,6 +690,8 @@
         for rule in self.rules():
             converted_arguments = {}
             valid = True
+            if rule.precondition is not None and not rule.precondition(self):
+                continue
             for k, v in rule.arguments.items():
                 if isinstance(v, Bundle):
                     bundle = self.bundle(v.name)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hypothesis-1.14.0/src/hypothesis/strategies.py 
new/hypothesis-1.16.0/src/hypothesis/strategies.py
--- old/hypothesis-1.14.0/src/hypothesis/strategies.py  2015-11-01 
15:01:37.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis/strategies.py  2015-12-08 
13:50:10.000000000 +0100
@@ -24,17 +24,17 @@
 from hypothesis.control import assume
 from hypothesis.settings import Settings
 from hypothesis.searchstrategy import SearchStrategy
-from hypothesis.internal.compat import hrange, ArgSpec, text_type, \
-    getargspec, integer_types, float_to_decimal, unicode_safe_repr
+from hypothesis.internal.compat import ArgSpec, text_type, getargspec, \
+    integer_types, float_to_decimal, unicode_safe_repr
 from hypothesis.searchstrategy.reprwrapper import ReprWrapperStrategy
 
 __all__ = [
     'just', 'one_of',
     'none',
-
+    'choices',
     'booleans', 'integers', 'floats', 'complex_numbers', 'fractions',
     'decimals',
-    'text', 'binary',
+    'characters', 'text', 'binary',
     'tuples', 'lists', 'sets', 'frozensets',
     'dictionaries', 'fixed_dictionaries',
     'sampled_from',
@@ -45,32 +45,12 @@
 
 
 def defines_strategy(strategy_definition):
-    from hypothesis.internal.reflection import proxies, arg_string, \
-        convert_positional_arguments
-    argspec = getargspec(strategy_definition)
-    defaults = {}
-    if argspec.defaults is not None:
-        for k in hrange(1, len(argspec.defaults) + 1):
-            defaults[argspec.args[-k]] = argspec.defaults[-k]
+    from hypothesis.internal.reflection import proxies
+    from hypothesis.searchstrategy.deferred import DeferredStrategy
 
     @proxies(strategy_definition)
     def accept(*args, **kwargs):
-        result = strategy_definition(*args, **kwargs)
-
-        def calc_repr():
-            _args = args
-            _kwargs = kwargs
-            _args, _kwargs = convert_positional_arguments(
-                strategy_definition, _args, _kwargs)
-            kwargs_for_repr = dict(_kwargs)
-            for k, v in defaults.items():
-                if k in kwargs_for_repr and kwargs_for_repr[k] is defaults[k]:
-                    del kwargs_for_repr[k]
-            return u'%s(%s)' % (
-                strategy_definition.__name__,
-                arg_string(strategy_definition, _args, kwargs_for_repr)
-            )
-        return ReprWrapperStrategy(result, calc_repr)
+        return DeferredStrategy(strategy_definition, args, kwargs)
     return accept
 
 
@@ -307,6 +287,7 @@
     return TupleStrategy(args, tuple)
 
 
+@defines_strategy
 def sampled_from(elements):
     """Returns a strategy which generates any value present in the iterable
     elements.
@@ -324,17 +305,9 @@
             u'sampled_from requires at least one value'
         )
     if len(elements) == 1:
-        result = JustStrategy(elements[0])
+        return JustStrategy(elements[0])
     else:
-        result = SampledFromStrategy(elements)
-
-    def calc_repr():
-        return u'sampled_from((%s%s))' % (
-            u', '.join(map(unicode_safe_repr, elements)),
-            ',' if len(elements) == 1 else '',
-        )
-
-    return ReprWrapperStrategy(result, calc_repr)
+        return SampledFromStrategy(elements)
 
 
 @defines_strategy
@@ -532,6 +505,32 @@
 
 
 @defines_strategy
+def characters(whitelist_categories=None, blacklist_categories=None,
+               blacklist_characters=None, min_codepoint=None,
+               max_codepoint=None):
+    """Generates unicode text type (unicode on python 2, str on python 3)
+    characters following specified filtering rules.
+
+    This strategy accepts lists of Unicode categories, characters of which
+    should (`whitelist_categories`) or should not (`blacklist_categories`)
+    be produced.
+
+    Also there could be applied limitation by minimal and maximal produced
+    code point of the characters.
+
+    If you know what exactly characters you don't want to be produced,
+    pass them with `blacklist_characters` argument.
+
+    """
+    from hypothesis.searchstrategy.strings import OneCharStringStrategy
+    return OneCharStringStrategy(whitelist_categories=whitelist_categories,
+                                 blacklist_categories=blacklist_categories,
+                                 blacklist_characters=blacklist_characters,
+                                 min_codepoint=min_codepoint,
+                                 max_codepoint=max_codepoint)
+
+
+@defines_strategy
 def text(
     alphabet=None,
     min_size=None, average_size=None, max_size=None
@@ -548,7 +547,7 @@
     from hypothesis.searchstrategy.strings import OneCharStringStrategy, \
         StringStrategy
     if alphabet is None:
-        char_strategy = OneCharStringStrategy()
+        char_strategy = OneCharStringStrategy(blacklist_categories=['Cs'])
     elif not alphabet:
         if (min_size or 0) > 0:
             raise InvalidArgument(
@@ -674,8 +673,10 @@
 @defines_strategy
 def recursive(base, extend, max_leaves=100):
     """
-    base: A strategy to start from
-    extend: A function which takes a strategy and returns a new strategy
+    base: A strategy to start from.
+
+    extend: A function which takes a strategy and returns a new strategy.
+
     max_leaves: The maximum number of elements to be drawn from base on a given
     run.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hypothesis-1.14.0/src/hypothesis/utils/conventions.py 
new/hypothesis-1.16.0/src/hypothesis/utils/conventions.py
--- old/hypothesis-1.14.0/src/hypothesis/utils/conventions.py   2015-11-01 
13:58:11.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis/utils/conventions.py   2015-12-08 
13:17:41.000000000 +0100
@@ -1,6 +1,3 @@
-from __future__ import division, print_function, absolute_import
-
-
 # coding=utf-8
 #
 # This file is part of Hypothesis (https://github.com/DRMacIver/hypothesis)
@@ -17,6 +14,9 @@
 #
 # END HEADER
 
+from __future__ import division, print_function, absolute_import
+
+
 class UniqueIdentifier(object):
 
     def __init__(self, identifier):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hypothesis-1.14.0/src/hypothesis/utils/idkey.py 
new/hypothesis-1.16.0/src/hypothesis/utils/idkey.py
--- old/hypothesis-1.14.0/src/hypothesis/utils/idkey.py 2015-11-01 
13:58:11.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis/utils/idkey.py 2015-12-08 
13:17:41.000000000 +0100
@@ -1,6 +1,3 @@
-from __future__ import division, print_function, absolute_import
-
-
 # coding=utf-8
 #
 # This file is part of Hypothesis (https://github.com/DRMacIver/hypothesis)
@@ -17,6 +14,9 @@
 #
 # END HEADER
 
+from __future__ import division, print_function, absolute_import
+
+
 class IdKey(object):
 
     def __repr__(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hypothesis-1.14.0/src/hypothesis/version.py 
new/hypothesis-1.16.0/src/hypothesis/version.py
--- old/hypothesis-1.14.0/src/hypothesis/version.py     2015-11-01 
15:01:24.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis/version.py     2015-12-08 
18:00:46.000000000 +0100
@@ -16,5 +16,5 @@
 
 from __future__ import division, print_function, absolute_import
 
-__version_info__ = (1, 14, 0)
+__version_info__ = (1, 16, 0)
 __version__ = u'.'.join(map(str, __version_info__))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hypothesis-1.14.0/src/hypothesis.egg-info/PKG-INFO 
new/hypothesis-1.16.0/src/hypothesis.egg-info/PKG-INFO
--- old/hypothesis-1.14.0/src/hypothesis.egg-info/PKG-INFO      2015-11-01 
15:01:58.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis.egg-info/PKG-INFO      2015-12-08 
19:06:20.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: hypothesis
-Version: 1.14.0
+Version: 1.16.0
 Summary: A library for property based testing
 Home-page: https://github.com/DRMacIver/hypothesis
 Author: David R. MacIver
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hypothesis-1.14.0/src/hypothesis.egg-info/SOURCES.txt 
new/hypothesis-1.16.0/src/hypothesis.egg-info/SOURCES.txt
--- old/hypothesis-1.14.0/src/hypothesis.egg-info/SOURCES.txt   2015-11-01 
15:01:59.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis.egg-info/SOURCES.txt   2015-12-08 
19:06:20.000000000 +0100
@@ -34,9 +34,11 @@
 src/hypothesis/extra/django/fixtures.py
 src/hypothesis/extra/django/models.py
 src/hypothesis/internal/__init__.py
+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
@@ -47,6 +49,7 @@
 src/hypothesis/searchstrategy/__init__.py
 src/hypothesis/searchstrategy/basic.py
 src/hypothesis/searchstrategy/collections.py
+src/hypothesis/searchstrategy/deferred.py
 src/hypothesis/searchstrategy/flatmapped.py
 src/hypothesis/searchstrategy/misc.py
 src/hypothesis/searchstrategy/morphers.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hypothesis-1.14.0/src/hypothesis.egg-info/not-zip-safe 
new/hypothesis-1.16.0/src/hypothesis.egg-info/not-zip-safe
--- old/hypothesis-1.14.0/src/hypothesis.egg-info/not-zip-safe  2015-10-07 
10:09:31.000000000 +0200
+++ new/hypothesis-1.16.0/src/hypothesis.egg-info/not-zip-safe  2015-12-08 
19:06:20.000000000 +0100
@@ -0,0 +1 @@
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hypothesis-1.14.0/src/hypothesis.egg-info/requires.txt 
new/hypothesis-1.16.0/src/hypothesis.egg-info/requires.txt
--- old/hypothesis-1.14.0/src/hypothesis.egg-info/requires.txt  2015-11-01 
15:01:58.000000000 +0100
+++ new/hypothesis-1.16.0/src/hypothesis.egg-info/requires.txt  2015-12-08 
19:06:20.000000000 +0100
@@ -5,12 +5,12 @@
 Counter
 
 [all]
+pytz
+django>=1.7
 pytest>=2.7.0
+pytz
 numpy>=1.9.0
 fake-factory>=0.5.2,<=0.5.3
-pytz
-pytz
-django>=1.7
 
 [datetime]
 pytz


Reply via email to