aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrobot-piglet <robot-piglet@yandex-team.com>2024-10-21 08:31:52 +0300
committerrobot-piglet <robot-piglet@yandex-team.com>2024-10-21 08:43:19 +0300
commitb5e6a1542676ac2636493eb78803c57d37fdeb1c (patch)
tree99120ac267a31afd36d8fbbbab0c0c357bf811e4
parente7e3842c488b522105e8cdb33bd099e2747823ef (diff)
downloadydb-b5e6a1542676ac2636493eb78803c57d37fdeb1c.tar.gz
Intermediate changes
commit_hash:04a153065be0050f5e911b9ff8b6dccbfe1b3cc8
-rw-r--r--contrib/python/hypothesis/py3/.dist-info/METADATA2
-rw-r--r--contrib/python/hypothesis/py3/_hypothesis_ftz_detector.py26
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/configuration.py6
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/errors.py4
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/extra/_patching.py59
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/internal/cache.py2
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/internal/cathetus.py2
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/internal/compat.py2
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py47
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/internal/conjecture/engine.py1
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/internal/detection.py2
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/internal/filtering.py4
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/internal/scrutineer.py12
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/provisional.py11
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/stateful.py8
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/statistics.py14
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/strategies/_internal/random.py19
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/strategies/_internal/regex.py4
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/strategies/_internal/strategies.py4
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/strategies/_internal/types.py8
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/utils/dynamicvariables.py13
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/version.py2
-rw-r--r--contrib/python/hypothesis/py3/ya.make2
23 files changed, 169 insertions, 85 deletions
diff --git a/contrib/python/hypothesis/py3/.dist-info/METADATA b/contrib/python/hypothesis/py3/.dist-info/METADATA
index a0ba8f627f..418a478f2c 100644
--- a/contrib/python/hypothesis/py3/.dist-info/METADATA
+++ b/contrib/python/hypothesis/py3/.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: hypothesis
-Version: 6.112.3
+Version: 6.112.4
Summary: A library for property-based testing
Home-page: https://hypothesis.works
Author: David R. MacIver and Zac Hatfield-Dodds
diff --git a/contrib/python/hypothesis/py3/_hypothesis_ftz_detector.py b/contrib/python/hypothesis/py3/_hypothesis_ftz_detector.py
index abc1d65655..2c73530c9a 100644
--- a/contrib/python/hypothesis/py3/_hypothesis_ftz_detector.py
+++ b/contrib/python/hypothesis/py3/_hypothesis_ftz_detector.py
@@ -18,6 +18,14 @@ import of Hypothesis itself from each subprocess which must import the worker fu
import importlib
import sys
+from typing import TYPE_CHECKING, Callable, Optional, Set, Tuple
+
+if TYPE_CHECKING:
+ from multiprocessing import Queue
+ from typing import TypeAlias
+
+FTZCulprits: "TypeAlias" = Tuple[Optional[bool], Set[str]]
+
KNOWN_EVER_CULPRITS = (
# https://moyix.blogspot.com/2022/09/someones-been-messing-with-my-subnormals.html
@@ -35,16 +43,16 @@ KNOWN_EVER_CULPRITS = (
)
-def flush_to_zero():
+def flush_to_zero() -> bool:
# If this subnormal number compares equal to zero we have a problem
return 2.0**-1073 == 0
-def run_in_process(fn, *args):
+def run_in_process(fn: Callable[..., FTZCulprits], *args: object) -> FTZCulprits:
import multiprocessing as mp
mp.set_start_method("spawn", force=True)
- q = mp.Queue()
+ q: "Queue[FTZCulprits]" = mp.Queue()
p = mp.Process(target=target, args=(q, fn, *args))
p.start()
retval = q.get()
@@ -52,15 +60,17 @@ def run_in_process(fn, *args):
return retval
-def target(q, fn, *args):
+def target(
+ q: "Queue[FTZCulprits]", fn: Callable[..., FTZCulprits], *args: object
+) -> None:
q.put(fn(*args))
-def always_imported_modules():
+def always_imported_modules() -> FTZCulprits:
return flush_to_zero(), set(sys.modules)
-def modules_imported_by(mod):
+def modules_imported_by(mod: str) -> FTZCulprits:
"""Return the set of modules imported transitively by mod."""
before = set(sys.modules)
try:
@@ -77,7 +87,7 @@ KNOWN_FTZ = None
CHECKED_CACHE = set()
-def identify_ftz_culprits():
+def identify_ftz_culprits() -> str:
"""Find the modules in sys.modules which cause "mod" to be imported."""
# If we've run this function before, return the same result.
global KNOWN_FTZ
@@ -94,7 +104,7 @@ def identify_ftz_culprits():
# that importing them in a new process sets the FTZ state. As a heuristic, we'll
# start with packages known to have ever enabled FTZ, then top-level packages as
# a way to eliminate large fractions of the search space relatively quickly.
- def key(name):
+ def key(name: str) -> Tuple[bool, int, str]:
"""Prefer known-FTZ modules, then top-level packages, then alphabetical."""
return (name not in KNOWN_EVER_CULPRITS, name.count("."), name)
diff --git a/contrib/python/hypothesis/py3/hypothesis/configuration.py b/contrib/python/hypothesis/py3/hypothesis/configuration.py
index b7bc8879ce..cd9115533a 100644
--- a/contrib/python/hypothesis/py3/hypothesis/configuration.py
+++ b/contrib/python/hypothesis/py3/hypothesis/configuration.py
@@ -12,22 +12,22 @@ import os
import sys
import warnings
from pathlib import Path
+from typing import Union
import _hypothesis_globals
from hypothesis.errors import HypothesisSideeffectWarning
__hypothesis_home_directory_default = Path.cwd() / ".hypothesis"
-
__hypothesis_home_directory = None
-def set_hypothesis_home_dir(directory):
+def set_hypothesis_home_dir(directory: Union[str, Path, None]) -> None:
global __hypothesis_home_directory
__hypothesis_home_directory = None if directory is None else Path(directory)
-def storage_directory(*names, intent_to_write=True):
+def storage_directory(*names: str, intent_to_write: bool = True) -> Path:
if intent_to_write:
check_sideeffect_during_initialization(
"accessing storage for {}", "/".join(names)
diff --git a/contrib/python/hypothesis/py3/hypothesis/errors.py b/contrib/python/hypothesis/py3/hypothesis/errors.py
index 1dcf4493b2..7da59ebd90 100644
--- a/contrib/python/hypothesis/py3/hypothesis/errors.py
+++ b/contrib/python/hypothesis/py3/hypothesis/errors.py
@@ -214,7 +214,7 @@ class StopTest(BaseException):
the Hypothesis engine, which should then continue normally.
"""
- def __init__(self, testcounter):
+ def __init__(self, testcounter: int) -> None:
super().__init__(repr(testcounter))
self.testcounter = testcounter
@@ -230,7 +230,7 @@ class Found(HypothesisException):
class RewindRecursive(Exception):
"""Signal that the type inference should be rewound due to recursive types. Internal use only."""
- def __init__(self, target):
+ def __init__(self, target: object) -> None:
self.target = target
diff --git a/contrib/python/hypothesis/py3/hypothesis/extra/_patching.py b/contrib/python/hypothesis/py3/hypothesis/extra/_patching.py
index b8fbfa3c7a..b508f199d6 100644
--- a/contrib/python/hypothesis/py3/hypothesis/extra/_patching.py
+++ b/contrib/python/hypothesis/py3/hypothesis/extra/_patching.py
@@ -18,11 +18,13 @@ discovered during testing, and by HypoFuzz for _covering_ examples discovered
during fuzzing.
"""
+import ast
import difflib
import hashlib
import inspect
import re
import sys
+import types
from ast import literal_eval
from contextlib import suppress
from datetime import date, datetime, timedelta, timezone
@@ -31,6 +33,7 @@ from pathlib import Path
import libcst as cst
from libcst import matchers as m
from libcst.codemod import CodemodContext, VisitorBasedCodemodCommand
+from libcst.metadata import ExpressionContext, ExpressionContextProvider
from hypothesis.configuration import storage_directory
from hypothesis.version import __version__
@@ -148,18 +151,64 @@ def get_patch_for(func, failing_examples, *, strip_via=()):
except Exception:
return None
+ modules_in_test_scope = sorted(
+ (
+ (k, v)
+ for (k, v) in module.__dict__.items()
+ if isinstance(v, types.ModuleType)
+ ),
+ key=lambda kv: len(kv[1].__name__),
+ )
+
# The printed examples might include object reprs which are invalid syntax,
# so we parse here and skip over those. If _none_ are valid, there's no patch.
call_nodes = []
for ex, via in set(failing_examples):
with suppress(Exception):
- node = cst.parse_expression(ex)
- assert isinstance(node, cst.Call), node
+ node = cst.parse_module(ex)
+ the_call = node.body[0].body[0].value
+ assert isinstance(the_call, cst.Call), the_call
# Check for st.data(), which doesn't support explicit examples
data = m.Arg(m.Call(m.Name("data"), args=[m.Arg(m.Ellipsis())]))
- if m.matches(node, m.Call(args=[m.ZeroOrMore(), data, m.ZeroOrMore()])):
+ if m.matches(the_call, m.Call(args=[m.ZeroOrMore(), data, m.ZeroOrMore()])):
return None
+
+ # Many reprs use the unqualified name of the type, e.g. np.array()
+ # -> array([...]), so here we find undefined names and look them up
+ # on each module which was in the test's global scope.
+ names = {}
+ for anode in ast.walk(ast.parse(ex, "eval")):
+ if (
+ isinstance(anode, ast.Name)
+ and isinstance(anode.ctx, ast.Load)
+ and anode.id not in names
+ and anode.id not in module.__dict__
+ ):
+ for k, v in modules_in_test_scope:
+ if anode.id in v.__dict__:
+ names[anode.id] = cst.parse_expression(f"{k}.{anode.id}")
+ break
+
+ # LibCST doesn't track Load()/Store() state of names by default, so we have
+ # to do a bit of a dance here, *and* explicitly handle keyword arguments
+ # which are treated as Load() context - but even if that's fixed later
+ # we'll still want to support older versions.
+ with suppress(Exception):
+ wrapper = cst.metadata.MetadataWrapper(node)
+ kwarg_names = {
+ a.keyword for a in m.findall(wrapper, m.Arg(keyword=m.Name()))
+ }
+ node = m.replace(
+ wrapper,
+ m.Name(value=m.MatchIfTrue(names.__contains__))
+ & m.MatchMetadata(ExpressionContextProvider, ExpressionContext.LOAD)
+ & m.MatchIfTrue(lambda n, k=kwarg_names: n not in k),
+ replacement=lambda node, _, ns=names: ns[node.value],
+ )
+ node = node.body[0].body[0].value
+ assert isinstance(node, cst.Call), node
call_nodes.append((node, via))
+
if not call_nodes:
return None
@@ -205,8 +254,8 @@ def make_patch(triples, *, msg="Hypothesis: add explicit examples", when=None):
ud = difflib.unified_diff(
source_before.splitlines(keepends=True),
source_after.splitlines(keepends=True),
- fromfile=str(fname),
- tofile=str(fname),
+ fromfile=f"./{fname}", # git strips the first part of the path by default
+ tofile=f"./{fname}",
)
diffs.append("".join(ud))
return "".join(diffs)
diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/cache.py b/contrib/python/hypothesis/py3/hypothesis/internal/cache.py
index a41cdb0549..8eb1bdba7e 100644
--- a/contrib/python/hypothesis/py3/hypothesis/internal/cache.py
+++ b/contrib/python/hypothesis/py3/hypothesis/internal/cache.py
@@ -307,7 +307,7 @@ class LRUCache:
# Anecdotally, OrderedDict seems quite competitive with lru_cache, but perhaps
# that is localized to our access patterns.
- def __init__(self, max_size):
+ def __init__(self, max_size: int) -> None:
assert max_size > 0
self.max_size = max_size
self._threadlocal = threading.local()
diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/cathetus.py b/contrib/python/hypothesis/py3/hypothesis/internal/cathetus.py
index 1f8f2fe82b..2012df4cdd 100644
--- a/contrib/python/hypothesis/py3/hypothesis/internal/cathetus.py
+++ b/contrib/python/hypothesis/py3/hypothesis/internal/cathetus.py
@@ -12,7 +12,7 @@ from math import fabs, inf, isinf, isnan, nan, sqrt
from sys import float_info
-def cathetus(h, a):
+def cathetus(h: float, a: float) -> float:
"""Given the lengths of the hypotenuse and a side of a right triangle,
return the length of the other side.
diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/compat.py b/contrib/python/hypothesis/py3/hypothesis/internal/compat.py
index 4a3a94a084..df1ba067e9 100644
--- a/contrib/python/hypothesis/py3/hypothesis/internal/compat.py
+++ b/contrib/python/hypothesis/py3/hypothesis/internal/compat.py
@@ -110,7 +110,7 @@ def int_to_byte(i: int) -> bytes:
return bytes([i])
-def is_typed_named_tuple(cls):
+def is_typed_named_tuple(cls: type) -> bool:
"""Return True if cls is probably a subtype of `typing.NamedTuple`.
Unfortunately types created with `class T(NamedTuple):` actually
diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py
index 0f4f1138f3..2d24f984e5 100644
--- a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py
+++ b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py
@@ -271,7 +271,7 @@ class Example:
return self.owner.labels[self.owner.label_indices[self.index]]
@property
- def parent(self):
+ def parent(self) -> Optional[int]:
"""The index of the example that this one is nested directly within."""
if self.index == 0:
return None
@@ -298,13 +298,13 @@ class Example:
return self.owner.ir_ends[self.index]
@property
- def depth(self):
+ def depth(self) -> int:
"""Depth of this example in the example tree. The top-level example has a
depth of 0."""
return self.owner.depths[self.index]
@property
- def trivial(self):
+ def trivial(self) -> bool:
"""An example is "trivial" if it only contains forced bytes and zero bytes.
All examples start out as trivial, and then get marked non-trivial when
we see a byte that is neither forced nor zero."""
@@ -352,6 +352,7 @@ class ExampleProperty:
self.example_count = 0
self.block_count = 0
self.ir_node_count = 0
+ self.result: Any = None
def run(self) -> Any:
"""Rerun the test case with this visitor and return the
@@ -425,7 +426,7 @@ def calculated_example_property(cls: Type[ExampleProperty]) -> Any:
name = cls.__name__
cache_name = "__" + name
- def lazy_calculate(self: "Examples") -> IntList:
+ def lazy_calculate(self: "Examples") -> Any:
result = getattr(self, cache_name, None)
if result is None:
result = cls(self).run()
@@ -465,7 +466,14 @@ class ExampleRecord:
def freeze(self) -> None:
self.__index_of_labels = None
- def record_ir_draw(self, ir_type, value, *, kwargs, was_forced):
+ def record_ir_draw(
+ self,
+ ir_type: IRTypeName,
+ value: IRType,
+ *,
+ kwargs: IRKWargsType,
+ was_forced: bool,
+ ) -> None:
self.trail.append(IR_NODE_RECORD)
node = IRNode(
ir_type=ir_type,
@@ -517,7 +525,7 @@ class Examples:
self.__children: "Optional[List[Sequence[int]]]" = None
class _starts_and_ends(ExampleProperty):
- def begin(self):
+ def begin(self) -> None:
self.starts = IntList.of_length(len(self.examples))
self.ends = IntList.of_length(len(self.examples))
@@ -543,7 +551,7 @@ class Examples:
return self.starts_and_ends[1]
class _ir_starts_and_ends(ExampleProperty):
- def begin(self):
+ def begin(self) -> None:
self.starts = IntList.of_length(len(self.examples))
self.ends = IntList.of_length(len(self.examples))
@@ -570,7 +578,7 @@ class Examples:
class _discarded(ExampleProperty):
def begin(self) -> None:
- self.result: "Set[int]" = set() # type: ignore # IntList in parent class
+ self.result: "Set[int]" = set()
def finish(self) -> FrozenSet[int]:
return frozenset(self.result)
@@ -584,7 +592,7 @@ class Examples:
class _trivial(ExampleProperty):
def begin(self) -> None:
self.nontrivial = IntList.of_length(len(self.examples))
- self.result: "Set[int]" = set() # type: ignore # IntList in parent class
+ self.result: "Set[int]" = set()
def block(self, i: int) -> None:
if not self.examples.blocks.trivial(i):
@@ -610,7 +618,7 @@ class Examples:
parentage: IntList = calculated_example_property(_parentage)
class _depths(ExampleProperty):
- def begin(self):
+ def begin(self) -> None:
self.result = IntList.of_length(len(self.examples))
def start_example(self, i: int, label_index: int) -> None:
@@ -619,10 +627,10 @@ class Examples:
depths: IntList = calculated_example_property(_depths)
class _ir_tree_nodes(ExampleProperty):
- def begin(self):
+ def begin(self) -> None:
self.result = []
- def ir_node(self, ir_node):
+ def ir_node(self, ir_node: "IRNode") -> None:
self.result.append(ir_node)
ir_tree_nodes: "List[IRNode]" = calculated_example_property(_ir_tree_nodes)
@@ -788,7 +796,7 @@ class Blocks:
prev = e
@property
- def last_block_length(self):
+ def last_block_length(self) -> int:
return self.end(-1) - self.start(-1)
def __len__(self) -> int:
@@ -869,7 +877,7 @@ class Blocks:
return result
- def __check_completion(self):
+ def __check_completion(self) -> None:
"""The list of blocks is complete if we have created every ``Block``
object that we currently good and know that no more will be created.
@@ -899,7 +907,7 @@ class Blocks:
class _Overrun:
status = Status.OVERRUN
- def __repr__(self):
+ def __repr__(self) -> str:
return "Overrun"
@@ -1052,7 +1060,7 @@ class IRNode:
and self.was_forced == other.was_forced
)
- def __hash__(self):
+ def __hash__(self) -> int:
return hash(
(
self.ir_type,
@@ -1062,7 +1070,7 @@ class IRNode:
)
)
- def __repr__(self):
+ def __repr__(self) -> str:
# repr to avoid "BytesWarning: str() on a bytes instance" for bytes nodes
forced_marker = " [forced]" if self.was_forced else ""
return f"{self.ir_type} {self.value!r}{forced_marker} {self.kwargs!r}"
@@ -1911,8 +1919,7 @@ class HypothesisProvider(PrimitiveProvider):
"writeup - and good luck!"
)
- def permitted(f):
- assert isinstance(f, float)
+ def permitted(f: float) -> bool:
if math.isnan(f):
return allow_nan
if 0 < abs(f) < smallest_nonzero_magnitude:
@@ -2080,7 +2087,7 @@ class ConjectureData:
self._node_index = 0
self.start_example(TOP_LABEL)
- def __repr__(self):
+ def __repr__(self) -> str:
return "ConjectureData(%s, %d bytes%s)" % (
self.status.name,
len(self.buffer),
diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/engine.py b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/engine.py
index 7126918736..8c8fd18add 100644
--- a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/engine.py
+++ b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/engine.py
@@ -197,6 +197,7 @@ StatisticsDict = TypedDict(
"shrink-phase": NotRequired[PhaseStatistics],
"stopped-because": NotRequired[str],
"targets": NotRequired[Dict[str, float]],
+ "nodeid": NotRequired[str],
},
)
diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/detection.py b/contrib/python/hypothesis/py3/hypothesis/internal/detection.py
index 9d3496176a..8ce11808c3 100644
--- a/contrib/python/hypothesis/py3/hypothesis/internal/detection.py
+++ b/contrib/python/hypothesis/py3/hypothesis/internal/detection.py
@@ -11,7 +11,7 @@
from types import MethodType
-def is_hypothesis_test(test):
+def is_hypothesis_test(test: object) -> bool:
if isinstance(test, MethodType):
return is_hypothesis_test(test.__func__)
return getattr(test, "is_hypothesis_test", False)
diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/filtering.py b/contrib/python/hypothesis/py3/hypothesis/internal/filtering.py
index f352e9cb6d..bfe858ccfe 100644
--- a/contrib/python/hypothesis/py3/hypothesis/internal/filtering.py
+++ b/contrib/python/hypothesis/py3/hypothesis/internal/filtering.py
@@ -331,9 +331,9 @@ def get_float_predicate_bounds(predicate: Predicate) -> ConstructivePredicate:
return ConstructivePredicate(kwargs, predicate)
-def max_len(size: int, element: Collection) -> bool:
+def max_len(size: int, element: Collection[object]) -> bool:
return len(element) <= size
-def min_len(size: int, element: Collection) -> bool:
+def min_len(size: int, element: Collection[object]) -> bool:
return size <= len(element)
diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/scrutineer.py b/contrib/python/hypothesis/py3/hypothesis/internal/scrutineer.py
index 0cd760cf17..8f7aa4c503 100644
--- a/contrib/python/hypothesis/py3/hypothesis/internal/scrutineer.py
+++ b/contrib/python/hypothesis/py3/hypothesis/internal/scrutineer.py
@@ -18,7 +18,7 @@ from collections import defaultdict
from functools import lru_cache, reduce
from os import sep
from pathlib import Path
-from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple
+from typing import TYPE_CHECKING, Dict, Iterable, List, Optional, Set, Tuple
from hypothesis._settings import Phase, Verbosity
from hypothesis.internal.compat import PYPY
@@ -35,7 +35,7 @@ Trace: TypeAlias = Set[Branch]
@lru_cache(maxsize=None)
-def should_trace_file(fname):
+def should_trace_file(fname: str) -> bool:
# fname.startswith("<") indicates runtime code-generation via compile,
# e.g. compile("def ...", "<string>", "exec") in e.g. attrs methods.
return not (is_hypothesis_file(fname) or fname.startswith("<"))
@@ -55,12 +55,12 @@ class Tracer:
__slots__ = ("branches", "_previous_location")
- def __init__(self):
+ def __init__(self) -> None:
self.branches: Trace = set()
- self._previous_location = None
+ self._previous_location: Optional[Location] = None
@staticmethod
- def can_trace():
+ def can_trace() -> bool:
return (
(sys.version_info[:2] < (3, 12) and sys.gettrace() is None)
or (
@@ -138,7 +138,7 @@ UNHELPFUL_LOCATIONS = (
)
-def _glob_to_re(locs):
+def _glob_to_re(locs: Iterable[str]) -> str:
"""Translate a list of glob patterns to a combined regular expression.
Only the * wildcard is supported, and patterns including special
characters will only work by chance."""
diff --git a/contrib/python/hypothesis/py3/hypothesis/provisional.py b/contrib/python/hypothesis/py3/hypothesis/provisional.py
index a6f1c4afc5..aac93b6a0e 100644
--- a/contrib/python/hypothesis/py3/hypothesis/provisional.py
+++ b/contrib/python/hypothesis/py3/hypothesis/provisional.py
@@ -20,6 +20,7 @@ definitions it links to. If not, report the bug!
import string
from importlib import resources
+from typing import Optional
from hypothesis import strategies as st
from hypothesis.errors import InvalidArgument
@@ -48,7 +49,9 @@ TOP_LEVEL_DOMAINS = ["COM", *sorted((d for d in _tlds if d != "ARPA"), key=len)]
class DomainNameStrategy(st.SearchStrategy):
@staticmethod
- def clean_inputs(minimum, maximum, value, variable_name):
+ def clean_inputs(
+ minimum: int, maximum: int, value: Optional[int], variable_name: str
+ ) -> int:
if value is None:
value = maximum
elif not isinstance(value, int):
@@ -61,7 +64,9 @@ class DomainNameStrategy(st.SearchStrategy):
)
return value
- def __init__(self, max_length=None, max_element_length=None):
+ def __init__(
+ self, max_length: Optional[int] = None, max_element_length: Optional[int] = None
+ ) -> None:
"""
A strategy for :rfc:`1035` fully qualified domain names.
@@ -165,7 +170,7 @@ _url_fragments_strategy = (
def urls() -> st.SearchStrategy[str]:
"""A strategy for :rfc:`3986`, generating http/https URLs."""
- def url_encode(s):
+ def url_encode(s: str) -> str:
return "".join(c if c in URL_SAFE_CHARACTERS else "%%%02X" % ord(c) for c in s)
schemes = st.sampled_from(["http", "https"])
diff --git a/contrib/python/hypothesis/py3/hypothesis/stateful.py b/contrib/python/hypothesis/py3/hypothesis/stateful.py
index 711762d252..06e97b7ba5 100644
--- a/contrib/python/hypothesis/py3/hypothesis/stateful.py
+++ b/contrib/python/hypothesis/py3/hypothesis/stateful.py
@@ -1004,6 +1004,10 @@ class RuleStrategy(SearchStrategy):
return (rule, arguments)
def is_valid(self, rule):
+ for b in rule.bundles:
+ if not self.machine.bundle(b.name):
+ return False
+
predicates = self.machine._observability_predicates
desc = f"{self.machine.__class__.__qualname__}, rule {rule.function.__name__},"
for pred in rule.preconditions:
@@ -1013,8 +1017,4 @@ class RuleStrategy(SearchStrategy):
if not meets_precond:
return False
- for b in rule.bundles:
- bundle = self.machine.bundle(b.name)
- if not bundle:
- return False
return True
diff --git a/contrib/python/hypothesis/py3/hypothesis/statistics.py b/contrib/python/hypothesis/py3/hypothesis/statistics.py
index 465c92e9c1..bd3f4e3e30 100644
--- a/contrib/python/hypothesis/py3/hypothesis/statistics.py
+++ b/contrib/python/hypothesis/py3/hypothesis/statistics.py
@@ -10,20 +10,24 @@
import math
from collections import Counter
+from typing import TYPE_CHECKING, Dict, Iterable, List, cast
from hypothesis._settings import Phase
from hypothesis.utils.dynamicvariables import DynamicVariable
+if TYPE_CHECKING:
+ from hypothesis.internal.conjecture.engine import PhaseStatistics, StatisticsDict
+
collector = DynamicVariable(None)
-def note_statistics(stats_dict):
+def note_statistics(stats_dict: "StatisticsDict") -> None:
callback = collector.value
if callback is not None:
callback(stats_dict)
-def describe_targets(best_targets):
+def describe_targets(best_targets: Dict[str, float]) -> List[str]:
"""Return a list of lines describing the results of `target`, if any."""
# These lines are included in the general statistics description below,
# but also printed immediately below failing examples to alleviate the
@@ -41,7 +45,7 @@ def describe_targets(best_targets):
return lines
-def format_ms(times):
+def format_ms(times: Iterable[float]) -> str:
"""Format `times` into a string representing approximate milliseconds.
`times` is a collection of durations in seconds.
@@ -60,7 +64,7 @@ def format_ms(times):
return f"~ {lower}-{upper} ms"
-def describe_statistics(stats_dict):
+def describe_statistics(stats_dict: "StatisticsDict") -> str:
"""Return a multi-line string describing the passed run statistics.
`stats_dict` must be a dictionary of data in the format collected by
@@ -76,7 +80,7 @@ def describe_statistics(stats_dict):
lines = [stats_dict["nodeid"] + ":\n"] if "nodeid" in stats_dict else []
prev_failures = 0
for phase in (p.name for p in list(Phase)[1:]):
- d = stats_dict.get(phase + "-phase", {})
+ d = cast("PhaseStatistics", stats_dict.get(phase + "-phase", {}))
# Basic information we report for every phase
cases = d.get("test-cases", [])
if not cases:
diff --git a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/random.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/random.py
index 41c9feb523..30de91e234 100644
--- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/random.py
+++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/random.py
@@ -364,30 +364,31 @@ def convert_kwargs(name, kwargs):
kwargs = dict(kwargs)
signature = sig_of(name)
+ params = signature.parameters
bound = signature.bind(DUMMY_RANDOM, **kwargs)
bound.apply_defaults()
for k in list(kwargs):
if (
- kwargs[k] is signature.parameters[k].default
- or signature.parameters[k].kind != inspect.Parameter.KEYWORD_ONLY
+ kwargs[k] is params[k].default
+ or params[k].kind != inspect.Parameter.KEYWORD_ONLY
):
kwargs.pop(k)
- arg_names = list(signature.parameters)[1:]
+ arg_names = list(params)[1:]
args = []
for a in arg_names:
- if signature.parameters[a].kind == inspect.Parameter.KEYWORD_ONLY:
+ if params[a].kind == inspect.Parameter.KEYWORD_ONLY:
break
args.append(bound.arguments[a])
kwargs.pop(a, None)
while args:
name = arg_names[len(args) - 1]
- if args[-1] is signature.parameters[name].default:
+ if args[-1] is params[name].default:
args.pop()
else:
break
@@ -402,9 +403,13 @@ class TrueRandom(HypothesisRandom):
self.__random = Random(seed)
def _hypothesis_do_random(self, method, kwargs):
+ fn = getattr(self.__random, method)
+ try:
+ return fn(**kwargs)
+ except TypeError:
+ pass
args, kwargs = convert_kwargs(method, kwargs)
-
- return getattr(self.__random, method)(*args, **kwargs)
+ return fn(*args, **kwargs)
def __copy__(self):
result = TrueRandom(
diff --git a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/regex.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/regex.py
index 8de137a422..b51e90ec0c 100644
--- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/regex.py
+++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/regex.py
@@ -39,8 +39,8 @@ UNICODE_CATEGORIES = set(categories())
SPACE_CHARS = set(" \t\n\r\f\v")
UNICODE_SPACE_CHARS = SPACE_CHARS | set("\x1c\x1d\x1e\x1f\x85")
UNICODE_DIGIT_CATEGORIES = {"Nd"}
-UNICODE_SPACE_CATEGORIES = set(as_general_categories("Z"))
-UNICODE_LETTER_CATEGORIES = set(as_general_categories("L"))
+UNICODE_SPACE_CATEGORIES = set(as_general_categories(["Z"]))
+UNICODE_LETTER_CATEGORIES = set(as_general_categories(["L"]))
UNICODE_WORD_CATEGORIES = set(as_general_categories(["L", "N"]))
# This is verbose, but correct on all versions of Python
diff --git a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/strategies.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/strategies.py
index 53bee1fe22..dc7a129d06 100644
--- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/strategies.py
+++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/strategies.py
@@ -29,7 +29,7 @@ from typing import (
)
from hypothesis._settings import HealthCheck, Phase, Verbosity, settings
-from hypothesis.control import _current_build_context
+from hypothesis.control import _current_build_context, current_build_context
from hypothesis.errors import (
HypothesisException,
HypothesisWarning,
@@ -843,7 +843,7 @@ class MappedStrategy(SearchStrategy[Ex]):
x = data.draw(self.mapped_strategy)
result = self.pack(x) # type: ignore
data.stop_example()
- _current_build_context.value.record_call(result, self.pack, [x], {})
+ current_build_context().record_call(result, self.pack, [x], {})
return result
except UnsatisfiedAssumption:
data.stop_example(discard=True)
diff --git a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/types.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/types.py
index 13e01b0b05..7288d8b73a 100644
--- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/types.py
+++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/types.py
@@ -304,24 +304,24 @@ def is_a_new_type(thing):
return isinstance(thing, typing.NewType)
-def is_a_union(thing):
+def is_a_union(thing: object) -> bool:
"""Return True if thing is a typing.Union or types.UnionType (in py310)."""
return isinstance(thing, UnionType) or get_origin(thing) is typing.Union
-def is_a_type(thing):
+def is_a_type(thing: object) -> bool:
"""Return True if thing is a type or a generic type like thing."""
return isinstance(thing, type) or is_generic_type(thing) or is_a_new_type(thing)
-def is_typing_literal(thing):
+def is_typing_literal(thing: object) -> bool:
return get_origin(thing) in (
typing.Literal,
getattr(typing_extensions, "Literal", object()),
)
-def is_annotated_type(thing):
+def is_annotated_type(thing: object) -> bool:
return (
isinstance(thing, _AnnotatedAlias)
and getattr(thing, "__args__", None) is not None
diff --git a/contrib/python/hypothesis/py3/hypothesis/utils/dynamicvariables.py b/contrib/python/hypothesis/py3/hypothesis/utils/dynamicvariables.py
index ad00cc8b48..cb823628b2 100644
--- a/contrib/python/hypothesis/py3/hypothesis/utils/dynamicvariables.py
+++ b/contrib/python/hypothesis/py3/hypothesis/utils/dynamicvariables.py
@@ -10,23 +10,26 @@
import threading
from contextlib import contextmanager
+from typing import Generator, Generic, TypeVar
+T = TypeVar("T")
-class DynamicVariable:
- def __init__(self, default):
+
+class DynamicVariable(Generic[T]):
+ def __init__(self, default: T) -> None:
self.default = default
self.data = threading.local()
@property
- def value(self):
+ def value(self) -> T:
return getattr(self.data, "value", self.default)
@value.setter
- def value(self, value):
+ def value(self, value: T) -> None:
self.data.value = value
@contextmanager
- def with_value(self, value):
+ def with_value(self, value: T) -> Generator[None, None, None]:
old_value = self.value
try:
self.data.value = value
diff --git a/contrib/python/hypothesis/py3/hypothesis/version.py b/contrib/python/hypothesis/py3/hypothesis/version.py
index 59f3d40b73..a2112a2f36 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, 112, 3)
+__version_info__ = (6, 112, 4)
__version__ = ".".join(map(str, __version_info__))
diff --git a/contrib/python/hypothesis/py3/ya.make b/contrib/python/hypothesis/py3/ya.make
index d735c78f1a..7dc523a75e 100644
--- a/contrib/python/hypothesis/py3/ya.make
+++ b/contrib/python/hypothesis/py3/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(6.112.3)
+VERSION(6.112.4)
LICENSE(MPL-2.0)