Browse Source

Intermediate changes

robot-piglet 1 year ago
parent
commit
806165cf8b

+ 1 - 1
contrib/python/hypothesis/py3/.dist-info/METADATA

@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: hypothesis
-Version: 6.96.1
+Version: 6.96.2
 Summary: A library for property-based testing
 Home-page: https://hypothesis.works
 Author: David R. MacIver and Zac Hatfield-Dodds

+ 11 - 1
contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py

@@ -1487,7 +1487,7 @@ class ConjectureData:
             assert min_value is not None
             assert max_value is not None
             width = max_value - min_value + 1
-            assert width <= 1024  # arbitrary practical limit
+            assert width <= 255  # arbitrary practical limit
             assert len(weights) == width
 
         if forced is not None and (min_value is None or max_value is None):
@@ -1558,6 +1558,16 @@ class ConjectureData:
         return self.provider.draw_bytes(size, forced=forced)
 
     def draw_boolean(self, p: float = 0.5, *, forced: Optional[bool] = None) -> bool:
+        # Internally, we treat probabilities lower than 1 / 2**64 as
+        # unconditionally false.
+        #
+        # Note that even if we lift this 64 bit restriction in the future, p
+        # cannot be 0 (1) when forced is True (False).
+        if forced is True:
+            assert p > 2 ** (-64)
+        if forced is False:
+            assert p < (1 - 2 ** (-64))
+
         return self.provider.draw_boolean(p, forced=forced)
 
     def as_result(self) -> Union[ConjectureResult, _Overrun]:

+ 14 - 4
contrib/python/hypothesis/py3/hypothesis/internal/conjecture/utils.py

@@ -172,14 +172,24 @@ class Sampler:
         forced_choice = (  # pragma: no branch # https://github.com/nedbat/coveragepy/issues/1617
             None
             if forced is None
-            else next((b, a, a_c) for (b, a, a_c) in self.table if forced in (b, a))
+            else next(
+                (base, alternate, alternate_chance)
+                for (base, alternate, alternate_chance) in self.table
+                if forced == base or (forced == alternate and alternate_chance > 0)
+            )
         )
         base, alternate, alternate_chance = data.choice(
             self.table, forced=forced_choice
         )
-        use_alternate = data.draw_boolean(
-            alternate_chance, forced=None if forced is None else forced == alternate
-        )
+        forced_use_alternate = None
+        if forced is not None:
+            # we maintain this invariant when picking forced_choice above.
+            # This song and dance about alternate_chance > 0 is to avoid forcing
+            # e.g. draw_boolean(p=0, forced=True), which is an error.
+            forced_use_alternate = forced == alternate and alternate_chance > 0
+            assert forced == base or forced_use_alternate
+
+        use_alternate = data.draw_boolean(alternate_chance, forced=forced_use_alternate)
         data.stop_example()
         if use_alternate:
             assert forced is None or alternate == forced, (forced, alternate)

+ 4 - 3
contrib/python/hypothesis/py3/hypothesis/strategies/_internal/strategies.py

@@ -473,6 +473,8 @@ class SampledFromStrategy(SearchStrategy):
     non-empty subset of the elements.
     """
 
+    _MAX_FILTER_CALLS = 10_000
+
     def __init__(self, elements, repr_=None, transformations=()):
         super().__init__()
         self.elements = cu.check_sample(elements, "sampled_from")
@@ -567,8 +569,7 @@ class SampledFromStrategy(SearchStrategy):
 
         # Impose an arbitrary cutoff to prevent us from wasting too much time
         # on very large element lists.
-        cutoff = 10000
-        max_good_indices = min(max_good_indices, cutoff)
+        max_good_indices = min(max_good_indices, self._MAX_FILTER_CALLS - 3)
 
         # Before building the list of allowed indices, speculatively choose
         # one of them. We don't yet know how many allowed indices there will be,
@@ -580,7 +581,7 @@ class SampledFromStrategy(SearchStrategy):
         # just use that and return immediately.  Note that we also track the
         # allowed elements, in case of .map(some_stateful_function)
         allowed = []
-        for i in range(min(len(self.elements), cutoff)):
+        for i in range(min(len(self.elements), self._MAX_FILTER_CALLS - 3)):
             if i not in known_bad_indices:
                 element = self.get_element(i)
                 if element is not filter_not_satisfied:

+ 1 - 1
contrib/python/hypothesis/py3/hypothesis/version.py

@@ -8,5 +8,5 @@
 # v. 2.0. If a copy of the MPL was not distributed with this file, You can
 # obtain one at https://mozilla.org/MPL/2.0/.
 
-__version_info__ = (6, 96, 1)
+__version_info__ = (6, 96, 2)
 __version__ = ".".join(map(str, __version_info__))

+ 1 - 1
contrib/python/hypothesis/py3/ya.make

@@ -2,7 +2,7 @@
 
 PY3_LIBRARY()
 
-VERSION(6.96.1)
+VERSION(6.96.2)
 
 LICENSE(MPL-2.0)