diff options
author | robot-piglet <robot-piglet@yandex-team.com> | 2024-06-06 09:56:42 +0300 |
---|---|---|
committer | robot-piglet <robot-piglet@yandex-team.com> | 2024-06-06 10:05:35 +0300 |
commit | caa721da15eab69ba0c5eae383d494627ff115f5 (patch) | |
tree | a92dcdb254b2688950c2215bcd33e7dbfac39911 /contrib/python/hypothesis | |
parent | f44820822073337ca895dee0ce177e5cf40260df (diff) | |
download | ydb-caa721da15eab69ba0c5eae383d494627ff115f5.tar.gz |
Intermediate changes
Diffstat (limited to 'contrib/python/hypothesis')
5 files changed, 75 insertions, 47 deletions
diff --git a/contrib/python/hypothesis/py3/.dist-info/METADATA b/contrib/python/hypothesis/py3/.dist-info/METADATA index 31be46f1d4..2fd0b3adc1 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.102.4 +Version: 6.102.5 Summary: A library for property-based testing Home-page: https://hypothesis.works Author: David R. MacIver and Zac Hatfield-Dodds @@ -44,7 +44,7 @@ Requires-Dist: click >=7.0 ; extra == 'all' Requires-Dist: crosshair-tool >=0.0.54 ; extra == 'all' Requires-Dist: django >=3.2 ; extra == 'all' Requires-Dist: dpcontracts >=0.4 ; extra == 'all' -Requires-Dist: hypothesis-crosshair >=0.0.2 ; extra == 'all' +Requires-Dist: hypothesis-crosshair >=0.0.4 ; extra == 'all' Requires-Dist: lark >=0.10.1 ; extra == 'all' Requires-Dist: libcst >=0.3.16 ; extra == 'all' Requires-Dist: numpy >=1.17.3 ; extra == 'all' @@ -63,7 +63,7 @@ Requires-Dist: rich >=9.0.0 ; extra == 'cli' Provides-Extra: codemods Requires-Dist: libcst >=0.3.16 ; extra == 'codemods' Provides-Extra: crosshair -Requires-Dist: hypothesis-crosshair >=0.0.2 ; extra == 'crosshair' +Requires-Dist: hypothesis-crosshair >=0.0.4 ; extra == 'crosshair' Requires-Dist: crosshair-tool >=0.0.54 ; extra == 'crosshair' Provides-Extra: dateutil Requires-Dist: python-dateutil >=1.4 ; extra == 'dateutil' diff --git a/contrib/python/hypothesis/py3/hypothesis/extra/ghostwriter.py b/contrib/python/hypothesis/py3/hypothesis/extra/ghostwriter.py index 2854b48c29..0c4a5d8523 100644 --- a/contrib/python/hypothesis/py3/hypothesis/extra/ghostwriter.py +++ b/contrib/python/hypothesis/py3/hypothesis/extra/ghostwriter.py @@ -452,54 +452,72 @@ def _guess_strategy_by_argname(name: str) -> st.SearchStrategy: return st.nothing() +def _get_params_builtin_fn(func: Callable) -> List[inspect.Parameter]: + if ( + isinstance(func, (types.BuiltinFunctionType, types.BuiltinMethodType)) + and hasattr(func, "__doc__") + and isinstance(func.__doc__, str) + ): + # inspect.signature doesn't work on all builtin functions or methods. + # In such cases, we can try to reconstruct simple signatures from the docstring. + match = re.match(rf"^{func.__name__}\((.+?)\)", func.__doc__) + if match is None: + return [] + args = match.group(1).replace("[", "").replace("]", "") + params = [] + # Even if the signature doesn't contain a /, we assume that arguments + # are positional-only until shown otherwise - the / is often omitted. + kind: inspect._ParameterKind = inspect.Parameter.POSITIONAL_ONLY + for arg in args.split(", "): + arg, *_ = arg.partition("=") + arg = arg.strip() + if arg == "/": + kind = inspect.Parameter.POSITIONAL_OR_KEYWORD + continue + if arg.startswith("*") or arg == "...": + kind = inspect.Parameter.KEYWORD_ONLY + continue # we omit *varargs, if there are any + if _iskeyword(arg.lstrip("*")) or not arg.lstrip("*").isidentifier(): + break # skip all subsequent params if this name is invalid + params.append(inspect.Parameter(name=arg, kind=kind)) + return params + return [] + + +def _get_params_ufunc(func: Callable) -> List[inspect.Parameter]: + if _is_probably_ufunc(func): + # `inspect.signature` results vary for ufunc objects, but we can work out + # what the required parameters would look like if it was reliable. + # Note that we use args named a, b, c... to match the `operator` module, + # rather than x1, x2, x3... like the Numpy docs. Because they're pos-only + # this doesn't make a runtime difference, and it's much nicer for use-cases + # like `equivalent(numpy.add, operator.add)`. + return [ + inspect.Parameter(name=name, kind=inspect.Parameter.POSITIONAL_ONLY) + for name in ascii_lowercase[: func.nin] # type: ignore + ] + return [] + + def _get_params(func: Callable) -> Dict[str, inspect.Parameter]: """Get non-vararg parameters of `func` as an ordered dict.""" try: params = list(get_signature(func).parameters.values()) except Exception: - if ( - isinstance(func, (types.BuiltinFunctionType, types.BuiltinMethodType)) - and hasattr(func, "__doc__") - and isinstance(func.__doc__, str) - ): - # inspect.signature doesn't work on all builtin functions or methods. - # In such cases, we can try to reconstruct simple signatures from the docstring. - match = re.match(rf"^{func.__name__}\((.+?)\)", func.__doc__) - if match is None: - raise - args = match.group(1).replace("[", "").replace("]", "") - params = [] - # Even if the signature doesn't contain a /, we assume that arguments - # are positional-only until shown otherwise - the / is often omitted. - kind: inspect._ParameterKind = inspect.Parameter.POSITIONAL_ONLY - for arg in args.split(", "): - arg, *_ = arg.partition("=") - arg = arg.strip() - if arg == "/": - kind = inspect.Parameter.POSITIONAL_OR_KEYWORD - continue - if arg.startswith("*") or arg == "...": - kind = inspect.Parameter.KEYWORD_ONLY - continue # we omit *varargs, if there are any - if _iskeyword(arg.lstrip("*")) or not arg.lstrip("*").isidentifier(): - break # skip all subsequent params if this name is invalid - params.append(inspect.Parameter(name=arg, kind=kind)) - - elif _is_probably_ufunc(func): - # `inspect.signature` doesn't work on ufunc objects, but we can work out - # what the required parameters would look like if it did. - # Note that we use args named a, b, c... to match the `operator` module, - # rather than x1, x2, x3... like the Numpy docs. Because they're pos-only - # this doesn't make a runtime difference, and it's much nicer for use-cases - # like `equivalent(numpy.add, operator.add)`. - params = [ - inspect.Parameter(name=name, kind=inspect.Parameter.POSITIONAL_ONLY) - for name in ascii_lowercase[: func.nin] # type: ignore - ] + if params := _get_params_ufunc(func): + pass + elif params := _get_params_builtin_fn(func): + pass else: # If we haven't managed to recover a signature through the tricks above, # we're out of ideas and should just re-raise the exception. raise + else: + # If the params we got look like an uninformative placeholder, try fallbacks. + P = inspect.Parameter + placeholder = [("args", P.VAR_POSITIONAL), ("kwargs", P.VAR_KEYWORD)] + if [(p.name, p.kind) for p in params] == placeholder: + params = _get_params_ufunc(func) or _get_params_builtin_fn(func) or params return _params_to_dict(params) diff --git a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/types.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/types.py index 46c4339fab..11e6aa381b 100644 --- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/types.py +++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/types.py @@ -388,7 +388,12 @@ def is_generic_type(type_): ) -def _try_import_forward_ref(thing, bound): # pragma: no cover +__EVAL_TYPE_TAKES_TYPE_PARAMS = ( + "type_params" in inspect.signature(typing._eval_type).parameters # type: ignore +) + + +def _try_import_forward_ref(thing, bound, *, type_params): # pragma: no cover """ Tries to import a real bound type from ``TypeVar`` bound to a ``ForwardRef``. @@ -397,7 +402,10 @@ def _try_import_forward_ref(thing, bound): # pragma: no cover because we can only cover each path in a separate python version. """ try: - return typing._eval_type(bound, vars(sys.modules[thing.__module__]), None) + kw = {"globalns": vars(sys.modules[thing.__module__]), "localns": None} + if __EVAL_TYPE_TAKES_TYPE_PARAMS: + kw["type_params"] = type_params + return typing._eval_type(bound, **kw) except (KeyError, AttributeError, NameError): # We fallback to `ForwardRef` instance, you can register it as a type as well: # >>> from typing import ForwardRef @@ -1030,7 +1038,9 @@ def resolve_TypeVar(thing): if getattr(thing, "__bound__", None) is not None: bound = thing.__bound__ if isinstance(bound, typing.ForwardRef): - bound = _try_import_forward_ref(thing, bound) + # TODO: on Python 3.13 and later, we should work out what type_params + # could be part of this type, and pass them in here. + bound = _try_import_forward_ref(thing, bound, type_params=()) strat = unwrap_strategies(st.from_type(bound)) if not isinstance(strat, OneOfStrategy): return strat diff --git a/contrib/python/hypothesis/py3/hypothesis/version.py b/contrib/python/hypothesis/py3/hypothesis/version.py index 6f39e34255..4bc7530118 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, 102, 4) +__version_info__ = (6, 102, 5) __version__ = ".".join(map(str, __version_info__)) diff --git a/contrib/python/hypothesis/py3/ya.make b/contrib/python/hypothesis/py3/ya.make index f2c0ffc956..7df369619b 100644 --- a/contrib/python/hypothesis/py3/ya.make +++ b/contrib/python/hypothesis/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(6.102.4) +VERSION(6.102.5) LICENSE(MPL-2.0) |