diff options
author | robot-piglet <robot-piglet@yandex-team.com> | 2024-03-18 11:23:15 +0300 |
---|---|---|
committer | robot-piglet <robot-piglet@yandex-team.com> | 2024-03-18 12:07:29 +0300 |
commit | f76d5c18094373da03ee99d739fa6e889834348d (patch) | |
tree | ad3ce3dfc0dfe6a091ca945258a1ef0359665bb2 | |
parent | ad1397315931a7eed7876705ab0722fec53d76bd (diff) | |
download | ydb-f76d5c18094373da03ee99d739fa6e889834348d.tar.gz |
Intermediate changes
6 files changed, 139 insertions, 32 deletions
diff --git a/contrib/python/hypothesis/py3/.dist-info/METADATA b/contrib/python/hypothesis/py3/.dist-info/METADATA index 6b4024e132..8215d8ef3d 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.98.15 +Version: 6.98.16 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/core.py b/contrib/python/hypothesis/py3/hypothesis/core.py index 536d7f0156..4e4411fadf 100644 --- a/contrib/python/hypothesis/py3/hypothesis/core.py +++ b/contrib/python/hypothesis/py3/hypothesis/core.py @@ -108,6 +108,7 @@ from hypothesis.internal.reflection import ( repr_call, ) from hypothesis.internal.scrutineer import ( + MONITORING_TOOL_ID, Trace, Tracer, explanatory_lines, @@ -983,8 +984,27 @@ class StateForActualGivenExecution: """ trace: Trace = set() try: + # this is actually covered by our tests, but only on >= 3.12. + if ( + sys.version_info[:2] >= (3, 12) + and sys.monitoring.get_tool(MONITORING_TOOL_ID) is not None + ): # pragma: no cover + warnings.warn( + "avoiding tracing test function because tool id " + f"{MONITORING_TOOL_ID} is already taken by tool " + f"{sys.monitoring.get_tool(MONITORING_TOOL_ID)}.", + HypothesisWarning, + # I'm not sure computing a correct stacklevel is reasonable + # given the number of entry points here. + stacklevel=1, + ) + _can_trace = ( - sys.gettrace() is None or sys.version_info[:2] >= (3, 12) + (sys.version_info[:2] < (3, 12) and sys.gettrace() is None) + or ( + sys.version_info[:2] >= (3, 12) + and sys.monitoring.get_tool(MONITORING_TOOL_ID) is None + ) ) and not PYPY _trace_obs = TESTCASE_CALLBACKS and OBSERVABILITY_COLLECT_COVERAGE _trace_failure = ( diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py index b84db4df85..10c4e17faf 100644 --- a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py +++ b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py @@ -203,6 +203,8 @@ NASTY_FLOATS.extend([-x for x in NASTY_FLOATS]) FLOAT_INIT_LOGIC_CACHE = LRUReusedCache(4096) +POOLED_KWARGS_CACHE = LRUReusedCache(4096) + DRAW_STRING_DEFAULT_MAX_SIZE = 10**10 # "arbitrarily large" @@ -334,6 +336,7 @@ class ExampleProperty: self.bytes_read = 0 self.example_count = 0 self.block_count = 0 + self.ir_node_count = 0 def run(self) -> Any: """Rerun the test case with this visitor and return the @@ -347,6 +350,10 @@ class ExampleProperty: self.block(self.block_count) self.block_count += 1 self.__pop(discarded=False) + elif record == IR_NODE_RECORD: + data = self.examples.ir_nodes[self.ir_node_count] + self.ir_node(data) + self.ir_node_count += 1 elif record >= START_EXAMPLE_RECORD: self.__push(record - START_EXAMPLE_RECORD) else: @@ -387,6 +394,9 @@ class ExampleProperty: index of the example and ``discarded`` being ``True`` if ``stop_example`` was called with ``discard=True``.""" + def ir_node(self, node: "IRNode") -> None: + """Called when an ir node is drawn.""" + def finish(self) -> Any: return self.result @@ -419,6 +429,8 @@ STOP_EXAMPLE_DISCARD_RECORD = 1 STOP_EXAMPLE_NO_DISCARD_RECORD = 2 START_EXAMPLE_RECORD = 3 +IR_NODE_RECORD = calc_label_from_name("ir draw record") + class ExampleRecord: """Records the series of ``start_example``, ``stop_example``, and @@ -435,10 +447,18 @@ class ExampleRecord: self.labels = [DRAW_BYTES_LABEL] self.__index_of_labels: "Optional[Dict[int, int]]" = {DRAW_BYTES_LABEL: 0} self.trail = IntList() + self.ir_nodes: List[IRNode] = [] def freeze(self) -> None: self.__index_of_labels = None + def record_ir_draw(self, ir_type, value, *, kwargs, was_forced): + self.trail.append(IR_NODE_RECORD) + node = IRNode( + ir_type=ir_type, value=value, kwargs=kwargs, was_forced=was_forced + ) + self.ir_nodes.append(node) + def start_example(self, label: int) -> None: assert self.__index_of_labels is not None try: @@ -454,7 +474,7 @@ class ExampleRecord: else: self.trail.append(STOP_EXAMPLE_NO_DISCARD_RECORD) - def draw_bits(self, n: int, forced: Optional[int]) -> None: + def draw_bits(self) -> None: self.trail.append(DRAW_BITS_RECORD) @@ -471,6 +491,7 @@ class Examples: def __init__(self, record: ExampleRecord, blocks: "Blocks") -> None: self.trail = record.trail + self.ir_nodes = record.ir_nodes self.labels = record.labels self.__length = ( self.trail.count(STOP_EXAMPLE_DISCARD_RECORD) @@ -556,6 +577,15 @@ class Examples: depths: IntList = calculated_example_property(_depths) + class _ir_tree_nodes(ExampleProperty): + def begin(self): + self.result = [] + + def ir_node(self, ir_node): + self.result.append(ir_node) + + ir_tree_nodes: "List[IRNode]" = calculated_example_property(_ir_tree_nodes) + class _label_indices(ExampleProperty): def start_example(self, i: int, label_index: int) -> None: self.result[i] = label_index @@ -856,31 +886,39 @@ class DataObserver: """Mark this part of the tree as not worth re-exploring.""" def draw_integer( - self, value: int, *, was_forced: bool, kwargs: IntegerKWargs + self, value: int, *, kwargs: IntegerKWargs, was_forced: bool ) -> None: pass def draw_float( - self, value: float, *, was_forced: bool, kwargs: FloatKWargs + self, value: float, *, kwargs: FloatKWargs, was_forced: bool ) -> None: pass def draw_string( - self, value: str, *, was_forced: bool, kwargs: StringKWargs + self, value: str, *, kwargs: StringKWargs, was_forced: bool ) -> None: pass def draw_bytes( - self, value: bytes, *, was_forced: bool, kwargs: BytesKWargs + self, value: bytes, *, kwargs: BytesKWargs, was_forced: bool ) -> None: pass def draw_boolean( - self, value: bool, *, was_forced: bool, kwargs: BooleanKWargs + self, value: bool, *, kwargs: BooleanKWargs, was_forced: bool ) -> None: pass +@attr.s(slots=True) +class IRNode: + ir_type: IRTypeName = attr.ib() + value: IRType = attr.ib() + kwargs: IRKWargsType = attr.ib() + was_forced: bool = attr.ib() + + @dataclass_transform() @attr.s(slots=True) class ConjectureResult: @@ -1142,7 +1180,9 @@ class PrimitiveProvider: result = self._draw_float( forced_sign_bit=forced_sign_bit, forced=forced ) - if math.copysign(1.0, result) == -1: + if allow_nan and math.isnan(result): + clamped = result + elif math.copysign(1.0, result) == -1: assert neg_clamper is not None clamped = -neg_clamper(-result) else: @@ -1568,16 +1608,22 @@ class ConjectureData: if forced is not None and max_value is not None: assert forced <= max_value - kwargs: IntegerKWargs = { - "min_value": min_value, - "max_value": max_value, - "weights": weights, - "shrink_towards": shrink_towards, - } + kwargs: IntegerKWargs = self._pooled_kwargs( + "integer", + { + "min_value": min_value, + "max_value": max_value, + "weights": weights, + "shrink_towards": shrink_towards, + }, + ) value = self.provider.draw_integer(**kwargs, forced=forced) if observe: self.observer.draw_integer( - value, was_forced=forced is not None, kwargs=kwargs + value, kwargs=kwargs, was_forced=forced is not None + ) + self.__example_record.record_ir_draw( + "integer", value, kwargs=kwargs, was_forced=forced is not None ) return value @@ -1605,17 +1651,23 @@ class ConjectureData: sign_aware_lte(min_value, forced) and sign_aware_lte(forced, max_value) ) - kwargs: FloatKWargs = { - "min_value": min_value, - "max_value": max_value, - "allow_nan": allow_nan, - "smallest_nonzero_magnitude": smallest_nonzero_magnitude, - } + kwargs: FloatKWargs = self._pooled_kwargs( + "float", + { + "min_value": min_value, + "max_value": max_value, + "allow_nan": allow_nan, + "smallest_nonzero_magnitude": smallest_nonzero_magnitude, + }, + ) value = self.provider.draw_float(**kwargs, forced=forced) if observe: self.observer.draw_float( value, kwargs=kwargs, was_forced=forced is not None ) + self.__example_record.record_ir_draw( + "float", value, kwargs=kwargs, was_forced=forced is not None + ) return value def draw_string( @@ -1629,16 +1681,22 @@ class ConjectureData: ) -> str: assert forced is None or min_size <= len(forced) - kwargs: StringKWargs = { - "intervals": intervals, - "min_size": min_size, - "max_size": max_size, - } + kwargs: StringKWargs = self._pooled_kwargs( + "string", + { + "intervals": intervals, + "min_size": min_size, + "max_size": max_size, + }, + ) value = self.provider.draw_string(**kwargs, forced=forced) if observe: self.observer.draw_string( value, kwargs=kwargs, was_forced=forced is not None ) + self.__example_record.record_ir_draw( + "string", value, kwargs=kwargs, was_forced=forced is not None + ) return value def draw_bytes( @@ -1652,12 +1710,15 @@ class ConjectureData: assert forced is None or len(forced) == size assert size >= 0 - kwargs: BytesKWargs = {"size": size} + kwargs: BytesKWargs = self._pooled_kwargs("bytes", {"size": size}) value = self.provider.draw_bytes(**kwargs, forced=forced) if observe: self.observer.draw_bytes( value, kwargs=kwargs, was_forced=forced is not None ) + self.__example_record.record_ir_draw( + "bytes", value, kwargs=kwargs, was_forced=forced is not None + ) return value def draw_boolean( @@ -1673,14 +1734,37 @@ class ConjectureData: if forced is False: assert p < (1 - 2 ** (-64)) - kwargs: BooleanKWargs = {"p": p} + kwargs: BooleanKWargs = self._pooled_kwargs("boolean", {"p": p}) value = self.provider.draw_boolean(**kwargs, forced=forced) if observe: self.observer.draw_boolean( value, kwargs=kwargs, was_forced=forced is not None ) + self.__example_record.record_ir_draw( + "boolean", value, kwargs=kwargs, was_forced=forced is not None + ) return value + def _pooled_kwargs(self, ir_type, kwargs): + """Memoize common dictionary objects to reduce memory pressure.""" + key = [] + for k, v in kwargs.items(): + if ir_type == "float" and k in ["min_value", "max_value"]: + # handle -0.0 vs 0.0, etc. + v = float_to_int(v) + elif ir_type == "integer" and k == "weights": + # make hashable + v = v if v is None else tuple(v) + key.append((k, v)) + + key = (ir_type, *sorted(key)) + + try: + return POOLED_KWARGS_CACHE[key] + except KeyError: + POOLED_KWARGS_CACHE[key] = kwargs + return kwargs + def as_result(self) -> Union[ConjectureResult, _Overrun]: """Convert the result of running this test into either an Overrun object or a ConjectureResult.""" @@ -1901,7 +1985,7 @@ class ConjectureData: buf = bytes(buf) result = int_from_bytes(buf) - self.__example_record.draw_bits(n, forced) + self.__example_record.draw_bits() initial = self.index diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/intervalsets.py b/contrib/python/hypothesis/py3/hypothesis/internal/intervalsets.py index 88162b6332..e48802ee77 100644 --- a/contrib/python/hypothesis/py3/hypothesis/internal/intervalsets.py +++ b/contrib/python/hypothesis/py3/hypothesis/internal/intervalsets.py @@ -102,6 +102,9 @@ class IntervalSet: def __eq__(self, other): return isinstance(other, IntervalSet) and (other.intervals == self.intervals) + def __hash__(self): + return hash(self.intervals) + def union(self, other): """Merge two sequences of intervals into a single tuple of intervals. diff --git a/contrib/python/hypothesis/py3/hypothesis/version.py b/contrib/python/hypothesis/py3/hypothesis/version.py index f7e0632c1c..2c4aff4b5b 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, 98, 15) +__version_info__ = (6, 98, 16) __version__ = ".".join(map(str, __version_info__)) diff --git a/contrib/python/hypothesis/py3/ya.make b/contrib/python/hypothesis/py3/ya.make index 9f6cd41682..ed3cec24db 100644 --- a/contrib/python/hypothesis/py3/ya.make +++ b/contrib/python/hypothesis/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(6.98.15) +VERSION(6.98.16) LICENSE(MPL-2.0) |