aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Smirnov <alex@ydb.tech>2025-05-23 00:51:59 +0000
committerAlexander Smirnov <alex@ydb.tech>2025-05-23 00:51:59 +0000
commit95cb2090f734bfe45593f1b7b7bb4423bf42acb8 (patch)
tree11f326cd782858f25df2064e027c3fccd3db7f6a
parent778fd6216f12e7ca0a9c16e83522da6c7e121d40 (diff)
parentbb919ff615bff1f8a16a321843cd843497ae83d1 (diff)
downloadydb-95cb2090f734bfe45593f1b7b7bb4423bf42acb8.tar.gz
Merge branch 'rightlib' into merge-libs-250523-0050
-rw-r--r--build/export_generators/ide-gradle/common_vars.jinja3
-rw-r--r--build/export_generators/ide-gradle/gradle/wrapper/gradle-wrapper.properties2
-rw-r--r--build/export_generators/ide-gradle/kotlin_plugins.jinja1
-rw-r--r--build/export_generators/ide-gradle/proto_plugins.jinja2
-rw-r--r--build/external_resources/gdb/resources.json4
-rw-r--r--build/mapping.conf.json4
-rw-r--r--build/platform/yfm/resources.json8
-rw-r--r--build/plugins/nots.py2
-rw-r--r--build/ymake.core.conf2
-rw-r--r--contrib/libs/cxxsupp/builtins/.yandex_meta/build.ym2
-rw-r--r--contrib/libs/cxxsupp/builtins/ya.make4
-rw-r--r--contrib/libs/libfuzzer/.yandex_meta/override.nix4
-rw-r--r--contrib/libs/libfuzzer/lib/fuzzer/afl/ya.make2
-rw-r--r--contrib/libs/libfuzzer/ya.make4
-rw-r--r--contrib/libs/libunwind/.yandex_meta/override.nix4
-rw-r--r--contrib/libs/libunwind/ya.make4
-rw-r--r--contrib/python/google-auth/py3/.dist-info/METADATA2
-rw-r--r--contrib/python/google-auth/py3/google/auth/aio/_helpers.py7
-rw-r--r--contrib/python/google-auth/py3/google/auth/version.py2
-rw-r--r--contrib/python/google-auth/py3/tests/aio/test__helpers.py8
-rw-r--r--contrib/python/google-auth/py3/ya.make2
-rw-r--r--contrib/restricted/google/benchmark/.yandex_meta/override.nix4
-rw-r--r--contrib/restricted/google/benchmark/src/benchmark.cc20
-rw-r--r--contrib/restricted/google/benchmark/src/sysinfo.cc2
-rw-r--r--contrib/restricted/google/benchmark/test/ya.make2
-rw-r--r--contrib/restricted/google/benchmark/tools/compare/ya.make4
-rw-r--r--contrib/restricted/google/benchmark/tools/ya.make2
-rw-r--r--contrib/restricted/google/benchmark/ya.make6
-rw-r--r--contrib/tools/cython/.dist-info/METADATA2
-rw-r--r--contrib/tools/cython/.yandex_meta/override.nix6
-rw-r--r--contrib/tools/cython/CHANGES.rst129
-rw-r--r--contrib/tools/cython/Cython/Build/Inline.py5
-rw-r--r--contrib/tools/cython/Cython/Build/IpythonMagic.py2
-rw-r--r--contrib/tools/cython/Cython/Compiler/Code.py39
-rw-r--r--contrib/tools/cython/Cython/Compiler/ExprNodes.py9
-rw-r--r--contrib/tools/cython/Cython/Compiler/ModuleNode.py4
-rw-r--r--contrib/tools/cython/Cython/Compiler/Nodes.py1
-rw-r--r--contrib/tools/cython/Cython/Compiler/Optimize.py6
-rw-r--r--contrib/tools/cython/Cython/Compiler/PyrexTypes.py17
-rw-r--r--contrib/tools/cython/Cython/Compiler/TypeInference.py5
-rw-r--r--contrib/tools/cython/Cython/Compiler/TypeSlots.py1
-rw-r--r--contrib/tools/cython/Cython/Debugger/libpython.py2
-rw-r--r--contrib/tools/cython/Cython/Includes/cpython/time.pxd42
-rw-r--r--contrib/tools/cython/Cython/Includes/libcpp/deque.pxd2
-rw-r--r--contrib/tools/cython/Cython/Includes/libcpp/optional.pxd2
-rw-r--r--contrib/tools/cython/Cython/Shadow.py2
-rw-r--r--contrib/tools/cython/Cython/Utility/AsyncGen.c12
-rw-r--r--contrib/tools/cython/Cython/Utility/Builtins.c6
-rw-r--r--contrib/tools/cython/Cython/Utility/Coroutine.c12
-rw-r--r--contrib/tools/cython/Cython/Utility/CythonFunction.c6
-rw-r--r--contrib/tools/cython/Cython/Utility/Exceptions.c2
-rw-r--r--contrib/tools/cython/Cython/Utility/MemoryView.pyx2
-rw-r--r--contrib/tools/cython/Cython/Utility/StringTools.c2
-rw-r--r--contrib/tools/cython/Cython/Utility/TypeConversion.c390
-rwxr-xr-xcontrib/tools/cython/cython.py2
-rw-r--r--contrib/tools/cython/patches/pr6343.patch36
-rw-r--r--contrib/tools/cython/ya.make4
-rw-r--r--library/cpp/yt/logging/logger-inl.h4
-rw-r--r--util/thread/pool.cpp21
-rw-r--r--yql/essentials/core/cbo/cbo_interesting_orderings.cpp7
-rw-r--r--yt/python/yt/yson/convert.py81
-rw-r--r--yt/python/yt/yson/yson_types.py24
-rw-r--r--yt/yt/client/api/query_tracker_client.h10
-rw-r--r--yt/yt/client/api/rpc_proxy/client_impl.cpp2
-rw-r--r--yt/yt/client/api/security_client.h6
-rw-r--r--yt/yt/client/complex_types/check_type_compatibility.cpp6
-rw-r--r--yt/yt/client/driver/config.cpp3
-rw-r--r--yt/yt/client/driver/config.h4
-rw-r--r--yt/yt/client/driver/driver.cpp11
-rw-r--r--yt/yt/client/driver/query_commands.cpp8
-rw-r--r--yt/yt/client/table_client/logical_type-inl.h32
-rw-r--r--yt/yt/client/table_client/logical_type.cpp40
-rw-r--r--yt/yt/client/table_client/logical_type.h7
-rw-r--r--yt/yt/client/table_client/public.h9
-rw-r--r--yt/yt/client/table_client/row_base.h15
-rw-r--r--yt/yt/client/table_client/unversioned_row.cpp7
-rw-r--r--yt/yt/client/table_client/validate_logical_type-inl.h36
-rw-r--r--yt/yt/client/table_client/validate_logical_type.cpp6
-rw-r--r--yt/yt/client/unittests/validate_logical_type_ut.cpp64
-rw-r--r--yt/yt/client/ya.make3
-rw-r--r--yt/yt/core/yson/lexer.cpp8
-rw-r--r--yt/yt/core/yson/lexer.h4
-rw-r--r--yt/yt/core/ytree/polymorphic_yson_struct-inl.h6
-rw-r--r--yt/yt/core/ytree/polymorphic_yson_struct.h2
-rw-r--r--yt/yt/core/ytree/yson_struct.cpp30
-rw-r--r--yt/yt/core/ytree/yson_struct.h22
-rw-r--r--yt/yt/core/ytree/yson_struct_detail-inl.h108
-rw-r--r--yt/yt/core/ytree/yson_struct_detail.cpp32
-rw-r--r--yt/yt/core/ytree/yson_struct_detail.h18
-rw-r--r--yt/yt/library/formats/arrow_parser.cpp7
-rw-r--r--yt/yt/library/formats/skiff_parser.cpp8
-rw-r--r--yt/yt/library/formats/skiff_writer.cpp8
-rw-r--r--yt/yt/library/formats/skiff_yson_converter.cpp16
-rw-r--r--yt/yt/library/formats/unittests/skiff_format_ut.cpp4
-rw-r--r--yt/yt/library/formats/unittests/value_examples.cpp9
-rw-r--r--yt/yt/library/formats/web_json_writer.cpp12
-rw-r--r--yt/yt/library/logical_type_shortcuts/logical_type_shortcuts.h7
-rw-r--r--yt/yt/library/tz_types/tz_types-inl.h162
-rw-r--r--yt/yt/library/tz_types/tz_types.cpp1
-rw-r--r--yt/yt/library/tz_types/tz_types.h37
-rw-r--r--yt/yt/library/tz_types/unittests/tz_ut.cpp57
-rw-r--r--yt/yt/library/tz_types/unittests/ya.make16
-rw-r--r--yt/yt/library/tz_types/ya.make19
103 files changed, 1376 insertions, 486 deletions
diff --git a/build/export_generators/ide-gradle/common_vars.jinja b/build/export_generators/ide-gradle/common_vars.jinja
index bb3cbc63a1e..92ae2bf8d14 100644
--- a/build/export_generators/ide-gradle/common_vars.jinja
+++ b/build/export_generators/ide-gradle/common_vars.jinja
@@ -17,9 +17,6 @@
{#- KAPT -#}
{%- set with_kapt = target.with_kapt -%}
{%- set with_test_kapt = extra_targets|selectattr('with_kapt', 'eq', true)|map(attribute='with_kapt')|length -%}
-{#- WAIT ya-bin release, disable just now -#}
-{%- set with_kapt = false -%}
-{%- set with_test_kapt = false -%}
{%- endif -%}
{#- ErrorProne -#}
diff --git a/build/export_generators/ide-gradle/gradle/wrapper/gradle-wrapper.properties b/build/export_generators/ide-gradle/gradle/wrapper/gradle-wrapper.properties
index f2df14bc09c..38b02ac9670 100644
--- a/build/export_generators/ide-gradle/gradle/wrapper/gradle-wrapper.properties
+++ b/build/export_generators/ide-gradle/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://bucket.yandex-team.ru/v1/maven/gradle-distributions/distributions/gradle-8.6-bin.zip
+distributionUrl=https\://bucket.yandex-team.ru/v1/maven/gradle-distributions/distributions/gradle-8.14-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/build/export_generators/ide-gradle/kotlin_plugins.jinja b/build/export_generators/ide-gradle/kotlin_plugins.jinja
index 1735112c30c..0a2e7cd48d2 100644
--- a/build/export_generators/ide-gradle/kotlin_plugins.jinja
+++ b/build/export_generators/ide-gradle/kotlin_plugins.jinja
@@ -59,7 +59,6 @@ noArg {
{%- if with_kotlin %}
kotlin {
- kotlinDaemonJvmArgs = listOf("-Xmx2G")
jvmToolchain({{ jdk_version }})
}
{% endif -%}
diff --git a/build/export_generators/ide-gradle/proto_plugins.jinja b/build/export_generators/ide-gradle/proto_plugins.jinja
index 28b9910492a..8bce751c965 100644
--- a/build/export_generators/ide-gradle/proto_plugins.jinja
+++ b/build/export_generators/ide-gradle/proto_plugins.jinja
@@ -1,7 +1,7 @@
{#- empty string #}
plugins {
id("java-library")
- id("com.google.protobuf") version "0.9.4"
+ id("com.google.protobuf") version "0.9.5"
{%- if publish %}
`maven-publish`
`signing`
diff --git a/build/external_resources/gdb/resources.json b/build/external_resources/gdb/resources.json
index fa013ee2de6..ea1833d4ee2 100644
--- a/build/external_resources/gdb/resources.json
+++ b/build/external_resources/gdb/resources.json
@@ -7,10 +7,10 @@
"uri": "sbr:3833498694"
},
"linux-aarch64": {
- "uri": "sbr:8509776935"
+ "uri": "sbr:8784096409"
},
"linux-x86_64": {
- "uri": "sbr:8509757921"
+ "uri": "sbr:8784094118"
}
}
}
diff --git a/build/mapping.conf.json b/build/mapping.conf.json
index be35db7cc6e..5ecd508a105 100644
--- a/build/mapping.conf.json
+++ b/build/mapping.conf.json
@@ -1104,6 +1104,7 @@
"6164166258": "{registry_endpoint}/6164166258",
"6682389529": "{registry_endpoint}/6682389529",
"6478436039": "{registry_endpoint}/6478436039",
+ "8784096409": "{registry_endpoint}/8784096409",
"6406540582": "{registry_endpoint}/6406540582",
"6447362348": "{registry_endpoint}/6447362348",
"6133337898": "{registry_endpoint}/6133337898",
@@ -1111,6 +1112,7 @@
"6164128408": "{registry_endpoint}/6164128408",
"6682380912": "{registry_endpoint}/6682380912",
"6478494211": "{registry_endpoint}/6478494211",
+ "8784094118": "{registry_endpoint}/8784094118",
"6406437536": "{registry_endpoint}/6406437536",
"6447316775": "{registry_endpoint}/6447316775",
"6133419349": "{registry_endpoint}/6133419349",
@@ -2524,6 +2526,7 @@
"6164166258": "gdb-14-linux-aarch64-2f60b923acb68d45b101313954b70779c13a19b8",
"6682389529": "gdb-14-linux-aarch64-533b7767fda1a4ec616af8b575d10c4694ae1f2f",
"6478436039": "gdb-14-linux-aarch64-67ef8a9f1868bf62959ac3a14d552999a108ed38",
+ "8784096409": "gdb-14-linux-aarch64-6ea280bfa165555cc850c4ee3d49f07745e6f21b",
"6406540582": "gdb-14-linux-aarch64-9d91f66a1caff272af94e2fc97e690a18d910204",
"6447362348": "gdb-14-linux-aarch64-9db71d8b25a56ee316036c53fd941934a95831a3",
"6133337898": "gdb-14-linux-aarch64-b1fa9be28bbf4ee845d6a39a049c7b60018a3695",
@@ -2531,6 +2534,7 @@
"6164128408": "gdb-14-linux-x86_64-2f60b923acb68d45b101313954b70779c13a19b8",
"6682380912": "gdb-14-linux-x86_64-533b7767fda1a4ec616af8b575d10c4694ae1f2f",
"6478494211": "gdb-14-linux-x86_64-67ef8a9f1868bf62959ac3a14d552999a108ed38",
+ "8784094118": "gdb-14-linux-x86_64-6ea280bfa165555cc850c4ee3d49f07745e6f21b",
"6406437536": "gdb-14-linux-x86_64-9d91f66a1caff272af94e2fc97e690a18d910204",
"6447316775": "gdb-14-linux-x86_64-9db71d8b25a56ee316036c53fd941934a95831a3",
"6133419349": "gdb-14-linux-x86_64-b1fa9be28bbf4ee845d6a39a049c7b60018a3695",
diff --git a/build/platform/yfm/resources.json b/build/platform/yfm/resources.json
index b9e9aedeb45..a27dd38d54e 100644
--- a/build/platform/yfm/resources.json
+++ b/build/platform/yfm/resources.json
@@ -1,16 +1,16 @@
{
"by_platform": {
"win32-x86_64": {
- "uri": "sbr:8714329658"
+ "uri": "sbr:8778298308"
},
"darwin-x86_64": {
- "uri": "sbr:8714328247"
+ "uri": "sbr:8778297068"
},
"linux-x86_64": {
- "uri": "sbr:8714326826"
+ "uri": "sbr:8778295807"
},
"darwin-arm64": {
- "uri": "sbr:8714328247"
+ "uri": "sbr:8778297068"
}
}
}
diff --git a/build/plugins/nots.py b/build/plugins/nots.py
index 3fc54dde0f2..5f9c4480ac4 100644
--- a/build/plugins/nots.py
+++ b/build/plugins/nots.py
@@ -654,7 +654,6 @@ def _setup_tsc_typecheck(unit: NotsUnitType) -> None:
unit.on_peerdir_ts_resource("typescript")
user_recipes = unit.get("TEST_RECIPES_VALUE")
unit.on_setup_install_node_modules_recipe()
- unit.on_setup_extract_output_tars_recipe([unit.get("MODDIR")])
test_type = TsTestType.TSC_TYPECHECK
@@ -707,7 +706,6 @@ def _setup_stylelint(unit: NotsUnitType) -> None:
recipes_value = unit.get("TEST_RECIPES_VALUE")
unit.on_setup_install_node_modules_recipe()
- unit.on_setup_extract_output_tars_recipe([unit.get("MODDIR")])
test_type = TsTestType.TS_STYLELINT
diff --git a/build/ymake.core.conf b/build/ymake.core.conf
index 9e94e66b827..1c4d6ce2047 100644
--- a/build/ymake.core.conf
+++ b/build/ymake.core.conf
@@ -13,7 +13,7 @@ CPP_FAKEID=2024-01-23
GO_FAKEID=11100371
ANDROID_FAKEID=2023-05-17
CLANG_TIDY_FAKEID=2023-06-06
-CYTHON_FAKEID=16584065
+CYTHON_FAKEID=16586418
JAVA_FAKEID=14386852
PROTO_FAKEID=0
FBS_FAKEID=2024-03-13
diff --git a/contrib/libs/cxxsupp/builtins/.yandex_meta/build.ym b/contrib/libs/cxxsupp/builtins/.yandex_meta/build.ym
index 149266d27fc..7b0fcdf701b 100644
--- a/contrib/libs/cxxsupp/builtins/.yandex_meta/build.ym
+++ b/contrib/libs/cxxsupp/builtins/.yandex_meta/build.ym
@@ -1,6 +1,6 @@
{% extends '//builtin/bag.ym' %}
-{% block current_version %}20.1.4{% endblock %}
+{% block current_version %}20.1.5{% endblock %}
{% block current_url %}
https://github.com/llvm/llvm-project/releases/download/llvmorg-{{self.version().strip()}}/compiler-rt-{{self.version().strip()}}.src.tar.xz
diff --git a/contrib/libs/cxxsupp/builtins/ya.make b/contrib/libs/cxxsupp/builtins/ya.make
index 5335f7cc9fc..3b86670e076 100644
--- a/contrib/libs/cxxsupp/builtins/ya.make
+++ b/contrib/libs/cxxsupp/builtins/ya.make
@@ -12,9 +12,9 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20.1.4)
+VERSION(20.1.5)
-ORIGINAL_SOURCE(https://github.com/llvm/llvm-project/releases/download/llvmorg-20.1.4/compiler-rt-20.1.4.src.tar.xz)
+ORIGINAL_SOURCE(https://github.com/llvm/llvm-project/releases/download/llvmorg-20.1.5/compiler-rt-20.1.5.src.tar.xz)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/libfuzzer/.yandex_meta/override.nix b/contrib/libs/libfuzzer/.yandex_meta/override.nix
index afac6b61fbd..38c1a7c3091 100644
--- a/contrib/libs/libfuzzer/.yandex_meta/override.nix
+++ b/contrib/libs/libfuzzer/.yandex_meta/override.nix
@@ -1,11 +1,11 @@
pkgs: attrs: with pkgs; with attrs; rec {
- version = "20.1.4";
+ version = "20.1.5";
src = fetchFromGitHub {
owner = "llvm";
repo = "llvm-project";
rev = "llvmorg-${version}";
- hash = "sha256-/WomqG2DdnUHwlVsMfpzaK/dhGV3zychfU0wLmihQac=";
+ hash = "sha256-WKfY+VvAsZEEc0xYgF6+MsXDXZz7haMU6bxqmUpaHuQ=";
};
sourceRoot = "source/compiler-rt";
diff --git a/contrib/libs/libfuzzer/lib/fuzzer/afl/ya.make b/contrib/libs/libfuzzer/lib/fuzzer/afl/ya.make
index 11a466f2bb7..c5b7a537747 100644
--- a/contrib/libs/libfuzzer/lib/fuzzer/afl/ya.make
+++ b/contrib/libs/libfuzzer/lib/fuzzer/afl/ya.make
@@ -8,7 +8,7 @@ LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
SUBSCRIBER(g:cpp-contrib)
-VERSION(20.1.4)
+VERSION(20.1.5)
PEERDIR(
contrib/libs/afl/llvm_mode
diff --git a/contrib/libs/libfuzzer/ya.make b/contrib/libs/libfuzzer/ya.make
index 6084aae3b5b..f838cd2693f 100644
--- a/contrib/libs/libfuzzer/ya.make
+++ b/contrib/libs/libfuzzer/ya.make
@@ -12,9 +12,9 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20.1.4)
+VERSION(20.1.5)
-ORIGINAL_SOURCE(https://github.com/llvm/llvm-project/archive/llvmorg-20.1.4.tar.gz)
+ORIGINAL_SOURCE(https://github.com/llvm/llvm-project/archive/llvmorg-20.1.5.tar.gz)
SET(SANITIZER_CFLAGS)
diff --git a/contrib/libs/libunwind/.yandex_meta/override.nix b/contrib/libs/libunwind/.yandex_meta/override.nix
index 0cd3ba022d9..150f6a04f70 100644
--- a/contrib/libs/libunwind/.yandex_meta/override.nix
+++ b/contrib/libs/libunwind/.yandex_meta/override.nix
@@ -1,11 +1,11 @@
pkgs: attrs: with pkgs; with attrs; rec {
- version = "20.1.4";
+ version = "20.1.5";
src = fetchFromGitHub {
owner = "llvm";
repo = "llvm-project";
rev = "llvmorg-${version}";
- hash = "sha256-/WomqG2DdnUHwlVsMfpzaK/dhGV3zychfU0wLmihQac=";
+ hash = "sha256-WKfY+VvAsZEEc0xYgF6+MsXDXZz7haMU6bxqmUpaHuQ=";
};
patches = [];
diff --git a/contrib/libs/libunwind/ya.make b/contrib/libs/libunwind/ya.make
index 0b2e66c37d0..036523dcb81 100644
--- a/contrib/libs/libunwind/ya.make
+++ b/contrib/libs/libunwind/ya.make
@@ -11,9 +11,9 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20.1.4)
+VERSION(20.1.5)
-ORIGINAL_SOURCE(https://github.com/llvm/llvm-project/archive/llvmorg-20.1.4.tar.gz)
+ORIGINAL_SOURCE(https://github.com/llvm/llvm-project/archive/llvmorg-20.1.5.tar.gz)
PEERDIR(
library/cpp/sanitizer/include
diff --git a/contrib/python/google-auth/py3/.dist-info/METADATA b/contrib/python/google-auth/py3/.dist-info/METADATA
index ddba2bddaed..6d1bff83523 100644
--- a/contrib/python/google-auth/py3/.dist-info/METADATA
+++ b/contrib/python/google-auth/py3/.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: google-auth
-Version: 2.40.0
+Version: 2.40.1
Summary: Google Authentication Library
Home-page: https://github.com/googleapis/google-auth-library-python
Author: Google Cloud Platform
diff --git a/contrib/python/google-auth/py3/google/auth/aio/_helpers.py b/contrib/python/google-auth/py3/google/auth/aio/_helpers.py
index fd7d37a2f7b..1d5a4618cb6 100644
--- a/contrib/python/google-auth/py3/google/auth/aio/_helpers.py
+++ b/contrib/python/google-auth/py3/google/auth/aio/_helpers.py
@@ -53,5 +53,10 @@ async def response_log_async(logger: logging.Logger, response: Any) -> None:
response: The HTTP response object to log.
"""
if _helpers.is_logging_enabled(logger):
- json_response = await _parse_response_async(response)
+ # TODO(https://github.com/googleapis/google-auth-library-python/issues/1755):
+ # Parsing the response for async streaming logging results in
+ # the stream to be empty downstream. For now, we will not be logging
+ # the response for async responses until we investigate further.
+ # json_response = await _parse_response_async(response)
+ json_response = None
_helpers._response_log_base(logger, json_response)
diff --git a/contrib/python/google-auth/py3/google/auth/version.py b/contrib/python/google-auth/py3/google/auth/version.py
index d1363c1ef0e..ee0bb12609d 100644
--- a/contrib/python/google-auth/py3/google/auth/version.py
+++ b/contrib/python/google-auth/py3/google/auth/version.py
@@ -12,4 +12,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-__version__ = "2.40.0"
+__version__ = "2.40.1"
diff --git a/contrib/python/google-auth/py3/tests/aio/test__helpers.py b/contrib/python/google-auth/py3/tests/aio/test__helpers.py
index 7642431caec..829dc97ff33 100644
--- a/contrib/python/google-auth/py3/tests/aio/test__helpers.py
+++ b/contrib/python/google-auth/py3/tests/aio/test__helpers.py
@@ -65,17 +65,13 @@ async def test_response_log_debug_disabled(logger, caplog, base_logger):
@pytest.mark.asyncio
async def test_response_log_debug_enabled_response_json(logger, caplog, base_logger):
- class MockResponse:
- async def json(self):
- return {"key1": "value1", "key2": "value2", "key3": "value3"}
-
- response = MockResponse()
+ response = None
caplog.set_level(logging.DEBUG, logger=_MOCK_CHILD_LOGGER_NAME)
await _helpers.response_log_async(logger, response)
assert len(caplog.records) == 1
record = caplog.records[0]
assert record.message == "Response received..."
- assert record.httpResponse == {"key1": "value1", "key2": "value2", "key3": "value3"}
+ assert record.httpResponse == "<class 'NoneType'>"
@pytest.mark.asyncio
diff --git a/contrib/python/google-auth/py3/ya.make b/contrib/python/google-auth/py3/ya.make
index 7ceec35306e..83c9200ad11 100644
--- a/contrib/python/google-auth/py3/ya.make
+++ b/contrib/python/google-auth/py3/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(2.40.0)
+VERSION(2.40.1)
LICENSE(Apache-2.0)
diff --git a/contrib/restricted/google/benchmark/.yandex_meta/override.nix b/contrib/restricted/google/benchmark/.yandex_meta/override.nix
index 48bdca47f1e..e36f8bcc55e 100644
--- a/contrib/restricted/google/benchmark/.yandex_meta/override.nix
+++ b/contrib/restricted/google/benchmark/.yandex_meta/override.nix
@@ -1,11 +1,11 @@
pkgs: attrs: with pkgs; with attrs; rec {
- version = "1.9.3";
+ version = "1.9.4";
src = fetchFromGitHub {
owner = "google";
repo = "benchmark";
rev = "v${version}";
- hash = "sha256-iPK3qLrZL2L08XW1a7SGl7GAt5InQ5nY+Dn8hBuxSOg=";
+ hash = "sha256-P7wJcKkIBoWtN9FCRticpBzYbEZPq71a0iW/2oDTZRU=";
};
buildInputs = [ gtest ];
diff --git a/contrib/restricted/google/benchmark/src/benchmark.cc b/contrib/restricted/google/benchmark/src/benchmark.cc
index 48a2accdf90..8672c8a94f8 100644
--- a/contrib/restricted/google/benchmark/src/benchmark.cc
+++ b/contrib/restricted/google/benchmark/src/benchmark.cc
@@ -815,6 +815,12 @@ int InitializeStreams() {
return 0;
}
+template <typename T>
+std::make_unsigned_t<T> get_as_unsigned(T v) {
+ using UnsignedT = std::make_unsigned_t<T>;
+ return static_cast<UnsignedT>(v);
+}
+
} // end namespace internal
void MaybeReenterWithoutASLR(int /*argc*/, char** argv) {
@@ -829,15 +835,23 @@ void MaybeReenterWithoutASLR(int /*argc*/, char** argv) {
if (curr_personality == -1) return;
// If ASLR is already disabled, we have nothing more to do.
- if (curr_personality & ADDR_NO_RANDOMIZE) return;
+ if (internal::get_as_unsigned(curr_personality) & ADDR_NO_RANDOMIZE) return;
// Try to change the personality to disable ASLR.
- const auto prev_personality = personality(
- static_cast<unsigned long>(curr_personality) | ADDR_NO_RANDOMIZE);
+ const auto proposed_personality =
+ internal::get_as_unsigned(curr_personality) | ADDR_NO_RANDOMIZE;
+ const auto prev_personality = personality(proposed_personality);
// Have we failed to change the personality? That may happen.
if (prev_personality == -1) return;
+ // Make sure the parsona has been updated with the no-ASLR flag,
+ // otherwise we will try to reenter infinitely.
+ // This seems impossible, but can happen in some docker configurations.
+ const auto new_personality = personality(0xffffffff);
+ if ((internal::get_as_unsigned(new_personality) & ADDR_NO_RANDOMIZE) == 0)
+ return;
+
execv(argv[0], argv);
// The exec() functions return only if an error has occurred,
// in which case we want to just continue as-is.
diff --git a/contrib/restricted/google/benchmark/src/sysinfo.cc b/contrib/restricted/google/benchmark/src/sysinfo.cc
index ea1dae40f14..4ca249da4fd 100644
--- a/contrib/restricted/google/benchmark/src/sysinfo.cc
+++ b/contrib/restricted/google/benchmark/src/sysinfo.cc
@@ -439,7 +439,7 @@ std::vector<CPUInfo::CacheInfo> GetCacheSizes() {
return GetCacheSizesWindows();
#elif defined(BENCHMARK_OS_QNX)
return GetCacheSizesQNX();
-#elif defined(BENCHMARK_OS_QURT)
+#elif defined(BENCHMARK_OS_QURT) || defined(__EMSCRIPTEN__)
return std::vector<CPUInfo::CacheInfo>();
#else
return GetCacheSizesFromKVFS();
diff --git a/contrib/restricted/google/benchmark/test/ya.make b/contrib/restricted/google/benchmark/test/ya.make
index 27a3a0fb0fc..3e2b7047516 100644
--- a/contrib/restricted/google/benchmark/test/ya.make
+++ b/contrib/restricted/google/benchmark/test/ya.make
@@ -4,7 +4,7 @@ GTEST(benchmark_gtest)
WITHOUT_LICENSE_TEXTS()
-VERSION(1.9.3)
+VERSION(1.9.4)
LICENSE(Apache-2.0)
diff --git a/contrib/restricted/google/benchmark/tools/compare/ya.make b/contrib/restricted/google/benchmark/tools/compare/ya.make
index 39eafaddf36..8bfa31414ad 100644
--- a/contrib/restricted/google/benchmark/tools/compare/ya.make
+++ b/contrib/restricted/google/benchmark/tools/compare/ya.make
@@ -4,9 +4,9 @@ PY3_PROGRAM()
WITHOUT_LICENSE_TEXTS()
-VERSION(1.9.3)
+VERSION(1.9.4)
-ORIGINAL_SOURCE(https://github.com/google/benchmark/archive/v1.9.3.tar.gz)
+ORIGINAL_SOURCE(https://github.com/google/benchmark/archive/v1.9.4.tar.gz)
LICENSE(Apache-2.0)
diff --git a/contrib/restricted/google/benchmark/tools/ya.make b/contrib/restricted/google/benchmark/tools/ya.make
index 90fb103e020..c49a52e605b 100644
--- a/contrib/restricted/google/benchmark/tools/ya.make
+++ b/contrib/restricted/google/benchmark/tools/ya.make
@@ -1,6 +1,6 @@
# Generated by devtools/yamaker.
-VERSION(1.9.3)
+VERSION(1.9.4)
IF (NOT USE_STL_SYSTEM)
IF (NOT USE_SYSTEM_PYTHON OR NOT _SYSTEM_PYTHON27)
diff --git a/contrib/restricted/google/benchmark/ya.make b/contrib/restricted/google/benchmark/ya.make
index 5218377accd..88a14ddd1eb 100644
--- a/contrib/restricted/google/benchmark/ya.make
+++ b/contrib/restricted/google/benchmark/ya.make
@@ -2,9 +2,9 @@
LIBRARY()
-VERSION(1.9.3)
+VERSION(1.9.4)
-ORIGINAL_SOURCE(https://github.com/google/benchmark/archive/v1.9.3.tar.gz)
+ORIGINAL_SOURCE(https://github.com/google/benchmark/archive/v1.9.4.tar.gz)
LICENSE(Apache-2.0)
@@ -21,7 +21,7 @@ NO_UTIL()
CFLAGS(
GLOBAL -DBENCHMARK_STATIC_DEFINE
- -DBENCHMARK_VERSION=\"v1.9.3\"
+ -DBENCHMARK_VERSION=\"v1.9.4\"
-DHAVE_POSIX_REGEX
-DHAVE_PTHREAD_AFFINITY
-DHAVE_STD_REGEX
diff --git a/contrib/tools/cython/.dist-info/METADATA b/contrib/tools/cython/.dist-info/METADATA
index 237a1673400..197a6e14edc 100644
--- a/contrib/tools/cython/.dist-info/METADATA
+++ b/contrib/tools/cython/.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: Cython
-Version: 3.0.10
+Version: 3.0.11
Summary: The Cython compiler for writing C extensions in the Python language.
Home-page: https://cython.org/
Author: Robert Bradshaw, Stefan Behnel, Dag Seljebotn, Greg Ewing, et al.
diff --git a/contrib/tools/cython/.yandex_meta/override.nix b/contrib/tools/cython/.yandex_meta/override.nix
index 1c3e41ff9d3..68cfcf5e2ba 100644
--- a/contrib/tools/cython/.yandex_meta/override.nix
+++ b/contrib/tools/cython/.yandex_meta/override.nix
@@ -1,10 +1,10 @@
pkgs: attrs: with pkgs; with pkgs.python311.pkgs; with attrs; rec {
- version = "3.0.10";
+ version = "3.0.11";
src = fetchPypi {
- pname = "Cython";
+ pname = "cython";
inherit version;
- hash = "sha256-3MlnOTMfuFTc9QP5RgdXbP6EiAZsYcpQ39VYNvEy3pk=";
+ hash = "sha256-cUbdKvhoK0ymEzGFHmrrzp/lFY51MAND+AwHyoCx+v8=";
};
patches = [];
diff --git a/contrib/tools/cython/CHANGES.rst b/contrib/tools/cython/CHANGES.rst
index e4a744da721..895bc335486 100644
--- a/contrib/tools/cython/CHANGES.rst
+++ b/contrib/tools/cython/CHANGES.rst
@@ -2,6 +2,49 @@
Cython Changelog
================
+3.0.11 (2024-08-05)
+===================
+
+Features added
+--------------
+
+* The C++11 ``emplace*`` methods were added to ``libcpp.deque``.
+ Patch by Somin An. (Github issue :issue:`6159`)
+
+Bugs fixed
+----------
+
+* The exception check value of functions declared in pxd files was not always applied in 3.0.10.
+ (Github issue :issue:`6122`)
+
+* A crash on exception deallocations was fixed.
+ (Github issue :issue:`6022`)
+
+* A crash was fixed when assigning a zero-length slice to a memoryview.
+ Patch by Michael Man. (Github issue :issue:`6227`)
+
+* ``libcpp.optional.value()`` could crash if it raised a C++ exception.
+ Patch by Alexander Condello. (Github issue :issue:`6190`)
+
+* The return type of ``str()`` was mishandled, leading to crashes with ``language_level=3``.
+ (Github issue :issue:`6166`)
+
+* ``bytes.startswith/endswith()`` failed for non-bytes substrings (e.g. ``bytearray``).
+ (Github issue :issue:`6168`)
+
+* Fused ctuples crashed Cython.
+ (Github issue :issue:`6068`)
+
+* A compiler crash was fixed when using extension types in fused types.
+ (Github issue :issue:`6204`)
+
+* The module cleanup code was incorrect for globally defined memory view slices.
+ (Github issue :issue:`6276`)
+
+* Some adaptations were made to enable compilation in Python 3.13.
+ (Github issues :issue:`5997`, :issue:`6182`, :issue:`6251`)
+
+
3.0.10 (2024-03-30)
===================
@@ -540,12 +583,12 @@ Related changes
* The Python ``int`` handling code was adapted to make use of the new ``PyLong``
internals in CPython 3.12.
(Github issue :issue:`5353`)
-
+
* A compile error when using ``__debug__`` was resolved.
-
+
* The deprecated ``_PyGC_FINALIZED()`` C-API macro is no longer used.
Patch by Thomas Caswell and Matúš Valo. (Github issue :issue:`5481`)
-
+
* A crash in Python 2.7 was fixed when cleaning up extension type instances
at program end.
@@ -592,7 +635,7 @@ without recompilation.
There is initial support for this in Cython. By defining the ``CYTHON_LIMITED_API``
macro, Cython cuts down its C-API usage and tries to adhere to the Limited C-API,
probably at the cost of a bit of performance.
-In order to get full benefit from the limited API you will also need to define the
+In order to get full benefit from the limited API you will also need to define the
CPython macro ``Py_LIMITED_API`` to a specific CPython compatibility version,
which additionally restricts the C-API during the C compilation,
thus enforcing the forward compatibility of the extension module.
@@ -647,7 +690,7 @@ Related changes
(Github issue :issue:`5419`)
* Custom buffer slot methods are now supported in the Limited C-API of Python 3.9+.
- Patch by Lisandro Dalcin. (Github issue :issue:`5422`)
+ Patch by Lisandro Dalcin. (Github issue :issue:`5422`)
Improved fidelity to Python semantics
@@ -705,24 +748,24 @@ Related changes
* Binding staticmethods of Cython functions were not behaving like Python methods.
Patch by Jeroen Demeyer. (Github issue :issue:`3106`, :issue:`3102`)
-
+
* Compiling package ``__init__`` files could fail under Windows due to an
- undefined export symbol. (Github issue :issue:`2968`)
-
+ undefined export symbol. (Github issue :issue:`2968`)
+
* ``__init__.pyx`` files were not always considered as package indicators.
(Github issue :issue:`2665`)
-
+
* Setting ``language_level=2`` in a file did not work if ``language_level=3``
was enabled globally before.
Patch by Jeroen Demeyer. (Github issue :issue:`2791`)
-
+
* ``__doc__`` was not available inside of the class body during class creation.
(Github issue :issue:`1635`)
* The first function line number of functions with decorators pointed to the
signature line and not the first decorator line, as in Python.
Patch by Felix Kohlgrüber. (Github issue :issue:`2536`)
-
+
* Pickling unbound methods of Python classes failed.
Patch by Pierre Glaser. (Github issue :issue:`2972`)
@@ -763,7 +806,7 @@ Related changes
* ``__arg`` argument names in methods were not mangled with the class name.
Patch by David Woods. (Github issue :issue:`1382`)
-
+
* With ``language_level=3/3str``, Python classes without explicit base class
are now new-style (type) classes also in Py2. Previously, they were created
as old-style (non-type) classes.
@@ -778,7 +821,7 @@ Related changes
globals, since double-underscore names are not uncommon in C. Unmangled Python
names are also still found as a legacy fallback but produce a warning.
Patch by David Woods. (Github issue :issue:`3548`)
-
+
* The ``print`` statement (not the ``print()`` function) is allowed in
``nogil`` code without an explicit ``with gil`` section.
@@ -843,7 +886,7 @@ Related changes
* Default values for memory views arguments were not properly supported.
Patch by Corentin Cadiou. (Github issue :issue:`4313`)
-
+
* Python object types were not allowed as ``->`` return type annotations.
Patch by Matúš Valo. (Github issue :issue:`4433`)
@@ -859,7 +902,7 @@ Related changes
* Decorators on inner functions were not evaluated in the right scope.
Patch by David Woods. (Github issue :issue:`4367`)
-
+
* Cython did not type the ``self`` argument in special binary methods.
Patch by David Woods. (Github issue :issue:`4434`)
@@ -869,7 +912,7 @@ Related changes
* ``__del__(self)`` on extension types now maps to ``tp_finalize`` in Python 3.
Original patch by ax487. (Github issue :issue:`3612`)
-
+
* Reusing an extension type attribute name as a method name is now an error.
Patch by 0dminnimda. (Github issue :issue:`4661`)
@@ -922,14 +965,14 @@ Related changes
* ``int(Py_UCS4)`` returned the code point instead of the parsed digit value.
(Github issue :issue:`5216`)
-
+
* Calling bound classmethods of builtin types could fail trying to call the unbound method.
(Github issue :issue:`5051`)
* Generator expressions and comprehensions now look up their outer-most iterable
on creation, as Python does, and not later on start, as they did previously.
(Github issue :issue:`1159`)
-
+
* Bound C methods can now coerce to Python objects.
(Github issues :issue:`4890`, :issue:`5062`)
@@ -942,7 +985,7 @@ Related changes
* The special ``__*pow__`` methods now support the 2- and 3-argument variants.
(Github issue :issue:`5160`)
-
+
* The ``**`` power operator now behaves more like in Python by returning the correct complex
result if required by math. A new ``cpow`` directive was added to turn on the previous
C-like behaviour.
@@ -997,7 +1040,7 @@ Related changes
* ``nogil`` functions now avoid acquiring the GIL on function exit if possible
even if they contain ``with gil`` blocks.
(Github issue :issue:`3554`)
-
+
* The ``@returns()`` decorator propagates exceptions by default for suitable C
return types when no ``@exceptval()`` is defined.
(Github issues :issue:`3625`, :issue:`3664`)
@@ -1005,13 +1048,13 @@ Related changes
* Extension types inheriting from Python classes could not safely
be exposed in ``.pxd`` files.
(Github issue :issue:`4106`)
-
+
* Default arguments of methods were not exposed for introspection.
Patch by Vladimir Matveev. (Github issue :issue:`4061`)
* Literal list assignments to pointer variables declared in PEP-526
notation failed to compile.
-
+
* The type ``cython.Py_hash_t`` is available in Python mode.
* A ``cimport`` is now supported in pure Python code by prefixing the
@@ -1100,12 +1143,12 @@ Related changes
* Generated NumPy ufuncs could crash for large arrays due to incorrect GIL handling.
(Github issue :issue:`5328`)
-
+
* Some invalid directive usages are now detected and rejected, e.g. using ``@ccall``
together with ``@cfunc``, and applying ``@cfunc`` to a ``@ufunc``. Cython also
warns now when a directive is applied needlessly.
(Github issue :issue:`5399` et al.)
-
+
* The normal ``@dataclasses.dataclass`` and ``@functools.total_ordering`` decorators
can now be used on extension types. Using the corresponding ``@cython.*`` decorator
will automatically turn a Python class into an extension type (no need for ``@cclass``).
@@ -1209,7 +1252,7 @@ Related changes
(Github issue :issue:`5430`)
* Handling freshly raised exceptions that didn't have a traceback yet could crash.
- (Github issue :issue:`5495`)
+ (Github issue :issue:`5495`)
Optimizations
@@ -1240,11 +1283,11 @@ Related changes
* String concatenation can now happen in place if possible, by extending the
existing string rather than always creating a new one.
Patch by David Woods. (Github issue :issue:`3453`)
-
+
* The ``str()`` builtin now calls ``PyObject_Str()`` instead of going
through a Python call.
Patch by William Ayd. (Github issue :issue:`3279`)
-
+
* Reimports of already imported modules are substantially faster.
(Github issue :issue:`2854`)
@@ -1255,17 +1298,17 @@ Related changes
* The fastcall/vectorcall protocols are used for several internal Python calls.
(Github issue :issue:`3540`)
-
+
* ``nogil`` functions now avoid acquiring the GIL on function exit if possible
even if they contain ``with gil`` blocks.
(Github issue :issue:`3554`)
-
+
* Type inference now works for memory views and slices.
Patch by David Woods. (Github issue :issue:`2227`)
* For-in-loop iteration over ``bytearray`` and memory views is optimised.
Patch by David Woods. (Github issue :issue:`2227`)
-
+
* For-in-loop iteration over ``bytearray`` and memory views is optimised.
Patch by David Woods. (Github issue :issue:`2227`)
@@ -1383,7 +1426,7 @@ Related changes
* ``cdef public`` functions declared in .pxd files could use an incorrectly mangled C name.
Patch by EpigeneMax. (Github issue :issue:`2940`)
-
+
* ``const`` types could not be returned from functions.
Patch by Mike Graham. (Github issue :issue:`5135`)
@@ -1398,11 +1441,11 @@ Related changes
* Very long Python integer constants could exceed the maximum C name length of MSVC.
Patch by 0dminnimda. (Github issue :issue:`5290`)
-
+
* Some C compiler warnings were resolved.
Patches by Matt Tyson, Lisandro Dalcin, Philipp Wagner, Matti Picus et al.
(Github issues :issue:`5417`, :issue:`5418`, :issue:`5421`, :issue:`5437`, :issue:`5438`, :issue:`5443`)
-
+
* Some typedef declarations for libc function types were fixed.
(Github issue :issue:`5498`)
@@ -1566,7 +1609,7 @@ Related changes
* C++ containers of item type ``bint`` could conflict with those of item type ``int``.
(Github issue :issue:`5516`)
-
+
* Reverse iteration in C++ no longer removes the ``const`` qualifier from the item type.
Patch by Isuru Fernando. (Github issue :issue:`5478`)
@@ -1615,7 +1658,7 @@ Related changes
* ``cython --version`` now prints the version to both stdout and stderr (unless that is a TTY).
(Github issue :issue:`5504`)
-
+
Build integration
-----------------
@@ -1633,7 +1676,7 @@ Related changes
* Binary Linux wheels now follow the manylinux2010 standard.
Patch by Alexey Stepanov. (Github issue :issue:`3355`)
-
+
* The search order for include files was changed. Previously it was
``include_directories``, ``Cython/Includes``, ``sys.path``. Now it is
``include_directories``, ``sys.path``, ``Cython/Includes``. This was done to
@@ -1701,7 +1744,7 @@ Related changes
* A new Cython build option ``--cython-compile-minimal`` was added to compile only a
smaller set of Cython's own modules, which can be used to reduce the package
and install size.
-
+
* The environment variable ``CYTHON_FORCE_REGEN=1`` can be used to force ``cythonize``
to regenerate the output files regardless of modification times and changes.
@@ -1713,15 +1756,15 @@ Related changes
* Wheels now include a compiled parser again, which increases their size a little
but gives about a 10% speed-up when running Cython.
-
+
* The wheel building process was migrated to use the ``cibuildwheel`` tool.
Patch by Thomas Li. (Github issue :issue:`4736`)
-
+
* ``setup.cfg`` was missing from the source distribution.
(Github issue :issue:`5199`)
* Extended glob paths with ``/**/`` and ``\**\`` for finding source files failed on Windows.
-
+
* Coverage analysis failed in projects with a separate source subdirectory.
Patch by Sviatoslav Sydorenko and Ruben Vorderman. (Github issue :issue:`3636`)
@@ -1789,12 +1832,12 @@ Other changes
* Memoryviews failed to compile when the ``cache_builtins`` feature was disabled.
Patch by David Woods. (Github issue :issue:`3406`)
-
+
* Broadcast assignments to a multi-dimensional memory view slice could end
up in the wrong places when the underlying memory view is known to be
contiguous but the slice is not.
(Github issue :issue:`2941`)
-
+
* The Pythran ``shape`` attribute is supported.
Patch by Serge Guelton. (Github issue :issue:`3307`)
@@ -1824,7 +1867,7 @@ Other changes
* Casting to ctuples is now allowed.
Patch by David Woods. (Github issue :issue:`3808`)
-
+
* Some issues were resolved that could lead to duplicated C names.
Patch by David Woods. (Github issue :issue:`3716`, :issue:`3741`, :issue:`3734`)
diff --git a/contrib/tools/cython/Cython/Build/Inline.py b/contrib/tools/cython/Cython/Build/Inline.py
index fac6a79b9c3..fe62d4ca9ea 100644
--- a/contrib/tools/cython/Cython/Build/Inline.py
+++ b/contrib/tools/cython/Cython/Build/Inline.py
@@ -151,6 +151,11 @@ def _populate_unbound(kwds, unbound_symbols, locals=None, globals=None):
locals = calling_frame.f_locals
if globals is None:
globals = calling_frame.f_globals
+ if not isinstance(locals, dict):
+ # FrameLocalsProxy is stricter than dict on how it looks up keys
+ # and this means our "EncodedStrings" don't match the keys in locals.
+ # Therefore copy to a dict.
+ locals = dict(locals)
if symbol in locals:
kwds[symbol] = locals[symbol]
elif symbol in globals:
diff --git a/contrib/tools/cython/Cython/Build/IpythonMagic.py b/contrib/tools/cython/Cython/Build/IpythonMagic.py
index 3fa43c96d1e..315862e3660 100644
--- a/contrib/tools/cython/Cython/Build/IpythonMagic.py
+++ b/contrib/tools/cython/Cython/Build/IpythonMagic.py
@@ -565,7 +565,7 @@ class CythonMagics(Magics):
__doc__ = __doc__.format(
# rST doesn't see the -+ flag as part of an option list, so we
# hide it from the module-level docstring.
- CYTHON_DOC=dedent(CythonMagics.cython.__doc__\
+ CYTHON_DOC=dedent(CythonMagics.cython.__doc__
.replace('-+, --cplus', '--cplus ')),
CYTHON_INLINE_DOC=dedent(CythonMagics.cython_inline.__doc__),
CYTHON_PYXIMPORT_DOC=dedent(CythonMagics.cython_pyximport.__doc__),
diff --git a/contrib/tools/cython/Cython/Compiler/Code.py b/contrib/tools/cython/Cython/Compiler/Code.py
index ac384d99fd3..cd7ca03443d 100644
--- a/contrib/tools/cython/Cython/Compiler/Code.py
+++ b/contrib/tools/cython/Cython/Compiler/Code.py
@@ -66,7 +66,7 @@ uncachable_builtins = [
# Global/builtin names that cannot be cached because they may or may not
# be available at import time, for various reasons:
## Python 3.13+
- 'IncompleteInputError',
+ '_IncompleteInputError',
'PythonFinalizationError',
## Python 3.11+
'BaseExceptionGroup',
@@ -641,18 +641,23 @@ class UtilityCode(UtilityCodeBase):
self.cleanup(writer, output.module_pos)
-def sub_tempita(s, context, file=None, name=None):
+def sub_tempita(s, context, file=None, name=None, __cache={}):
"Run tempita on string s with given context."
if not s:
return None
if file:
- context['__name'] = "%s:%s" % (file, name)
- elif name:
+ name = "%s:%s" % (file, name)
+ if name:
context['__name'] = name
- from ..Tempita import sub
- return sub(s, **context)
+ try:
+ template = __cache[s]
+ except KeyError:
+ from ..Tempita import Template
+ template = __cache[s] = Template(s, name=name)
+
+ return template.substitute(context)
class TempitaUtilityCode(UtilityCode):
@@ -1542,8 +1547,18 @@ class GlobalState(object):
# which aren't necessarily PyObjects, so aren't appropriate
# to clear.
continue
- self.parts['module_state_clear'].putln(
- "Py_CLEAR(clear_module_state->%s);" % cname)
+
+ self.parts['module_state_clear'].put_xdecref_clear(
+ "clear_module_state->%s" % cname,
+ c.type,
+ clear_before_decref=True,
+ nanny=False,
+ )
+
+ if c.type.is_memoryviewslice:
+ # TODO: Implement specific to type like CodeWriter.put_xdecref_clear()
+ cname += "->memview"
+
self.parts['module_state_traverse'].putln(
"Py_VISIT(traverse_module_state->%s);" % cname)
@@ -2084,14 +2099,6 @@ class CCodeWriter(object):
elif fix_indent:
self.level += 1
- def putln_tempita(self, code, **context):
- from ..Tempita import sub
- self.putln(sub(code, **context))
-
- def put_tempita(self, code, **context):
- from ..Tempita import sub
- self.put(sub(code, **context))
-
def increase_indent(self):
self.level += 1
diff --git a/contrib/tools/cython/Cython/Compiler/ExprNodes.py b/contrib/tools/cython/Cython/Compiler/ExprNodes.py
index 7876d09470f..952617e375d 100644
--- a/contrib/tools/cython/Cython/Compiler/ExprNodes.py
+++ b/contrib/tools/cython/Cython/Compiler/ExprNodes.py
@@ -481,7 +481,12 @@ class ExprNode(Node):
constant_result = constant_value_not_set
- child_attrs = property(fget=operator.attrgetter('subexprs'))
+ if getattr(getattr(sys, "implementation", None), "name", "cpython") == "cpython":
+ child_attrs = property(fget=operator.attrgetter('subexprs'))
+ else:
+ @property
+ def child_attrs(self):
+ return self.subexprs
def analyse_annotations(self, env):
pass
@@ -6590,7 +6595,7 @@ class PyMethodCallNode(SimpleCallNode):
self_arg = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
code.putln("%s = NULL;" % self_arg)
- arg_offset_cname = code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False)
+ arg_offset_cname = code.funcstate.allocate_temp(PyrexTypes.c_uint_type, manage_ref=False)
code.putln("%s = 0;" % arg_offset_cname)
def attribute_is_likely_method(attr):
diff --git a/contrib/tools/cython/Cython/Compiler/ModuleNode.py b/contrib/tools/cython/Cython/Compiler/ModuleNode.py
index 493926637ad..469b968f6a8 100644
--- a/contrib/tools/cython/Cython/Compiler/ModuleNode.py
+++ b/contrib/tools/cython/Cython/Compiler/ModuleNode.py
@@ -972,7 +972,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
pass
elif type.is_struct_or_union or type.is_cpp_class:
self.generate_struct_union_predeclaration(entry, code)
- elif type.is_ctuple and entry.used:
+ elif type.is_ctuple and not type.is_fused and entry.used:
self.generate_struct_union_predeclaration(entry.type.struct_entry, code)
elif type.is_extension_type:
self.generate_objstruct_predeclaration(type, code)
@@ -987,7 +987,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self.generate_enum_definition(entry, code)
elif type.is_struct_or_union:
self.generate_struct_union_definition(entry, code)
- elif type.is_ctuple and entry.used:
+ elif type.is_ctuple and not type.is_fused and entry.used:
self.generate_struct_union_definition(entry.type.struct_entry, code)
elif type.is_cpp_class:
self.generate_cpp_class_definition(entry, code)
diff --git a/contrib/tools/cython/Cython/Compiler/Nodes.py b/contrib/tools/cython/Cython/Compiler/Nodes.py
index c2fcd9d6727..e1fe6ee56c9 100644
--- a/contrib/tools/cython/Cython/Compiler/Nodes.py
+++ b/contrib/tools/cython/Cython/Compiler/Nodes.py
@@ -3126,6 +3126,7 @@ class DefNode(FuncDefNode):
if scope is None:
scope = cfunc.scope
cfunc_type = cfunc.type
+ has_explicit_exc_clause=True
if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
error(self.pos, "wrong number of arguments")
error(cfunc.pos, "previous declaration here")
diff --git a/contrib/tools/cython/Cython/Compiler/Optimize.py b/contrib/tools/cython/Cython/Compiler/Optimize.py
index da5f64c29b9..8dd48e951ac 100644
--- a/contrib/tools/cython/Cython/Compiler/Optimize.py
+++ b/contrib/tools/cython/Cython/Compiler/Optimize.py
@@ -2450,6 +2450,9 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
def _handle_simple_function_str(self, node, function, pos_args):
"""Optimize single argument calls to str().
"""
+ if node.type is Builtin.unicode_type:
+ # type already deduced as unicode (language_level=3)
+ return self._handle_simple_function_unicode(node, function, pos_args)
if len(pos_args) != 1:
if len(pos_args) == 0:
return ExprNodes.StringNode(node.pos, value=EncodedString(), constant_result='')
@@ -3516,7 +3519,8 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
if not result:
return node
func_cname, utility_code, extra_args, num_type = result
- args = list(args)+extra_args
+ assert all([arg.type.is_pyobject for arg in args])
+ args = list(args) + extra_args
call_node = self._substitute_method_call(
node, function,
diff --git a/contrib/tools/cython/Cython/Compiler/PyrexTypes.py b/contrib/tools/cython/Cython/Compiler/PyrexTypes.py
index e84fcb5f93a..b522a131751 100644
--- a/contrib/tools/cython/Cython/Compiler/PyrexTypes.py
+++ b/contrib/tools/cython/Cython/Compiler/PyrexTypes.py
@@ -1498,7 +1498,7 @@ class BuiltinObjectType(PyObjectType):
# For backwards compatibility of (Py3) 'x: int' annotations in Py2, we also allow 'long' there.
type_check = '__Pyx_Py3Int_Check'
elif type_name == "memoryview":
- # captialize doesn't catch the 'V'
+ # capitalize doesn't catch the 'V'
type_check = "PyMemoryView_Check"
else:
type_check = 'Py%s_Check' % type_name.capitalize()
@@ -4582,6 +4582,8 @@ class CTupleType(CType):
is_ctuple = True
+ subtypes = ['components']
+
def __init__(self, cname, components):
self.cname = cname
self.components = components
@@ -4666,10 +4668,19 @@ class CTupleType(CType):
def cast_code(self, expr_code):
return expr_code
+ def specialize(self, values):
+ assert hasattr(self, "entry")
+ components = [c.specialize(values) for c in self.components]
+ new_entry = self.entry.scope.declare_tuple_type(self.entry.pos, components)
+ return new_entry.type
+
def c_tuple_type(components):
components = tuple(components)
- cname = Naming.ctuple_type_prefix + type_list_identifier(components)
+ if any(c.is_fused for c in components):
+ cname = "<dummy fused ctuple>" # should never end up in code
+ else:
+ cname = Naming.ctuple_type_prefix + type_list_identifier(components)
tuple_type = CTupleType(cname, components)
return tuple_type
@@ -5051,7 +5062,7 @@ def best_match(arg_types, functions, pos=None, env=None, args=None):
if len(candidates) == 1:
return candidates[0][0]
elif len(candidates) == 0:
- if pos is not None:
+ if pos is not None and errors:
func, errmsg = errors[0]
if len(errors) == 1 or [1 for func, e in errors if e == errmsg]:
error(pos, errmsg)
diff --git a/contrib/tools/cython/Cython/Compiler/TypeInference.py b/contrib/tools/cython/Cython/Compiler/TypeInference.py
index 70d64fcf525..bb68db8976a 100644
--- a/contrib/tools/cython/Cython/Compiler/TypeInference.py
+++ b/contrib/tools/cython/Cython/Compiler/TypeInference.py
@@ -233,10 +233,7 @@ class MarkParallelAssignments(EnvTransform):
self.parallel_errors = True
if node.is_prange:
- child_attrs = node.child_attrs
- node.child_attrs = ['body', 'target', 'args']
- self.visitchildren(node)
- node.child_attrs = child_attrs
+ self.visitchildren(node, attrs=('body', 'target', 'args'))
self.parallel_block_stack.pop()
if node.else_clause:
diff --git a/contrib/tools/cython/Cython/Compiler/TypeSlots.py b/contrib/tools/cython/Cython/Compiler/TypeSlots.py
index 2c891f64810..ad27e0d6eaa 100644
--- a/contrib/tools/cython/Cython/Compiler/TypeSlots.py
+++ b/contrib/tools/cython/Cython/Compiler/TypeSlots.py
@@ -1102,6 +1102,7 @@ class SlotTable(object):
EmptySlot("tp_vectorcall", ifdef="PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800)"),
EmptySlot("tp_print", ifdef="__PYX_NEED_TP_PRINT_SLOT == 1"),
EmptySlot("tp_watched", ifdef="PY_VERSION_HEX >= 0x030C0000"),
+ EmptySlot("tp_versions_used", ifdef="PY_VERSION_HEX >= 0x030d00A4"),
# PyPy specific extension - only here to avoid C compiler warnings.
EmptySlot("tp_pypy_flags", ifdef="CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000"),
)
diff --git a/contrib/tools/cython/Cython/Debugger/libpython.py b/contrib/tools/cython/Cython/Debugger/libpython.py
index 6e548800e25..0a680f9cf8e 100644
--- a/contrib/tools/cython/Cython/Debugger/libpython.py
+++ b/contrib/tools/cython/Cython/Debugger/libpython.py
@@ -1312,7 +1312,7 @@ class PyUnicodeObjectPtr(PyObjectPtr):
ucs = ch + ch2
i += 1
- # Unfortuately, Python 2's unicode type doesn't seem
+ # Unfortunately, Python 2's unicode type doesn't seem
# to expose the "isprintable" method
printable = _unichr_is_printable(ucs)
if printable:
diff --git a/contrib/tools/cython/Cython/Includes/cpython/time.pxd b/contrib/tools/cython/Cython/Includes/cpython/time.pxd
index 3f333a72a9d..f1a9f2967cd 100644
--- a/contrib/tools/cython/Cython/Includes/cpython/time.pxd
+++ b/contrib/tools/cython/Cython/Includes/cpython/time.pxd
@@ -5,10 +5,38 @@ Cython implementation of (parts of) the standard library time module.
from libc.stdint cimport int64_t
from cpython.exc cimport PyErr_SetFromErrno
-cdef extern from "Python.h":
- ctypedef int64_t _PyTime_t
- _PyTime_t _PyTime_GetSystemClock() nogil
- double _PyTime_AsSecondsDouble(_PyTime_t t) nogil
+cdef extern from *:
+ """
+ #if PY_VERSION_HEX >= 0x030d00b1 || defined(PyTime_t)
+ #define __Pyx_PyTime_t PyTime_t
+ #else
+ #define __Pyx_PyTime_t _PyTime_t
+ #endif
+
+ #if PY_VERSION_HEX >= 0x030d00b1 || defined(PyTime_TimeRaw)
+ static CYTHON_INLINE __Pyx_PyTime_t __Pyx_PyTime_TimeUnchecked(void) {
+ __Pyx_PyTime_t tic;
+ (void) PyTime_TimeRaw(&tic);
+ return tic;
+ }
+ #else
+ #define __Pyx_PyTime_TimeUnchecked() _PyTime_GetSystemClock()
+ #endif
+
+ #if PY_VERSION_HEX >= 0x030d00b1 || defined(PyTime_AsSecondsDouble)
+ #define __Pyx_PyTime_AsSecondsDouble(t) PyTime_AsSecondsDouble(t)
+ #else
+ #define __Pyx_PyTime_AsSecondsDouble(t) _PyTime_AsSecondsDouble(t)
+ #endif
+ """
+ ctypedef int64_t PyTime_t "__Pyx_PyTime_t"
+ ctypedef int64_t _PyTime_t "__Pyx_PyTime_t"
+
+ _PyTime_t _PyTime_GetSystemClock "__Pyx_PyTime_TimeUnchecked" () nogil
+ _PyTime_t PyTime_TimeUnchecked "__Pyx_PyTime_TimeUnchecked" () nogil
+
+ double _PyTime_AsSecondsDouble "__Pyx_PyTime_AsSecondsDouble" (_PyTime_t t) nogil
+ double PyTime_AsSecondsDouble "__Pyx_PyTime_AsSecondsDouble" (_PyTime_t t) nogil
from libc.time cimport (
tm,
@@ -21,8 +49,8 @@ cdef inline double time() noexcept nogil:
cdef:
_PyTime_t tic
- tic = _PyTime_GetSystemClock()
- return _PyTime_AsSecondsDouble(tic)
+ tic = PyTime_TimeUnchecked()
+ return PyTime_AsSecondsDouble(tic)
cdef inline int _raise_from_errno() except -1 with gil:
@@ -46,6 +74,6 @@ cdef inline tm localtime() except * nogil:
# See tmtotuple() in https://github.com/python/cpython/blob/master/Modules/timemodule.c
result.tm_year += 1900
result.tm_mon += 1
- result.tm_wday = (result.tm_wday + 6) % 7
+ result.tm_wday = <int> ((result.tm_wday + 6) % 7)
result.tm_yday += 1
return result[0]
diff --git a/contrib/tools/cython/Cython/Includes/libcpp/deque.pxd b/contrib/tools/cython/Cython/Includes/libcpp/deque.pxd
index 5f189ffd1c1..e625318bd00 100644
--- a/contrib/tools/cython/Cython/Includes/libcpp/deque.pxd
+++ b/contrib/tools/cython/Cython/Includes/libcpp/deque.pxd
@@ -161,3 +161,5 @@ cdef extern from "<deque>" namespace "std" nogil:
# C++11 methods
void shrink_to_fit() except +
+ T& emplace_front(...) except +
+ T& emplace_back(...) except +
diff --git a/contrib/tools/cython/Cython/Includes/libcpp/optional.pxd b/contrib/tools/cython/Cython/Includes/libcpp/optional.pxd
index 284dfcd6e50..9b0b07a6d2b 100644
--- a/contrib/tools/cython/Cython/Includes/libcpp/optional.pxd
+++ b/contrib/tools/cython/Cython/Includes/libcpp/optional.pxd
@@ -13,7 +13,7 @@ cdef extern from "<optional>" namespace "std" nogil:
optional(optional&) except +
optional(T&) except +
bool has_value()
- T& value()
+ T& value() except +
T& value_or[U](U& default_value)
void swap(optional&)
void reset()
diff --git a/contrib/tools/cython/Cython/Shadow.py b/contrib/tools/cython/Cython/Shadow.py
index d75cd3379b3..1400f1657c8 100644
--- a/contrib/tools/cython/Cython/Shadow.py
+++ b/contrib/tools/cython/Cython/Shadow.py
@@ -2,7 +2,7 @@
from __future__ import absolute_import
# Possible version formats: "3.1.0", "3.1.0a1", "3.1.0a1.dev0"
-__version__ = "3.0.10"
+__version__ = "3.0.11"
try:
from __builtin__ import basestring
diff --git a/contrib/tools/cython/Cython/Utility/AsyncGen.c b/contrib/tools/cython/Cython/Utility/AsyncGen.c
index 9bffedcfa9c..94b68f19f3d 100644
--- a/contrib/tools/cython/Cython/Utility/AsyncGen.c
+++ b/contrib/tools/cython/Cython/Utility/AsyncGen.c
@@ -478,6 +478,9 @@ static PyTypeObject __pyx_AsyncGenType_type = {
#if PY_VERSION_HEX >= 0x030C0000
0, /*tp_watched*/
#endif
+#if PY_VERSION_HEX >= 0x030d00A4
+ 0, /*tp_versions_used*/
+#endif
#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000
0, /*tp_pypy_flags*/
#endif
@@ -753,6 +756,9 @@ static PyTypeObject __pyx__PyAsyncGenASendType_type = {
#if PY_VERSION_HEX >= 0x030C0000
0, /*tp_watched*/
#endif
+#if PY_VERSION_HEX >= 0x030d00A4
+ 0, /*tp_versions_used*/
+#endif
#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000
0, /*tp_pypy_flags*/
#endif
@@ -891,6 +897,9 @@ static PyTypeObject __pyx__PyAsyncGenWrappedValueType_type = {
#if PY_VERSION_HEX >= 0x030C0000
0, /*tp_watched*/
#endif
+#if PY_VERSION_HEX >= 0x030d00A4
+ 0, /*tp_versions_used*/
+#endif
#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000
0, /*tp_pypy_flags*/
#endif
@@ -1235,6 +1244,9 @@ static PyTypeObject __pyx__PyAsyncGenAThrowType_type = {
#if PY_VERSION_HEX >= 0x030C0000
0, /*tp_watched*/
#endif
+#if PY_VERSION_HEX >= 0x030d00A4
+ 0, /*tp_versions_used*/
+#endif
#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000
0, /*tp_pypy_flags*/
#endif
diff --git a/contrib/tools/cython/Cython/Utility/Builtins.c b/contrib/tools/cython/Cython/Utility/Builtins.c
index 87609b5f13a..063d5e4bfd9 100644
--- a/contrib/tools/cython/Cython/Utility/Builtins.c
+++ b/contrib/tools/cython/Cython/Utility/Builtins.c
@@ -170,16 +170,11 @@ static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject
//////////////////// HasAttr.proto ////////////////////
-#if __PYX_LIMITED_VERSION_HEX >= 0x030d00A1
-#define __Pyx_HasAttr(o, n) PyObject_HasAttrWithError(o, n)
-#else
static CYTHON_INLINE int __Pyx_HasAttr(PyObject *, PyObject *); /*proto*/
-#endif
//////////////////// HasAttr ////////////////////
//@requires: ObjectHandling.c::GetAttr
-#if __PYX_LIMITED_VERSION_HEX < 0x030d00A1
static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) {
PyObject *r;
if (unlikely(!__Pyx_PyBaseString_Check(n))) {
@@ -196,7 +191,6 @@ static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) {
return 1;
}
}
-#endif
//////////////////// Intern.proto ////////////////////
diff --git a/contrib/tools/cython/Cython/Utility/Coroutine.c b/contrib/tools/cython/Cython/Utility/Coroutine.c
index 688a62d8efb..c7ec8ee9ba0 100644
--- a/contrib/tools/cython/Cython/Utility/Coroutine.c
+++ b/contrib/tools/cython/Cython/Utility/Coroutine.c
@@ -1683,6 +1683,9 @@ static PyTypeObject __pyx_CoroutineAwaitType_type = {
#if PY_VERSION_HEX >= 0x030C0000
0, /*tp_watched*/
#endif
+#if PY_VERSION_HEX >= 0x030d00A4
+ 0, /*tp_versions_used*/
+#endif
#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000
0, /*tp_pypy_flags*/
#endif
@@ -1878,6 +1881,9 @@ static PyTypeObject __pyx_CoroutineType_type = {
#if PY_VERSION_HEX >= 0x030C0000
0, /*tp_watched*/
#endif
+#if PY_VERSION_HEX >= 0x030d00A4
+ 0, /*tp_versions_used*/
+#endif
#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000
0, /*tp_pypy_flags*/
#endif
@@ -2029,6 +2035,9 @@ static PyTypeObject __pyx_IterableCoroutineType_type = {
#if PY_VERSION_HEX >= 0x030C0000
0, /*tp_watched*/
#endif
+#if PY_VERSION_HEX >= 0x030d00A4
+ 0, /*tp_versions_used*/
+#endif
#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000
0, /*tp_pypy_flags*/
#endif
@@ -2178,6 +2187,9 @@ static PyTypeObject __pyx_GeneratorType_type = {
#if PY_VERSION_HEX >= 0x030C0000
0, /*tp_watched*/
#endif
+#if PY_VERSION_HEX >= 0x030d00A4
+ 0, /*tp_versions_used*/
+#endif
#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000
0, /*tp_pypy_flags*/
#endif
diff --git a/contrib/tools/cython/Cython/Utility/CythonFunction.c b/contrib/tools/cython/Cython/Utility/CythonFunction.c
index 2ca461f6654..023701c63ae 100644
--- a/contrib/tools/cython/Cython/Utility/CythonFunction.c
+++ b/contrib/tools/cython/Cython/Utility/CythonFunction.c
@@ -1198,6 +1198,9 @@ static PyTypeObject __pyx_CyFunctionType_type = {
#if PY_VERSION_HEX >= 0x030C0000
0, /*tp_watched*/
#endif
+#if PY_VERSION_HEX >= 0x030d00A4
+ 0, /*tp_versions_used*/
+#endif
#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000
0, /*tp_pypy_flags*/
#endif
@@ -1725,6 +1728,9 @@ static PyTypeObject __pyx_FusedFunctionType_type = {
#if PY_VERSION_HEX >= 0x030C0000
0, /*tp_watched*/
#endif
+#if PY_VERSION_HEX >= 0x030d00A4
+ 0, /*tp_versions_used*/
+#endif
#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000
0, /*tp_pypy_flags*/
#endif
diff --git a/contrib/tools/cython/Cython/Utility/Exceptions.c b/contrib/tools/cython/Cython/Utility/Exceptions.c
index daf6578eb96..46f7dd57812 100644
--- a/contrib/tools/cython/Cython/Utility/Exceptions.c
+++ b/contrib/tools/cython/Cython/Utility/Exceptions.c
@@ -819,7 +819,7 @@ static void __Pyx_WriteUnraisable(const char *name, int clineno,
Py_XINCREF(old_val);
Py_XINCREF(old_tb);
__Pyx_ErrRestore(old_exc, old_val, old_tb);
- PyErr_PrintEx(1);
+ PyErr_PrintEx(0);
}
#if PY_MAJOR_VERSION < 3
ctx = PyString_FromString(name);
diff --git a/contrib/tools/cython/Cython/Utility/MemoryView.pyx b/contrib/tools/cython/Cython/Utility/MemoryView.pyx
index 57ffaf92b48..b84c05d3360 100644
--- a/contrib/tools/cython/Cython/Utility/MemoryView.pyx
+++ b/contrib/tools/cython/Cython/Utility/MemoryView.pyx
@@ -420,7 +420,7 @@ cdef class memoryview:
if have_slices:
obj = self.is_slice(value)
- if obj:
+ if obj is not None:
self.setitem_slice_assignment(self[index], obj)
else:
self.setitem_slice_assign_scalar(self[index], value)
diff --git a/contrib/tools/cython/Cython/Utility/StringTools.c b/contrib/tools/cython/Cython/Utility/StringTools.c
index 2ec61d0a616..c49a56950e1 100644
--- a/contrib/tools/cython/Cython/Utility/StringTools.c
+++ b/contrib/tools/cython/Cython/Utility/StringTools.c
@@ -759,7 +759,7 @@ static int __Pyx_PyBytes_SingleTailmatch(PyObject* self, PyObject* arg,
}
#endif
else {
- if (unlikely(PyObject_GetBuffer(self, &view, PyBUF_SIMPLE) == -1))
+ if (unlikely(PyObject_GetBuffer(arg, &view, PyBUF_SIMPLE) == -1))
return -1;
sub_ptr = (const char*) view.buf;
sub_len = view.len;
diff --git a/contrib/tools/cython/Cython/Utility/TypeConversion.c b/contrib/tools/cython/Cython/Utility/TypeConversion.c
index 2e881eb3b7c..e918d354633 100644
--- a/contrib/tools/cython/Cython/Utility/TypeConversion.c
+++ b/contrib/tools/cython/Cython/Utility/TypeConversion.c
@@ -826,13 +826,20 @@ static CYTHON_INLINE PyObject* {{TO_PY_FUNCTION}}({{TYPE}} value) {
}
}
{
- int one = 1; int little = (int)*(unsigned char *)&one;
unsigned char *bytes = (unsigned char *)&value;
-#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000
+#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d00A4
+ if (is_unsigned) {
+ return PyLong_FromUnsignedNativeBytes(bytes, sizeof(value), -1);
+ } else {
+ return PyLong_FromNativeBytes(bytes, sizeof(value), -1);
+ }
+#elif !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000
+ int one = 1; int little = (int)*(unsigned char *)&one;
return _PyLong_FromByteArray(bytes, sizeof({{TYPE}}),
little, !is_unsigned);
#else
// call int.from_bytes()
+ int one = 1; int little = (int)*(unsigned char *)&one;
PyObject *from_bytes, *result = NULL;
PyObject *py_bytes = NULL, *arg_tuple = NULL, *kwds = NULL, *order_str = NULL;
from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes");
@@ -1075,220 +1082,219 @@ static CYTHON_INLINE {{TYPE}} {{FROM_PY_FUNCTION}}(PyObject *x) {
}
return ({{TYPE}}) val;
}
- } else
+ }
#endif
- if (likely(PyLong_Check(x))) {
- if (is_unsigned) {
+
+ if (unlikely(!PyLong_Check(x))) {
+ {{TYPE}} val;
+ PyObject *tmp = __Pyx_PyNumber_IntOrLong(x);
+ if (!tmp) return ({{TYPE}}) -1;
+ val = {{FROM_PY_FUNCTION}}(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+
+ if (is_unsigned) {
#if CYTHON_USE_PYLONG_INTERNALS
- if (unlikely(__Pyx_PyLong_IsNeg(x))) {
- goto raise_neg_overflow;
- //} else if (__Pyx_PyLong_IsZero(x)) {
- // return ({{TYPE}}) 0;
- } else if (__Pyx_PyLong_IsCompact(x)) {
- __PYX_VERIFY_RETURN_INT({{TYPE}}, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x))
- } else {
- const digit* digits = __Pyx_PyLong_Digits(x);
- assert(__Pyx_PyLong_DigitCount(x) > 1);
- switch (__Pyx_PyLong_DigitCount(x)) {
- {{for _size in (2, 3, 4)}}
- case {{_size}}:
- if ((8 * sizeof({{TYPE}}) > {{_size-1}} * PyLong_SHIFT)) {
- if ((8 * sizeof(unsigned long) > {{_size}} * PyLong_SHIFT)) {
- __PYX_VERIFY_RETURN_INT({{TYPE}}, unsigned long, {{pylong_join(_size, 'digits')}})
- } else if ((8 * sizeof({{TYPE}}) >= {{_size}} * PyLong_SHIFT)) {
- return ({{TYPE}}) {{pylong_join(_size, 'digits', TYPE)}};
- }
+ if (unlikely(__Pyx_PyLong_IsNeg(x))) {
+ goto raise_neg_overflow;
+ //} else if (__Pyx_PyLong_IsZero(x)) {
+ // return ({{TYPE}}) 0;
+ } else if (__Pyx_PyLong_IsCompact(x)) {
+ __PYX_VERIFY_RETURN_INT({{TYPE}}, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x))
+ } else {
+ const digit* digits = __Pyx_PyLong_Digits(x);
+ assert(__Pyx_PyLong_DigitCount(x) > 1);
+ switch (__Pyx_PyLong_DigitCount(x)) {
+ {{for _size in (2, 3, 4)}}
+ case {{_size}}:
+ if ((8 * sizeof({{TYPE}}) > {{_size-1}} * PyLong_SHIFT)) {
+ if ((8 * sizeof(unsigned long) > {{_size}} * PyLong_SHIFT)) {
+ __PYX_VERIFY_RETURN_INT({{TYPE}}, unsigned long, {{pylong_join(_size, 'digits')}})
+ } else if ((8 * sizeof({{TYPE}}) >= {{_size}} * PyLong_SHIFT)) {
+ return ({{TYPE}}) {{pylong_join(_size, 'digits', TYPE)}};
}
- break;
- {{endfor}}
- }
+ }
+ break;
+ {{endfor}}
}
+ }
#endif
#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7
- if (unlikely(Py_SIZE(x) < 0)) {
- goto raise_neg_overflow;
- }
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
#else
- {
- // misuse Py_False as a quick way to compare to a '0' int object in PyPy
- int result = PyObject_RichCompareBool(x, Py_False, Py_LT);
- if (unlikely(result < 0))
- return ({{TYPE}}) -1;
- if (unlikely(result == 1))
- goto raise_neg_overflow;
- }
+ {
+ // misuse Py_False as a quick way to compare to a '0' int object in PyPy
+ int result = PyObject_RichCompareBool(x, Py_False, Py_LT);
+ if (unlikely(result < 0))
+ return ({{TYPE}}) -1;
+ if (unlikely(result == 1))
+ goto raise_neg_overflow;
+ }
#endif
- if ((sizeof({{TYPE}}) <= sizeof(unsigned long))) {
- __PYX_VERIFY_RETURN_INT_EXC({{TYPE}}, unsigned long, PyLong_AsUnsignedLong(x))
+ if ((sizeof({{TYPE}}) <= sizeof(unsigned long))) {
+ __PYX_VERIFY_RETURN_INT_EXC({{TYPE}}, unsigned long, PyLong_AsUnsignedLong(x))
#ifdef HAVE_LONG_LONG
- } else if ((sizeof({{TYPE}}) <= sizeof(unsigned PY_LONG_LONG))) {
- __PYX_VERIFY_RETURN_INT_EXC({{TYPE}}, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x))
+ } else if ((sizeof({{TYPE}}) <= sizeof(unsigned PY_LONG_LONG))) {
+ __PYX_VERIFY_RETURN_INT_EXC({{TYPE}}, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x))
#endif
- }
- } else {
- // signed
+ }
+
+ } else {
+ // signed
#if CYTHON_USE_PYLONG_INTERNALS
- if (__Pyx_PyLong_IsCompact(x)) {
- __PYX_VERIFY_RETURN_INT({{TYPE}}, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x))
- } else {
- const digit* digits = __Pyx_PyLong_Digits(x);
- assert(__Pyx_PyLong_DigitCount(x) > 1);
- switch (__Pyx_PyLong_SignedDigitCount(x)) {
- {{for _size in (2, 3, 4)}}
- {{for _case in (-_size, _size)}}
- case {{_case}}:
- if ((8 * sizeof({{TYPE}}){{' - 1' if _case < 0 else ''}} > {{_size-1}} * PyLong_SHIFT)) {
- if ((8 * sizeof(unsigned long) > {{_size}} * PyLong_SHIFT)) {
- __PYX_VERIFY_RETURN_INT({{TYPE}}, {{'long' if _case < 0 else 'unsigned long'}}, {{'-(long) ' if _case < 0 else ''}}{{pylong_join(_size, 'digits')}})
- } else if ((8 * sizeof({{TYPE}}) - 1 > {{_size}} * PyLong_SHIFT)) {
- return ({{TYPE}}) ({{'((%s)-1)*' % TYPE if _case < 0 else ''}}{{pylong_join(_size, 'digits', TYPE)}});
- }
+ if (__Pyx_PyLong_IsCompact(x)) {
+ __PYX_VERIFY_RETURN_INT({{TYPE}}, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x))
+ } else {
+ const digit* digits = __Pyx_PyLong_Digits(x);
+ assert(__Pyx_PyLong_DigitCount(x) > 1);
+ switch (__Pyx_PyLong_SignedDigitCount(x)) {
+ {{for _size in (2, 3, 4)}}
+ {{for _case in (-_size, _size)}}
+ case {{_case}}:
+ if ((8 * sizeof({{TYPE}}){{' - 1' if _case < 0 else ''}} > {{_size-1}} * PyLong_SHIFT)) {
+ if ((8 * sizeof(unsigned long) > {{_size}} * PyLong_SHIFT)) {
+ __PYX_VERIFY_RETURN_INT({{TYPE}}, {{'long' if _case < 0 else 'unsigned long'}}, {{'-(long) ' if _case < 0 else ''}}{{pylong_join(_size, 'digits')}})
+ } else if ((8 * sizeof({{TYPE}}) - 1 > {{_size}} * PyLong_SHIFT)) {
+ return ({{TYPE}}) ({{'((%s)-1)*' % TYPE if _case < 0 else ''}}{{pylong_join(_size, 'digits', TYPE)}});
}
- break;
- {{endfor}}
- {{endfor}}
- }
+ }
+ break;
+ {{endfor}}
+ {{endfor}}
}
+ }
#endif
- if ((sizeof({{TYPE}}) <= sizeof(long))) {
- __PYX_VERIFY_RETURN_INT_EXC({{TYPE}}, long, PyLong_AsLong(x))
+ if ((sizeof({{TYPE}}) <= sizeof(long))) {
+ __PYX_VERIFY_RETURN_INT_EXC({{TYPE}}, long, PyLong_AsLong(x))
#ifdef HAVE_LONG_LONG
- } else if ((sizeof({{TYPE}}) <= sizeof(PY_LONG_LONG))) {
- __PYX_VERIFY_RETURN_INT_EXC({{TYPE}}, PY_LONG_LONG, PyLong_AsLongLong(x))
+ } else if ((sizeof({{TYPE}}) <= sizeof(PY_LONG_LONG))) {
+ __PYX_VERIFY_RETURN_INT_EXC({{TYPE}}, PY_LONG_LONG, PyLong_AsLongLong(x))
#endif
- }
}
+ }
- {{if IS_ENUM}}
- PyErr_SetString(PyExc_RuntimeError,
- "_PyLong_AsByteArray() not available, cannot convert large enums");
- return ({{TYPE}}) -1;
- {{else}}
- // large integer type and no access to PyLong internals => allow for a more expensive conversion
- {
- {{TYPE}} val;
- PyObject *v = __Pyx_PyNumber_IntOrLong(x);
-#if PY_MAJOR_VERSION < 3
- if (likely(v) && !PyLong_Check(v)) {
- PyObject *tmp = v;
- v = PyNumber_Long(tmp);
- Py_DECREF(tmp);
- }
-#endif
- if (likely(v)) {
- int ret = -1;
-#if PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray)
- int one = 1; int is_little = (int)*(unsigned char *)&one;
- unsigned char *bytes = (unsigned char *)&val;
- ret = _PyLong_AsByteArray((PyLongObject *)v,
- bytes, sizeof(val),
- is_little, !is_unsigned);
+ // large integer type and no access to PyLong internals => allow for a more expensive conversion
+ {
+ {{TYPE}} val;
+ int ret = -1;
+#if PY_VERSION_HEX >= 0x030d00A6 && !CYTHON_COMPILING_IN_LIMITED_API
+ Py_ssize_t bytes_copied = PyLong_AsNativeBytes(
+ x, &val, sizeof(val), Py_ASNATIVEBYTES_NATIVE_ENDIAN | (is_unsigned ? Py_ASNATIVEBYTES_UNSIGNED_BUFFER | Py_ASNATIVEBYTES_REJECT_NEGATIVE : 0));
+ if (unlikely(bytes_copied == -1)) {
+ // failed
+ } else if (unlikely(bytes_copied > (Py_ssize_t) sizeof(val))) {
+ goto raise_overflow;
+ } else {
+ ret = 0;
+ }
+#elif PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray)
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ ret = _PyLong_AsByteArray((PyLongObject *)x,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
#else
+{{if IS_ENUM}}
+ // The fallback implementation uses math operations like shifting, which do not work well with enums.
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() or PyLong_AsNativeBytes() not available, cannot convert large enums");
+ val = ({{TYPE}}) -1;
+{{else}}
// Inefficient copy of bit chunks through the C-API. Probably still better than a "cannot do this" exception.
-// This is substantially faster in CPython (>30%) than calling "int.to_bytes()"
- PyObject *stepval = NULL, *mask = NULL, *shift = NULL;
- int bits, remaining_bits, is_negative = 0;
- long idigit;
- int chunk_size = (sizeof(long) < 8) ? 30 : 62;
-
- // use exact PyLong to prevent user defined &&/<</etc. implementations
- if (unlikely(!PyLong_CheckExact(v))) {
- PyObject *tmp = v;
- v = PyNumber_Long(v);
- assert(PyLong_CheckExact(v));
- Py_DECREF(tmp);
- if (unlikely(!v)) return ({{TYPE}}) -1;
- }
-
-#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000
- if (Py_SIZE(x) == 0)
- return ({{TYPE}}) 0;
- is_negative = Py_SIZE(x) < 0;
-#else
- {
- // misuse Py_False as a quick way to compare to a '0' int object
- int result = PyObject_RichCompareBool(x, Py_False, Py_LT);
- if (unlikely(result < 0))
- return ({{TYPE}}) -1;
- is_negative = result == 1;
- }
-#endif
+// This is substantially faster in CPython (>30%) than calling "int.to_bytes()" through the C-API.
+ PyObject *v;
+ PyObject *stepval = NULL, *mask = NULL, *shift = NULL;
+ int bits, remaining_bits, is_negative = 0;
+ int chunk_size = (sizeof(long) < 8) ? 30 : 62;
+
+ // Use exact PyLong to prevent user defined &&/<</etc. implementations (and make Py_SIZE() work below).
+ if (likely(PyLong_CheckExact(x))) {
+ v = __Pyx_NewRef(x);
+ } else {
+ v = PyNumber_Long(x);
+ if (unlikely(!v)) return ({{TYPE}}) -1;
+ assert(PyLong_CheckExact(v));
+ }
- if (is_unsigned && unlikely(is_negative)) {
- goto raise_neg_overflow;
- } else if (is_negative) {
- // bit-invert to make sure we can safely convert it
- stepval = PyNumber_Invert(v);
- if (unlikely(!stepval))
- return ({{TYPE}}) -1;
- } else {
- stepval = __Pyx_NewRef(v);
- }
-
- // unpack full chunks of bits
- val = ({{TYPE}}) 0;
- mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done;
- shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done;
- for (bits = 0; bits < (int) sizeof({{TYPE}}) * 8 - chunk_size; bits += chunk_size) {
- PyObject *tmp, *digit;
-
- digit = PyNumber_And(stepval, mask);
- if (unlikely(!digit)) goto done;
- idigit = PyLong_AsLong(digit);
- Py_DECREF(digit);
- if (unlikely(idigit < 0)) goto done;
-
- tmp = PyNumber_Rshift(stepval, shift);
- if (unlikely(!tmp)) goto done;
- Py_DECREF(stepval); stepval = tmp;
-
- val |= (({{TYPE}}) idigit) << bits;
-
- #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000
- if (Py_SIZE(stepval) == 0)
- goto unpacking_done;
- #endif
- }
-
- // detect overflow when adding the last bits
- idigit = PyLong_AsLong(stepval);
- if (unlikely(idigit < 0)) goto done;
- remaining_bits = ((int) sizeof({{TYPE}}) * 8) - bits - (is_unsigned ? 0 : 1);
- if (unlikely(idigit >= (1L << remaining_bits)))
- goto raise_overflow;
- val |= (({{TYPE}}) idigit) << bits;
-
- #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000
- unpacking_done:
- #endif
- // handle sign and overflow into sign bit
- if (!is_unsigned) {
- // gcc warns about unsigned (val < 0) => test sign bit instead
- if (unlikely(val & ((({{TYPE}}) 1) << (sizeof({{TYPE}}) * 8 - 1))))
- goto raise_overflow;
- // undo the PyNumber_Invert() above
- if (is_negative)
- val = ~val;
- }
- ret = 0;
- done:
- Py_XDECREF(shift);
- Py_XDECREF(mask);
- Py_XDECREF(stepval);
-#endif
+ // Misuse Py_False as a quick way to compare to a '0' int object.
+ {
+ int result = PyObject_RichCompareBool(v, Py_False, Py_LT);
+ if (unlikely(result < 0)) {
Py_DECREF(v);
- if (likely(!ret))
- return val;
+ return ({{TYPE}}) -1;
}
- return ({{TYPE}}) -1;
+ is_negative = result == 1;
}
- {{endif}}
- } else {
- {{TYPE}} val;
- PyObject *tmp = __Pyx_PyNumber_IntOrLong(x);
- if (!tmp) return ({{TYPE}}) -1;
- val = {{FROM_PY_FUNCTION}}(tmp);
- Py_DECREF(tmp);
+
+ if (is_unsigned && unlikely(is_negative)) {
+ Py_DECREF(v);
+ goto raise_neg_overflow;
+ } else if (is_negative) {
+ // bit-invert to make sure we can safely convert it
+ stepval = PyNumber_Invert(v);
+ Py_DECREF(v);
+ if (unlikely(!stepval))
+ return ({{TYPE}}) -1;
+ } else {
+ stepval = v;
+ }
+ v = NULL;
+
+ // Unpack full chunks of bits.
+ val = ({{TYPE}}) 0;
+ mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done;
+ shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done;
+ for (bits = 0; bits < (int) sizeof({{TYPE}}) * 8 - chunk_size; bits += chunk_size) {
+ PyObject *tmp, *digit;
+ long idigit;
+
+ digit = PyNumber_And(stepval, mask);
+ if (unlikely(!digit)) goto done;
+
+ idigit = PyLong_AsLong(digit);
+ Py_DECREF(digit);
+ if (unlikely(idigit < 0)) goto done;
+ val |= (({{TYPE}}) idigit) << bits;
+
+ tmp = PyNumber_Rshift(stepval, shift);
+ if (unlikely(!tmp)) goto done;
+ Py_DECREF(stepval); stepval = tmp;
+ }
+
+ Py_DECREF(shift); shift = NULL;
+ Py_DECREF(mask); mask = NULL;
+
+ // Add the last bits and detect overflow.
+ {
+ long idigit = PyLong_AsLong(stepval);
+ if (unlikely(idigit < 0)) goto done;
+ remaining_bits = ((int) sizeof({{TYPE}}) * 8) - bits - (is_unsigned ? 0 : 1);
+ if (unlikely(idigit >= (1L << remaining_bits)))
+ goto raise_overflow;
+ val |= (({{TYPE}}) idigit) << bits;
+ }
+
+ // Handle sign and overflow into sign bit.
+ if (!is_unsigned) {
+ // gcc warns about unsigned (val < 0) => test sign bit instead
+ if (unlikely(val & ((({{TYPE}}) 1) << (sizeof({{TYPE}}) * 8 - 1))))
+ goto raise_overflow;
+ // undo the PyNumber_Invert() above
+ if (is_negative)
+ val = ~val;
+ }
+ ret = 0;
+ done:
+ Py_XDECREF(shift);
+ Py_XDECREF(mask);
+ Py_XDECREF(stepval);
+{{endif}}
+#endif
+ if (unlikely(ret))
+ return ({{TYPE}}) -1;
return val;
}
diff --git a/contrib/tools/cython/cython.py b/contrib/tools/cython/cython.py
index 3923742256e..d8ab80706b9 100755
--- a/contrib/tools/cython/cython.py
+++ b/contrib/tools/cython/cython.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-# Change content of this file to change uids for cython programs - cython 3.0.10 r0
+# Change content of this file to change uids for cython programs - cython 3.0.11 r0
#
# Cython -- Main Program, generic
diff --git a/contrib/tools/cython/patches/pr6343.patch b/contrib/tools/cython/patches/pr6343.patch
new file mode 100644
index 00000000000..faffef9e0b8
--- /dev/null
+++ b/contrib/tools/cython/patches/pr6343.patch
@@ -0,0 +1,36 @@
+From 2e774fca5ad55371b21ba2b531d218888319c151 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= <tornaria@cmat.edu.uy>
+Date: Sun, 18 Aug 2024 17:43:05 -0300
+Subject: [PATCH 1/2] Better fix for #6122 to avoid #6535
+
+The change in #6124 introduces a regression with functions that are
+implicit noexcept in a pxd file.
+---
+ Cython/Compiler/Nodes.py | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py
+index d4737f7c373..b70d766ed4e 100644
+--- a/Cython/Compiler/Nodes.py
++++ b/Cython/Compiler/Nodes.py
+@@ -710,10 +710,8 @@ def analyse(self, return_type, env, nonempty=0, directive_locals=None, visibilit
+ and not self.has_explicit_exc_clause
+ and self.exception_check
+ and visibility != 'extern'):
+- # If function is already declared from pxd, the exception_check has already correct value.
+- if not (self.declared_name() in env.entries and not in_pxd):
+- self.exception_check = False
+ # implicit noexcept, with a warning
++ self.exception_check = False
+ warning(self.pos,
+ "Implicit noexcept declaration is deprecated."
+ " Function declaration should contain 'noexcept' keyword.",
+@@ -3128,6 +3126,7 @@ def as_cfunction(self, cfunc=None, scope=None, overridable=True, returns=None, e
+ if scope is None:
+ scope = cfunc.scope
+ cfunc_type = cfunc.type
++ has_explicit_exc_clause=True
+ if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
+ error(self.pos, "wrong number of arguments")
+ error(cfunc.pos, "previous declaration here")
+
diff --git a/contrib/tools/cython/ya.make b/contrib/tools/cython/ya.make
index ba485359605..38619e6d9b4 100644
--- a/contrib/tools/cython/ya.make
+++ b/contrib/tools/cython/ya.make
@@ -11,9 +11,9 @@ LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
SUBSCRIBER(g:python-contrib)
-VERSION(3.0.10)
+VERSION(3.0.11)
-ORIGINAL_SOURCE(mirror://pypi/C/Cython/Cython-3.0.10.tar.gz)
+ORIGINAL_SOURCE(mirror://pypi/c/cython/cython-3.0.11.tar.gz)
NO_LINT()
diff --git a/library/cpp/yt/logging/logger-inl.h b/library/cpp/yt/logging/logger-inl.h
index f63f259d5f0..4a5df49f30a 100644
--- a/library/cpp/yt/logging/logger-inl.h
+++ b/library/cpp/yt/logging/logger-inl.h
@@ -332,9 +332,11 @@ inline void LogEventImpl(
event.SourceLine = sourceLocation.Line;
event.Anchor = anchor;
if (Y_UNLIKELY(event.Level >= ELogLevel::Alert)) {
+ logger.Write(TLogEvent(event));
OnCriticalLogEvent(logger, event);
+ } else {
+ logger.Write(std::move(event));
}
- logger.Write(std::move(event));
}
} // namespace NDetail
diff --git a/util/thread/pool.cpp b/util/thread/pool.cpp
index 2cc72e7f4cc..798a9cf9484 100644
--- a/util/thread/pool.cpp
+++ b/util/thread/pool.cpp
@@ -1,6 +1,7 @@
#include <atomic>
#include <util/system/defaults.h>
+#include <util/system/spinlock.h>
#if defined(_unix_)
#include <pthread.h>
@@ -295,30 +296,36 @@ private:
private:
void ChildAction() {
- TTryGuard guard{ActionMutex};
- // If you get an error here, it means you've used fork(2) in multi-threaded environment and probably created thread pools often.
- // Don't use fork(2) in multi-threaded programs, don't create thread pools often.
- // The mutex is locked after fork iff the fork(2) call was concurrent with RegisterObject / UnregisterObject in another thread.
- Y_ABORT_UNLESS(guard.WasAcquired(), "Failed to acquire ActionMutex after fork");
+ Y_ABORT_UNLESS(ActionMutex.IsLocked(), "ActionMutex must be locked after fork");
for (auto it = RegisteredObjects.Begin(); it != RegisteredObjects.End(); ++it) {
it->AtforkAction();
}
+
+ ActionMutex.Release();
}
static void ProcessChildAction() {
Get().ChildAction();
}
+ static void ProcessParentBeforeFork() {
+ Get().ActionMutex.Acquire();
+ }
+
+ static void ProcessParentAfterFork() {
+ Get().ActionMutex.Release();
+ }
+
TIntrusiveList<TImpl> RegisteredObjects;
- TMutex ActionMutex;
+ TAdaptiveLock ActionMutex;
public:
inline TAtforkQueueRestarter() {
#if defined(_bionic_)
// no pthread_atfork on android libc
#elif defined(_unix_)
- pthread_atfork(nullptr, nullptr, ProcessChildAction);
+ pthread_atfork(ProcessParentBeforeFork, ProcessParentAfterFork, ProcessChildAction);
#endif
}
};
diff --git a/yql/essentials/core/cbo/cbo_interesting_orderings.cpp b/yql/essentials/core/cbo/cbo_interesting_orderings.cpp
index a0bcd96f250..82237151690 100644
--- a/yql/essentials/core/cbo/cbo_interesting_orderings.cpp
+++ b/yql/essentials/core/cbo/cbo_interesting_orderings.cpp
@@ -355,8 +355,11 @@ bool TOrderingsStateMachine::TLogicalOrderings::HasState() const {
}
bool TOrderingsStateMachine::TLogicalOrderings::IsSubsetOf(const TLogicalOrderings& logicalOrderings) {
- Y_ASSERT(DFSM == logicalOrderings.DFSM);
- return HasState() && logicalOrderings.HasState() && IsSubset(DFSM->Nodes[State].NFSMNodesBitset, logicalOrderings.DFSM->Nodes[logicalOrderings.State].NFSMNodesBitset);
+ if (DFSM == nullptr || logicalOrderings.DFSM == nullptr) {
+ return false;
+ }
+
+ return (DFSM == logicalOrderings.DFSM) && HasState() && logicalOrderings.HasState() && IsSubset(DFSM->Nodes[State].NFSMNodesBitset, logicalOrderings.DFSM->Nodes[logicalOrderings.State].NFSMNodesBitset);
}
i64 TOrderingsStateMachine::TLogicalOrderings::GetState() const {
diff --git a/yt/python/yt/yson/convert.py b/yt/python/yt/yson/convert.py
index 3868fa42441..947e708979e 100644
--- a/yt/python/yt/yson/convert.py
+++ b/yt/python/yt/yson/convert.py
@@ -119,44 +119,91 @@ def json_to_yson(json_tree, use_byte_strings=None):
return result
-def yson_to_json(yson_tree, print_attributes=True):
+def _yson_to_json(yson_tree, print_attributes=True, attributes_printed=False, annotate_with_types=False):
+ should_annotate_with_types = (
+ annotate_with_types and
+ not isinstance(yson_tree, list) and
+ not isinstance(yson_tree, dict) and
+ not isinstance(yson_tree, YsonEntity) and
+ yson_tree is not None
+ )
+
def encode_key(key):
- if PY3 and isinstance(key, binary_type):
+ if isinstance(key, binary_type):
key = key.decode("ascii")
if key and key[0] == "$":
return "$" + key
return key
def process_dict(d):
- return dict((encode_key(k), yson_to_json(v)) for k, v in iteritems(d))
+ return dict(
+ (
+ encode_key(k),
+ _yson_to_json(v, print_attributes=print_attributes, annotate_with_types=annotate_with_types),
+ ) for k, v in iteritems(d)
+ )
+
+ def get_type_name():
+ if isinstance(yson_tree, YsonType):
+ yson_type_str = yson_tree.get_yson_type_str()
+
+ if yson_type_str is not None:
+ return yson_type_str
+
+ if isinstance(yson_tree, bool):
+ return "bool"
+ elif isinstance(yson_tree, int):
+ return "int64"
+ elif isinstance(yson_tree, float):
+ return "double"
+ elif isinstance(yson_tree, str) or isinstance(yson_tree, binary_type):
+ return "string"
+ else:
+ raise RuntimeError("Failed to perform yson to json conversion of {!r}, unknown type {!r} to annotate with types".format(
+ yson_tree,
+ type(yson_tree)
+ ))
+
+ def do_annotate_with_types(value):
+ return {"$type": get_type_name(), "$value": value} if should_annotate_with_types else value
+
+ if hasattr(yson_tree, "attributes") and yson_tree.attributes and print_attributes and not attributes_printed:
+ # If value is primitive do not pass annotate with types.
+ value_annotate_with_types = False if should_annotate_with_types else annotate_with_types
+
+ result = {
+ "$attributes": process_dict(yson_tree.attributes),
+ "$value": _yson_to_json(yson_tree, print_attributes=print_attributes, attributes_printed=True, annotate_with_types=value_annotate_with_types),
+ }
+
+ if should_annotate_with_types:
+ result["$type"] = get_type_name()
+
+ return result
- if hasattr(yson_tree, "attributes") and yson_tree.attributes and print_attributes:
- return {"$attributes": process_dict(yson_tree.attributes),
- "$value": yson_to_json(yson_tree, print_attributes=False)}
if isinstance(yson_tree, list):
- return list(imap(yson_to_json, yson_tree))
+ return [_yson_to_json(element, print_attributes=print_attributes, annotate_with_types=annotate_with_types) for element in yson_tree]
elif isinstance(yson_tree, dict):
return process_dict(yson_tree)
elif isinstance(yson_tree, YsonEntity):
return None
- elif PY3 and (isinstance(yson_tree, YsonString) or isinstance(yson_tree, binary_type)):
- return yson_tree.decode("utf-8")
+ elif isinstance(yson_tree, YsonString) or isinstance(yson_tree, binary_type):
+ return do_annotate_with_types(yson_tree.decode("utf-8"))
elif isinstance(yson_tree, bool) or isinstance(yson_tree, YsonBoolean):
- return True if yson_tree else False
+ return do_annotate_with_types(True if yson_tree else False)
else:
- if type(yson_tree) is YsonEntity:
- return None
-
bases = type(yson_tree).__bases__
- iter = 0
while len(bases) == 1 and YsonType not in bases:
bases = bases[0].__bases__
- iter += 1
if YsonType in bases:
other_types = list(set(bases) - set([YsonType]))
if not other_types:
raise RuntimeError("Failed to perform yson to json conversion of {!r}".format(yson_tree))
other = other_types[0]
- return other(yson_tree)
- return yson_tree
+ return do_annotate_with_types(other(yson_tree))
+ return do_annotate_with_types(yson_tree)
+
+
+def yson_to_json(yson_tree, print_attributes=True, annotate_with_types=False):
+ return _yson_to_json(yson_tree, print_attributes=print_attributes, annotate_with_types=annotate_with_types)
diff --git a/yt/python/yt/yson/yson_types.py b/yt/python/yt/yson/yson_types.py
index 00dbcc55477..eaa6608876e 100644
--- a/yt/python/yt/yson/yson_types.py
+++ b/yt/python/yt/yson/yson_types.py
@@ -41,6 +41,9 @@ class YsonType(object):
raise TypeError("unhashable type: YSON has non-trivial attributes")
return hash(type_(self))
+ def get_yson_type_str(selfself):
+ return None
+
class YsonString(binary_type, YsonType):
def __eq__(self, other):
@@ -59,6 +62,9 @@ class YsonString(binary_type, YsonType):
def __repr__(self):
return self.to_str(binary_type, repr)
+ def get_yson_type_str(self):
+ return "string"
+
class YsonUnicode(text_type, YsonType):
def __eq__(self, other):
@@ -75,6 +81,9 @@ class YsonUnicode(text_type, YsonType):
def __repr__(self):
return self.to_str(text_type, repr)
+ def get_yson_type_str(self):
+ return "string"
+
class NotUnicodeError(YtError, TypeError):
pass
@@ -165,6 +174,9 @@ class YsonStringProxy(YsonType):
def __ne__(self, other):
return not (self == other)
+ def get_yson_type_str(self):
+ return "string"
+
def is_unicode(x):
return isinstance(x, text_type)
@@ -214,11 +226,13 @@ class YsonIntegerBase(_YsonIntegerBase, YsonType):
class YsonInt64(YsonIntegerBase):
- pass
+ def get_yson_type_str(self):
+ return "int64"
class YsonUint64(YsonIntegerBase):
- pass
+ def get_yson_type_str(self):
+ return "uint64"
class YsonDouble(float, YsonType):
@@ -239,6 +253,9 @@ class YsonDouble(float, YsonType):
def __str__(self):
return self.to_str(float, str)
+ def get_yson_type_str(self):
+ return "double"
+
class YsonBoolean(int, YsonType):
def __eq__(self, other):
@@ -261,6 +278,9 @@ class YsonBoolean(int, YsonType):
def __str__(self):
return self.__repr__()
+ def get_yson_type_str(self):
+ return "bool"
+
class YsonList(list, YsonType):
def __eq__(self, other):
diff --git a/yt/yt/client/api/query_tracker_client.h b/yt/yt/client/api/query_tracker_client.h
index 700f4fa8205..69990a38761 100644
--- a/yt/yt/client/api/query_tracker_client.h
+++ b/yt/yt/client/api/query_tracker_client.h
@@ -57,8 +57,8 @@ struct TStartQueryOptions
bool Draft = false;
NYTree::IMapNodePtr Annotations;
std::vector<TQueryFilePtr> Files;
- std::optional<TString> AccessControlObject; // COMPAT(mpereskokova)
- std::optional<std::vector<TString>> AccessControlObjects;
+ std::optional<std::string> AccessControlObject; // COMPAT(mpereskokova)
+ std::optional<std::vector<std::string>> AccessControlObjects;
std::vector<TQuerySecretPtr> Secrets;
};
@@ -157,8 +157,8 @@ struct TAlterQueryOptions
, public TQueryTrackerOptions
{
NYTree::IMapNodePtr Annotations;
- std::optional<TString> AccessControlObject; // COMPAT(mpereskokova)
- std::optional<std::vector<TString>> AccessControlObjects;
+ std::optional<std::string> AccessControlObject; // COMPAT(mpereskokova)
+ std::optional<std::vector<std::string>> AccessControlObjects;
};
struct TGetQueryTrackerInfoOptions
@@ -173,7 +173,7 @@ struct TGetQueryTrackerInfoResult
TString QueryTrackerStage;
std::string ClusterName;
NYson::TYsonString SupportedFeatures;
- std::vector<TString> AccessControlObjects;
+ std::vector<std::string> AccessControlObjects;
std::vector<std::string> Clusters;
};
diff --git a/yt/yt/client/api/rpc_proxy/client_impl.cpp b/yt/yt/client/api/rpc_proxy/client_impl.cpp
index 14517c47cae..61cf0e45dcf 100644
--- a/yt/yt/client/api/rpc_proxy/client_impl.cpp
+++ b/yt/yt/client/api/rpc_proxy/client_impl.cpp
@@ -2536,7 +2536,7 @@ TFuture<TGetQueryTrackerInfoResult> TClient::GetQueryTrackerInfo(
.QueryTrackerStage = FromProto<TString>(rsp->query_tracker_stage()),
.ClusterName = FromProto<std::string>(rsp->cluster_name()),
.SupportedFeatures = TYsonString(rsp->supported_features()),
- .AccessControlObjects = FromProto<std::vector<TString>>(rsp->access_control_objects()),
+ .AccessControlObjects = FromProto<std::vector<std::string>>(rsp->access_control_objects()),
.Clusters = FromProto<std::vector<std::string>>(rsp->clusters())
};
}));
diff --git a/yt/yt/client/api/security_client.h b/yt/yt/client/api/security_client.h
index 23a37b1a428..24c1831cf59 100644
--- a/yt/yt/client/api/security_client.h
+++ b/yt/yt/client/api/security_client.h
@@ -41,7 +41,7 @@ struct TCheckPermissionResult
NObjectClient::TObjectId ObjectId;
std::optional<TString> ObjectName;
NSecurityClient::TSubjectId SubjectId;
- std::optional<TString> SubjectName;
+ std::optional<std::string> SubjectName;
};
struct TCheckPermissionResponse
@@ -64,8 +64,8 @@ struct TCheckPermissionByAclResult
NSecurityClient::ESecurityAction Action;
NSecurityClient::TSubjectId SubjectId;
- std::optional<TString> SubjectName;
- std::vector<TString> MissingSubjects;
+ std::optional<std::string> SubjectName;
+ std::vector<std::string> MissingSubjects;
};
struct TSetUserPasswordOptions
diff --git a/yt/yt/client/complex_types/check_type_compatibility.cpp b/yt/yt/client/complex_types/check_type_compatibility.cpp
index 5d5ecf70b21..18aa1a3eb28 100644
--- a/yt/yt/client/complex_types/check_type_compatibility.cpp
+++ b/yt/yt/client/complex_types/check_type_compatibility.cpp
@@ -229,6 +229,12 @@ static TCompatibilityPair CheckTypeCompatibilitySimple(
case ESimpleLogicalValueType::Datetime64:
case ESimpleLogicalValueType::Timestamp64:
case ESimpleLogicalValueType::Interval64:
+ case ESimpleLogicalValueType::TzDate:
+ case ESimpleLogicalValueType::TzDatetime:
+ case ESimpleLogicalValueType::TzTimestamp:
+ case ESimpleLogicalValueType::TzDate32:
+ case ESimpleLogicalValueType::TzDatetime64:
+ case ESimpleLogicalValueType::TzTimestamp64:
case ESimpleLogicalValueType::Any: {
const auto compatibility =
oldElement == newElement ? ESchemaCompatibility::FullyCompatible : ESchemaCompatibility::Incompatible;
diff --git a/yt/yt/client/driver/config.cpp b/yt/yt/client/driver/config.cpp
index ea20d3a1ce9..bb36b67605d 100644
--- a/yt/yt/client/driver/config.cpp
+++ b/yt/yt/client/driver/config.cpp
@@ -49,6 +49,9 @@ void TDriverConfig::Register(TRegistrar registrar)
registrar.Parameter("token", &TThis::Token)
.Optional();
+ registrar.Parameter("multiproxy_target_cluster", &TThis::MultiproxyTargetCluster)
+ .Optional();
+
registrar.Parameter("proxy_discovery_cache", &TThis::ProxyDiscoveryCache)
.DefaultNew();
diff --git a/yt/yt/client/driver/config.h b/yt/yt/client/driver/config.h
index a5ddf95bf50..603abbd0498 100644
--- a/yt/yt/client/driver/config.h
+++ b/yt/yt/client/driver/config.h
@@ -38,6 +38,9 @@ struct TDriverConfig
std::optional<TString> Token;
+ //! Target cluster for multiproxy mode.
+ std::optional<std::string> MultiproxyTargetCluster;
+
TAsyncExpiringCacheConfigPtr ProxyDiscoveryCache;
bool EnableInternalCommands;
@@ -57,4 +60,3 @@ DEFINE_REFCOUNTED_TYPE(TDriverConfig)
////////////////////////////////////////////////////////////////////////////////
} // namespace NYT::NDriver
-
diff --git a/yt/yt/client/driver/driver.cpp b/yt/yt/client/driver/driver.cpp
index 1a2ee7a8399..a722af45c71 100644
--- a/yt/yt/client/driver/driver.cpp
+++ b/yt/yt/client/driver/driver.cpp
@@ -59,6 +59,13 @@ constinit const auto Logger = DriverLogger;
////////////////////////////////////////////////////////////////////////////////
+static TClientOptions GetRootClientOptions(const TDriverConfigPtr& config)
+{
+ auto result = TClientOptions::Root();
+ result.MultiproxyTargetCluster = config->MultiproxyTargetCluster;
+ return result;
+}
+
void Serialize(const TCommandDescriptor& descriptor, NYson::IYsonConsumer* consumer)
{
BuildYsonFluently(consumer)
@@ -107,7 +114,6 @@ TCommandDescriptor IDriver::GetCommandDescriptorOrThrow(const TString& commandNa
////////////////////////////////////////////////////////////////////////////////
-
class TDriver
: public IDriver
{
@@ -121,7 +127,7 @@ public:
, ClientCache_(New<TClientCache>(Config_->ClientCache, Connection_))
, RootClient_(ClientCache_->Get(
GetRootAuthenticationIdentity(),
- TClientOptions::FromAuthenticationIdentity(GetRootAuthenticationIdentity())))
+ GetRootClientOptions(Config_)))
, ProxyDiscoveryCache_(CreateProxyDiscoveryCache(
Config_->ProxyDiscoveryCache,
RootClient_))
@@ -451,6 +457,7 @@ public:
options.ServiceTicketAuth = request.ServiceTicket
? std::make_optional(New<NAuth::TServiceTicketFixedAuth>(*request.ServiceTicket))
: std::nullopt;
+ options.MultiproxyTargetCluster = Config_->MultiproxyTargetCluster;
auto client = ClientCache_->Get(identity, options);
diff --git a/yt/yt/client/driver/query_commands.cpp b/yt/yt/client/driver/query_commands.cpp
index 28ace5ea5b0..25aca01345f 100644
--- a/yt/yt/client/driver/query_commands.cpp
+++ b/yt/yt/client/driver/query_commands.cpp
@@ -63,14 +63,14 @@ void TStartQueryCommand::Register(TRegistrar registrar)
})
.Optional(/*init*/ false);
- registrar.ParameterWithUniversalAccessor<std::optional<TString>>(
+ registrar.ParameterWithUniversalAccessor<std::optional<std::string>>(
"access_control_object",
[] (TThis* command) -> auto& {
return command->Options.AccessControlObject;
})
.Optional(/*init*/ false);
- registrar.ParameterWithUniversalAccessor<std::optional<std::vector<TString>>>(
+ registrar.ParameterWithUniversalAccessor<std::optional<std::vector<std::string>>>(
"access_control_objects",
[] (TThis* command) -> auto& {
return command->Options.AccessControlObjects;
@@ -339,14 +339,14 @@ void TAlterQueryCommand::Register(TRegistrar registrar)
})
.Optional(/*init*/ false);
- registrar.ParameterWithUniversalAccessor<std::optional<TString>>(
+ registrar.ParameterWithUniversalAccessor<std::optional<std::string>>(
"access_control_object",
[] (TThis* command) -> auto& {
return command->Options.AccessControlObject;
})
.Optional(/*init*/ false);
- registrar.ParameterWithUniversalAccessor<std::optional<std::vector<TString>>>(
+ registrar.ParameterWithUniversalAccessor<std::optional<std::vector<std::string>>>(
"access_control_objects",
[] (TThis* command) -> auto& {
return command->Options.AccessControlObjects;
diff --git a/yt/yt/client/table_client/logical_type-inl.h b/yt/yt/client/table_client/logical_type-inl.h
index 28bd5b17a6c..fe193e42f7f 100644
--- a/yt/yt/client/table_client/logical_type-inl.h
+++ b/yt/yt/client/table_client/logical_type-inl.h
@@ -142,4 +142,34 @@ const TLogicalTypePtr& TTaggedLogicalType::GetElement() const
////////////////////////////////////////////////////////////////////////////////
-} // namespace NYT::NTableClient \ No newline at end of file
+#define XX(cppType, ytType) \
+ template <> \
+ struct TUnderlyingTimestampIntegerTypeImpl<ESimpleLogicalValueType::ytType> \
+ { \
+ using TValue = cppType; \
+ }; \
+ \
+ template <> \
+ struct TUnderlyingTzTypeImpl<ESimpleLogicalValueType::Tz##ytType> \
+ { \
+ static constexpr ESimpleLogicalValueType TValue = ESimpleLogicalValueType::ytType; \
+ };
+
+ XX(ui16, Date)
+ XX(ui32, Datetime)
+ XX(ui64, Timestamp)
+ XX(i32, Date32)
+ XX(i64, Datetime64)
+ XX(i64, Timestamp64)
+
+#undef XX
+
+template<ESimpleLogicalValueType type>
+constexpr ESimpleLogicalValueType GetUnderlyingDateType()
+{
+ return TUnderlyingTzTypeImpl<type>::TValue;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT::NTableClient
diff --git a/yt/yt/client/table_client/logical_type.cpp b/yt/yt/client/table_client/logical_type.cpp
index 9c635f4405d..409cd82d5f3 100644
--- a/yt/yt/client/table_client/logical_type.cpp
+++ b/yt/yt/client/table_client/logical_type.cpp
@@ -1287,6 +1287,12 @@ void TDictLogicalType::ValidateNode(const TWalkContext&) const
case ESimpleLogicalValueType::Datetime64:
case ESimpleLogicalValueType::Timestamp64:
case ESimpleLogicalValueType::Interval64:
+ case ESimpleLogicalValueType::TzDate:
+ case ESimpleLogicalValueType::TzDatetime:
+ case ESimpleLogicalValueType::TzTimestamp:
+ case ESimpleLogicalValueType::TzDate32:
+ case ESimpleLogicalValueType::TzDatetime64:
+ case ESimpleLogicalValueType::TzTimestamp64:
return;
}
YT_ABORT();
@@ -1891,6 +1897,13 @@ bool IsComparable(const TLogicalTypePtr& type)
case ESimpleLogicalValueType::Datetime64:
case ESimpleLogicalValueType::Timestamp64:
case ESimpleLogicalValueType::Interval64:
+
+ case ESimpleLogicalValueType::TzDate:
+ case ESimpleLogicalValueType::TzDatetime:
+ case ESimpleLogicalValueType::TzTimestamp:
+ case ESimpleLogicalValueType::TzDate32:
+ case ESimpleLogicalValueType::TzDatetime64:
+ case ESimpleLogicalValueType::TzTimestamp64:
return true;
case ESimpleLogicalValueType::Any:
@@ -1922,6 +1935,26 @@ bool IsComparable(const TLogicalTypePtr& type)
}
}
+bool IsTzType(const TLogicalTypePtr& logicalType)
+{
+ switch (logicalType->GetMetatype()) {
+ case ELogicalMetatype::Simple:
+ switch (logicalType->AsSimpleTypeRef().GetElement()) {
+ case ESimpleLogicalValueType::TzDate:
+ case ESimpleLogicalValueType::TzDatetime:
+ case ESimpleLogicalValueType::TzTimestamp:
+ case ESimpleLogicalValueType::TzDate32:
+ case ESimpleLogicalValueType::TzDatetime64:
+ case ESimpleLogicalValueType::TzTimestamp64:
+ return true;
+ default:
+ return false;
+ }
+ default:
+ return false;
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////
struct TV3Variant
@@ -1964,6 +1997,13 @@ static const std::pair<ESimpleLogicalValueType, TString> V3SimpleLogicalValueTyp
{ESimpleLogicalValueType::Datetime64, "datetime64"},
{ESimpleLogicalValueType::Timestamp64, "timestamp64"},
{ESimpleLogicalValueType::Interval64, "interval64"},
+
+ {ESimpleLogicalValueType::TzDate, "tz_date"},
+ {ESimpleLogicalValueType::TzDatetime, "tz_datetime"},
+ {ESimpleLogicalValueType::TzTimestamp, "tz_timestamp"},
+ {ESimpleLogicalValueType::TzDate32, "tz_date32"},
+ {ESimpleLogicalValueType::TzDatetime64, "tz_datetime64"},
+ {ESimpleLogicalValueType::TzTimestamp64, "tz_timestamp64"},
};
static_assert(std::size(V3SimpleLogicalValueTypeEncoding) == TEnumTraits<ESimpleLogicalValueType>::GetDomainSize());
diff --git a/yt/yt/client/table_client/logical_type.h b/yt/yt/client/table_client/logical_type.h
index 80cfebd081d..bffc45616fe 100644
--- a/yt/yt/client/table_client/logical_type.h
+++ b/yt/yt/client/table_client/logical_type.h
@@ -146,6 +146,8 @@ void FromProto(TLogicalTypePtr* logicalType, const NProto::TLogicalType& protoLo
bool IsComparable(const TLogicalTypePtr& type);
+bool IsTzType(const TLogicalTypePtr& logicalType);
+
////////////////////////////////////////////////////////////////////////////////
// Special wrapper class that allows to serialize LogicalType in type_v3 format
@@ -441,6 +443,11 @@ TLogicalTypePtr MakeLogicalType(ESimpleLogicalValueType type, bool required);
////////////////////////////////////////////////////////////////////////////////
+template<ESimpleLogicalValueType type>
+constexpr ESimpleLogicalValueType GetUnderlyingDateType();
+
+////////////////////////////////////////////////////////////////////////////////
+
} // namespace NYT::NTableClient
template <>
diff --git a/yt/yt/client/table_client/public.h b/yt/yt/client/table_client/public.h
index 5c6164a0466..d314028ccb7 100644
--- a/yt/yt/client/table_client/public.h
+++ b/yt/yt/client/table_client/public.h
@@ -466,6 +466,15 @@ using TUUComparerSignature = int(const TUnversionedValue*, const TUnversionedVal
struct TVersionedReadOptions;
struct TVersionedWriteOptions;
+template <ESimpleLogicalValueType type>
+struct TUnderlyingTzTypeImpl;
+
+template <ESimpleLogicalValueType type>
+struct TUnderlyingTimestampIntegerTypeImpl;
+
+template <ESimpleLogicalValueType type>
+using TUnderlyingTimestampIntegerType = TUnderlyingTimestampIntegerTypeImpl<type>::TValue;
+
////////////////////////////////////////////////////////////////////////////////
YT_DEFINE_STRONG_TYPEDEF(TSignedDistributedWriteSessionPtr, NSignature::TSignaturePtr);
diff --git a/yt/yt/client/table_client/row_base.h b/yt/yt/client/table_client/row_base.h
index cc4a34c4467..e66bb9a52e1 100644
--- a/yt/yt/client/table_client/row_base.h
+++ b/yt/yt/client/table_client/row_base.h
@@ -76,6 +76,13 @@ DEFINE_ENUM_WITH_UNDERLYING_TYPE(ESimpleLogicalValueType, ui32,
((Datetime64) (0x1011))
((Timestamp64) (0x1012))
((Interval64) (0x1013))
+
+ ((TzDate) (0x1014))
+ ((TzDatetime) (0x1015))
+ ((TzTimestamp) (0x1016))
+ ((TzDate32) (0x1017))
+ ((TzDatetime64) (0x1018))
+ ((TzTimestamp64) (0x1019))
);
//! Debug printers for Gtest unittests.
@@ -229,6 +236,14 @@ inline constexpr EValueType GetPhysicalType(ESimpleLogicalValueType type)
case ESimpleLogicalValueType::Interval64:
return EValueType::Int64;
+ case ESimpleLogicalValueType::TzDate:
+ case ESimpleLogicalValueType::TzDatetime:
+ case ESimpleLogicalValueType::TzTimestamp:
+ case ESimpleLogicalValueType::TzDate32:
+ case ESimpleLogicalValueType::TzDatetime64:
+ case ESimpleLogicalValueType::TzTimestamp64:
+ return EValueType::String;
+
default:
YT_ABORT();
}
diff --git a/yt/yt/client/table_client/unversioned_row.cpp b/yt/yt/client/table_client/unversioned_row.cpp
index 5cff922a3cd..ed7b8fed7aa 100644
--- a/yt/yt/client/table_client/unversioned_row.cpp
+++ b/yt/yt/client/table_client/unversioned_row.cpp
@@ -1074,6 +1074,13 @@ void ValidateValueType(
CASE(ESimpleLogicalValueType::Datetime64)
CASE(ESimpleLogicalValueType::Timestamp64)
CASE(ESimpleLogicalValueType::Interval64)
+
+ CASE(ESimpleLogicalValueType::TzDate)
+ CASE(ESimpleLogicalValueType::TzDatetime)
+ CASE(ESimpleLogicalValueType::TzTimestamp)
+ CASE(ESimpleLogicalValueType::TzDate32)
+ CASE(ESimpleLogicalValueType::TzDatetime64)
+ CASE(ESimpleLogicalValueType::TzTimestamp64)
#undef CASE
}
YT_ABORT();
diff --git a/yt/yt/client/table_client/validate_logical_type-inl.h b/yt/yt/client/table_client/validate_logical_type-inl.h
index e4e30051e0a..fe51870f8f0 100644
--- a/yt/yt/client/table_client/validate_logical_type-inl.h
+++ b/yt/yt/client/table_client/validate_logical_type-inl.h
@@ -8,6 +8,8 @@
#include <yt/yt/core/misc/error.h>
+#include <yt/yt/library/tz_types/tz_types.h>
+
#include <util/charset/utf8.h>
#include <cmath>
@@ -213,6 +215,40 @@ void ValidateSimpleLogicalType(TStringBuf value)
THROW_ERROR_EXCEPTION(NTableClient::EErrorCode::SchemaViolation,
"Not a valid Uuid");
}
+ } else if constexpr (
+ type == ESimpleLogicalValueType::TzDate ||
+ type == ESimpleLogicalValueType::TzDatetime ||
+ type == ESimpleLogicalValueType::TzTimestamp ||
+ type == ESimpleLogicalValueType::TzDate32 ||
+ type == ESimpleLogicalValueType::TzDatetime64 ||
+ type == ESimpleLogicalValueType::TzTimestamp64)
+ {
+ try {
+ constexpr ESimpleLogicalValueType underlyingDateType = GetUnderlyingDateType<type>();
+
+ using TInt = TUnderlyingTimestampIntegerType<underlyingDateType>;
+
+ const auto& [timestamp, tzName] = NTzTypes::ParseTzValue<TInt>(value);
+
+ try {
+ if constexpr (std::is_signed_v<TInt>) {
+ ValidateSimpleLogicalType<underlyingDateType>(static_cast<i64>(timestamp));
+ } else {
+ ValidateSimpleLogicalType<underlyingDateType>(static_cast<ui64>(timestamp));
+ }
+ } catch (const std::exception& ex) {
+ THROW_ERROR_EXCEPTION("Cannot validate underlying timestamp of %Qv type", type)
+ << ex;
+ }
+
+ NTzTypes::ValidateTzName(tzName);
+ } catch (const std::exception& ex) {
+ THROW_ERROR_EXCEPTION(
+ NTableClient::EErrorCode::SchemaViolation,
+ "Not a valid timezone time")
+ << TErrorAttribute("value", value)
+ << ex;
+ }
} else {
static_assert(type == ESimpleLogicalValueType::String, "Bad logical type");
}
diff --git a/yt/yt/client/table_client/validate_logical_type.cpp b/yt/yt/client/table_client/validate_logical_type.cpp
index b5af53f7797..f3c99ac7d74 100644
--- a/yt/yt/client/table_client/validate_logical_type.cpp
+++ b/yt/yt/client/table_client/validate_logical_type.cpp
@@ -206,6 +206,12 @@ private:
CASE(ESimpleLogicalValueType::Datetime64)
CASE(ESimpleLogicalValueType::Timestamp64)
CASE(ESimpleLogicalValueType::Interval64)
+ CASE(ESimpleLogicalValueType::TzDate)
+ CASE(ESimpleLogicalValueType::TzDatetime)
+ CASE(ESimpleLogicalValueType::TzTimestamp)
+ CASE(ESimpleLogicalValueType::TzDate32)
+ CASE(ESimpleLogicalValueType::TzDatetime64)
+ CASE(ESimpleLogicalValueType::TzTimestamp64)
#undef CASE
}
YT_ABORT();
diff --git a/yt/yt/client/unittests/validate_logical_type_ut.cpp b/yt/yt/client/unittests/validate_logical_type_ut.cpp
index 67ff680f635..b8fe177b5b3 100644
--- a/yt/yt/client/unittests/validate_logical_type_ut.cpp
+++ b/yt/yt/client/unittests/validate_logical_type_ut.cpp
@@ -9,6 +9,8 @@
namespace NYT::NTableClient {
+using namespace NTzTypes;
+
////////////////////////////////////////////////////////////////////////////////
#define ERROR_ATTRS(logicalType, ysonString) \
@@ -182,6 +184,68 @@ TEST(TValidateLogicalTypeTest, TestAnyType)
EXPECT_GOOD_TYPE(SimpleLogicalType(ESimpleLogicalValueType::Any), "[<>1]");
}
+TEST(TValidateLogicalTypeTest, TestTimezoneType)
+{
+ // Simple example.
+ auto correctValue = MakeTzString<ui16>(42, "Europe/Moscow");
+ EXPECT_NO_THROW(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzDate>(correctValue));
+
+ // Short buffer.
+ TString shortValue = "1";
+ EXPECT_THROW_WITH_SUBSTRING(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzDate>(shortValue), "Not a valid timezone time");
+
+ // Wrong timezone.
+ auto wrongTimezoneValue = MakeTzString<ui16>(42, "Wrong/Timezone");
+ EXPECT_THROW_WITH_SUBSTRING(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzDate>(wrongTimezoneValue), "Not a valid timezone time");
+
+ // Empty timezone.
+ auto emptyTimezoneValue = MakeTzString<ui16>(42, "");
+ EXPECT_THROW_WITH_SUBSTRING(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzDate>(emptyTimezoneValue), "Not a valid timezone time");
+
+ // Validate max value.
+ auto maxDate = MakeTzString<ui16>(DateUpperBound - 1, "Europe/Moscow");
+ EXPECT_NO_THROW(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzDate>(maxDate));
+ auto maxDatetime = MakeTzString<ui32>(DatetimeUpperBound - 1, "Europe/Moscow");
+ EXPECT_NO_THROW(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzDatetime>(maxDatetime));
+ auto maxTimestamp = MakeTzString<ui64>(TimestampUpperBound - 1, "Europe/Moscow");
+ EXPECT_NO_THROW(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzTimestamp>(maxTimestamp));
+ auto maxDate32 = MakeTzString<i32>(Date32UpperBound - 1, "Europe/Moscow");
+ EXPECT_NO_THROW(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzDate32>(maxDate32));
+ auto maxDatetime64 = MakeTzString<i64>(Datetime64UpperBound - 1, GetTzName(1));
+ EXPECT_NO_THROW(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzDatetime64>(maxDatetime64));
+ auto maxTimestamp64 = MakeTzString<i64>(Timestamp64UpperBound - 1, GetTzName(1));
+ EXPECT_NO_THROW(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzTimestamp64>(maxTimestamp64));
+
+ // Validate too big value.
+ auto tooBigDate = MakeTzString<ui16>(DateUpperBound, GetTzName(1));
+ EXPECT_THROW_WITH_SUBSTRING(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzDate>(tooBigDate), "Not a valid timezone time");
+ auto tooBigDatetime = MakeTzString<ui32>(DatetimeUpperBound, GetTzName(1));
+ EXPECT_THROW_WITH_SUBSTRING(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzDatetime>(tooBigDatetime), "Not a valid timezone time");
+ auto tooBigTimestamp = MakeTzString<ui64>(TimestampUpperBound, GetTzName(1));
+ EXPECT_THROW_WITH_SUBSTRING(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzTimestamp>(tooBigTimestamp), "Not a valid timezone time");
+ auto tooBigDate32 = MakeTzString<i32>(Date32UpperBound, GetTzName(1));
+ EXPECT_THROW_WITH_SUBSTRING(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzDate32>(tooBigDate32), "Not a valid timezone time");
+ auto tooBigDatetime64 = MakeTzString<i64>(Datetime64UpperBound, GetTzName(1));
+ EXPECT_THROW_WITH_SUBSTRING(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzDatetime64>(tooBigDatetime64), "Not a valid timezone time");
+ auto tooBigTimestamp64 = MakeTzString<i64>(Timestamp64UpperBound, GetTzName(1));
+ EXPECT_THROW_WITH_SUBSTRING(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzTimestamp64>(tooBigTimestamp64), "Not a valid timezone time");
+
+ // Validate min value.
+ auto minDate32 = MakeTzString<i32>(Date32LowerBound, GetTzName(1));
+ EXPECT_NO_THROW(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzDate32>(minDate32));
+ auto minDatetime64 = MakeTzString<i64>(Datetime64LowerBound, GetTzName(1));
+ EXPECT_NO_THROW(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzDatetime64>(minDatetime64));
+ auto minTimestamp64 = MakeTzString<i64>(Timestamp64LowerBound, GetTzName(1));
+ EXPECT_NO_THROW(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzTimestamp64>(minTimestamp64));
+
+ // Validate too small value.
+ auto tooSmallDate32 = MakeTzString<i32>(Date32LowerBound - 1, GetTzName(1));
+ EXPECT_THROW_WITH_SUBSTRING(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzDate32>(tooSmallDate32), "Not a valid timezone time");
+ auto tooSmallDatetime64 = MakeTzString<i64>(Datetime64LowerBound - 1, GetTzName(1));
+ EXPECT_THROW_WITH_SUBSTRING(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzDatetime64>(tooSmallDatetime64), "Not a valid timezone time");
+ auto tooSmallTimestamp64 = MakeTzString<i64>(Timestamp64LowerBound - 1, GetTzName(1));
+ EXPECT_THROW_WITH_SUBSTRING(ValidateSimpleLogicalType<ESimpleLogicalValueType::TzTimestamp64>(tooSmallTimestamp64), "Not a valid timezone time");
+}
TEST(TValidateLogicalTypeTest, TestJsonType)
{
diff --git a/yt/yt/client/ya.make b/yt/yt/client/ya.make
index 49d8db4c084..224cc1ba304 100644
--- a/yt/yt/client/ya.make
+++ b/yt/yt/client/ya.make
@@ -219,10 +219,11 @@ PEERDIR(
yt/yt/core/https
yt/yt/library/auth
yt/yt/library/decimal
- yt/yt/library/re2
yt/yt/library/erasure
yt/yt/library/numeric
yt/yt/library/quantile_digest
+ yt/yt/library/re2
+ yt/yt/library/tz_types
yt/yt_proto/yt/client
library/cpp/digest/crc32c
library/cpp/json
diff --git a/yt/yt/core/yson/lexer.cpp b/yt/yt/core/yson/lexer.cpp
index e23e0bd5c16..3f1c6462b11 100644
--- a/yt/yt/core/yson/lexer.cpp
+++ b/yt/yt/core/yson/lexer.cpp
@@ -14,12 +14,4 @@ size_t TStatelessLexer::ParseToken(TStringBuf data, TToken* token)
////////////////////////////////////////////////////////////////////////////////
-size_t ParseToken(TStringBuf data, TToken* token)
-{
- TStatelessLexer lexer;
- return lexer.ParseToken(data, token);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
} // namespace NYT::NYson
diff --git a/yt/yt/core/yson/lexer.h b/yt/yt/core/yson/lexer.h
index 1d38ca1327d..7f05e5e09f1 100644
--- a/yt/yt/core/yson/lexer.h
+++ b/yt/yt/core/yson/lexer.h
@@ -18,8 +18,4 @@ private:
////////////////////////////////////////////////////////////////////////////////
-size_t ParseToken(TStringBuf data, TToken* token);
-
-////////////////////////////////////////////////////////////////////////////////
-
} // namespace NYT::NYson
diff --git a/yt/yt/core/ytree/polymorphic_yson_struct-inl.h b/yt/yt/core/ytree/polymorphic_yson_struct-inl.h
index d0a4f2b6a8e..b9ea6afaf45 100644
--- a/yt/yt/core/ytree/polymorphic_yson_struct-inl.h
+++ b/yt/yt/core/ytree/polymorphic_yson_struct-inl.h
@@ -65,7 +65,7 @@ void TPolymorphicYsonStruct<TMapping>::Load(
TSource source,
bool postprocess,
bool setDefaults,
- const NYPath::TYPath& path,
+ const std::function<NYPath::TYPath()>& pathGetter,
std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy)
{
using TTraits = NPrivate::TYsonSourceTraits<TSource>;
@@ -101,7 +101,7 @@ void TPolymorphicYsonStruct<TMapping>::Load(
// "type" must be unrecognized for the original struct
// therefore we must delete it prior to |Load| call.
map->RemoveChild("type");
- Storage_->Load(map, postprocess, setDefaults, path);
+ Storage_->Load(map, postprocess, setDefaults, pathGetter);
// NB(arkady-e1ppa): We must not actually remove contents of the node as a postcondition
// since it mutates serialized data which might be used for config validation.
@@ -180,7 +180,7 @@ void TPolymorphicYsonStruct<TMapping>::MergeWith(const TPolymorphicYsonStruct& o
SerializedStorage_,
/*postprocess*/ true,
/*setDefaults*/ true,
- /*path*/ "",
+ /*path*/ {},
/*recursiveUnrecognizedStrategy*/ std::nullopt);
}
diff --git a/yt/yt/core/ytree/polymorphic_yson_struct.h b/yt/yt/core/ytree/polymorphic_yson_struct.h
index 3c89ee758bd..ee4732fa8e7 100644
--- a/yt/yt/core/ytree/polymorphic_yson_struct.h
+++ b/yt/yt/core/ytree/polymorphic_yson_struct.h
@@ -153,7 +153,7 @@ public:
TSource source,
bool postprocess = true,
bool setDefaults = true,
- const NYPath::TYPath& path = {},
+ const std::function<NYPath::TYPath()>& pathGetter = {},
std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy = {});
void Save(NYson::IYsonConsumer* consumer) const;
diff --git a/yt/yt/core/ytree/yson_struct.cpp b/yt/yt/core/ytree/yson_struct.cpp
index e019fc22fac..e4a6b30df76 100644
--- a/yt/yt/core/ytree/yson_struct.cpp
+++ b/yt/yt/core/ytree/yson_struct.cpp
@@ -64,9 +64,29 @@ void TYsonStructBase::Load(
INodePtr node,
bool postprocess,
bool setDefaults,
+ const std::function<NYPath::TYPath()>& pathGetter)
+{
+ Meta_->LoadStruct(this, std::move(node), postprocess, setDefaults, pathGetter);
+}
+
+void TYsonStructBase::Load(
+ TYsonPullParserCursor* cursor,
+ bool postprocess,
+ bool setDefaults,
+ const std::function<NYPath::TYPath()>& pathGetter)
+{
+ Meta_->LoadStruct(this, cursor, postprocess, setDefaults, pathGetter);
+}
+
+void TYsonStructBase::Load(
+ INodePtr node,
+ bool postprocess,
+ bool setDefaults,
const NYPath::TYPath& path)
{
- Meta_->LoadStruct(this, std::move(node), postprocess, setDefaults, path);
+ Load(std::move(node), postprocess, setDefaults, [&] {
+ return path;
+ });
}
void TYsonStructBase::Load(
@@ -75,7 +95,9 @@ void TYsonStructBase::Load(
bool setDefaults,
const NYPath::TYPath& path)
{
- Meta_->LoadStruct(this, cursor, postprocess, setDefaults, path);
+ Load(cursor, postprocess, setDefaults, [&] {
+ return path;
+ });
}
void TYsonStructBase::Load(IInputStream* input)
@@ -154,9 +176,9 @@ void TYsonStructBase::Save(IOutputStream* output) const
context.Finish();
}
-void TYsonStructBase::Postprocess(const TYPath& path)
+void TYsonStructBase::Postprocess(const std::function<NYPath::TYPath()>& pathGetter)
{
- Meta_->PostprocessStruct(this, path);
+ Meta_->PostprocessStruct(this, pathGetter);
}
void TYsonStructBase::SetDefaults()
diff --git a/yt/yt/core/ytree/yson_struct.h b/yt/yt/core/ytree/yson_struct.h
index cd93566f865..7cceb5a2288 100644
--- a/yt/yt/core/ytree/yson_struct.h
+++ b/yt/yt/core/ytree/yson_struct.h
@@ -68,17 +68,29 @@ public:
INodePtr node,
bool postprocess = true,
bool setDefaults = true,
- const NYPath::TYPath& path = {});
+ const std::function<NYPath::TYPath()>& pathGetter = {});
void Load(
NYson::TYsonPullParserCursor* cursor,
bool postprocess = true,
bool setDefaults = true,
- const NYPath::TYPath& path = {});
+ const std::function<NYPath::TYPath()>& pathGetter = {});
+
+ void Load(
+ INodePtr node,
+ bool postprocess,
+ bool setDefaults,
+ const NYPath::TYPath& path);
+
+ void Load(
+ NYson::TYsonPullParserCursor* cursor,
+ bool postprocess,
+ bool setDefaults,
+ const NYPath::TYPath& path);
void Load(IInputStream* input);
- void Postprocess(const NYPath::TYPath& path = {});
+ void Postprocess(const std::function<NYPath::TYPath()>& pathGetter = {});
void SetDefaults();
@@ -241,7 +253,7 @@ concept CYsonStructLoadableFieldFor =
S source,
bool postprocess,
bool setDefaults,
- const NYPath::TYPath& path,
+ const std::function<NYPath::TYPath()>& pathGetter,
std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy)
{
// For YsonStruct.
@@ -249,7 +261,7 @@ concept CYsonStructLoadableFieldFor =
source,
postprocess,
setDefaults,
- path,
+ pathGetter,
recursiveUnrecognizedStrategy);
};
diff --git a/yt/yt/core/ytree/yson_struct_detail-inl.h b/yt/yt/core/ytree/yson_struct_detail-inl.h
index adff17d5d72..4e7722381ad 100644
--- a/yt/yt/core/ytree/yson_struct_detail-inl.h
+++ b/yt/yt/core/ytree/yson_struct_detail-inl.h
@@ -208,7 +208,7 @@ template <CYsonStructSource TSource, class T>
void LoadFromSource(
std::optional<T>& parameter,
TSource source,
- const NYPath::TYPath& path,
+ const std::function<NYPath::TYPath()>& pathGetter,
std::optional<EUnrecognizedStrategy> unrecognizedStrategy);
// std::vector
@@ -216,7 +216,7 @@ template <CYsonStructSource TSource, CStdVector TVector>
void LoadFromSource(
TVector& parameter,
TSource source,
- const NYPath::TYPath& path,
+ const std::function<NYPath::TYPath()>& pathGetter,
std::optional<EUnrecognizedStrategy> unrecognizedStrategy);
// any map.
@@ -224,7 +224,7 @@ template <CYsonStructSource TSource, CAnyMap TMap>
void LoadFromSource(
TMap& parameter,
TSource source,
- const NYPath::TYPath& path,
+ const std::function<NYPath::TYPath()>& pathGetter,
std::optional<EUnrecognizedStrategy> unrecognizedStrategy);
////////////////////////////////////////////////////////////////////////////////
@@ -234,7 +234,7 @@ template <CYsonStructSource TSource, class T>
void LoadFromSource(
T& parameter,
TSource source,
- const NYPath::TYPath& path,
+ const std::function<NYPath::TYPath()>& pathGetter,
std::optional<EUnrecognizedStrategy> /*ignored*/)
{
using TTraits = TYsonSourceTraits<TSource>;
@@ -242,7 +242,7 @@ void LoadFromSource(
try {
Deserialize(parameter, TTraits::AsNode(source));
} catch (const std::exception& ex) {
- THROW_ERROR_EXCEPTION("Error reading parameter %v", path)
+ THROW_ERROR_EXCEPTION("Error reading parameter %v", pathGetter())
<< ex;
}
}
@@ -252,7 +252,7 @@ template <CYsonStructSource TSource>
void LoadFromSource(
::NYT::NYson::TYsonString& parameter,
TSource source,
- const NYPath::TYPath& path,
+ const std::function<NYPath::TYPath()>& pathGetter,
std::optional<EUnrecognizedStrategy> /*ignored*/)
{
using TTraits = TYsonSourceTraits<TSource>;
@@ -260,7 +260,7 @@ void LoadFromSource(
try {
parameter = NYson::ConvertToYsonString(TTraits::AsNode(source));
} catch (const std::exception& ex) {
- THROW_ERROR_EXCEPTION("Error loading parameter %v", path)
+ THROW_ERROR_EXCEPTION("Error loading parameter %v", pathGetter())
<< ex;
}
}
@@ -270,7 +270,7 @@ template <CYsonStructSource TSource>
void LoadFromSource(
INodePtr& parameter,
TSource source,
- const NYPath::TYPath& path,
+ const std::function<NYPath::TYPath()>& pathGetter,
std::optional<EUnrecognizedStrategy> /*ignored*/)
{
using TTraits = TYsonSourceTraits<TSource>;
@@ -283,7 +283,7 @@ void LoadFromSource(
parameter = PatchNode(parameter, std::move(node));
}
} catch (const std::exception& ex) {
- THROW_ERROR_EXCEPTION("Error loading parameter %v", path)
+ THROW_ERROR_EXCEPTION("Error loading parameter %v", pathGetter())
<< ex;
}
}
@@ -293,7 +293,7 @@ template <CYsonStructSource TSource, CYsonStructDerived T>
void LoadFromSource(
TIntrusivePtr<T>& parameter,
TSource source,
- const NYPath::TYPath& path,
+ const std::function<NYPath::TYPath()>& pathGetter,
std::optional<EUnrecognizedStrategy> unrecognizedStrategy)
{
if (!parameter) {
@@ -304,7 +304,7 @@ void LoadFromSource(
parameter->SetUnrecognizedStrategy(*unrecognizedStrategy);
}
- parameter->Load(std::move(source), /*postprocess*/ false, /*setDefaults*/ false, path);
+ parameter->Load(std::move(source), /*postprocess*/ false, /*setDefaults*/ false, pathGetter);
}
// YsonStructLite
@@ -312,16 +312,16 @@ template <CYsonStructSource TSource, std::derived_from<TYsonStructLite> T>
void LoadFromSource(
T& parameter,
TSource source,
- const NYPath::TYPath& path,
+ const std::function<NYPath::TYPath()>& pathGetter,
std::optional<EUnrecognizedStrategy> unrecognizedStrategy)
{
try {
if (unrecognizedStrategy) {
parameter.SetUnrecognizedStrategy(*unrecognizedStrategy);
}
- parameter.Load(std::move(source), /*postprocess*/ false, /*setDefaults*/ false, path);
+ parameter.Load(std::move(source), /*postprocess*/ false, /*setDefaults*/ false, pathGetter);
} catch (const std::exception& ex) {
- THROW_ERROR_EXCEPTION("Error reading parameter %v", path)
+ THROW_ERROR_EXCEPTION("Error reading parameter %v", pathGetter())
<< ex;
}
}
@@ -331,13 +331,13 @@ template <CYsonStructSource TSource, CExternallySerializable T>
void LoadFromSource(
T& parameter,
TSource source,
- const NYPath::TYPath& path,
+ const std::function<NYPath::TYPath()>& pathGetter,
std::optional<EUnrecognizedStrategy> unrecognizedStrategy)
{
try {
Deserialize(parameter, std::move(source), /*postprocess*/ false, /*setDefaults*/ false, unrecognizedStrategy);
} catch (const std::exception& ex) {
- THROW_ERROR_EXCEPTION("Error reading parameter %v", path)
+ THROW_ERROR_EXCEPTION("Error reading parameter %v", pathGetter())
<< ex;
}
}
@@ -350,7 +350,7 @@ template <CYsonStructSource TSource, CYsonStructLoadableFieldFor<TSource> TExten
void LoadFromSource(
TExtension& parameter,
TSource source,
- const NYPath::TYPath& path,
+ const std::function<NYPath::TYPath()>& pathGetter,
std::optional<EUnrecognizedStrategy> unrecognizedStrategy)
{
static_assert(CYsonStructFieldFor<TExtension, TSource>, "You must add alias TImplementsYsonStructField");
@@ -360,10 +360,10 @@ void LoadFromSource(
std::move(source),
/*postprocess*/ false,
/*setDefaults*/ false,
- path,
+ pathGetter,
unrecognizedStrategy);
} catch (const std::exception& ex) {
- THROW_ERROR_EXCEPTION("Error loading parameter %v", path)
+ THROW_ERROR_EXCEPTION("Error loading parameter %v", pathGetter())
<< ex;
}
}
@@ -373,7 +373,7 @@ template <CYsonStructSource TSource, class T>
void LoadFromSource(
std::optional<T>& parameter,
TSource source,
- const NYPath::TYPath& path,
+ const std::function<NYPath::TYPath()>& pathGetter,
std::optional<EUnrecognizedStrategy> unrecognizedStrategy)
{
using TTraits = TYsonSourceTraits<TSource>;
@@ -386,16 +386,16 @@ void LoadFromSource(
}
if (parameter.has_value()) {
- LoadFromSource(*parameter, std::move(source), path, unrecognizedStrategy);
+ LoadFromSource(*parameter, std::move(source), pathGetter, unrecognizedStrategy);
return;
}
T value;
- LoadFromSource(value, std::move(source), path, unrecognizedStrategy);
+ LoadFromSource(value, std::move(source), pathGetter, unrecognizedStrategy);
parameter = std::move(value);
} catch (const std::exception& ex) {
- THROW_ERROR_EXCEPTION("Error loading parameter %v", path)
+ THROW_ERROR_EXCEPTION("Error loading parameter %v", pathGetter())
<< ex;
}
}
@@ -405,7 +405,7 @@ template <CYsonStructSource TSource, CStdVector TVector>
void LoadFromSource(
TVector& parameter,
TSource source,
- const NYPath::TYPath& path,
+ const std::function<NYPath::TYPath()>& pathGetter,
std::optional<EUnrecognizedStrategy> unrecognizedStrategy)
{
using TTraits = TYsonSourceTraits<TSource>;
@@ -418,12 +418,14 @@ void LoadFromSource(
LoadFromSource(
vector.emplace_back(),
elementSource,
- path + "/" + NYPath::ToYPathLiteral(index),
+ [&] {
+ return pathGetter() + "/" + NYPath::ToYPathLiteral(index);
+ },
unrecognizedStrategy);
++index;
});
} catch (const std::exception& ex) {
- THROW_ERROR_EXCEPTION("Error loading parameter %v", path)
+ THROW_ERROR_EXCEPTION("Error loading parameter %v", pathGetter())
<< ex;
}
}
@@ -433,7 +435,7 @@ template <CYsonStructSource TSource, CAnyMap TMap>
void LoadFromSource(
TMap& parameter,
TSource source,
- const NYPath::TYPath& path,
+ const std::function<NYPath::TYPath()>& pathGetter,
std::optional<EUnrecognizedStrategy> unrecognizedStrategy)
{
using TTraits = TYsonSourceTraits<TSource>;
@@ -447,12 +449,14 @@ void LoadFromSource(
LoadFromSource(
value,
childSource,
- path + "/" + NYPath::ToYPathLiteral(key),
+ [&] {
+ return pathGetter() + "/" + NYPath::ToYPathLiteral(key);
+ },
unrecognizedStrategy);
map[DeserializeMapKey<TKey>(key)] = std::move(value);
});
} catch (const std::exception& ex) {
- THROW_ERROR_EXCEPTION("Error loading parameter %v", path)
+ THROW_ERROR_EXCEPTION("Error loading parameter %v", pathGetter())
<< ex;
}
}
@@ -495,7 +499,7 @@ struct TGetRecursiveUnrecognized<TIntrusivePtr<T>>
template <class T>
inline void PostprocessRecursive(
T&,
- const NYPath::TYPath&)
+ const std::function<NYPath::TYPath()>&)
{
// Random class is not postprocessed.
}
@@ -503,22 +507,22 @@ inline void PostprocessRecursive(
template <CExternallySerializable T>
inline void PostprocessRecursive(
T& parameter,
- const NYPath::TYPath& path)
+ const std::function<NYPath::TYPath()>& pathGetter)
{
using TTraits = TGetExternalizedYsonStructTraits<T>;
using TSerializer = typename TTraits::TExternalSerializer;
auto serializer = TSerializer::template CreateWritable<T, TSerializer>(parameter, false);
- serializer.Postprocess(path);
+ serializer.Postprocess(pathGetter);
}
// TYsonStruct
template <std::derived_from<TYsonStruct> T>
inline void PostprocessRecursive(
TIntrusivePtr<T>& parameter,
- const NYPath::TYPath& path)
+ const std::function<NYPath::TYPath()>& pathGetter)
{
if (parameter) {
- parameter->Postprocess(path);
+ parameter->Postprocess(pathGetter);
}
}
@@ -526,19 +530,19 @@ inline void PostprocessRecursive(
template <std::derived_from<TYsonStructLite> T>
inline void PostprocessRecursive(
T& parameter,
- const NYPath::TYPath& path)
+ const std::function<NYPath::TYPath()>& pathGetter)
{
- parameter.Postprocess(path);
+ parameter.Postprocess(pathGetter);
}
// std::optional
template <class T>
inline void PostprocessRecursive(
std::optional<T>& parameter,
- const NYPath::TYPath& path)
+ const std::function<NYPath::TYPath()>& pathGetter)
{
if (parameter.has_value()) {
- PostprocessRecursive(*parameter, path);
+ PostprocessRecursive(*parameter, pathGetter);
}
}
@@ -546,12 +550,14 @@ inline void PostprocessRecursive(
template <CStdVector TVector>
inline void PostprocessRecursive(
TVector& parameter,
- const NYPath::TYPath& path)
+ const std::function<NYPath::TYPath()>& pathGetter)
{
for (size_t i = 0; i < parameter.size(); ++i) {
PostprocessRecursive(
parameter[i],
- path + "/" + NYPath::ToYPathLiteral(i));
+ [&] {
+ return pathGetter() + "/" + NYPath::ToYPathLiteral(i);
+ });
}
}
@@ -559,12 +565,14 @@ inline void PostprocessRecursive(
template <CAnyMap TMap>
inline void PostprocessRecursive(
TMap& parameter,
- const NYPath::TYPath& path)
+ const std::function<NYPath::TYPath()>& pathGetter)
{
for (auto& [key, value] : parameter) {
PostprocessRecursive(
value,
- path + "/" + NYPath::ToYPathLiteral(key));
+ [&pathGetter, &key = key] {
+ return pathGetter() + "/" + NYPath::ToYPathLiteral(key);
+ });
}
}
@@ -825,7 +833,7 @@ void TYsonStructParameter<TValue>::Load(
NPrivate::LoadFromSource(
FieldAccessor_->GetValue(self),
std::move(node),
- options.Path,
+ options.PathGetter,
unrecognizedStrategy);
if (auto* bitmap = self->GetSetFieldsBitmap()) {
@@ -833,7 +841,7 @@ void TYsonStructParameter<TValue>::Load(
}
} else if (!Optional_) {
THROW_ERROR_EXCEPTION("Missing required parameter %v",
- options.Path);
+ options.PathGetter());
}
}
@@ -857,7 +865,7 @@ void TYsonStructParameter<TValue>::Load(
NPrivate::LoadFromSource(
FieldAccessor_->GetValue(self),
cursor,
- options.Path,
+ options.PathGetter,
unrecognizedStrategy);
if (auto* bitmap = self->GetSetFieldsBitmap()) {
@@ -865,7 +873,7 @@ void TYsonStructParameter<TValue>::Load(
}
} else if (!Optional_) {
THROW_ERROR_EXCEPTION("Missing required parameter %v",
- options.Path);
+ options.PathGetter());
}
}
@@ -883,7 +891,7 @@ void TYsonStructParameter<TValue>::SafeLoad(
NPrivate::LoadFromSource(
FieldAccessor_->GetValue(self),
node,
- options.Path,
+ options.PathGetter,
/*recursivelyUnrecognizedStrategy*/ std::nullopt);
validate();
@@ -898,17 +906,17 @@ void TYsonStructParameter<TValue>::SafeLoad(
}
template <class TValue>
-void TYsonStructParameter<TValue>::PostprocessParameter(const TYsonStructBase* self, const NYPath::TYPath& path) const
+void TYsonStructParameter<TValue>::PostprocessParameter(const TYsonStructBase* self, const std::function<NYPath::TYPath()>& pathGetter) const
{
TValue& value = FieldAccessor_->GetValue(self);
- NPrivate::PostprocessRecursive(value, path);
+ NPrivate::PostprocessRecursive(value, pathGetter);
for (const auto& validator : Validators_) {
try {
validator(value);
} catch (const std::exception& ex) {
THROW_ERROR_EXCEPTION("Validation failed at %v",
- path.empty() ? "root" : path)
+ !pathGetter ? "root" : pathGetter())
<< ex;
}
}
diff --git a/yt/yt/core/ytree/yson_struct_detail.cpp b/yt/yt/core/ytree/yson_struct_detail.cpp
index 8f136387d15..2adc349726f 100644
--- a/yt/yt/core/ytree/yson_struct_detail.cpp
+++ b/yt/yt/core/ytree/yson_struct_detail.cpp
@@ -76,7 +76,9 @@ void TYsonStructMeta::LoadParameter(TYsonStructBase* target, const std::string&
{
const auto& parameter = GetParameter(key);
auto validate = [&] {
- parameter->PostprocessParameter(target, "/" + key);
+ parameter->PostprocessParameter(target, [&] {
+ return "/" + key;
+ });
try {
for (const auto& postprocessor : Postprocessors_) {
postprocessor(target);
@@ -90,16 +92,18 @@ void TYsonStructMeta::LoadParameter(TYsonStructBase* target, const std::string&
}
};
auto loadOptions = TLoadParameterOptions{
- .Path = "",
+ .PathGetter = {},
};
parameter->SafeLoad(target, node, loadOptions, validate);
}
-void TYsonStructMeta::PostprocessStruct(TYsonStructBase* target, const TYPath& path) const
+void TYsonStructMeta::PostprocessStruct(TYsonStructBase* target, const std::function<TYPath()>& pathGetter) const
{
for (const auto& [name, parameter] : SortedParameters_) {
- parameter->PostprocessParameter(target, path + "/" + ToYPathLiteral(name));
+ parameter->PostprocessParameter(target, [&] {
+ return (pathGetter ? pathGetter() : TYPath("")) + "/" + ToYPathLiteral(name);
+ });
}
try {
@@ -108,7 +112,7 @@ void TYsonStructMeta::PostprocessStruct(TYsonStructBase* target, const TYPath& p
}
} catch (const std::exception& ex) {
THROW_ERROR_EXCEPTION("Postprocess failed at %v",
- path.empty() ? "root" : path)
+ !pathGetter ? "root" : pathGetter())
<< ex;
}
}
@@ -118,7 +122,7 @@ void TYsonStructMeta::LoadStruct(
INodePtr node,
bool postprocess,
bool setDefaults,
- const TYPath& path) const
+ const std::function<TYPath()>& pathGetter) const
{
YT_VERIFY(*StructType_ == typeid(*target));
YT_VERIFY(node);
@@ -145,7 +149,9 @@ void TYsonStructMeta::LoadStruct(
}
}
auto loadOptions = TLoadParameterOptions{
- .Path = path + "/" + ToYPathLiteral(key),
+ .PathGetter = [&] {
+ return (pathGetter ? pathGetter() : TYPath("")) + "/" + ToYPathLiteral(key);
+ },
.RecursiveUnrecognizedRecursively = GetRecursiveUnrecognizedStrategy(unrecognizedStrategy),
};
parameter->Load(target, child, loadOptions);
@@ -159,6 +165,7 @@ void TYsonStructMeta::LoadStruct(
for (const auto& [key, child] : mapNode->GetChildren()) {
if (!registeredKeys.contains(key)) {
if (ShouldThrow(unrecognizedStrategy)) {
+ auto path = (pathGetter ? pathGetter() : TYPath(""));
THROW_ERROR_EXCEPTION("Unrecognized field %Qv has been encountered", path + "/" + ToYPathLiteral(key))
<< TErrorAttribute("key", key)
<< TErrorAttribute("path", path);
@@ -170,7 +177,7 @@ void TYsonStructMeta::LoadStruct(
}
if (postprocess) {
- PostprocessStruct(target, path);
+ PostprocessStruct(target, pathGetter);
}
}
@@ -179,7 +186,7 @@ void TYsonStructMeta::LoadStruct(
NYson::TYsonPullParserCursor* cursor,
bool postprocess,
bool setDefaults,
- const TYPath& path) const
+ const std::function<TYPath()>& pathGetter) const
{
YT_VERIFY(*StructType_ == typeid(*target));
YT_VERIFY(cursor);
@@ -192,7 +199,9 @@ void TYsonStructMeta::LoadStruct(
auto createLoadOptions = [&] (TStringBuf key) {
return TLoadParameterOptions{
- .Path = path + "/" + ToYPathLiteral(key),
+ .PathGetter = [&pathGetter, key] {
+ return (pathGetter ? pathGetter() : TYPath("")) + "/" + ToYPathLiteral(key);
+ },
.RecursiveUnrecognizedRecursively = GetRecursiveUnrecognizedStrategy(unrecognizedStrategy),
};
};
@@ -247,6 +256,7 @@ void TYsonStructMeta::LoadStruct(
return;
}
if (ShouldThrow(unrecognizedStrategy)) {
+ auto path = (pathGetter ? pathGetter() : TYPath(""));
THROW_ERROR_EXCEPTION("Unrecognized field %Qv has been encountered", path + "/" + ToYPathLiteral(key))
<< TErrorAttribute("key", key)
<< TErrorAttribute("path", path);
@@ -286,7 +296,7 @@ void TYsonStructMeta::LoadStruct(
}
if (postprocess) {
- PostprocessStruct(target, path);
+ PostprocessStruct(target, pathGetter);
}
}
diff --git a/yt/yt/core/ytree/yson_struct_detail.h b/yt/yt/core/ytree/yson_struct_detail.h
index 150c0e6254e..3f5f73c91b4 100644
--- a/yt/yt/core/ytree/yson_struct_detail.h
+++ b/yt/yt/core/ytree/yson_struct_detail.h
@@ -64,7 +64,7 @@ ITypeErasedYsonStructFieldPtr CreateTypeErasedYsonStructField(TYsonStructField<T
struct TLoadParameterOptions
{
- NYPath::TYPath Path;
+ std::function<NYPath::TYPath()> PathGetter;
std::optional<EUnrecognizedStrategy> RecursiveUnrecognizedRecursively;
};
@@ -91,7 +91,7 @@ struct IYsonStructParameter
virtual void Save(const TYsonStructBase* self, NYson::IYsonConsumer* consumer) const = 0;
- virtual void PostprocessParameter(const TYsonStructBase* self, const NYPath::TYPath& path) const = 0;
+ virtual void PostprocessParameter(const TYsonStructBase* self, const std::function<NYPath::TYPath()>& pathGetter) const = 0;
virtual void SetDefaultsInitialized(TYsonStructBase* self) = 0;
@@ -122,7 +122,7 @@ struct IYsonStructMeta
virtual const std::vector<std::pair<std::string, IYsonStructParameterPtr>>& GetParameterSortedList() const = 0;
virtual void SetDefaultsOfInitializedStruct(TYsonStructBase* target) const = 0;
virtual const THashSet<std::string>& GetRegisteredKeys() const = 0;
- virtual void PostprocessStruct(TYsonStructBase* target, const TYPath& path) const = 0;
+ virtual void PostprocessStruct(TYsonStructBase* target, const std::function<NYPath::TYPath()>& pathGetter) const = 0;
virtual IYsonStructParameterPtr GetParameter(const std::string& keyOrAlias) const = 0;
virtual void LoadParameter(TYsonStructBase* target, const std::string& key, const NYTree::INodePtr& node) const = 0;
@@ -131,14 +131,14 @@ struct IYsonStructMeta
INodePtr node,
bool postprocess,
bool setDefaults,
- const TYPath& path) const = 0;
+ const std::function<NYPath::TYPath()>& pathGetter) const = 0;
virtual void LoadStruct(
TYsonStructBase* target,
NYson::TYsonPullParserCursor* cursor,
bool postprocess,
bool setDefaults,
- const TYPath& path) const = 0;
+ const std::function<NYPath::TYPath()>& pathGetter) const = 0;
virtual IMapNodePtr GetRecursiveUnrecognized(const TYsonStructBase* target) const = 0;
@@ -171,21 +171,21 @@ public:
IYsonStructParameterPtr GetParameter(const std::string& keyOrAlias) const override;
void LoadParameter(TYsonStructBase* target, const std::string& key, const NYTree::INodePtr& node) const override;
- void PostprocessStruct(TYsonStructBase* target, const TYPath& path) const override;
+ void PostprocessStruct(TYsonStructBase* target, const std::function<NYPath::TYPath()>& pathGetter) const override;
void LoadStruct(
TYsonStructBase* target,
INodePtr node,
bool postprocess,
bool setDefaults,
- const TYPath& path) const override;
+ const std::function<NYPath::TYPath()>& pathGetter) const override;
void LoadStruct(
TYsonStructBase* target,
NYson::TYsonPullParserCursor* cursor,
bool postprocess,
bool setDefaults,
- const TYPath& path) const override;
+ const std::function<NYPath::TYPath()>& pathGetter) const override;
IMapNodePtr GetRecursiveUnrecognized(const TYsonStructBase* target) const override;
@@ -293,7 +293,7 @@ public:
const TLoadParameterOptions& options,
const std::function<void()>& validate) override;
- void PostprocessParameter(const TYsonStructBase* self, const NYPath::TYPath& path) const override;
+ void PostprocessParameter(const TYsonStructBase* self, const std::function<NYPath::TYPath()>& pathGetter) const override;
void SetDefaultsInitialized(TYsonStructBase* self) override;
void Save(const TYsonStructBase* self, NYson::IYsonConsumer* consumer) const override;
bool CanOmitValue(const TYsonStructBase* self) const override;
diff --git a/yt/yt/library/formats/arrow_parser.cpp b/yt/yt/library/formats/arrow_parser.cpp
index 7064fb39f94..eb0bfb10914 100644
--- a/yt/yt/library/formats/arrow_parser.cpp
+++ b/yt/yt/library/formats/arrow_parser.cpp
@@ -386,6 +386,13 @@ void CheckArrowTypeMatch(
break;
case ESimpleLogicalValueType::Interval64:
+ case ESimpleLogicalValueType::TzDate:
+ case ESimpleLogicalValueType::TzDatetime:
+ case ESimpleLogicalValueType::TzTimestamp:
+ case ESimpleLogicalValueType::TzDate32:
+ case ESimpleLogicalValueType::TzDatetime64:
+ case ESimpleLogicalValueType::TzTimestamp64:
+ // TODO(nadya02): YT-15805: Support tz types.
THROW_ERROR_EXCEPTION("Unexpected column type %Qv",
columnType);
}
diff --git a/yt/yt/library/formats/skiff_parser.cpp b/yt/yt/library/formats/skiff_parser.cpp
index cf4c74c885c..299a4162212 100644
--- a/yt/yt/library/formats/skiff_parser.cpp
+++ b/yt/yt/library/formats/skiff_parser.cpp
@@ -276,6 +276,14 @@ TSkiffToUnversionedValueConverter CreateSimpleValueConverter(
} else {
return CreatePrimitiveTypeConverter(wireType, required, columnId, ysonConverter);
}
+ case ESimpleLogicalValueType::TzDate:
+ case ESimpleLogicalValueType::TzDatetime:
+ case ESimpleLogicalValueType::TzTimestamp:
+ case ESimpleLogicalValueType::TzDate32:
+ case ESimpleLogicalValueType::TzDatetime64:
+ case ESimpleLogicalValueType::TzTimestamp64:
+ // TODO(nadya02): YT-15805: Support tz types.
+ THROW_ERROR_EXCEPTION("Tz types are not supported now");
}
}
diff --git a/yt/yt/library/formats/skiff_writer.cpp b/yt/yt/library/formats/skiff_writer.cpp
index 86315ea7166..b8f6feb27ac 100644
--- a/yt/yt/library/formats/skiff_writer.cpp
+++ b/yt/yt/library/formats/skiff_writer.cpp
@@ -455,6 +455,14 @@ TUnversionedValueToSkiffConverter CreateSimpleValueConverter(
} else {
return CreatePrimitiveValueConverter(wireType, required);
}
+ case ESimpleLogicalValueType::TzDate:
+ case ESimpleLogicalValueType::TzDatetime:
+ case ESimpleLogicalValueType::TzTimestamp:
+ case ESimpleLogicalValueType::TzDate32:
+ case ESimpleLogicalValueType::TzDatetime64:
+ case ESimpleLogicalValueType::TzTimestamp64:
+ // TODO(nadya02): YT-15805: Support tz types.
+ THROW_ERROR_EXCEPTION("Tz types are not supported now");
}
}
diff --git a/yt/yt/library/formats/skiff_yson_converter.cpp b/yt/yt/library/formats/skiff_yson_converter.cpp
index ebde4dcb3d9..76797b7fd8f 100644
--- a/yt/yt/library/formats/skiff_yson_converter.cpp
+++ b/yt/yt/library/formats/skiff_yson_converter.cpp
@@ -722,6 +722,14 @@ TYsonToSkiffConverter CreateSimpleYsonToSkiffConverter(
case ESimpleLogicalValueType::Interval64:
CheckWireType(wireType, {EWireType::Int32, EWireType::Int64, EWireType::String32});
return CreatePrimitiveTypeYsonToSkiffConverter(std::move(descriptor), wireType);
+ case ESimpleLogicalValueType::TzDate32:
+ case ESimpleLogicalValueType::TzDatetime64:
+ case ESimpleLogicalValueType::TzTimestamp64:
+ case ESimpleLogicalValueType::TzDate:
+ case ESimpleLogicalValueType::TzDatetime:
+ case ESimpleLogicalValueType::TzTimestamp:
+ // TODO(nadya02): YT-15805: support tz types.
+ THROW_ERROR_EXCEPTION("Tz types are not supported now");
}
} catch (const std::exception& ex) {
RethrowCannotMatchField(descriptor, skiffSchema, ex);
@@ -1430,6 +1438,14 @@ TSkiffToYsonConverter CreateSimpleSkiffToYsonConverter(
case ESimpleLogicalValueType::Interval64:
CheckWireType(wireType, {EWireType::Int32, EWireType::Int64, EWireType::String32});
return CreatePrimitiveTypeSkiffToYsonConverter(wireType);
+ case ESimpleLogicalValueType::TzDate:
+ case ESimpleLogicalValueType::TzDatetime:
+ case ESimpleLogicalValueType::TzTimestamp:
+ case ESimpleLogicalValueType::TzDate32:
+ case ESimpleLogicalValueType::TzDatetime64:
+ case ESimpleLogicalValueType::TzTimestamp64:
+ // TODO(nadya02): YT-15805: Support tz types.
+ THROW_ERROR_EXCEPTION("Tz types are not supported now");
}
YT_ABORT();
} catch (const std::exception& ex) {
diff --git a/yt/yt/library/formats/unittests/skiff_format_ut.cpp b/yt/yt/library/formats/unittests/skiff_format_ut.cpp
index 9bc6204ff83..aede7270d0f 100644
--- a/yt/yt/library/formats/unittests/skiff_format_ut.cpp
+++ b/yt/yt/library/formats/unittests/skiff_format_ut.cpp
@@ -629,6 +629,10 @@ public:
}
for (const auto type : TEnumTraits<ESimpleLogicalValueType>::GetDomainValues()) {
+ if (IsTzType(SimpleLogicalType(type))) {
+ // TODO(nadya02): YT-15805: Support tz types.
+ continue;
+ }
auto logicalType = OptionalLogicalType(SimpleLogicalType(type));
if (IsV3Composite(logicalType)) {
// Optional<Null> is not v1 type
diff --git a/yt/yt/library/formats/unittests/value_examples.cpp b/yt/yt/library/formats/unittests/value_examples.cpp
index da41a6341e8..335ac6c3b5c 100644
--- a/yt/yt/library/formats/unittests/value_examples.cpp
+++ b/yt/yt/library/formats/unittests/value_examples.cpp
@@ -151,10 +151,11 @@ std::vector<TValueExample> GetPrimitiveValueExamples()
allValueTypes.erase(example.LogicalType->AsSimpleTypeRef().GetElement());
}
}
- if (!allValueTypes.empty()) {
- THROW_ERROR_EXCEPTION("PrimitiveTypeExample variable doesn't contain values: %v",
- allValueTypes);
- }
+ // TODO(nadya02): YT-15805: Support tz types.
+ // if (!allValueTypes.empty()) {
+ // THROW_ERROR_EXCEPTION("PrimitiveTypeExample variable doesn't contain values: %v",
+ // allValueTypes);
+ // }
return valueExamples;
}
diff --git a/yt/yt/library/formats/web_json_writer.cpp b/yt/yt/library/formats/web_json_writer.cpp
index 3458af2efc1..f15570aa539 100644
--- a/yt/yt/library/formats/web_json_writer.cpp
+++ b/yt/yt/library/formats/web_json_writer.cpp
@@ -157,6 +157,18 @@ TStringBuf GetSimpleYqlTypeName(ESimpleLogicalValueType type)
return TStringBuf("Timestamp64");
case ESimpleLogicalValueType::Interval64:
return TStringBuf("Interval64");
+ case ESimpleLogicalValueType::TzDate:
+ return TStringBuf("TzDate");
+ case ESimpleLogicalValueType::TzDatetime:
+ return TStringBuf("TzDatetime");
+ case ESimpleLogicalValueType::TzTimestamp:
+ return TStringBuf("TzTimestamp");
+ case ESimpleLogicalValueType::TzDate32:
+ return TStringBuf("TzDate32");
+ case ESimpleLogicalValueType::TzDatetime64:
+ return TStringBuf("TzDatetime64");
+ case ESimpleLogicalValueType::TzTimestamp64:
+ return TStringBuf("TzTimestamp64");
case ESimpleLogicalValueType::Null:
case ESimpleLogicalValueType::Void:
// This case must have been processed earlier.
diff --git a/yt/yt/library/logical_type_shortcuts/logical_type_shortcuts.h b/yt/yt/library/logical_type_shortcuts/logical_type_shortcuts.h
index 1dddc290ace..025b6b5b541 100644
--- a/yt/yt/library/logical_type_shortcuts/logical_type_shortcuts.h
+++ b/yt/yt/library/logical_type_shortcuts/logical_type_shortcuts.h
@@ -51,6 +51,13 @@ CREATE_SIMPLE_TYPE_FUNCTION(Datetime64)
CREATE_SIMPLE_TYPE_FUNCTION(Timestamp64)
CREATE_SIMPLE_TYPE_FUNCTION(Interval64)
+CREATE_SIMPLE_TYPE_FUNCTION(TzDate)
+CREATE_SIMPLE_TYPE_FUNCTION(TzDatetime)
+CREATE_SIMPLE_TYPE_FUNCTION(TzTimestamp)
+CREATE_SIMPLE_TYPE_FUNCTION(TzDate32)
+CREATE_SIMPLE_TYPE_FUNCTION(TzDatetime64)
+CREATE_SIMPLE_TYPE_FUNCTION(TzTimestamp64)
+
#undef CREATE_SIMPLE_TYPE_FUNCTION
////////////////////////////////////////////////////////////////////////////////
diff --git a/yt/yt/library/tz_types/tz_types-inl.h b/yt/yt/library/tz_types/tz_types-inl.h
new file mode 100644
index 00000000000..1e0cb22c2da
--- /dev/null
+++ b/yt/yt/library/tz_types/tz_types-inl.h
@@ -0,0 +1,162 @@
+#ifndef TIMEZONE_HELPER_INL_H_
+#error "Direct inclusion of this file is not allowed, include timezone_helper.h.h"
+#include "tz_types.h"
+#endif
+
+#include <library/cpp/type_info/tz/tz.h>
+
+namespace NYT::NTzTypes {
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace {
+
+class TTzRegistry
+{
+public:
+ TTzRegistry()
+ {
+ const auto timezones = NTi::GetTimezones();
+ TzBuffer_.resize(timezones.size());
+ for (int index = 0; index < std::ssize(timezones); ++index) {
+ TzBuffer_[index] = std::string(timezones[index]);
+ if (!timezones[index].empty()) {
+ NameToTimezoneIndex_[std::string_view(TzBuffer_[index])] = index;
+ }
+ }
+ }
+
+ int GetTzIndex(std::string_view timezoneName) const
+ {
+ auto result = NameToTimezoneIndex_.find(timezoneName);
+ if (result == NameToTimezoneIndex_.end()) {
+ THROW_ERROR_EXCEPTION("Invalid timezone name")
+ << TErrorAttribute("timezone_name", timezoneName);
+ }
+ return result->second;
+ }
+
+ std::string_view GetTzName(int index) const
+ {
+ if (index < 0 || index >= std::ssize(TzBuffer_)) {
+ THROW_ERROR_EXCEPTION("Invalid timezone index, value %v not in range [0:%v]",
+ index,
+ std::ssize(TzBuffer_) - 1)
+ << TErrorAttribute("timezone_index", index);
+ }
+ if (TzBuffer_[index].empty()) {
+ THROW_ERROR_EXCEPTION("Index of an empty timezone is not valid")
+ << TErrorAttribute("timezone_index", index);
+ }
+ return TzBuffer_[index];
+ }
+
+ void ValidateTzName(std::string_view timezoneName) const
+ {
+ auto result = NameToTimezoneIndex_.find(timezoneName);
+ if (result == NameToTimezoneIndex_.end()) {
+ THROW_ERROR_EXCEPTION("Invalid timezone name")
+ << TErrorAttribute("timezone_name", timezoneName);
+ }
+ }
+
+private:
+ THashMap<std::string_view, int> NameToTimezoneIndex_;
+ std::vector<std::string> TzBuffer_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+inline std::string_view ParseTzNameFromTzString(std::string_view tzString, int byteCount)
+{
+ YT_VERIFY(byteCount <= std::ssize(tzString));
+ return tzString.substr(byteCount);
+}
+
+template <typename T>
+T FlipHighestBit(T value)
+{
+ constexpr size_t bitCount = sizeof(T) * 8;
+ return value ^ (T(1) << (bitCount - 1));
+}
+
+template <typename T>
+T ParseTimestampFromTzString(std::string_view tzString, bool isSigned)
+{
+ constexpr size_t byteCount = sizeof(T);
+ if (byteCount > tzString.size()) {
+ THROW_ERROR_EXCEPTION("The number of bytes in the tz time string is not sufficient")
+ << TErrorAttribute("actual_byte_coun", tzString.size())
+ << TErrorAttribute("min_expected_bytes_count", byteCount);
+ }
+ auto byteDate = std::string(std::make_reverse_iterator(tzString.begin() + byteCount),
+ std::make_reverse_iterator(tzString.begin()));
+ auto value = ReadUnaligned<T>(byteDate.data());
+ return isSigned ? FlipHighestBit(value) : value;
+}
+
+template <typename T>
+T ParseTimestampFromTzString(std::string_view tzString)
+{
+ if constexpr (std::is_signed_v<T>) {
+ return ParseTimestampFromTzString<T>(tzString, true);
+ } else {
+ return ParseTimestampFromTzString<T>(tzString, false);
+ }
+}
+
+} // namespace
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <typename T>
+TTZItem<T> ParseTzValue(std::string_view tzString)
+{
+ return TTZItem<T>({ParseTimestampFromTzString<T>(tzString), ParseTzNameFromTzString(tzString, sizeof(T))});
+}
+
+inline void ValidateTzName(std::string_view tzName)
+{
+ Singleton<TTzRegistry>()->ValidateTzName(tzName);
+}
+
+template <typename T>
+std::string_view MakeTzString(T timeValue, std::string_view tzName, char* buffer, size_t bufferSize)
+{
+ YT_VERIFY(bufferSize >= sizeof(T) + tzName.size());
+
+ auto converted = timeValue;
+ if constexpr (std::is_signed_v<T>) {
+ converted = FlipHighestBit<T>(timeValue);
+ }
+ // Make big-endian representation of numeric value.
+ auto* bytes = reinterpret_cast<unsigned char*>(&converted);
+ std::reverse(bytes, bytes + sizeof(T));
+
+ std::memcpy(buffer, &converted, sizeof(T));
+ std::memcpy(buffer + sizeof(T), tzName.data(), tzName.size());
+ return std::string_view(buffer, sizeof(T) + tzName.size());
+}
+
+template <typename T>
+std::string MakeTzString(T timeValue, std::string_view tzName)
+{
+ std::string buffer;
+ buffer.resize(sizeof(T) + tzName.size());
+ Y_UNUSED(MakeTzString<T>(timeValue, tzName, buffer.data(), buffer.size()));
+ return buffer;
+}
+
+inline std::string_view GetTzName(int tzIndex)
+{
+ return Singleton<TTzRegistry>()->GetTzName(tzIndex);
+}
+
+inline int GetTzIndex(std::string_view tzName)
+{
+ return Singleton<TTzRegistry>()->GetTzIndex(tzName);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT::NTzTypes
diff --git a/yt/yt/library/tz_types/tz_types.cpp b/yt/yt/library/tz_types/tz_types.cpp
new file mode 100644
index 00000000000..62c3dc077f1
--- /dev/null
+++ b/yt/yt/library/tz_types/tz_types.cpp
@@ -0,0 +1 @@
+#include "tz_types.h"
diff --git a/yt/yt/library/tz_types/tz_types.h b/yt/yt/library/tz_types/tz_types.h
new file mode 100644
index 00000000000..4b53d59c271
--- /dev/null
+++ b/yt/yt/library/tz_types/tz_types.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include <library/cpp/yt/error/error.h>
+
+#include <string>
+
+namespace NYT::NTzTypes {
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <typename T>
+using TTZItem = std::pair<T, std::string_view>;
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <typename T>
+TTZItem<T> ParseTzValue(std::string_view tzString);
+
+template <typename T>
+std::string MakeTzString(T timeValue, std::string_view tzName);
+
+template <typename T>
+std::string_view MakeTzString(T timeValue, std::string_view tzName, char* buffer, size_t bufferSize);
+
+void ValidateTzName(std::string_view tzName);
+
+std::string_view GetTzName(int tzIndex);
+
+int GetTzIndex(std::string_view tzName);
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT::NTzTypes
+
+#define TIMEZONE_HELPER_INL_H_
+#include "tz_types-inl.h"
+#undef TIMEZONE_HELPER_INL_H_
diff --git a/yt/yt/library/tz_types/unittests/tz_ut.cpp b/yt/yt/library/tz_types/unittests/tz_ut.cpp
new file mode 100644
index 00000000000..7dd896d2a2f
--- /dev/null
+++ b/yt/yt/library/tz_types/unittests/tz_ut.cpp
@@ -0,0 +1,57 @@
+#include <yt/yt/library/tz_types/tz_types.h>
+
+#include <yt/yt/core/test_framework/framework.h>
+
+#include <string>
+
+namespace NYT::NTzTypes {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+
+TEST(TTzHelpers, Unsigned)
+{
+ ui32 timestamp = 42;
+ auto presortedString = MakeTzString<ui32>(timestamp, "Europe/Moscow");
+ ASSERT_EQ(presortedString.substr(4), "Europe/Moscow");
+ auto res = ParseTzValue<ui32>(presortedString);
+ ASSERT_EQ(timestamp, res.first);
+ ASSERT_EQ(res.second, "Europe/Moscow");
+}
+
+TEST(TTzHelpers, Signed)
+{
+ i32 timestamp = -42;
+ auto presortedString = MakeTzString<i32>(timestamp, "Europe/Moscow");
+ ASSERT_EQ(presortedString.substr(4), "Europe/Moscow");
+ auto res = ParseTzValue<i32>(presortedString);
+ ASSERT_EQ(timestamp, res.first);
+ ASSERT_EQ(res.second, "Europe/Moscow");
+}
+
+TEST(TTzHelpers, TzName)
+{
+ for (int i = 0; i < 5; i++) {
+ ASSERT_EQ(GetTzIndex(GetTzName(i)), i);
+ }
+}
+
+TEST(TTzHelpers, CorrectSort)
+{
+ // Make sure that our string representations are sorted correctly.
+ std::vector<i32> timestamps = {0, -1, -10, 4322, 12};
+ std::vector<std::string> presortedStrings;
+ for (auto timestamp : timestamps) {
+ presortedStrings.push_back(MakeTzString<i32>(timestamp, "Europe/Moscow"));
+ }
+ std::sort(timestamps.begin(), timestamps.end());
+ std::sort(presortedStrings.begin(), presortedStrings.end());
+ for (int i = 0; i < std::ssize(timestamps); i++) {
+ ASSERT_EQ(timestamps[i], ParseTzValue<i32>(presortedStrings[i]).first);
+ }
+}
+
+//////////////////////////////////////////////////////////
+
+} // namespace
+} // namespace NYT::NTzTypes
diff --git a/yt/yt/library/tz_types/unittests/ya.make b/yt/yt/library/tz_types/unittests/ya.make
new file mode 100644
index 00000000000..5695ba0c5d1
--- /dev/null
+++ b/yt/yt/library/tz_types/unittests/ya.make
@@ -0,0 +1,16 @@
+GTEST(unittester-library-decimal)
+
+INCLUDE(${ARCADIA_ROOT}/yt/ya_cpp.make.inc)
+
+SRCS(
+ tz_ut.cpp
+)
+
+INCLUDE(${ARCADIA_ROOT}/yt/opensource.inc)
+
+PEERDIR(
+ yt/yt/core/test_framework
+ yt/yt/library/tz_types
+)
+
+END()
diff --git a/yt/yt/library/tz_types/ya.make b/yt/yt/library/tz_types/ya.make
new file mode 100644
index 00000000000..327502a8e8a
--- /dev/null
+++ b/yt/yt/library/tz_types/ya.make
@@ -0,0 +1,19 @@
+LIBRARY()
+
+INCLUDE(${ARCADIA_ROOT}/yt/ya_cpp.make.inc)
+
+SRCS(
+ tz_types.cpp
+)
+
+PEERDIR(
+ library/cpp/type_info/tz
+ library/cpp/yt/memory
+ library/cpp/yt/error
+)
+
+END()
+
+RECURSE_FOR_TESTS(
+ unittests
+)