summaryrefslogtreecommitdiffstats
path: root/contrib/python/hypothesis
diff options
context:
space:
mode:
authorrobot-piglet <[email protected]>2026-01-21 14:56:31 +0300
committerrobot-piglet <[email protected]>2026-01-21 15:25:33 +0300
commit772bcb8c73ca0e16e9d7e6eb160a71a307a9f782 (patch)
tree7bd2b3e2d10ea79cee26aeb80b236863b658296b /contrib/python/hypothesis
parent2c412ab837315b2641bf6b9e8000794aa34b6128 (diff)
Intermediate changes
commit_hash:78d308c309026e9488e5896412b56dc40cb67ed8
Diffstat (limited to 'contrib/python/hypothesis')
-rw-r--r--contrib/python/hypothesis/py3/.dist-info/METADATA2
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/strategies/_internal/core.py6
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/strategies/_internal/recursive.py63
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/version.py2
-rw-r--r--contrib/python/hypothesis/py3/ya.make2
5 files changed, 58 insertions, 17 deletions
diff --git a/contrib/python/hypothesis/py3/.dist-info/METADATA b/contrib/python/hypothesis/py3/.dist-info/METADATA
index 00267a4c202..5ad4e36bad2 100644
--- a/contrib/python/hypothesis/py3/.dist-info/METADATA
+++ b/contrib/python/hypothesis/py3/.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: hypothesis
-Version: 6.149.1
+Version: 6.150.0
Summary: The property-based testing library for Python
Author-email: "David R. MacIver and Zac Hatfield-Dodds" <[email protected]>
License-Expression: MPL-2.0
diff --git a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/core.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/core.py
index ac48b450cd3..1006fc792d6 100644
--- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/core.py
+++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/core.py
@@ -1857,12 +1857,16 @@ def recursive(
base: SearchStrategy[Ex],
extend: Callable[[SearchStrategy[Any]], SearchStrategy[T]],
*,
+ min_leaves: int = 1,
max_leaves: int = 100,
) -> SearchStrategy[T | Ex]:
"""base: A strategy to start from.
extend: A function which takes a strategy and returns a new strategy.
+ min_leaves: The minimum number of elements to be drawn from base on a given
+ run.
+
max_leaves: The maximum number of elements to be drawn from base on a given
run.
@@ -1881,7 +1885,7 @@ def recursive(
"""
- return RecursiveStrategy(base, extend, max_leaves)
+ return RecursiveStrategy(base, extend, min_leaves, max_leaves)
class PermutationStrategy(SearchStrategy):
diff --git a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/recursive.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/recursive.py
index aa665ce0b82..2621600cc40 100644
--- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/recursive.py
+++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/recursive.py
@@ -9,10 +9,14 @@
# obtain one at https://mozilla.org/MPL/2.0/.
import threading
+import warnings
from contextlib import contextmanager
-from hypothesis.errors import InvalidArgument
-from hypothesis.internal.reflection import get_pretty_function_description
+from hypothesis.errors import HypothesisWarning, InvalidArgument
+from hypothesis.internal.reflection import (
+ get_pretty_function_description,
+ is_identity_function,
+)
from hypothesis.internal.validation import check_type
from hypothesis.strategies._internal.strategies import (
OneOfStrategy,
@@ -72,24 +76,36 @@ class LimitedStrategy(SearchStrategy):
class RecursiveStrategy(SearchStrategy):
- def __init__(self, base, extend, max_leaves):
+ def __init__(self, base, extend, min_leaves, max_leaves):
super().__init__()
+ self.min_leaves = min_leaves
self.max_leaves = max_leaves
self.base = base
self.limited_base = LimitedStrategy(base)
self.extend = extend
+ if is_identity_function(extend):
+ warnings.warn(
+ "extend=lambda x: x is a no-op; you probably want to use a "
+ "different extend function, or just use the base strategy directly.",
+ HypothesisWarning,
+ stacklevel=5,
+ )
+
strategies = [self.limited_base, self.extend(self.limited_base)]
while 2 ** (len(strategies) - 1) <= max_leaves:
strategies.append(extend(OneOfStrategy(tuple(strategies))))
+ # If min_leaves > 1, we can never draw from base directly
+ if min_leaves > 1:
+ strategies = strategies[1:]
self.strategy = OneOfStrategy(strategies)
def __repr__(self) -> str:
if not hasattr(self, "_cached_repr"):
- self._cached_repr = "recursive(%r, %s, max_leaves=%d)" % (
- self.base,
- get_pretty_function_description(self.extend),
- self.max_leaves,
+ self._cached_repr = (
+ f"recursive({self.base!r}, "
+ f"{get_pretty_function_description(self.extend)}, "
+ f"min_leaves={self.min_leaves}, max_leaves={self.max_leaves})"
)
return self._cached_repr
@@ -99,20 +115,41 @@ class RecursiveStrategy(SearchStrategy):
check_strategy(extended, f"extend({self.limited_base!r})")
self.limited_base.validate()
extended.validate()
+ check_type(int, self.min_leaves, "min_leaves")
check_type(int, self.max_leaves, "max_leaves")
+ if self.min_leaves <= 0:
+ raise InvalidArgument(
+ f"min_leaves={self.min_leaves!r} must be greater than zero"
+ )
if self.max_leaves <= 0:
raise InvalidArgument(
f"max_leaves={self.max_leaves!r} must be greater than zero"
)
+ if self.min_leaves > self.max_leaves:
+ raise InvalidArgument(
+ f"min_leaves={self.min_leaves!r} must be less than or equal to "
+ f"max_leaves={self.max_leaves!r}"
+ )
def do_draw(self, data):
- count = 0
+ min_leaves_retries = 0
while True:
try:
with self.limited_base.capped(self.max_leaves):
- return data.draw(self.strategy)
+ result = data.draw(self.strategy)
+ leaves_drawn = self.max_leaves - self.limited_base.marker
+ if leaves_drawn < self.min_leaves:
+ data.events[
+ f"Draw for {self!r} had fewer than "
+ f"min_leaves={self.min_leaves} and had to be retried"
+ ] = ""
+ min_leaves_retries += 1
+ if min_leaves_retries < 5:
+ continue
+ data.mark_invalid(f"min_leaves={self.min_leaves} unsatisfied")
+ return result
except LimitReached:
- if count == 0:
- msg = f"Draw for {self!r} exceeded max_leaves and had to be retried"
- data.events[msg] = ""
- count += 1
+ data.events[
+ f"Draw for {self!r} exceeded "
+ f"max_leaves={self.max_leaves} and had to be retried"
+ ] = ""
diff --git a/contrib/python/hypothesis/py3/hypothesis/version.py b/contrib/python/hypothesis/py3/hypothesis/version.py
index 41812a39d47..2ac8a20a828 100644
--- a/contrib/python/hypothesis/py3/hypothesis/version.py
+++ b/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, 149, 1)
+__version_info__ = (6, 150, 0)
__version__ = ".".join(map(str, __version_info__))
diff --git a/contrib/python/hypothesis/py3/ya.make b/contrib/python/hypothesis/py3/ya.make
index 89ea7a2df29..e949f9b0fa8 100644
--- a/contrib/python/hypothesis/py3/ya.make
+++ b/contrib/python/hypothesis/py3/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(6.149.1)
+VERSION(6.150.0)
LICENSE(MPL-2.0)