Hello community,

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

Package is "python-hypothesis"

Fri Dec  8 21:47:50 2017 rev:13 rq:554735 version:3.40.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-hypothesis/python-hypothesis.changes      
2017-11-30 12:38:20.629292841 +0100
+++ /work/SRC/openSUSE:Factory/.python-hypothesis.new/python-hypothesis.changes 
2017-12-08 21:47:53.341776459 +0100
@@ -1,0 +2,57 @@
+Wed Dec  6 02:52:35 UTC 2017 - a...@gmx.de
+
+- update to version 3.40.1:
+
+3.40.1 - 2017-12-04
+  * This release makes two changes:
+    + It makes the calculation of some of the metadata that Hypothesis
+      uses for shrinking occur lazily. This should speed up
+      performance of test case generation a bit because it no longer
+      calculates information it doesn’t need.
+    + It improves the shrinker for certain classes of nested
+      examples. e.g. when shrinking lists of lists, the shrinker is
+      now able to concatenate two adjacent lists together into a
+      single list. As a result of this change, shrinking may get
+      somewhat slower when the minimal example found is large.
+
+- changes from version 3.40.0:
+  * This release improves how various ways of seeding Hypothesis
+    interact with the example database:
+    + Using the example database with seed() is now deprecated. You
+      should set database=None if you are doing that. This will only
+      warn if you actually load examples from the database while using
+      @seed.
+    + The derandomize will behave the same way as @seed.
+    + Using --hypothesis-seed will disable use of the database.
+    + If a test used examples from the database, it will not suggest
+      using a seed to reproduce it, because that won’t work.
+
+- changes from version 3.39.0:
+  * This release adds a new health check that checks if the smallest
+    “natural” possible example of your test case is very large - this
+    will tend to cause Hypothesis to generate bad examples and be
+    quite slow.
+
+- changes from version 3.38.9:
+  * This is a documentation release to improve the documentation of
+    shrinking behaviour for Hypothesis’s strategies.
+
+- changes from version 3.38.8:
+  * This release improves the performance of characters() when using
+    blacklist_characters and from_regex() when using negative
+    character classes.
+
+- changes from version 3.38.7:
+  * This is a patch release for from_regex(), which had a bug in
+    handling of the re.VERBOSE flag (issue #992). Flags are now
+    handled correctly when parsing regex.
+
+-------------------------------------------------------------------
+Tue Nov 28 19:04:24 UTC 2017 - a...@gmx.de
+
+- update to version 3.38.6:
+  * This patch changes a few byte-string literals from double to
+    single quotes, thanks to an update in unify. There are no
+    user-visible changes.
+
+-------------------------------------------------------------------

Old:
----
  hypothesis-3.38.5.tar.gz

New:
----
  hypothesis-3.40.1.tar.gz

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

Other differences:
------------------
++++++ python-hypothesis.spec ++++++
--- /var/tmp/diff_new_pack.OnGafi/_old  2017-12-08 21:47:54.421730003 +0100
+++ /var/tmp/diff_new_pack.OnGafi/_new  2017-12-08 21:47:54.425729832 +0100
@@ -24,7 +24,7 @@
 %endif
 %bcond_with test
 Name:           python-hypothesis
-Version:        3.38.5
+Version:        3.40.1
 Release:        0
 Summary:        A library for property based testing
 License:        MPL-2.0

++++++ hypothesis-3.38.5.tar.gz -> hypothesis-3.40.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hypothesis-3.38.5/PKG-INFO 
new/hypothesis-3.40.1/PKG-INFO
--- old/hypothesis-3.38.5/PKG-INFO      2017-11-23 20:40:32.000000000 +0100
+++ new/hypothesis-3.40.1/PKG-INFO      2017-12-04 10:02:53.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: hypothesis
-Version: 3.38.5
+Version: 3.40.1
 Summary: A library for property based testing
 Home-page: https://github.com/HypothesisWorks/hypothesis-python
 Author: David R. MacIver
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hypothesis-3.38.5/src/hypothesis/_settings.py 
new/hypothesis-3.40.1/src/hypothesis/_settings.py
--- old/hypothesis-3.38.5/src/hypothesis/_settings.py   2017-11-23 
20:40:05.000000000 +0100
+++ new/hypothesis-3.40.1/src/hypothesis/_settings.py   2017-12-04 
10:02:20.000000000 +0100
@@ -517,6 +517,9 @@
     hung_test = 6
     """Checks if your tests have been running for a very long time."""
 
+    large_base_example = 7
+    """Checks if the natural example to shrink towards is very large."""
+
 
 @unique
 class Statistics(IntEnum):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hypothesis-3.38.5/src/hypothesis/core.py 
new/hypothesis-3.40.1/src/hypothesis/core.py
--- old/hypothesis-3.38.5/src/hypothesis/core.py        2017-11-23 
20:40:05.000000000 +0100
+++ new/hypothesis-3.40.1/src/hypothesis/core.py        2017-12-04 
10:02:20.000000000 +0100
@@ -388,7 +388,9 @@
 
 class StateForActualGivenExecution(object):
 
-    def __init__(self, test_runner, search_strategy, test, settings, random):
+    def __init__(
+        self, test_runner, search_strategy, test, settings, random, had_seed
+    ):
         self.test_runner = test_runner
         self.search_strategy = search_strategy
         self.settings = settings
@@ -400,12 +402,15 @@
         self.__warned_deadline = False
         self.__existing_collector = None
         self.__test_runtime = None
+        self.__had_seed = had_seed
 
         self.test = test
 
         self.coverage_data = CoverageData()
         self.files_to_propagate = set()
 
+        self.used_examples_from_database = False
+
         if settings.use_coverage and not IN_COVERAGE_TESTS:  # pragma: no cover
             if Collector._collectors:
                 self.hijack_collector(Collector._collectors[-1])
@@ -625,7 +630,10 @@
     def run(self):
         # Tell pytest to omit the body of this function from tracebacks
         __tracebackhide__ = True
-        database_key = str_to_bytes(fully_qualified_name(self.test))
+        if global_force_seed is None:
+            database_key = str_to_bytes(fully_qualified_name(self.test))
+        else:
+            database_key = None
         self.start_time = time.time()
         global in_given
         runner = ConjectureRunner(
@@ -647,6 +655,25 @@
                 sys.settrace(original_trace)
         note_engine_for_statistics(runner)
         run_time = time.time() - self.start_time
+
+        self.used_examples_from_database = runner.used_examples_from_database
+
+        if runner.used_examples_from_database:
+            if self.settings.derandomize:
+                note_deprecation(
+                    'In future derandomize will imply database=None, but your '
+                    'test is currently using examples from the database. To '
+                    'get the future behaviour, update your settings to '
+                    'include database=None.'
+                )
+            if self.__had_seed:
+                note_deprecation(
+                    'In future use of @seed will imply database=None in your '
+                    'settings, but your test is currently using examples from '
+                    'the database. To get the future behaviour, update your '
+                    'settings for this test to include database=None.'
+                )
+
         timed_out = runner.exit_reason == ExitReason.timeout
         if runner.last_data is None:
             return
@@ -827,12 +854,17 @@
 
             try:
                 state = StateForActualGivenExecution(
-                    test_runner, search_strategy, test, settings, random)
+                    test_runner, search_strategy, test, settings, random,
+                    had_seed=wrapped_test._hypothesis_internal_use_seed
+                )
                 state.run()
             except BaseException:
                 generated_seed = \
                     wrapped_test._hypothesis_internal_use_generated_seed
-                if generated_seed is not None:
+                if (
+                    generated_seed is not None and
+                    not state.used_examples_from_database
+                ):
                     if running_under_pytest:
                         report((
                             'You can add @seed(%(seed)d) to this test or run '
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hypothesis-3.38.5/src/hypothesis/errors.py 
new/hypothesis-3.40.1/src/hypothesis/errors.py
--- old/hypothesis-3.38.5/src/hypothesis/errors.py      2017-11-23 
20:40:05.000000000 +0100
+++ new/hypothesis-3.40.1/src/hypothesis/errors.py      2017-12-04 
10:02:20.000000000 +0100
@@ -174,6 +174,10 @@
     """Raised when a test fails a preliminary healthcheck that occurs before
     execution."""
 
+    def __init__(self, message, check):
+        super(FailedHealthCheck, self).__init__(message)
+        self.health_check = check
+
 
 class HypothesisDeprecationWarning(HypothesisException, DeprecationWarning):
     pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hypothesis-3.38.5/src/hypothesis/internal/charmap.py 
new/hypothesis-3.40.1/src/hypothesis/internal/charmap.py
--- old/hypothesis-3.38.5/src/hypothesis/internal/charmap.py    2017-11-23 
20:40:05.000000000 +0100
+++ new/hypothesis-3.40.1/src/hypothesis/internal/charmap.py    2017-12-04 
10:02:20.000000000 +0100
@@ -141,6 +141,82 @@
     return tuple(result)
 
 
+def _subtract_intervals(x, y):
+    """Set difference for lists of intervals. That is, returns a list of
+    intervals that bounds all values bounded by x that are not also bounded by
+    y. x and y are expected to be in sorted order.
+
+    For example _subtract_intervals([(1, 10)], [(2, 3), (9, 15)]) would
+    return [(1, 1), (4, 8)], removing the values 2, 3, 9 and 10 from the
+    interval.
+
+    """
+    if not y:
+        return tuple(x)
+    x = list(map(list, x))
+    i = 0
+    j = 0
+    result = []
+    while i < len(x) and j < len(y):
+        # Iterate in parallel over x and y. j stays pointing at the smallest
+        # interval in the left hand side that could still overlap with some
+        # element of x at index >= i.
+        # Similarly, i is not incremented until we know that it does not
+        # overlap with any element of y at index >= j.
+
+        xl, xr = x[i]
+        assert xl <= xr
+        yl, yr = y[j]
+        assert yl <= yr
+
+        if yr < xl:
+            # The interval at y[j] is strictly to the left of the interval at
+            # x[i], so will not overlap with it or any later interval of x.
+            j += 1
+        elif yl > xr:
+            # The interval at y[j] is strictly to the right of the interval at
+            # x[i], so all of x[i] goes into the result as no further intervals
+            # in y will intersect it.
+            result.append(x[i])
+            i += 1
+        elif yl <= xl:
+            if yr >= xr:
+                # x[i] is contained entirely in y[j], so we just skip over it
+                # without adding it to the result.
+                i += 1
+            else:
+                # The beginning of x[i] is contained in y[j], so we update the
+                # left endpoint of x[i] to remove this, and increment j as we
+                # now have moved past it. Note that this is not added to the
+                # result as is, as more intervals from y may intersect it so it
+                # may need updating further.
+                x[i][0] = yr + 1
+                j += 1
+        else:
+            # yl > xl, so the left hand part of x[i] is not contained in y[j],
+            # so there are some values we should add to the result.
+            result.append((xl, yl - 1))
+
+            if yr + 1 <= xr:
+                # If y[j] finishes before x[i] does, there may be some values
+                # in x[i] left that should go in the result (or they may be
+                # removed by a later interval in y), so we update x[i] to
+                # reflect that and increment j because it no longer overlaps
+                # with any remaining element of x.
+                x[i][0] = yr + 1
+                j += 1
+            else:
+                # Every element of x[i] other than the initial part we have
+                # already added is contained in y[j], so we move to the next
+                # interval.
+                i += 1
+    # Any remaining intervals in x do not overlap with any of y, as if they did
+    # we would not have incremented j to the end, so can be added to the result
+    # as they are.
+    result.extend(x[i:])
+    return tuple(map(tuple, result))
+
+
 def _intervals(s):
     """Return a tuple of intervals, covering the codepoints of characters in
     `s`.
@@ -212,7 +288,8 @@
     exclude_categories=(), include_categories=None,
     min_codepoint=None,
     max_codepoint=None,
-    include_characters=''
+    include_characters='',
+    exclude_characters='',
 ):
     """Return a tuple of intervals covering the codepoints for all characters
     that meet the critera (min_codepoint <= codepoint(c) <= max_codepoint and
@@ -236,7 +313,11 @@
         max_codepoint = sys.maxunicode
     catkey = _category_key(exclude_categories, include_categories)
     character_intervals = _intervals(include_characters or '')
-    qkey = (catkey, min_codepoint, max_codepoint, character_intervals)
+    exclude_intervals = _intervals(exclude_characters or '')
+    qkey = (
+        catkey, min_codepoint, max_codepoint,
+        character_intervals, exclude_intervals
+    )
     try:
         return limited_category_index_cache[qkey]
     except KeyError:
@@ -250,5 +331,6 @@
             ))
     result = tuple(result)
     result = _union_intervals(result, character_intervals)
+    result = _subtract_intervals(result, exclude_intervals)
     limited_category_index_cache[qkey] = result
     return result
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hypothesis-3.38.5/src/hypothesis/internal/conjecture/data.py 
new/hypothesis-3.40.1/src/hypothesis/internal/conjecture/data.py
--- old/hypothesis-3.38.5/src/hypothesis/internal/conjecture/data.py    
2017-11-23 20:40:05.000000000 +0100
+++ new/hypothesis-3.40.1/src/hypothesis/internal/conjecture/data.py    
2017-12-04 10:02:20.000000000 +0100
@@ -64,7 +64,6 @@
         self.status = Status.VALID
         self.frozen = False
         self.intervals_by_level = []
-        self.intervals = []
         self.interval_stack = []
         global global_test_counter
         self.testcounter = global_test_counter
@@ -76,6 +75,7 @@
         self.interesting_origin = None
         self.tags = set()
         self.draw_times = []
+        self.__intervals = None
 
     def __assert_not_frozen(self, name):
         if self.frozen:
@@ -157,12 +157,30 @@
         if k != self.index:
             t = (k, self.index)
             self.intervals_by_level[self.level].append(t)
-            if not self.intervals or self.intervals[-1] != t:
-                self.intervals.append(t)
 
     def note_event(self, event):
         self.events.add(event)
 
+    @property
+    def intervals(self):
+        assert self.frozen
+        if self.__intervals is None:
+            intervals = set(self.blocks)
+            for l in self.intervals_by_level:
+                intervals.update(l)
+                for i in hrange(len(l) - 1):
+                    if l[i][1] == l[i + 1][0]:
+                        intervals.add((l[i][0], l[i + 1][1]))
+            for i in hrange(len(self.blocks) - 1):
+                intervals.add((self.blocks[i][0], self.blocks[i + 1][1]))
+            # Intervals are sorted as longest first, then by interval start.
+            self.__intervals = tuple(sorted(
+                set(intervals),
+                key=lambda se: (se[0] - se[1], se[0])
+            ))
+            del self.intervals_by_level
+        return self.__intervals
+
     def freeze(self):
         if self.frozen:
             assert isinstance(self.buffer, hbytes)
@@ -170,15 +188,6 @@
         self.frozen = True
         self.finish_time = benchmark_time()
 
-        # Intervals are sorted as longest first, then by interval start.
-        for l in self.intervals_by_level:
-            for i in hrange(len(l) - 1):
-                if l[i][1] == l[i + 1][0]:
-                    self.intervals.append((l[i][0], l[i + 1][1]))
-        self.intervals = sorted(
-            set(self.intervals),
-            key=lambda se: (se[0] - se[1], se[0])
-        )
         self.buffer = hbytes(self.buffer)
         self.events = frozenset(self.events)
         del self._draw_bytes
@@ -227,7 +236,6 @@
         assert len(result) == n
         assert self.index == initial
         self.buffer.extend(result)
-        self.intervals.append((initial, self.index))
 
     def draw_bytes(self, n):
         self.__assert_not_frozen('draw_bytes')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hypothesis-3.38.5/src/hypothesis/internal/conjecture/engine.py 
new/hypothesis-3.40.1/src/hypothesis/internal/conjecture/engine.py
--- old/hypothesis-3.38.5/src/hypothesis/internal/conjecture/engine.py  
2017-11-23 20:40:05.000000000 +0100
+++ new/hypothesis-3.40.1/src/hypothesis/internal/conjecture/engine.py  
2017-12-04 10:02:20.000000000 +0100
@@ -136,6 +136,8 @@
 
         self.health_check_state = None
 
+        self.used_examples_from_database = False
+
     def __tree_is_exhausted(self):
         return 0 in self.dead
 
@@ -368,11 +370,11 @@
 
     @property
     def secondary_key(self):
-        return b'.'.join((self.database_key, b"secondary"))
+        return b'.'.join((self.database_key, b'secondary'))
 
     @property
     def covering_key(self):
-        return b'.'.join((self.database_key, b"coverage"))
+        return b'.'.join((self.database_key, b'coverage'))
 
     def note_details(self, data):
         if data.status == Status.INTERESTING:
@@ -629,9 +631,12 @@
                 node_index = node[data.buffer[i]]
                 assert node_index not in self.dead
                 node = self.tree[node_index]
-            except KeyError:
-                data.__hit_novelty = True
-                return result
+            except KeyError:  # pragma: no cover
+                assert False, (
+                    'This should be impossible. If you see this error, please '
+                    'report it as a bug (ideally with a reproducible test '
+                    'case).'
+                )
 
         for i, b in enumerate(result):
             assert isinstance(b, int)
@@ -728,6 +733,8 @@
                     extra.sort(key=sort_key)
                     corpus.extend(extra)
 
+            self.used_examples_from_database = len(corpus) > 0
+
             for existing in corpus:
                 self.last_data = ConjectureData.for_buffer(existing)
                 try:
@@ -747,11 +754,27 @@
         if Phase.generate not in self.settings.phases:
             return
 
-        zero_data = ConjectureData(
-            max_length=self.settings.buffer_size,
-            draw_bytes=lambda data, n: self.__rewrite_for_novelty(
-                data, hbytes(n)))
-        self.test_function(zero_data)
+        zero_data = self.cached_test_function(
+            hbytes(self.settings.buffer_size))
+        if zero_data.status == Status.OVERRUN or (
+            zero_data.status == Status.VALID and
+            len(zero_data.buffer) * 2 > self.settings.buffer_size
+        ):
+            fail_health_check(
+                self.settings,
+                'The smallest natural example for your test is extremely '
+                'large. This makes it difficult for Hypothesis to generate '
+                'good examples, especially when trying to reduce failing ones '
+                'at the end. Consider reducing the size of your data if it is '
+                'of a fixed size. You could also fix this by improving how '
+                'your data shrinks (see https://hypothesis.readthedocs.io/en/'
+                'latest/data.html#shrinking for details), or by introducing '
+                'default values inside your strategy. e.g. could you replace '
+                'some arguments with their defaults by using '
+                'one_of(none(), some_complex_strategy)?',
+                HealthCheck.large_base_example
+            )
+
         if self.settings.perform_health_check:
             self.health_check_state = HealthCheckState()
 
@@ -885,22 +908,29 @@
             self.shrunk_examples.add(target)
         self.exit_with(ExitReason.finished)
 
-    def try_buffer_with_rewriting_from(self, initial_attempt, v):
-        initial_data = None
+    def cached_test_function(self, buffer):
         node_index = 0
-        for c in initial_attempt:
+        for i in hrange(self.settings.buffer_size):
+            try:
+                c = self.forced[node_index]
+            except KeyError:
+                if i < len(buffer):
+                    c = buffer[i]
+                else:
+                    c = 0
             try:
                 node_index = self.tree[node_index][c]
             except KeyError:
                 break
             node = self.tree[node_index]
             if isinstance(node, ConjectureData):
-                initial_data = node
-                break
+                return node
+        result = ConjectureData.for_buffer(buffer)
+        self.test_function(result)
+        return result
 
-        if initial_data is None:
-            initial_data = ConjectureData.for_buffer(initial_attempt)
-            self.test_function(initial_data)
+    def try_buffer_with_rewriting_from(self, initial_attempt, v):
+        initial_data = self.cached_test_function(initial_attempt)
 
         if initial_data.status == Status.INTERESTING:
             return initial_data is self.last_data
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hypothesis-3.38.5/src/hypothesis/internal/healthcheck.py 
new/hypothesis-3.40.1/src/hypothesis/internal/healthcheck.py
--- old/hypothesis-3.38.5/src/hypothesis/internal/healthcheck.py        
2017-11-23 20:40:05.000000000 +0100
+++ new/hypothesis-3.40.1/src/hypothesis/internal/healthcheck.py        
2017-12-04 10:02:20.000000000 +0100
@@ -35,4 +35,4 @@
         'If you want to disable just this health check, add %s '
         'to the suppress_health_check settings for this test.'
     ) % (label,)
-    raise FailedHealthCheck(message)
+    raise FailedHealthCheck(message, label)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hypothesis-3.38.5/src/hypothesis/searchstrategy/regex.py 
new/hypothesis-3.40.1/src/hypothesis/searchstrategy/regex.py
--- old/hypothesis-3.38.5/src/hypothesis/searchstrategy/regex.py        
2017-11-23 20:40:05.000000000 +0100
+++ new/hypothesis-3.40.1/src/hypothesis/searchstrategy/regex.py        
2017-12-04 10:02:20.000000000 +0100
@@ -232,11 +232,11 @@
 
 def base_regex_strategy(regex, parsed=None):
     if parsed is None:
-        parsed = sre_parse.parse(regex.pattern)
+        parsed = sre_parse.parse(regex.pattern, flags=regex.flags)
     return clear_cache_after_draw(_strategy(
         parsed,
         Context(flags=regex.flags),
-        regex.pattern
+        isinstance(regex.pattern, text_type)
     ))
 
 
@@ -246,7 +246,7 @@
 
     is_unicode = isinstance(regex.pattern, text_type)
 
-    parsed = sre_parse.parse(regex.pattern)
+    parsed = sre_parse.parse(regex.pattern, flags=regex.flags)
 
     if not parsed:
         if is_unicode:
@@ -294,7 +294,7 @@
     return maybe_pad(regex, base, left_pad, right_pad)
 
 
-def _strategy(codes, context, pattern):
+def _strategy(codes, context, is_unicode):
     """Convert SRE regex parse tree to strategy that generates strings matching
     that regex represented by that parse tree.
 
@@ -323,9 +323,9 @@
 
     """
     def recurse(codes):
-        return _strategy(codes, context, pattern)
+        return _strategy(codes, context, is_unicode)
 
-    if isinstance(pattern, text_type):
+    if is_unicode:
         empty = u''
         to_char = hunichr
     else:
@@ -387,7 +387,7 @@
             if context.flags & re.IGNORECASE and \
                     re.match(c, c.swapcase(), re.IGNORECASE) is not None:
                 blacklist |= set(c.swapcase())
-            if isinstance(pattern, text_type):
+            if is_unicode:
                 return st.characters(blacklist_characters=blacklist)
             else:
                 return binary_char.filter(lambda c: c not in blacklist)
@@ -395,7 +395,7 @@
         elif code == sre.IN:
             # Regex '[abc0-9]' (set of characters)
             negate = value[0][0] == sre.NEGATE
-            if isinstance(pattern, text_type):
+            if is_unicode:
                 builder = CharactersBuilder(negate, context.flags)
             else:
                 builder = BytesBuilder(negate, context.flags)
@@ -425,7 +425,7 @@
 
         elif code == sre.ANY:
             # Regex '.' (any char)
-            if isinstance(pattern, text_type):
+            if is_unicode:
                 if context.flags & re.DOTALL:
                     return st.characters()
                 return st.characters(blacklist_characters=u'\n')
@@ -447,7 +447,7 @@
                 # This feature is available only in specific Python versions
                 context.flags = (context.flags | value[1]) & ~value[2]
 
-            strat = _strategy(value[-1], context, pattern)
+            strat = _strategy(value[-1], context, is_unicode)
 
             context.flags = old_flags
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hypothesis-3.38.5/src/hypothesis/searchstrategy/strings.py 
new/hypothesis-3.40.1/src/hypothesis/searchstrategy/strings.py
--- old/hypothesis-3.38.5/src/hypothesis/searchstrategy/strings.py      
2017-11-23 20:40:05.000000000 +0100
+++ new/hypothesis-3.40.1/src/hypothesis/searchstrategy/strings.py      
2017-12-04 10:02:20.000000000 +0100
@@ -45,6 +45,7 @@
             min_codepoint=min_codepoint,
             max_codepoint=max_codepoint,
             include_characters=whitelist_characters,
+            exclude_characters=blacklist_characters,
         )
         if not intervals:
             raise InvalidArgument(
@@ -55,28 +56,14 @@
             self.whitelist_characters = set(whitelist_characters)
         else:
             self.whitelist_characters = set()
-        if blacklist_characters:
-            self.blacklist_characters = set(
-                b for b in blacklist_characters if ord(b) in self.intervals
-            )
-            if (len(self.whitelist_characters) == 0 and
-                    len(self.blacklist_characters) == len(self.intervals)):
-                raise InvalidArgument(
-                    'No valid characters in set'
-                )
-        else:
-            self.blacklist_characters = set()
         self.zero_point = self.intervals.index_above(ord('0'))
 
     def do_draw(self, data):
-        while True:
-            i = integer_range(
-                data, 0, len(self.intervals) - 1,
-                center=self.zero_point,
-            )
-            c = hunichr(self.intervals[i])
-            if c not in self.blacklist_characters:
-                return c
+        i = integer_range(
+            data, 0, len(self.intervals) - 1,
+            center=self.zero_point,
+        )
+        return hunichr(self.intervals[i])
 
 
 class StringStrategy(MappedSearchStrategy):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hypothesis-3.38.5/src/hypothesis/strategies.py 
new/hypothesis-3.40.1/src/hypothesis/strategies.py
--- old/hypothesis-3.38.5/src/hypothesis/strategies.py  2017-11-23 
20:40:05.000000000 +0100
+++ new/hypothesis-3.40.1/src/hypothesis/strategies.py  2017-12-04 
10:02:20.000000000 +0100
@@ -167,7 +167,11 @@
 @cacheable
 def nothing():
     """This strategy never successfully draws a value and will always reject on
-    an attempt to draw."""
+    an attempt to draw.
+
+    Examples from this strategy do not shrink (because there are none).
+
+    """
     return NOTHING
 
 
@@ -180,6 +184,8 @@
     :func:`builds(callable) <hypothesis.strategies.builds>` instead
     of ``just(callable())`` to get a fresh value each time.
 
+    Examples from this strategy do not shrink (because there is only one).
+
     """
     from hypothesis.searchstrategy.misc import JustStrategy
 
@@ -188,7 +194,12 @@
 
 @defines_strategy
 def none():
-    """Return a strategy which only generates None."""
+    """Return a strategy which only generates None.
+
+    Examples from this strategy do not shrink (because there is only
+    one).
+
+    """
     return just(None)
 
 
@@ -200,6 +211,17 @@
     strategy arguments. In which case one_of(x) and one_of(\*x) are
     equivalent.
 
+    Examples from this strategy will generally shrink to ones that come from
+    strategies earlier in the list, then shrink according to behaviour of the
+    strategy that produced them. In order to get good shrinking behaviour,
+    try to put simpler strategies first. e.g. ``one_of(none(), text())`` is
+    better than ``one_of(text(), none())``.
+
+    This is especially important when using recursive strategies. e.g.
+    ``x = st.deferred(lambda: st.none() | st.tuples(x, x))`` will shrink well,
+    but ``x = st.deferred(lambda: st.tuples(x, x) | st.none())`` will shrink
+    very badly indeed.
+
     """
     if len(args) == 1 and not isinstance(args[0], SearchStrategy):
         try:
@@ -219,6 +241,9 @@
     If min_value is not None then all values will be >= min_value. If
     max_value is not None then all values will be <= max_value
 
+    Examples from this strategy will shrink towards being positive (e.g. 1000
+    is considered simpler than -1) and then towards zero.
+
     """
 
     check_valid_bound(min_value, 'min_value')
@@ -264,7 +289,12 @@
 @cacheable
 @defines_strategy
 def booleans():
-    """Returns a strategy which generates instances of bool."""
+    """Returns a strategy which generates instances of bool.
+
+    Examples from this strategy will shrink towards False (i.e.
+    shrinking will try to replace True with False where possible).
+
+    """
     from hypothesis.searchstrategy.misc import BoolStrategy
     return BoolStrategy()
 
@@ -286,6 +316,11 @@
     Where not explicitly ruled out by the bounds, all of infinity, -infinity
     and NaN are possible values generated by this strategy.
 
+    Examples from this strategy have a complicated and hard to explain
+    shrinking behaviour, but it tries to improve "human readability". Finite
+    numbers will be preferred to infinity and infinity will be preferred to
+    NaN.
+
     """
 
     if allow_nan is None:
@@ -381,7 +416,12 @@
 @cacheable
 @defines_strategy_with_reusable_values
 def complex_numbers():
-    """Returns a strategy that generates complex numbers."""
+    """Returns a strategy that generates complex numbers.
+
+    Examples from this strategy shrink by shrinking their component real
+    and imaginary parts.
+
+    """
     from hypothesis.searchstrategy.numbers import ComplexStrategy
     return ComplexStrategy(
         tuples(floats(), floats())
@@ -397,6 +437,8 @@
     e.g. tuples(integers(), integers()) would generate a tuple of length
     two with both values an integer.
 
+    Examples from this strategy shrink by shrinking their component parts.
+
     """
     for arg in args:
         check_strategy(arg)
@@ -416,6 +458,11 @@
     :class:`~python:enum.Enum` objects.  :class:`~python:enum.Flag` objects
     may also generate any combination of their members.
 
+    Examples from this strategy shrink by replacing them with values earlier in
+    the list. So e.g. sampled_from((10, 1)) will shrink by trying to replace
+    1 values with 10, and sampled_from((1, 10)) will shrink by trying to
+    replace 10 values with 1.
+
     """
     from hypothesis.searchstrategy.misc import SampledFromStrategy
     from hypothesis.internal.conjecture.utils import check_sample
@@ -459,6 +506,9 @@
     when given a value drawn from elements. The resulting list will satisfy the
     condition that for i != j, unique_by(result[i]) != unique_by(result[j]).
 
+    Examples from this strategy shrink by trying to remove elements from the
+    list, and by shrinking each individual element of the list.
+
     """
     check_valid_sizes(min_size, average_size, max_size)
     if elements is None or (max_size is not None and max_size <= 0):
@@ -527,6 +577,9 @@
     are hashable until running the test, so you can define a strategy
     for sets of an unhashable type but it will fail at test time.
 
+    Examples from this strategy shrink by trying to remove elements from the
+    set, and by shrinking each individual element of the set.
+
     """
     return lists(
         elements=elements, min_size=min_size, average_size=average_size,
@@ -587,6 +640,9 @@
     instance of OrderedDict the keys will also be in the same order,
     otherwise the order is arbitrary.
 
+    Examples from this strategy shrink by shrinking each individual value in
+    the generated dictionary.
+
     """
     from hypothesis.searchstrategy.collections import FixedKeysDictStrategy
     check_type(dict, mapping, 'mapping')
@@ -606,6 +662,9 @@
 
     The size parameters have the same interpretation as for lists.
 
+    Examples from this strategy shrink by trying to remove keys from the
+    generated dictionary, and by shrinking each generated key and value.
+
     """
     check_valid_sizes(min_size, average_size, max_size)
     if max_size == 0:
@@ -628,6 +687,8 @@
     The result is iterable (the iterator will never terminate) and
     indexable.
 
+    Examples from this strategy shrink by trying to shrink each value drawn.
+
     .. deprecated:: 3.15.0
         Use :func:`data() <hypothesis.strategies.data>` instead.
 
@@ -672,6 +733,8 @@
     will be not be produced. Any overlap between ``whitelist_characters`` and
     ``blacklist_characters`` will raise an exception.
 
+    Examples from this strategy shrink towards smaller codepoints.
+
     """
     if (
         min_codepoint is not None and max_codepoint is not None and
@@ -732,6 +795,9 @@
 
     min_size, max_size and average_size have the usual interpretations.
 
+    Examples from this strategy shrink towards shorter strings, and with the
+    characters in the text shrinking as per the alphabet strategy.
+
     """
     from hypothesis.searchstrategy.strings import StringStrategy
     if alphabet is None:
@@ -779,6 +845,9 @@
     string, while ``"."`` will return any string, and ``r"\\A.$"`` will return
     a single character optionally followed by a ``"\\n"``.
 
+    Examples from this strategy shrink towards shorter strings and lower
+    character values.
+
     """
     from hypothesis.searchstrategy.regex import regex_strategy
     return regex_strategy(regex)
@@ -794,6 +863,9 @@
 
     min_size, average_size and max_size have the usual interpretations.
 
+    Examples from this strategy shrink towards smaller strings and lower byte
+    values.
+
     """
     from hypothesis.searchstrategy.strings import BinaryStringStrategy, \
         FixedSizeBytes
@@ -812,7 +884,11 @@
 @defines_strategy
 def randoms():
     """Generates instances of Random (actually a Hypothesis specific
-    RandomWithSeed class which displays what it was initially seeded with)"""
+    RandomWithSeed class which displays what it was initially seeded with)
+
+    Examples from this strategy shrink to seeds closer to zero.
+
+    """
     from hypothesis.searchstrategy.misc import RandomStrategy
     return RandomStrategy(integers())
 
@@ -839,6 +915,8 @@
     a random number generator you should use the randoms() strategy
     which will give you one.
 
+    Examples from these strategy shrink to seeds closer to zero.
+
     """
     from hypothesis.control import cleanup
     import random
@@ -870,6 +948,9 @@
     value :const:`hypothesis.infer` as a keyword argument to
     builds, instead of a strategy for that argument to ``target``.
 
+    Examples from this strategy shrink by shrinking the argument values to
+    the target.
+
     """
     if infer in args:
         # Avoid an implementation nightmare juggling tuples and worse things
@@ -1037,6 +1118,9 @@
     values is no greater than max_denominator. Note that max_denominator must
     be None or a positive integer.
 
+    Examples from this strategy shrink towards smaller denominators, then
+    closer to zero.
+
     """
     min_value = try_convert(Fraction, min_value, 'min_value')
     max_value = try_convert(Fraction, max_value, 'max_value')
@@ -1140,6 +1224,9 @@
     If ``places`` is not None, all finite values drawn from the strategy will
     have that number of digits after the decimal place.
 
+    Examples from this strategy do not have a well defined shrink order but
+    try to maximize human readability when shrinking.
+
     """
     # Convert min_value and max_value to Decimal values, and validate args
     check_valid_integer(places)
@@ -1232,6 +1319,10 @@
     So e.g. ``False``, ``[True]``, ``[False, []]``, and ``[[[[True]]]]`` are
     all valid values to be drawn from that strategy.
 
+    Examples from this strategy shrink by trying to reduce the amount of
+    recursion and by shrinking according to the shrinking behaviour of base
+    and the result of extend.
+
     """
 
     from hypothesis.searchstrategy.recursive import RecursiveStrategy
@@ -1241,7 +1332,12 @@
 @defines_strategy
 def permutations(values):
     """Return a strategy which returns permutations of the collection
-    ``values``."""
+    ``values``.
+
+    Examples from this strategy shrink by trying to become closer to the
+    original order of values.
+
+    """
     from hypothesis.internal.conjecture.utils import integer_range
 
     values = list(values)
@@ -1297,6 +1393,8 @@
     :py:func:`sampled_from`.  Ensure that simple values such as None or UTC
     are at the beginning of the list for proper minimisation.
 
+    Examples from this strategy shrink towards midnight on January 1st 2000.
+
     """
     # Why must bounds be naive?  In principle, we could also write a strategy
     # that took aware bounds, but the API and validation is much harder.
@@ -1335,7 +1433,11 @@
     min_value=dt.date.min, max_value=dt.date.max,
     min_date=None, max_date=None,
 ):
-    """A strategy for dates between ``min_date`` and ``max_date``."""
+    """A strategy for dates between ``min_date`` and ``max_date``.
+
+    Examples from this strategy shrink towards January 1st 2000.
+
+    """
     from hypothesis.searchstrategy.datetime import DateStrategy
 
     check_type(dt.date, min_value, 'min_value')
@@ -1359,6 +1461,9 @@
 
     The ``timezones`` argument is handled as for :py:func:`datetimes`.
 
+    Examples from this strategy shrink towards midnight, with the timezone
+    component shrinking as for the strategy that provided it.
+
     """
     check_type(dt.time, min_value, 'min_value')
     check_type(dt.time, max_value, 'max_value')
@@ -1382,7 +1487,11 @@
     min_value=dt.timedelta.min, max_value=dt.timedelta.max,
     min_delta=None, max_delta=None
 ):
-    """A strategy for timedeltas between ``min_value`` and ``max_value``."""
+    """A strategy for timedeltas between ``min_value`` and ``max_value``.
+
+    Examples from this strategy shrink towards zero.
+
+    """
     from hypothesis.searchstrategy.datetime import TimedeltaStrategy
 
     check_type(dt.timedelta, min_value, 'min_value')
@@ -1402,6 +1511,9 @@
     :ref:`the full documentation for more details <composite-strategies>`
     about how to use this function.
 
+    Examples from this strategy shrink by shrinking the output of each draw
+    call.
+
     """
 
     from hypothesis.internal.reflection import define_function_signature
@@ -1456,6 +1568,8 @@
     >>> x = shared(s, key="hi")
     >>> y = shared(s, key="hi")
 
+    Examples from this strategy shrink as per their base strategy.
+
     """
     from hypothesis.searchstrategy.shared import SharedStrategy
     return SharedStrategy(base, key)
@@ -1472,6 +1586,9 @@
         Use :func:`data() <hypothesis.strategies.data>` with
         :func:`sampled_from() <hypothesis.strategies.sampled_from>` instead.
 
+    Examples from this strategy shrink by making each choice function return
+    an earlier value in the sequence passed to it.
+
     """
     from hypothesis.control import note, current_build_context
     from hypothesis.internal.conjecture.utils import choice, check_sample
@@ -1524,6 +1641,8 @@
     All returned values from this will be unique, so e.g. if you do
     ``lists(uuids())`` the resulting list will never contain duplicates.
 
+    Examples from this strategy don't have any meaningful shrink order.
+
     """
     from uuid import UUID
     if version not in (None, 1, 2, 3, 4, 5):
@@ -1545,6 +1664,8 @@
     If there is no current test runner and a default is provided, return
     that default. If no default is provided, raises InvalidArgument.
 
+    Examples from this strategy do not shrink (because there is only one).
+
     """
     class RunnerStrategy(SearchStrategy):
 
@@ -1575,6 +1696,9 @@
     See :ref:`the rest of the documentation <interactive-draw>` for more
     complete information.
 
+    Examples from this strategy do not shrink (because there is only one),
+    but the result of calls to each draw() call shrink as they normally would.
+
     """
     from hypothesis.control import note
 
@@ -1684,6 +1808,9 @@
     >>> b.example()
     (False, True)
 
+    Examples from this strategy shrink as they normally would from the strategy
+    returned by the definition.
+
     """
     from hypothesis.searchstrategy.deferred import DeferredStrategy
     return DeferredStrategy(definition)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hypothesis-3.38.5/src/hypothesis/version.py 
new/hypothesis-3.40.1/src/hypothesis/version.py
--- old/hypothesis-3.38.5/src/hypothesis/version.py     2017-11-23 
20:40:32.000000000 +0100
+++ new/hypothesis-3.40.1/src/hypothesis/version.py     2017-12-04 
10:02:53.000000000 +0100
@@ -17,5 +17,5 @@
 
 from __future__ import division, print_function, absolute_import
 
-__version_info__ = (3, 38, 5)
+__version_info__ = (3, 40, 1)
 __version__ = '.'.join(map(str, __version_info__))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hypothesis-3.38.5/src/hypothesis.egg-info/PKG-INFO 
new/hypothesis-3.40.1/src/hypothesis.egg-info/PKG-INFO
--- old/hypothesis-3.38.5/src/hypothesis.egg-info/PKG-INFO      2017-11-23 
20:40:32.000000000 +0100
+++ new/hypothesis-3.40.1/src/hypothesis.egg-info/PKG-INFO      2017-12-04 
10:02:53.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: hypothesis
-Version: 3.38.5
+Version: 3.40.1
 Summary: A library for property based testing
 Home-page: https://github.com/HypothesisWorks/hypothesis-python
 Author: David R. MacIver


Reply via email to