diff options
author | robot-piglet <robot-piglet@yandex-team.com> | 2024-03-13 17:21:33 +0300 |
---|---|---|
committer | robot-piglet <robot-piglet@yandex-team.com> | 2024-03-13 17:30:21 +0300 |
commit | 24ae9da923df78e9797360c2514ead5910cf22b9 (patch) | |
tree | 5e1a697043b53b923a95df61d7487b7e40aec8fa | |
parent | 11a895b7e15d1c5a1f52706396b82e3f9db953cb (diff) | |
download | ydb-24ae9da923df78e9797360c2514ead5910cf22b9.tar.gz |
Intermediate changes
7 files changed, 128 insertions, 54 deletions
diff --git a/contrib/python/hypothesis/py3/.dist-info/METADATA b/contrib/python/hypothesis/py3/.dist-info/METADATA index 717ae021d6..fa11a20888 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.12 +Version: 6.98.13 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/strategies/_internal/core.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/core.py index 1efe75caec..83edacbfef 100644 --- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/core.py +++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/core.py @@ -134,7 +134,7 @@ from hypothesis.strategies._internal.strategies import ( one_of, ) from hypothesis.strategies._internal.strings import ( - FixedSizeBytes, + BytesStrategy, OneCharStringStrategy, TextStrategy, ) @@ -963,11 +963,7 @@ def binary( values. """ check_valid_sizes(min_size, max_size) - if min_size == max_size: - return FixedSizeBytes(min_size) - return lists( - integers(min_value=0, max_value=255), min_size=min_size, max_size=max_size - ).map(bytes) + return BytesStrategy(min_size, max_size) @cacheable diff --git a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/strings.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/strings.py index 021ce3c6e6..8df955e632 100644 --- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/strings.py +++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/strings.py @@ -11,14 +11,17 @@ import copy import re import warnings -from functools import lru_cache +from functools import lru_cache, partial from hypothesis.errors import HypothesisWarning, InvalidArgument from hypothesis.internal import charmap +from hypothesis.internal.filtering import max_len, min_len from hypothesis.internal.intervalsets import IntervalSet from hypothesis.strategies._internal.collections import ListStrategy from hypothesis.strategies._internal.lazy import unwrap_strategies +from hypothesis.strategies._internal.numbers import IntegersStrategy from hypothesis.strategies._internal.strategies import SearchStrategy +from hypothesis.vendor.pretty import pretty class OneCharStringStrategy(SearchStrategy): @@ -76,6 +79,33 @@ class OneCharStringStrategy(SearchStrategy): return data.draw_string(self.intervals, min_size=1, max_size=1) +_nonempty_names = ( + "capitalize", + "expandtabs", + "join", + "lower", + "rsplit", + "split", + "splitlines", + "swapcase", + "title", + "upper", +) +_nonempty_and_content_names = ( + "islower", + "isupper", + "isalnum", + "isalpha", + "isascii", + "isdigit", + "isspace", + "istitle", + "lstrip", + "rstrip", + "strip", +) + + class TextStrategy(ListStrategy): def do_draw(self, data): # if our element strategy is OneCharStringStrategy, we can skip the @@ -104,44 +134,17 @@ class TextStrategy(ListStrategy): _nonempty_filters = ( *ListStrategy._nonempty_filters, str, - str.capitalize, str.casefold, str.encode, - str.expandtabs, - str.join, - str.lower, - str.rsplit, - str.split, - str.splitlines, - str.swapcase, - str.title, - str.upper, + *(getattr(str, n) for n in _nonempty_names), ) _nonempty_and_content_filters = ( - str.isidentifier, - str.islower, - str.isupper, - str.isalnum, - str.isalpha, - str.isascii, str.isdecimal, - str.isdigit, str.isnumeric, - str.isspace, - str.istitle, - str.lstrip, - str.rstrip, - str.strip, + *(getattr(str, n) for n in _nonempty_and_content_names), ) def filter(self, condition): - if condition in (str.lower, str.title, str.upper): - warnings.warn( - f"You applied str.{condition.__name__} as a filter, but this allows " - f"all nonempty strings! Did you mean str.is{condition.__name__}?", - HypothesisWarning, - stacklevel=2, - ) elems = unwrap_strategies(self.element_strategy) if ( condition is str.isidentifier @@ -163,17 +166,76 @@ class TextStrategy(ListStrategy): ), # Filter to ensure that NFKC normalization keeps working in future ).filter(str.isidentifier) + if (new := _string_filter_rewrite(self, str, condition)) is not None: + return new + return super().filter(condition) - # We use ListStrategy filter logic for the conditions that *only* imply - # the string is nonempty. Here, we increment the min_size but still apply - # the filter for conditions that imply nonempty *and specific contents*. - if condition in self._nonempty_and_content_filters: - assert self.max_size >= 1, "Always-empty is special cased in st.text()" - self = copy.copy(self) - self.min_size = max(1, self.min_size) - return ListStrategy.filter(self, condition) - return super().filter(condition) +def _string_filter_rewrite(self, kind, condition): + if condition in (kind.lower, kind.title, kind.upper): + k = kind.__name__ + warnings.warn( + f"You applied {k}.{condition.__name__} as a filter, but this allows " + f"all nonempty strings! Did you mean {k}.is{condition.__name__}?", + HypothesisWarning, + stacklevel=2, + ) + + elems = unwrap_strategies(self.element_strategy) + if ( + (kind is bytes or isinstance(elems, OneCharStringStrategy)) + and isinstance(pattern := getattr(condition, "__self__", None), re.Pattern) + and isinstance(pattern.pattern, kind) + ): + from hypothesis.strategies._internal.regex import regex_strategy + + print(f"{condition=}") + print(f"{condition.__name__=}") + + if condition.__name__ == "match": + # Replace with an easier-to-handle equivalent condition + caret = "^" if kind is str else b"^" + pattern = re.compile(caret + pattern.pattern, flags=pattern.flags) + condition = pattern.search + + if condition.__name__ in ("search", "findall", "fullmatch"): + s = regex_strategy( + pattern, + fullmatch=condition.__name__ == "fullmatch", + alphabet=self.element_strategy if kind is str else None, + ) + if self.min_size > 0: + s = s.filter(partial(min_len, self.min_size)) + if self.max_size < 1e999: + s = s.filter(partial(max_len, self.max_size)) + return s + elif condition.__name__ in ("finditer", "scanner"): + # PyPy implements `finditer` as an alias to their `scanner` method + warnings.warn( + f"You applied {pretty(condition)} as a filter, but this allows " + f"any string at all! Did you mean .findall ?", + HypothesisWarning, + stacklevel=3, + ) + return self + elif condition.__name__ == "split": + warnings.warn( + f"You applied {pretty(condition)} as a filter, but this allows " + f"any nonempty string! Did you mean .search ?", + HypothesisWarning, + stacklevel=3, + ) + return self.filter(bool) + + # We use ListStrategy filter logic for the conditions that *only* imply + # the string is nonempty. Here, we increment the min_size but still apply + # the filter for conditions that imply nonempty *and specific contents*. + if condition in self._nonempty_and_content_filters and self.max_size >= 1: + self = copy.copy(self) + self.min_size = max(1, self.min_size) + return ListStrategy.filter(self, condition) + + return None # Excerpted from https://www.unicode.org/Public/15.0.0/ucd/PropList.txt @@ -229,9 +291,26 @@ def _identifier_characters(): return id_start, id_continue -class FixedSizeBytes(SearchStrategy): - def __init__(self, size): - self.size = size +class BytesStrategy(ListStrategy): + def __init__(self, min_size, max_size): + super().__init__(IntegersStrategy(0, 255), min_size=min_size, max_size=max_size) def do_draw(self, data): - return bytes(data.draw_bytes(self.size)) + # TODO: refactor the underlying provider to support variable-length bytes + if self.min_size == self.max_size: + return bytes(data.draw_bytes(self.min_size)) + return bytes(super().do_draw(data)) + + _nonempty_filters = ( + *ListStrategy._nonempty_filters, + bytes, + *(getattr(bytes, n) for n in _nonempty_names), + ) + _nonempty_and_content_filters = ( + *(getattr(bytes, n) for n in _nonempty_and_content_names), + ) + + def filter(self, condition): + if (new := _string_filter_rewrite(self, bytes, condition)) is not None: + return new + return super().filter(condition) diff --git a/contrib/python/hypothesis/py3/hypothesis/vendor/pretty.py b/contrib/python/hypothesis/py3/hypothesis/vendor/pretty.py index 35451b9961..ceffe3a6aa 100644 --- a/contrib/python/hypothesis/py3/hypothesis/vendor/pretty.py +++ b/contrib/python/hypothesis/py3/hypothesis/vendor/pretty.py @@ -747,7 +747,7 @@ _type_pprinters = { type: _type_pprint, types.FunctionType: _function_pprint, types.BuiltinFunctionType: _function_pprint, - types.MethodType: _repr_pprint, + types.MethodType: _function_pprint, datetime.datetime: _repr_pprint, datetime.timedelta: _repr_pprint, BaseException: _exception_pprint, diff --git a/contrib/python/hypothesis/py3/hypothesis/version.py b/contrib/python/hypothesis/py3/hypothesis/version.py index e986241037..187c174def 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, 12) +__version_info__ = (6, 98, 13) __version__ = ".".join(map(str, __version_info__)) diff --git a/contrib/python/hypothesis/py3/ya.make b/contrib/python/hypothesis/py3/ya.make index 33c8057a99..1c48b292f9 100644 --- a/contrib/python/hypothesis/py3/ya.make +++ b/contrib/python/hypothesis/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(6.98.12) +VERSION(6.98.13) LICENSE(MPL-2.0) diff --git a/yt/yt/library/formats/skiff_yson_converter.cpp b/yt/yt/library/formats/skiff_yson_converter.cpp index 106cb51fbe..e7d1d899ef 100644 --- a/yt/yt/library/formats/skiff_yson_converter.cpp +++ b/yt/yt/library/formats/skiff_yson_converter.cpp @@ -1420,7 +1420,6 @@ TSkiffToYsonConverter CreateSimpleSkiffToYsonConverter( case ESimpleLogicalValueType::Interval64: CheckWireType(wireType, {EWireType::Int32, EWireType::Int64, EWireType::String32}); return CreatePrimitiveTypeSkiffToYsonConverter(wireType); - } YT_ABORT(); } catch (const std::exception& ex) { |