diff options
| author | robot-piglet <[email protected]> | 2024-07-09 08:58:14 +0300 |
|---|---|---|
| committer | robot-piglet <[email protected]> | 2024-07-09 09:07:46 +0300 |
| commit | 749e098320dd9c0f8bf27fa600bf8cde20dac080 (patch) | |
| tree | f671dfdef5328069a1120dd39928c0de5fe3f035 /contrib/python | |
| parent | e01ebe0f63993394f721cc48adfd7e169ba4c709 (diff) | |
Intermediate changes
Diffstat (limited to 'contrib/python')
20 files changed, 171 insertions, 50 deletions
diff --git a/contrib/python/clickhouse-connect/.dist-info/METADATA b/contrib/python/clickhouse-connect/.dist-info/METADATA index a0dc6a83ebe..c82123d9e25 100644 --- a/contrib/python/clickhouse-connect/.dist-info/METADATA +++ b/contrib/python/clickhouse-connect/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: clickhouse-connect -Version: 0.7.12 +Version: 0.7.14 Summary: ClickHouse Database Core Driver for Python, Pandas, and Superset Home-page: https://github.com/ClickHouse/clickhouse-connect Author: ClickHouse Inc. @@ -34,7 +34,7 @@ Requires-Dist: pandas ; extra == 'pandas' Provides-Extra: sqlalchemy Requires-Dist: sqlalchemy <2.0,>1.3.21 ; extra == 'sqlalchemy' Provides-Extra: tzlocal -Requires-Dist: tzlocal ; extra == 'tzlocal' +Requires-Dist: tzlocal >=4.0 ; extra == 'tzlocal' ## ClickHouse Connect diff --git a/contrib/python/clickhouse-connect/clickhouse_connect/__version__.py b/contrib/python/clickhouse-connect/clickhouse_connect/__version__.py index 03ae4dc075f..3c2c07c720e 100644 --- a/contrib/python/clickhouse-connect/clickhouse_connect/__version__.py +++ b/contrib/python/clickhouse-connect/clickhouse_connect/__version__.py @@ -1 +1 @@ -version = '0.7.12' +version = '0.7.14' diff --git a/contrib/python/clickhouse-connect/clickhouse_connect/datatypes/special.py b/contrib/python/clickhouse-connect/clickhouse_connect/datatypes/special.py index d45abd47eea..29d28e3378f 100644 --- a/contrib/python/clickhouse-connect/clickhouse_connect/datatypes/special.py +++ b/contrib/python/clickhouse-connect/clickhouse_connect/datatypes/special.py @@ -42,7 +42,7 @@ class UUID(ClickHouseType): if isinstance(first, str) or self.write_format(ctx) == 'string': for v in column: if v: - x = int(v, 16) + x = int(v.replace('-', ''), 16) dest += (x >> 64).to_bytes(8, 'little') + (x & 0xffffffffffffffff).to_bytes(8, 'little') else: dest += empty diff --git a/contrib/python/clickhouse-connect/clickhouse_connect/driver/client.py b/contrib/python/clickhouse-connect/clickhouse_connect/driver/client.py index 2817f1e1e6a..144c279da52 100644 --- a/contrib/python/clickhouse-connect/clickhouse_connect/driver/client.py +++ b/contrib/python/clickhouse-connect/clickhouse_connect/driver/client.py @@ -133,7 +133,10 @@ class Client(ABC): def _prep_query(self, context: QueryContext): if context.is_select and not context.has_limit and self.query_limit: - return f'{context.final_query}\n LIMIT {self.query_limit}' + limit = f'\n LIMIT {self.query_limit}' + if isinstance(context.query, bytes): + return context.final_query + limit.encode() + return context.final_query + limit return context.final_query def _check_tz_change(self, new_tz) -> Optional[tzinfo]: @@ -386,7 +389,7 @@ class Client(ABC): streaming=True).df_stream def create_query_context(self, - query: Optional[str] = None, + query: Optional[Union[str, bytes]] = None, parameters: Optional[Union[Sequence, Dict[str, Any]]] = None, settings: Optional[Dict[str, Any]] = None, query_formats: Optional[Dict[str, str]] = None, diff --git a/contrib/python/clickhouse-connect/clickhouse_connect/driver/external.py b/contrib/python/clickhouse-connect/clickhouse_connect/driver/external.py index be78e4e2bc7..842ec7d59aa 100644 --- a/contrib/python/clickhouse-connect/clickhouse_connect/driver/external.py +++ b/contrib/python/clickhouse-connect/clickhouse_connect/driver/external.py @@ -43,16 +43,16 @@ class ExternalFile: self.file_name = file_name else: raise ProgrammingError('Either data or file_path must be specified for external data') + self.structure = None + self.types = None if types: if structure: raise ProgrammingError('Only types or structure should be specified for external data, not both') - self.structure = None if isinstance(types, str): self.types = types else: self.types = ','.join(types) elif structure: - self.types = None if isinstance(structure, str): self.structure = structure else: diff --git a/contrib/python/clickhouse-connect/clickhouse_connect/driver/httpclient.py b/contrib/python/clickhouse-connect/clickhouse_connect/driver/httpclient.py index 0d7a6b7fdb6..0af2612f93c 100644 --- a/contrib/python/clickhouse-connect/clickhouse_connect/driver/httpclient.py +++ b/contrib/python/clickhouse-connect/clickhouse_connect/driver/httpclient.py @@ -15,17 +15,17 @@ from urllib3.response import HTTPResponse from clickhouse_connect import common from clickhouse_connect.datatypes import registry from clickhouse_connect.datatypes.base import ClickHouseType -from clickhouse_connect.driver.ctypes import RespBuffCls from clickhouse_connect.driver.client import Client from clickhouse_connect.driver.common import dict_copy, coerce_bool, coerce_int from clickhouse_connect.driver.compression import available_compression +from clickhouse_connect.driver.ctypes import RespBuffCls from clickhouse_connect.driver.exceptions import DatabaseError, OperationalError, ProgrammingError from clickhouse_connect.driver.external import ExternalData from clickhouse_connect.driver.httputil import ResponseSource, get_pool_manager, get_response_data, \ default_pool_manager, get_proxy_manager, all_managers, check_env_proxy, check_conn_expiration from clickhouse_connect.driver.insert import InsertContext -from clickhouse_connect.driver.summary import QuerySummary from clickhouse_connect.driver.query import QueryResult, QueryContext, quote_identifier, bind_query +from clickhouse_connect.driver.summary import QuerySummary from clickhouse_connect.driver.transform import NativeTransform logger = logging.getLogger(__name__) @@ -173,7 +173,10 @@ class HttpClient(Client): final_query = super()._prep_query(context) if context.is_insert: return final_query - return f'{final_query}\n FORMAT {self._read_format}' + fmt = f'\n FORMAT {self._read_format}' + if isinstance(final_query, bytes): + return final_query + fmt.encode() + return final_query + fmt def _query_with_context(self, context: QueryContext) -> QueryResult: headers = {} @@ -349,20 +352,21 @@ class HttpClient(Client): return QuerySummary(self._summary(response)) def _error_handler(self, response: HTTPResponse, retried: bool = False) -> None: - err_str = f'HTTPDriver for {self.url} returned response code {response.status})' - try: - err_content = get_response_data(response) - except Exception: # pylint: disable=broad-except - err_content = None - finally: - response.close() + if self.show_clickhouse_errors: + try: + err_content = get_response_data(response) + except Exception: # pylint: disable=broad-except + err_content = None + finally: + response.close() - if err_content: - if self.show_clickhouse_errors: + err_str = f'HTTPDriver for {self.url} returned response code {response.status})' + if err_content: err_msg = common.format_error(err_content.decode(errors='backslashreplace')) - err_str = f':{err_str}\n {err_msg}' - else: - err_str = 'The ClickHouse server returned an error.' + err_str = f'{err_str}\n {err_msg}' + else: + err_str = 'The ClickHouse server returned an error.' + raise OperationalError(err_str) if retried else DatabaseError(err_str) from None def _raw_request(self, @@ -426,7 +430,8 @@ class HttpClient(Client): logger.debug('Retrying remotely closed connection') continue logger.warning('Unexpected Http Driver Exception') - raise OperationalError(f'Error {ex} executing HTTP request attempt {attempts} {self.url}') from ex + err_url = f' ({self.url})' if self.show_clickhouse_errors else '' + raise OperationalError(f'Error {ex} executing HTTP request attempt {attempts}{err_url}') from ex finally: if query_session: self._active_session = None # Make sure we always clear this @@ -471,14 +476,16 @@ class HttpClient(Client): fmt: str, use_database: bool, external_data: Optional[ExternalData]): - final_query, bind_params = bind_query(query, parameters, self.server_tz) if fmt: - final_query += f'\n FORMAT {fmt}' + query += f'\n FORMAT {fmt}' + final_query, bind_params = bind_query(query, parameters, self.server_tz) params = self._validate_settings(settings or {}) if use_database and self.database: params['database'] = self.database params.update(bind_params) if external_data: + if isinstance(final_query, bytes): + raise ProgrammingError('Cannot combine binary query data with `External Data`') body = bytes() params['query'] = final_query params.update(external_data.query_params) diff --git a/contrib/python/clickhouse-connect/clickhouse_connect/driver/query.py b/contrib/python/clickhouse-connect/clickhouse_connect/driver/query.py index ddb413e1939..c11e128ec6c 100644 --- a/contrib/python/clickhouse-connect/clickhouse_connect/driver/query.py +++ b/contrib/python/clickhouse-connect/clickhouse_connect/driver/query.py @@ -40,7 +40,7 @@ class QueryContext(BaseQueryContext): # pylint: disable=duplicate-code,too-many-arguments,too-many-locals def __init__(self, - query: str = '', + query: Union[str, bytes] = '', parameters: Optional[Dict[str, Any]] = None, settings: Optional[Dict[str, Any]] = None, query_formats: Optional[Dict[str, str]] = None, @@ -177,7 +177,7 @@ class QueryContext(BaseQueryContext): return active_tz def updated_copy(self, - query: Optional[str] = None, + query: Optional[Union[str, bytes]] = None, parameters: Optional[Dict[str, Any]] = None, settings: Optional[Dict[str, Any]] = None, query_formats: Optional[Dict[str, str]] = None, @@ -218,7 +218,11 @@ class QueryContext(BaseQueryContext): def _update_query(self): self.final_query, self.bind_params = bind_query(self.query, self.parameters, self.server_tz) - self.uncommented_query = remove_sql_comments(self.final_query) + if isinstance(self.final_query, bytes): + # If we've embedded binary data in the query, all bets are off, and we check the original query for comments + self.uncommented_query = remove_sql_comments(self.query) + else: + self.uncommented_query = remove_sql_comments(self.final_query) class QueryResult(Closable): @@ -368,9 +372,36 @@ def bind_query(query: str, parameters: Optional[Union[Sequence, Dict[str, Any]]] query = query[:-1] if not parameters: return query, {} + + binary_binds = None + if isinstance(parameters, dict): + binary_binds = {k: v for k, v in parameters.items() if k.startswith('$') and k.endswith('$') and len(k) > 1} + for key in binary_binds.keys(): + del parameters[key] if external_bind_re.search(query) is None: - return finalize_query(query, parameters, server_tz), {} - return query, {f'param_{k}': format_bind_value(v, server_tz) for k, v in parameters.items()} + query, bound_params = finalize_query(query, parameters, server_tz), {} + else: + bound_params = {f'param_{k}': format_bind_value(v, server_tz) for k, v in parameters.items()} + if binary_binds: + binary_query = query.encode() + binary_indexes = {} + for k, v in binary_binds.items(): + key = k.encode() + item_index = 0 + while True: + item_index = binary_query.find(key, item_index) + if item_index == -1: + break + binary_indexes[item_index + len(key)] = key, v + item_index += len(key) + query = b'' + start = 0 + for loc in sorted(binary_indexes.keys()): + key, value = binary_indexes[loc] + query += binary_query[start:loc] + value + key + start = loc + query += binary_query[start:] + return query, bound_params def format_str(value: str): diff --git a/contrib/python/clickhouse-connect/ya.make b/contrib/python/clickhouse-connect/ya.make index 35add5741f3..f7a5184c3b9 100644 --- a/contrib/python/clickhouse-connect/ya.make +++ b/contrib/python/clickhouse-connect/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(0.7.12) +VERSION(0.7.14) LICENSE(Apache-2.0) diff --git a/contrib/python/hypothesis/py3/.dist-info/METADATA b/contrib/python/hypothesis/py3/.dist-info/METADATA index ad18a5c15fd..cd866b19e8b 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.103.2 +Version: 6.104.0 Summary: A library for property-based testing Home-page: https://hypothesis.works Author: David R. MacIver and Zac Hatfield-Dodds @@ -41,7 +41,7 @@ Requires-Dist: exceptiongroup >=1.0.0 ; python_version < "3.11" Provides-Extra: all Requires-Dist: black >=19.10b0 ; extra == 'all' Requires-Dist: click >=7.0 ; extra == 'all' -Requires-Dist: crosshair-tool >=0.0.54 ; extra == 'all' +Requires-Dist: crosshair-tool >=0.0.55 ; extra == 'all' Requires-Dist: django >=3.2 ; extra == 'all' Requires-Dist: dpcontracts >=0.4 ; extra == 'all' Requires-Dist: hypothesis-crosshair >=0.0.4 ; extra == 'all' @@ -64,7 +64,7 @@ Provides-Extra: codemods Requires-Dist: libcst >=0.3.16 ; extra == 'codemods' Provides-Extra: crosshair Requires-Dist: hypothesis-crosshair >=0.0.4 ; extra == 'crosshair' -Requires-Dist: crosshair-tool >=0.0.54 ; extra == 'crosshair' +Requires-Dist: crosshair-tool >=0.0.55 ; extra == 'crosshair' Provides-Extra: dateutil Requires-Dist: python-dateutil >=1.4 ; extra == 'dateutil' Provides-Extra: django diff --git a/contrib/python/hypothesis/py3/hypothesis/core.py b/contrib/python/hypothesis/py3/hypothesis/core.py index 9af0381feaf..759d9b5afc5 100644 --- a/contrib/python/hypothesis/py3/hypothesis/core.py +++ b/contrib/python/hypothesis/py3/hypothesis/core.py @@ -1104,7 +1104,9 @@ class StateForActualGivenExecution: if TESTCASE_CALLBACKS: if runner := getattr(self, "_runner", None): phase = runner._current_phase - elif self.failed_normally or self.failed_due_to_deadline: + elif ( + self.failed_normally or self.failed_due_to_deadline + ): # pragma: no cover # FIXME phase = "shrink" else: # pragma: no cover # in case of messing with internals phase = "unknown" diff --git a/contrib/python/hypothesis/py3/hypothesis/extra/_patching.py b/contrib/python/hypothesis/py3/hypothesis/extra/_patching.py index d3678e3f9fc..b8fbfa3c7af 100644 --- a/contrib/python/hypothesis/py3/hypothesis/extra/_patching.py +++ b/contrib/python/hypothesis/py3/hypothesis/extra/_patching.py @@ -121,7 +121,7 @@ class AddExamplesCodemod(VisitorBasedCodemodCommand): cst.Module([]).code_for_node(via), mode=black.FileMode(line_length=self.line_length), ) - except (ImportError, AttributeError): + except (ImportError, AttributeError): # pragma: no cover return None # See https://github.com/psf/black/pull/4224 via = cst.parse_expression(pretty.strip()) return cst.Decorator(via) diff --git a/contrib/python/hypothesis/py3/hypothesis/extra/django/_fields.py b/contrib/python/hypothesis/py3/hypothesis/extra/django/_fields.py index b4a574d69d1..181c8869f91 100644 --- a/contrib/python/hypothesis/py3/hypothesis/extra/django/_fields.py +++ b/contrib/python/hypothesis/py3/hypothesis/extra/django/_fields.py @@ -262,6 +262,55 @@ def _for_form_boolean(field): return st.booleans() +def _model_choice_strategy(field): + def _strategy(): + if field.choices is None: + # The field was instantiated with queryset=None, and not + # subsequently updated. + raise InvalidArgument( + "Cannot create strategy for ModelChoicesField with no choices" + ) + elif hasattr(field, "_choices"): + # The choices property was set manually. + choices = field._choices + else: + # choices is not None, and was not set manually, so we + # must have a QuerySet. + choices = field.queryset + + if not choices.ordered: + raise InvalidArgument( + f"Cannot create strategy for {field.__class__.__name__} with a choices " + "attribute derived from a QuerySet without an explicit ordering - this may " + "cause Hypothesis to produce unstable results between runs." + ) + + return st.sampled_from( + [ + ( + choice.value + if isinstance(choice, df.models.ModelChoiceIteratorValue) + else choice # Empty value, if included. + ) + for choice, _ in field.choices + ] + ) + + # Accessing field.choices causes database access, so defer the strategy. + return st.deferred(_strategy) + + +@register_for(df.ModelChoiceField) +def _for_model_choice(field): + return _model_choice_strategy(field) + + +@register_for(df.ModelMultipleChoiceField) +def _for_model_multiple_choice(field): + min_size = 1 if field.required else 0 + return st.lists(_model_choice_strategy(field), min_size=min_size, unique=True) + + def register_field_strategy( field_type: Type[AnyField], strategy: st.SearchStrategy ) -> None: @@ -299,7 +348,13 @@ def from_field(field: F) -> st.SearchStrategy[Union[F, None]]: instance attributes such as string length and validators. """ check_type((dm.Field, df.Field), field, "field") - if getattr(field, "choices", False): + + # The following isinstance check must occur *before* the getattr + # check. In the case of ModelChoicesField, evaluating + # field.choices causes database access, which we want to avoid if + # we don't have a connection (the generated strategies for + # ModelChoicesField defer evaluation of `choices'). + if not isinstance(field, df.ModelChoiceField) and getattr(field, "choices", False): choices: list = [] for value, name_or_optgroup in field.choices: if isinstance(name_or_optgroup, (list, tuple)): diff --git a/contrib/python/hypothesis/py3/hypothesis/extra/numpy.py b/contrib/python/hypothesis/py3/hypothesis/extra/numpy.py index 9edca6ee006..3754192d707 100644 --- a/contrib/python/hypothesis/py3/hypothesis/extra/numpy.py +++ b/contrib/python/hypothesis/py3/hypothesis/extra/numpy.py @@ -1103,7 +1103,7 @@ def basic_indices( allow_newaxis: bool = False, allow_ellipsis: bool = True, ) -> st.SearchStrategy[BasicIndex]: - """Return a strategy for :doc:`basic indexes <numpy:reference/arrays.indexing>` of + """Return a strategy for :doc:`basic indexes <numpy:reference/routines.indexing>` of arrays with the specified shape, which may include dimensions of size zero. It generates tuples containing some mix of integers, :obj:`python:slice` diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/cache.py b/contrib/python/hypothesis/py3/hypothesis/internal/cache.py index 86241d3737d..eae61a25783 100644 --- a/contrib/python/hypothesis/py3/hypothesis/internal/cache.py +++ b/contrib/python/hypothesis/py3/hypothesis/internal/cache.py @@ -8,6 +8,8 @@ # 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/. +import threading + import attr @@ -51,7 +53,7 @@ class GenericCache: on_access and on_evict to implement a specific scoring strategy. """ - __slots__ = ("keys_to_indices", "data", "max_size", "__pinned_entry_count") + __slots__ = ("max_size", "_threadlocal") def __init__(self, max_size): self.max_size = max_size @@ -61,9 +63,31 @@ class GenericCache: # its children. keys_to_index then maps keys to their index in the # heap. We keep these two in sync automatically - the heap is never # reordered without updating the index. - self.keys_to_indices = {} - self.data = [] - self.__pinned_entry_count = 0 + self._threadlocal = threading.local() + + @property + def keys_to_indices(self): + try: + return self._threadlocal.keys_to_indices + except AttributeError: + self._threadlocal.keys_to_indices = {} + return self._threadlocal.keys_to_indices + + @property + def data(self): + try: + return self._threadlocal.data + except AttributeError: + self._threadlocal.data = [] + return self._threadlocal.data + + @property + def __pinned_entry_count(self): + return getattr(self._threadlocal, "_pinned_entry_count", 0) + + @__pinned_entry_count.setter + def __pinned_entry_count(self, value): + self._threadlocal._pinned_entry_count = value def __len__(self): assert len(self.keys_to_indices) == len(self.data) diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/entropy.py b/contrib/python/hypothesis/py3/hypothesis/internal/entropy.py index 6e4a30b99a9..eedd5919dc1 100644 --- a/contrib/python/hypothesis/py3/hypothesis/internal/entropy.py +++ b/contrib/python/hypothesis/py3/hypothesis/internal/entropy.py @@ -127,7 +127,7 @@ def register_random(r: RandomLike) -> None: "PRNG. See the docs for `register_random` for more " "details." ) - elif not FREE_THREADED_CPYTHON: + elif not FREE_THREADED_CPYTHON: # pragma: no cover # FIXME # On CPython, check for the free-threaded build because # gc.get_referrers() ignores objects with immortal refcounts # and objects are immortalized in the Python 3.13 diff --git a/contrib/python/hypothesis/py3/hypothesis/stateful.py b/contrib/python/hypothesis/py3/hypothesis/stateful.py index 067d9c77c62..0cdf33dd381 100644 --- a/contrib/python/hypothesis/py3/hypothesis/stateful.py +++ b/contrib/python/hypothesis/py3/hypothesis/stateful.py @@ -388,7 +388,7 @@ class RuleBasedStateMachine(metaclass=StateMachineMeta): for target in targets: name = self._new_name(target) - def printer(obj, p, cycle, name=name): + def printer(obj, p, cycle, name=name): # pragma: no cover # FIXME return p.text(name) self.__printer.singleton_pprinters.setdefault(id(result), printer) diff --git a/contrib/python/hypothesis/py3/hypothesis/statistics.py b/contrib/python/hypothesis/py3/hypothesis/statistics.py index 7425db7bcba..465c92e9c16 100644 --- a/contrib/python/hypothesis/py3/hypothesis/statistics.py +++ b/contrib/python/hypothesis/py3/hypothesis/statistics.py @@ -48,7 +48,7 @@ def format_ms(times): """ ordered = sorted(times) n = len(ordered) - 1 - if n < 0 or any(math.isnan(t) for t in ordered): + if n < 0 or any(math.isnan(t) for t in ordered): # pragma: no cover return "NaN ms" lower = int(ordered[int(math.floor(n * 0.05))] * 1000) upper = int(ordered[int(math.ceil(n * 0.95))] * 1000) 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 08ad35057e1..503af0851b4 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 2024033000, Last Updated Sat Mar 30 07:07:01 2024 UTC +# Version 2024062300, Last Updated Sun Jun 23 07:07:01 2024 UTC AAA AARP ABB @@ -802,7 +802,6 @@ NA NAB NAGOYA NAME -NATURA NAVY NBA NC diff --git a/contrib/python/hypothesis/py3/hypothesis/version.py b/contrib/python/hypothesis/py3/hypothesis/version.py index 86d564928e1..fff67d62911 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, 103, 2) +__version_info__ = (6, 104, 0) __version__ = ".".join(map(str, __version_info__)) diff --git a/contrib/python/hypothesis/py3/ya.make b/contrib/python/hypothesis/py3/ya.make index 715f22994ad..8bd9ebb97a0 100644 --- a/contrib/python/hypothesis/py3/ya.make +++ b/contrib/python/hypothesis/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(6.103.2) +VERSION(6.104.0) LICENSE(MPL-2.0) |
