From 33ea4d52a7e5bdde6d5541ae6b10d9d32940f31d Mon Sep 17 00:00:00 2001 From: robot-piglet Date: Sun, 18 Feb 2024 14:26:38 +0300 Subject: Intermediate changes --- contrib/python/hypothesis/py3/.dist-info/METADATA | 2 +- .../python/hypothesis/py3/hypothesis/control.py | 25 +++++++++++++++------- contrib/python/hypothesis/py3/hypothesis/core.py | 8 +++++-- .../py3/hypothesis/internal/conjecture/data.py | 3 +++ .../py3/hypothesis/internal/observability.py | 18 ++++++++++++++-- .../python/hypothesis/py3/hypothesis/stateful.py | 11 ++++++++-- .../python/hypothesis/py3/hypothesis/version.py | 2 +- contrib/python/hypothesis/py3/ya.make | 2 +- 8 files changed, 54 insertions(+), 17 deletions(-) (limited to 'contrib/python') diff --git a/contrib/python/hypothesis/py3/.dist-info/METADATA b/contrib/python/hypothesis/py3/.dist-info/METADATA index 04454aaec74..22fef6f6ba4 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.97.4 +Version: 6.97.5 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/control.py b/contrib/python/hypothesis/py3/hypothesis/control.py index 92b26069c5a..f4a400072f9 100644 --- a/contrib/python/hypothesis/py3/hypothesis/control.py +++ b/contrib/python/hypothesis/py3/hypothesis/control.py @@ -11,7 +11,7 @@ import inspect import math from collections import defaultdict -from typing import NoReturn, Union +from typing import Any, NoReturn, Union from weakref import WeakKeyDictionary from hypothesis import Verbosity, settings @@ -19,6 +19,7 @@ from hypothesis._settings import note_deprecation from hypothesis.errors import InvalidArgument, UnsatisfiedAssumption from hypothesis.internal.compat import BaseExceptionGroup from hypothesis.internal.conjecture.data import ConjectureData +from hypothesis.internal.observability import TESTCASE_CALLBACKS from hypothesis.internal.reflection import get_pretty_function_description from hypothesis.internal.validation import check_type from hypothesis.reporting import report, verbose_report @@ -26,8 +27,9 @@ from hypothesis.utils.dynamicvariables import DynamicVariable from hypothesis.vendor.pretty import IDKey, pretty -def _calling_function_name(frame): - return frame.f_back.f_code.co_name +def _calling_function_location(what: str, frame: Any) -> str: + where = frame.f_back + return f"{what}() in {where.f_code.co_name} (line {where.f_lineno})" def reject() -> NoReturn: @@ -37,8 +39,11 @@ def reject() -> NoReturn: since="2023-09-25", has_codemod=False, ) - f = _calling_function_name(inspect.currentframe()) - raise UnsatisfiedAssumption(f"reject() in {f}") + where = _calling_function_location("reject", inspect.currentframe()) + if currently_in_test_context(): + count = current_build_context().data._observability_predicates[where] + count["unsatisfied"] += 1 + raise UnsatisfiedAssumption(where) def assume(condition: object) -> bool: @@ -54,9 +59,13 @@ def assume(condition: object) -> bool: since="2023-09-25", has_codemod=False, ) - if not condition: - f = _calling_function_name(inspect.currentframe()) - raise UnsatisfiedAssumption(f"failed to satisfy assume() in {f}") + if TESTCASE_CALLBACKS or not condition: + where = _calling_function_location("assume", inspect.currentframe()) + if TESTCASE_CALLBACKS and currently_in_test_context(): + predicates = current_build_context().data._observability_predicates + predicates[where]["satisfied" if condition else "unsatisfied"] += 1 + if not condition: + raise UnsatisfiedAssumption(f"failed to satisfy {where}") return True diff --git a/contrib/python/hypothesis/py3/hypothesis/core.py b/contrib/python/hypothesis/py3/hypothesis/core.py index 601c33e176d..e000da174f3 100644 --- a/contrib/python/hypothesis/py3/hypothesis/core.py +++ b/contrib/python/hypothesis/py3/hypothesis/core.py @@ -91,6 +91,7 @@ from hypothesis.internal.healthcheck import fail_health_check from hypothesis.internal.observability import ( OBSERVABILITY_COLLECT_COVERAGE, TESTCASE_CALLBACKS, + _system_metadata, deliver_json_blob, make_testcase, ) @@ -1066,7 +1067,6 @@ class StateForActualGivenExecution: string_repr=self._string_repr, arguments={**self._jsonable_arguments, **data._observability_args}, timing=self._timing_features, - metadata={}, coverage=tractable_coverage_report(trace) or None, ) deliver_json_blob(tc) @@ -1195,7 +1195,11 @@ class StateForActualGivenExecution: }, "timing": self._timing_features, "coverage": None, # Not recorded when we're replaying the MFE - "metadata": {"traceback": tb}, + "metadata": { + "traceback": tb, + "predicates": ran_example._observability_predicates, + **_system_metadata(), + }, } deliver_json_blob(tc) # Whether or not replay actually raised the exception again, we want diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py index 8b8462d24d4..4e43477c5e9 100644 --- a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py +++ b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py @@ -1450,6 +1450,9 @@ class ConjectureData: self.arg_slices: Set[Tuple[int, int]] = set() self.slice_comments: Dict[Tuple[int, int], str] = {} self._observability_args: Dict[str, Any] = {} + self._observability_predicates: defaultdict = defaultdict( + lambda: {"satisfied": 0, "unsatisfied": 0} + ) self.extra_information = ExtraInformation() diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/observability.py b/contrib/python/hypothesis/py3/hypothesis/internal/observability.py index eb083f8be19..98753985f10 100644 --- a/contrib/python/hypothesis/py3/hypothesis/internal/observability.py +++ b/contrib/python/hypothesis/py3/hypothesis/internal/observability.py @@ -13,8 +13,10 @@ import json import os import sys +import time import warnings from datetime import date, timedelta +from functools import lru_cache from typing import Callable, Dict, List, Optional from hypothesis.configuration import storage_directory @@ -38,7 +40,6 @@ def make_testcase( string_repr: str = "", arguments: Optional[dict] = None, timing: Dict[str, float], - metadata: Optional[dict] = None, coverage: Optional[Dict[str, List[int]]] = None, ) -> dict: if data.interesting_origin: @@ -68,8 +69,9 @@ def make_testcase( }, "timing": timing, "metadata": { - **(metadata or {}), "traceback": getattr(data.extra_information, "_expected_traceback", None), + "predicates": data._observability_predicates, + **_system_metadata(), }, "coverage": coverage, } @@ -87,6 +89,18 @@ def _deliver_to_file(value): # pragma: no cover f.write(json.dumps(value) + "\n") +_imported_at = time.time() + + +@lru_cache +def _system_metadata(): + return { + "sys.argv": sys.argv, + "os.getpid()": os.getpid(), + "imported_at": _imported_at, + } + + OBSERVABILITY_COLLECT_COVERAGE = ( "HYPOTHESIS_EXPERIMENTAL_OBSERVABILITY_NOCOVER" not in os.environ ) diff --git a/contrib/python/hypothesis/py3/hypothesis/stateful.py b/contrib/python/hypothesis/py3/hypothesis/stateful.py index 39ce653981c..14275d940ec 100644 --- a/contrib/python/hypothesis/py3/hypothesis/stateful.py +++ b/contrib/python/hypothesis/py3/hypothesis/stateful.py @@ -116,6 +116,7 @@ def run_state_machine_as_test(state_machine_factory, *, settings=None, _min_step machine = factory() check_type(RuleBasedStateMachine, machine, "state_machine_factory()") cd.hypothesis_runner = machine + machine._observability_predicates = cd._observability_predicates # alias print_steps = ( current_build_context().is_final or current_verbosity() >= Verbosity.debug @@ -941,8 +942,14 @@ class RuleStrategy(SearchStrategy): return (rule, data.draw(rule.arguments_strategy)) def is_valid(self, rule): - if not all(precond(self.machine) for precond in rule.preconditions): - return False + predicates = self.machine._observability_predicates + desc = f"{self.machine.__class__.__qualname__}, rule {rule.function.__name__}," + for pred in rule.preconditions: + meets_precond = pred(self.machine) + where = f"{desc} precondition {get_pretty_function_description(pred)}" + predicates[where]["satisfied" if meets_precond else "unsatisfied"] += 1 + if not meets_precond: + return False for b in rule.bundles: bundle = self.machine.bundle(b.name) diff --git a/contrib/python/hypothesis/py3/hypothesis/version.py b/contrib/python/hypothesis/py3/hypothesis/version.py index 10be5636281..307de471d0c 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, 97, 4) +__version_info__ = (6, 97, 5) __version__ = ".".join(map(str, __version_info__)) diff --git a/contrib/python/hypothesis/py3/ya.make b/contrib/python/hypothesis/py3/ya.make index e0530c7a9e0..1914b61e35a 100644 --- a/contrib/python/hypothesis/py3/ya.make +++ b/contrib/python/hypothesis/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(6.97.4) +VERSION(6.97.5) LICENSE(MPL-2.0) -- cgit v1.3