aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrobot-piglet <robot-piglet@yandex-team.com>2023-12-12 09:19:01 +0300
committerrobot-piglet <robot-piglet@yandex-team.com>2023-12-12 09:56:20 +0300
commit965ccc1b60627c70d0cedc79d0a738dc6bcd03a5 (patch)
tree2ef73c31348105b0bd00977d490323b7869b25aa
parent1823321f2d789b9ae9ff875a4861d998c6071ed9 (diff)
downloadydb-965ccc1b60627c70d0cedc79d0a738dc6bcd03a5.tar.gz
Intermediate changes
-rw-r--r--contrib/python/hypothesis/py3/.dist-info/METADATA3
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/control.py29
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/core.py8
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py10
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/internal/conjecture/engine.py21
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/internal/escalation.py53
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/internal/lazyformat.py33
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/stateful.py2
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/strategies/_internal/datetime.py6
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/strategies/_internal/recursive.py13
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/strategies/_internal/strategies.py8
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/strategies/_internal/types.py4
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/vendor/tlds-alpha-by-domain.txt3
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/version.py2
-rw-r--r--contrib/python/hypothesis/py3/ya.make3
15 files changed, 86 insertions, 112 deletions
diff --git a/contrib/python/hypothesis/py3/.dist-info/METADATA b/contrib/python/hypothesis/py3/.dist-info/METADATA
index b6eca63e8f..2a7e253367 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.90.0
+Version: 6.91.0
Summary: A library for property-based testing
Home-page: https://hypothesis.works
Author: David R. MacIver and Zac Hatfield-Dodds
@@ -26,6 +26,7 @@ Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Education :: Testing
diff --git a/contrib/python/hypothesis/py3/hypothesis/control.py b/contrib/python/hypothesis/py3/hypothesis/control.py
index eb1768c565..c49dba2954 100644
--- a/contrib/python/hypothesis/py3/hypothesis/control.py
+++ b/contrib/python/hypothesis/py3/hypothesis/control.py
@@ -11,6 +11,7 @@
import math
from collections import defaultdict
from typing import NoReturn, Union
+from weakref import WeakKeyDictionary
from hypothesis import Verbosity, settings
from hypothesis._settings import note_deprecation
@@ -168,18 +169,38 @@ def note(value: str) -> None:
report(value)
-def event(value: str) -> None:
- """Record an event that occurred this test. Statistics on number of test
+def event(value: str, payload: Union[str, int, float] = "") -> None:
+ """Record an event that occurred during this test. Statistics on the number of test
runs with each event will be reported at the end if you run Hypothesis in
statistics reporting mode.
- Events should be strings or convertible to them.
+ Event values should be strings or convertible to them. If an optional
+ payload is given, it will be included in the string for :ref:`statistics`.
"""
context = _current_build_context.value
if context is None:
raise InvalidArgument("Cannot make record events outside of a test")
- context.data.note_event(value)
+ payload = _event_to_string(payload, (str, int, float))
+ context.data.events[_event_to_string(value)] = payload
+
+
+_events_to_strings: WeakKeyDictionary = WeakKeyDictionary()
+
+
+def _event_to_string(event, allowed_types=str):
+ if isinstance(event, allowed_types):
+ return event
+ try:
+ return _events_to_strings[event]
+ except (KeyError, TypeError):
+ pass
+ result = str(event)
+ try:
+ _events_to_strings[event] = result
+ except TypeError:
+ pass
+ return result
def target(observation: Union[int, float], *, label: str = "") -> Union[int, float]:
diff --git a/contrib/python/hypothesis/py3/hypothesis/core.py b/contrib/python/hypothesis/py3/hypothesis/core.py
index 1c4cf9e144..b2298418c8 100644
--- a/contrib/python/hypothesis/py3/hypothesis/core.py
+++ b/contrib/python/hypothesis/py3/hypothesis/core.py
@@ -80,10 +80,10 @@ from hypothesis.internal.conjecture.junkdrawer import ensure_free_stackframes
from hypothesis.internal.conjecture.shrinker import sort_key
from hypothesis.internal.entropy import deterministic_PRNG
from hypothesis.internal.escalation import (
+ InterestingOrigin,
current_pytest_item,
escalate_hypothesis_internal_error,
format_exception,
- get_interesting_origin,
get_trimmed_traceback,
)
from hypothesis.internal.healthcheck import fail_health_check
@@ -970,7 +970,7 @@ class StateForActualGivenExecution:
self.failed_normally = True
- interesting_origin = get_interesting_origin(e)
+ interesting_origin = InterestingOrigin.from_exception(e)
if trace: # pragma: no cover
# Trace collection is explicitly disabled under coverage.
self.explain_traces[interesting_origin].add(trace)
@@ -1037,7 +1037,9 @@ class StateForActualGivenExecution:
info = falsifying_example.extra_information
fragments = []
- ran_example = ConjectureData.for_buffer(falsifying_example.buffer)
+ ran_example = runner.new_conjecture_data_for_buffer(
+ falsifying_example.buffer
+ )
ran_example.slice_comments = falsifying_example.slice_comments
assert info.__expected_exception is not None
try:
diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py
index 7eb5fbe080..2f086bf04f 100644
--- a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py
+++ b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py
@@ -20,7 +20,6 @@ from typing import (
Callable,
Dict,
FrozenSet,
- Hashable,
Iterable,
Iterator,
List,
@@ -1367,7 +1366,7 @@ class ConjectureData:
self.testcounter = global_test_counter
global_test_counter += 1
self.start_time = time.perf_counter()
- self.events: "Union[Set[Hashable], FrozenSet[Hashable]]" = set()
+ self.events: Dict[str, Union[str, int, float]] = {}
self.forced_indices: "Set[int]" = set()
self.interesting_origin: Optional[InterestingOrigin] = None
self.draw_times: "List[float]" = []
@@ -1615,10 +1614,6 @@ class ConjectureData:
self.observer.kill_branch()
- def note_event(self, event: Hashable) -> None:
- assert isinstance(self.events, set)
- self.events.add(event)
-
@property
def examples(self) -> Examples:
assert self.frozen
@@ -1643,7 +1638,6 @@ class ConjectureData:
self.frozen = True
self.buffer = bytes(self.buffer)
- self.events = frozenset(self.events)
self.observer.conclude_test(self.status, self.interesting_origin)
def draw_bits(self, n: int, *, forced: Optional[int] = None) -> int:
@@ -1729,7 +1723,7 @@ class ConjectureData:
def mark_invalid(self, why: Optional[str] = None) -> NoReturn:
if why is not None:
- self.note_event(why)
+ self.events["invalid because"] = why
self.conclude_test(Status.INVALID)
def mark_overrun(self) -> NoReturn:
diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/engine.py b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/engine.py
index 6944e127de..c5d33480e2 100644
--- a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/engine.py
+++ b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/engine.py
@@ -15,7 +15,6 @@ from contextlib import contextmanager
from datetime import timedelta
from enum import Enum
from random import Random, getrandbits
-from weakref import WeakKeyDictionary
import attr
@@ -101,8 +100,6 @@ class ConjectureRunner:
self.statistics = {}
self.stats_per_test_case = []
- self.events_to_strings = WeakKeyDictionary()
-
self.interesting_examples = {}
# We use call_count because there may be few possible valid_examples.
self.first_bug_found_at = None
@@ -209,7 +206,9 @@ class ConjectureRunner:
"status": data.status.name.lower(),
"runtime": data.finish_time - data.start_time,
"drawtime": math.fsum(data.draw_times),
- "events": sorted({self.event_to_string(e) for e in data.events}),
+ "events": sorted(
+ k if v == "" else f"{k}: {v}" for k, v in data.events.items()
+ ),
}
self.stats_per_test_case.append(call_stats)
self.__data_cache[data.buffer] = data.as_result()
@@ -1055,20 +1054,6 @@ class ConjectureRunner:
self.__data_cache[buffer] = result
return result
- def event_to_string(self, event):
- if isinstance(event, str):
- return event
- try:
- return self.events_to_strings[event]
- except (KeyError, TypeError):
- pass
- result = str(event)
- try:
- self.events_to_strings[event] = result
- except TypeError:
- pass
- return result
-
def passing_buffers(self, prefix=b""):
"""Return a collection of bytestrings which cause the test to pass.
diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/escalation.py b/contrib/python/hypothesis/py3/hypothesis/internal/escalation.py
index 605ea52e97..9261d2aefc 100644
--- a/contrib/python/hypothesis/py3/hypothesis/internal/escalation.py
+++ b/contrib/python/hypothesis/py3/hypothesis/internal/escalation.py
@@ -11,10 +11,11 @@
import contextlib
import os
import sys
+import textwrap
import traceback
from inspect import getframeinfo
from pathlib import Path
-from typing import Dict
+from typing import Dict, NamedTuple, Optional, Type
import hypothesis
from hypothesis.errors import (
@@ -105,32 +106,46 @@ def get_trimmed_traceback(exception=None):
return tb
-def get_interesting_origin(exception):
+class InterestingOrigin(NamedTuple):
# The `interesting_origin` is how Hypothesis distinguishes between multiple
# failures, for reporting and also to replay from the example database (even
# if report_multiple_bugs=False). We traditionally use the exception type and
# location, but have extracted this logic in order to see through `except ...:`
# blocks and understand the __cause__ (`raise x from y`) or __context__ that
# first raised an exception as well as PEP-654 exception groups.
- tb = get_trimmed_traceback(exception)
- if tb is None:
+ exc_type: Type[BaseException]
+ filename: Optional[str]
+ lineno: Optional[int]
+ context: "InterestingOrigin | tuple[()]"
+ group_elems: "tuple[InterestingOrigin, ...]"
+
+ def __str__(self) -> str:
+ ctx = ""
+ if self.context:
+ ctx = textwrap.indent(f"\ncontext: {self.context}", prefix=" ")
+ group = ""
+ if self.group_elems:
+ chunks = "\n ".join(str(x) for x in self.group_elems)
+ group = textwrap.indent(f"\nchild exceptions:\n {chunks}", prefix=" ")
+ return f"{self.exc_type.__name__} at {self.filename}:{self.lineno}{ctx}{group}"
+
+ @classmethod
+ def from_exception(cls, exception: BaseException, /) -> "InterestingOrigin":
filename, lineno = None, None
- else:
- filename, lineno, *_ = traceback.extract_tb(tb)[-1]
- return (
- type(exception),
- filename,
- lineno,
- # Note that if __cause__ is set it is always equal to __context__, explicitly
- # to support introspection when debugging, so we can use that unconditionally.
- get_interesting_origin(exception.__context__) if exception.__context__ else (),
- # We distinguish exception groups by the inner exceptions, as for __context__
- tuple(
- map(get_interesting_origin, exception.exceptions)
+ if tb := get_trimmed_traceback(exception):
+ filename, lineno, *_ = traceback.extract_tb(tb)[-1]
+ return cls(
+ type(exception),
+ filename,
+ lineno,
+ # Note that if __cause__ is set it is always equal to __context__, explicitly
+ # to support introspection when debugging, so we can use that unconditionally.
+ cls.from_exception(exception.__context__) if exception.__context__ else (),
+ # We distinguish exception groups by the inner exceptions, as for __context__
+ tuple(map(cls.from_exception, exception.exceptions))
if isinstance(exception, BaseExceptionGroup)
- else []
- ),
- )
+ else (),
+ )
current_pytest_item = DynamicVariable(None)
diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/lazyformat.py b/contrib/python/hypothesis/py3/hypothesis/internal/lazyformat.py
deleted file mode 100644
index 9a728c6380..0000000000
--- a/contrib/python/hypothesis/py3/hypothesis/internal/lazyformat.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# This file is part of Hypothesis, which may be found at
-# https://github.com/HypothesisWorks/hypothesis/
-#
-# Copyright the Hypothesis Authors.
-# Individual contributors are listed in AUTHORS.rst and the git log.
-#
-# 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 https://mozilla.org/MPL/2.0/.
-
-
-class lazyformat:
- """A format string that isn't evaluated until it's needed."""
-
- def __init__(self, format_string, *args):
- self.__format_string = format_string
- self.__args = args
-
- def __str__(self):
- return self.__format_string % self.__args
-
- def __eq__(self, other):
- return (
- isinstance(other, lazyformat)
- and self.__format_string == other.__format_string
- and self.__args == other.__args
- )
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- def __hash__(self):
- return hash(self.__format_string)
diff --git a/contrib/python/hypothesis/py3/hypothesis/stateful.py b/contrib/python/hypothesis/py3/hypothesis/stateful.py
index e70c805815..39ce653981 100644
--- a/contrib/python/hypothesis/py3/hypothesis/stateful.py
+++ b/contrib/python/hypothesis/py3/hypothesis/stateful.py
@@ -402,7 +402,7 @@ class RuleBasedStateMachine(metaclass=StateMachineMeta):
settings = Settings(deadline=None, suppress_health_check=list(HealthCheck))
def runTest(self):
- run_state_machine_as_test(cls)
+ run_state_machine_as_test(cls, settings=self.settings)
runTest.is_hypothesis_test = True
diff --git a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/datetime.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/datetime.py
index abf77c5026..f2c33fa8c5 100644
--- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/datetime.py
+++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/datetime.py
@@ -163,8 +163,10 @@ class DatetimeStrategy(SearchStrategy):
try:
return replace_tzinfo(dt.datetime(**result), timezone=tz)
except (ValueError, OverflowError):
- msg = "Failed to draw a datetime between %r and %r with timezone from %r."
- data.mark_invalid(msg % (self.min_value, self.max_value, self.tz_strat))
+ data.mark_invalid(
+ f"Failed to draw a datetime between {self.min_value!r} and "
+ f"{self.max_value!r} with timezone from {self.tz_strat!r}."
+ )
@defines_strategy(force_reusable_values=True)
diff --git a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/recursive.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/recursive.py
index 7709b45460..cf7add9538 100644
--- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/recursive.py
+++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/recursive.py
@@ -12,7 +12,6 @@ import threading
from contextlib import contextmanager
from hypothesis.errors import InvalidArgument
-from hypothesis.internal.lazyformat import lazyformat
from hypothesis.internal.reflection import get_pretty_function_description
from hypothesis.internal.validation import check_type
from hypothesis.strategies._internal.strategies import (
@@ -112,13 +111,7 @@ class RecursiveStrategy(SearchStrategy):
with self.limited_base.capped(self.max_leaves):
return data.draw(self.strategy)
except LimitReached:
- # Workaround for possible coverage bug - this branch is definitely
- # covered but for some reason is showing up as not covered.
- if count == 0: # pragma: no branch
- data.note_event(
- lazyformat(
- "Draw for %r exceeded max_leaves and had to be retried",
- self,
- )
- )
+ if count == 0:
+ msg = f"Draw for {self!r} exceeded max_leaves and had to be retried"
+ data.events[msg] = ""
count += 1
diff --git a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/strategies.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/strategies.py
index 6b68a1d353..caf8d1ba9a 100644
--- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/strategies.py
+++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/strategies.py
@@ -43,7 +43,6 @@ from hypothesis.internal.conjecture.utils import (
combine_labels,
)
from hypothesis.internal.coverage import check_function
-from hypothesis.internal.lazyformat import lazyformat
from hypothesis.internal.reflection import (
get_pretty_function_description,
is_identity_function,
@@ -550,7 +549,7 @@ class SampledFromStrategy(SearchStrategy):
if element is not filter_not_satisfied:
return element
if not known_bad_indices:
- FilteredStrategy.note_retried(self, data)
+ data.events[f"Retried draw from {self!r} to satisfy filter"] = ""
known_bad_indices.add(i)
# If we've tried all the possible elements, give up now.
@@ -940,9 +939,6 @@ class FilteredStrategy(SearchStrategy[Ex]):
data.mark_invalid(f"Aborted test because unable to satisfy {self!r}")
raise NotImplementedError("Unreachable, for Mypy")
- def note_retried(self, data):
- data.note_event(lazyformat("Retried draw from %r to satisfy filter", self))
-
def do_filtered_draw(self, data):
for i in range(3):
start_index = data.index
@@ -954,7 +950,7 @@ class FilteredStrategy(SearchStrategy[Ex]):
else:
data.stop_example(discard=True)
if i == 0:
- self.note_retried(data)
+ data.events[f"Retried draw from {self!r} to satisfy filter"] = ""
# This is to guard against the case where we consume no data.
# As long as we consume data, we'll eventually pass or raise.
# But if we don't this could be an infinite loop.
diff --git a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/types.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/types.py
index d979081415..aba2e457a0 100644
--- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/types.py
+++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/types.py
@@ -275,7 +275,7 @@ def is_annotated_type(thing):
def get_constraints_filter_map():
- if at := sys.modules.get("annotated_types"): # pragma: no branch
+ if at := sys.modules.get("annotated_types"):
return {
# Due to the order of operator.gt/ge/lt/le arguments, order is inversed:
at.Gt: lambda constraint: partial(operator.lt, constraint.gt),
@@ -290,7 +290,7 @@ def get_constraints_filter_map():
def _get_constraints(args: Tuple[Any, ...]) -> Iterator["at.BaseMetadata"]:
- if at := sys.modules.get("annotated_types"): # pragma: no branch
+ if at := sys.modules.get("annotated_types"):
for arg in args:
if isinstance(arg, at.BaseMetadata):
yield arg
diff --git a/contrib/python/hypothesis/py3/hypothesis/vendor/tlds-alpha-by-domain.txt b/contrib/python/hypothesis/py3/hypothesis/vendor/tlds-alpha-by-domain.txt
index 5402c8d9cb..98deba4045 100644
--- a/contrib/python/hypothesis/py3/hypothesis/vendor/tlds-alpha-by-domain.txt
+++ b/contrib/python/hypothesis/py3/hypothesis/vendor/tlds-alpha-by-domain.txt
@@ -1,4 +1,4 @@
-# Version 2023111800, Last Updated Sat Nov 18 07:07:01 2023 UTC
+# Version 2023112500, Last Updated Sat Nov 25 07:07:01 2023 UTC
AAA
AARP
ABB
@@ -1234,7 +1234,6 @@ VIVO
VLAANDEREN
VN
VODKA
-VOLKSWAGEN
VOLVO
VOTE
VOTING
diff --git a/contrib/python/hypothesis/py3/hypothesis/version.py b/contrib/python/hypothesis/py3/hypothesis/version.py
index 158c609209..9b0a5e2eb1 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, 90, 0)
+__version_info__ = (6, 91, 0)
__version__ = ".".join(map(str, __version_info__))
diff --git a/contrib/python/hypothesis/py3/ya.make b/contrib/python/hypothesis/py3/ya.make
index b9abaef8bd..100509362e 100644
--- a/contrib/python/hypothesis/py3/ya.make
+++ b/contrib/python/hypothesis/py3/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(6.90.0)
+VERSION(6.91.0)
LICENSE(MPL-2.0)
@@ -82,7 +82,6 @@ PY_SRCS(
hypothesis/internal/floats.py
hypothesis/internal/healthcheck.py
hypothesis/internal/intervalsets.py
- hypothesis/internal/lazyformat.py
hypothesis/internal/reflection.py
hypothesis/internal/scrutineer.py
hypothesis/internal/validation.py