aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Smirnov <alex@ydb.tech>2025-03-04 16:15:41 +0000
committerAlexander Smirnov <alex@ydb.tech>2025-03-04 16:15:41 +0000
commitb21a377d1f5b24149cf65fd1f8feb44411ae38f9 (patch)
tree0459a651275d60cf60489d8142f20a8bd5e6a199
parent827cd39b843ead1adfaa20f8a55e2e17da62a4eb (diff)
parent00325857a11f51ad6b43a4d35f57e85e06866ab6 (diff)
downloadydb-b21a377d1f5b24149cf65fd1f8feb44411ae38f9.tar.gz
Merge pull request #15307 from ydb-platform/merge-libs-250304-1328
-rw-r--r--build/conf/autoincludes.json3
-rw-r--r--build/conf/java.conf39
-rw-r--r--build/conf/proto.conf2
-rw-r--r--build/export_generators/cmake/conanfile.py.jinja24
-rw-r--r--build/external_resources/ymake/public.resources.json10
-rw-r--r--build/external_resources/ymake/resources.json10
-rw-r--r--build/mapping.conf.json12
-rw-r--r--build/platform/test_tool/host.ya.make.inc10
-rw-r--r--build/platform/test_tool/host_os.ya.make.inc10
-rw-r--r--build/plugins/_dart_fields.py42
-rw-r--r--build/plugins/_requirements.py9
-rw-r--r--build/plugins/lib/nots/typescript/ts_config.py2
-rw-r--r--build/plugins/lib/test_const/__init__.py3
-rw-r--r--build/plugins/pybuild.py3
-rw-r--r--build/plugins/ytest.py7
-rw-r--r--build/ymake.core.conf4
-rw-r--r--contrib/libs/cxxsupp/libcxx/.yandex_meta/build.ym48
-rw-r--r--contrib/libs/cxxsupp/libcxx/glibcxx_eh_cxx17.cpp17
-rw-r--r--contrib/libs/cxxsupp/libcxx/ya.make47
-rw-r--r--contrib/libs/poco/Foundation/include/Poco/BufferedStreamBuf.h6
-rw-r--r--contrib/libs/re2/.yandex_meta/__init__.py2
-rw-r--r--contrib/libs/re2/include/re2/re2.h2
-rw-r--r--contrib/libs/re2/include/re2/regexp.h1
-rw-r--r--contrib/libs/re2/include/re2/walker-inl.h1
-rw-r--r--contrib/python/psutil/py3/.dist-info/METADATA24
-rw-r--r--contrib/python/psutil/py3/README.rst11
-rw-r--r--contrib/python/psutil/py3/patches/01-arcadia.patch14
-rw-r--r--contrib/python/psutil/py3/psutil/__init__.py323
-rw-r--r--contrib/python/psutil/py3/psutil/_common.py212
-rw-r--r--contrib/python/psutil/py3/psutil/_compat.py477
-rw-r--r--contrib/python/psutil/py3/psutil/_psaix.py62
-rw-r--r--contrib/python/psutil/py3/psutil/_psbsd.py102
-rw-r--r--contrib/python/psutil/py3/psutil/_pslinux.py427
-rw-r--r--contrib/python/psutil/py3/psutil/_psosx.py24
-rw-r--r--contrib/python/psutil/py3/psutil/_psposix.py62
-rw-r--r--contrib/python/psutil/py3/psutil/_pssunos.py101
-rw-r--r--contrib/python/psutil/py3/psutil/_psutil_common.c9
-rw-r--r--contrib/python/psutil/py3/psutil/_psutil_common.h21
-rw-r--r--contrib/python/psutil/py3/psutil/_psutil_linux.c51
-rw-r--r--contrib/python/psutil/py3/psutil/_psutil_osx.c46
-rw-r--r--contrib/python/psutil/py3/psutil/_psutil_posix.c47
-rw-r--r--contrib/python/psutil/py3/psutil/_psutil_windows.c35
-rw-r--r--contrib/python/psutil/py3/psutil/_pswindows.py220
-rw-r--r--contrib/python/psutil/py3/psutil/arch/linux/proc.c12
-rw-r--r--contrib/python/psutil/py3/psutil/arch/osx/disk.c6
-rw-r--r--contrib/python/psutil/py3/psutil/arch/osx/mem.c13
-rw-r--r--contrib/python/psutil/py3/psutil/arch/osx/proc.c4
-rw-r--r--contrib/python/psutil/py3/psutil/arch/windows/disk.c29
-rw-r--r--contrib/python/psutil/py3/psutil/arch/windows/net.c11
-rw-r--r--contrib/python/psutil/py3/psutil/arch/windows/proc.c4
-rw-r--r--contrib/python/psutil/py3/ya.make5
-rw-r--r--contrib/python/simplejson/py2/.dist-info/METADATA2
-rw-r--r--contrib/python/simplejson/py2/simplejson/__init__.py2
-rw-r--r--contrib/python/simplejson/py2/simplejson/_speedups.c34
-rw-r--r--contrib/python/simplejson/py2/simplejson/tests/test_dump.py6
-rw-r--r--contrib/python/simplejson/py2/ya.make2
-rw-r--r--contrib/python/simplejson/py3/.dist-info/METADATA2
-rw-r--r--contrib/python/simplejson/py3/simplejson/__init__.py2
-rw-r--r--contrib/python/simplejson/py3/simplejson/_speedups.c34
-rw-r--r--contrib/python/simplejson/py3/simplejson/tests/test_dump.py6
-rw-r--r--contrib/python/simplejson/py3/ya.make2
-rw-r--r--library/cpp/http/simple/http_client.cpp12
-rw-r--r--library/cpp/http/simple/http_client.h6
-rw-r--r--library/cpp/monlib/encode/buffered/buffered_encoder_base.cpp6
-rw-r--r--library/cpp/monlib/encode/buffered/buffered_encoder_base.h3
-rw-r--r--library/cpp/monlib/encode/fake/fake.cpp3
-rw-r--r--library/cpp/monlib/encode/protobuf/protobuf_encoder.cpp5
-rw-r--r--library/cpp/monlib/encode/protobuf/protos/samples.proto3
-rw-r--r--library/cpp/monlib/encode/spack/spack_v1_decoder.cpp8
-rw-r--r--library/cpp/monlib/encode/spack/spack_v1_encoder.cpp12
-rw-r--r--library/cpp/monlib/encode/spack/spack_v1_ut.cpp11
-rw-r--r--library/cpp/monlib/metrics/metric_consumer.h4
-rw-r--r--library/cpp/monlib/metrics/metric_registry.cpp182
-rw-r--r--library/cpp/monlib/metrics/metric_registry.h131
-rw-r--r--library/cpp/monlib/metrics/metric_registry_ut.cpp72
-rw-r--r--library/cpp/monlib/metrics/metric_sub_registry.h49
-rw-r--r--library/cpp/yt/memory/non_null_ptr-inl.h2
-rw-r--r--library/cpp/yt/memory/poison-inl.h60
-rw-r--r--library/cpp/yt/memory/poison.cpp64
-rw-r--r--library/cpp/yt/memory/poison.h25
-rw-r--r--library/cpp/yt/memory/range.h11
-rw-r--r--library/cpp/yt/memory/ya.make1
-rw-r--r--tools/cpp_style_checker/__main__.py4
-rwxr-xr-xya20
-rw-r--r--ydb/ci/rightlib.txt2
-rw-r--r--yql/essentials/core/facade/yql_facade.cpp1
-rw-r--r--yql/essentials/linters.make.inc0
-rw-r--r--yql/essentials/minikql/aligned_page_pool.cpp47
-rw-r--r--yql/essentials/minikql/aligned_page_pool.h6
-rw-r--r--yql/essentials/minikql/comp_nodes/mkql_apply.cpp17
-rw-r--r--yql/essentials/minikql/comp_nodes/mkql_dictitems.cpp19
-rw-r--r--yql/essentials/minikql/comp_nodes/mkql_factory.cpp1
-rw-r--r--yql/essentials/minikql/comp_nodes/mkql_replicate.cpp13
-rw-r--r--yql/essentials/minikql/comp_nodes/ut/mkql_chopper_ut.cpp4
-rw-r--r--yql/essentials/minikql/comp_nodes/ut/mkql_combine_ut.cpp4
-rw-r--r--yql/essentials/minikql/comp_nodes/ut/mkql_flatmap_ut.cpp3
-rw-r--r--yql/essentials/minikql/comp_nodes/ut/mkql_join_ut.cpp4
-rw-r--r--yql/essentials/minikql/comp_nodes/ut/mkql_map_join_ut.cpp4
-rw-r--r--yql/essentials/minikql/comp_nodes/ut/mkql_multimap_ut.cpp3
-rw-r--r--yql/essentials/minikql/comp_nodes/ut/mkql_wide_chopper_ut.cpp4
-rw-r--r--yql/essentials/minikql/comp_nodes/ut/mkql_wide_combine_ut.cpp3
-rw-r--r--yql/essentials/minikql/comp_nodes/ut/mkql_wide_condense_ut.cpp4
-rw-r--r--yql/essentials/minikql/comp_nodes/ut/mkql_wide_filter_ut.cpp4
-rw-r--r--yql/essentials/minikql/comp_nodes/ut/mkql_wide_map_ut.cpp4
-rw-r--r--yql/essentials/minikql/comp_nodes/ut/mkql_wide_nodes_ut.cpp4
-rw-r--r--yql/essentials/minikql/computation/mkql_block_reader.cpp18
-rw-r--r--yql/essentials/minikql/computation/mkql_block_transport.cpp56
-rw-r--r--yql/essentials/minikql/computation/mkql_block_trimmer.cpp16
-rw-r--r--yql/essentials/minikql/computation/mkql_computation_node_pack_ut.cpp15
-rw-r--r--yql/essentials/minikql/mkql_alloc.cpp97
-rw-r--r--yql/essentials/minikql/mkql_alloc.h9
-rw-r--r--yql/essentials/minikql/mkql_program_builder.cpp161
-rw-r--r--yql/essentials/minikql/mkql_type_builder.cpp43
-rw-r--r--yql/essentials/providers/common/mkql/yql_provider_mkql.cpp14
-rw-r--r--yql/essentials/providers/common/mkql/yql_type_mkql.cpp10
-rw-r--r--yql/essentials/providers/common/schema/mkql/yql_mkql_schema.cpp8
-rw-r--r--yql/essentials/public/issue/yql_warning.cpp8
-rw-r--r--yql/essentials/public/issue/yql_warning.h3
-rw-r--r--yql/essentials/public/udf/arrow/block_builder.h53
-rw-r--r--yql/essentials/public/udf/arrow/block_item.h12
-rw-r--r--yql/essentials/public/udf/arrow/block_item_comparator.h18
-rw-r--r--yql/essentials/public/udf/arrow/block_item_hasher.h8
-rw-r--r--yql/essentials/public/udf/arrow/block_reader.h51
-rw-r--r--yql/essentials/public/udf/arrow/dispatch_traits.h18
-rw-r--r--yql/essentials/public/udf/arrow/ut/array_builder_ut.cpp40
-rw-r--r--yql/essentials/public/udf/arrow/util.h15
-rw-r--r--yql/essentials/sql/settings/translation_settings.h1
-rw-r--r--yql/essentials/sql/v1/context.cpp1
-rw-r--r--yql/essentials/tests/sql/minirun/part0/canondata/result.json21
-rw-r--r--yql/essentials/tests/sql/minirun/part2/canondata/result.json21
-rw-r--r--yql/essentials/tests/sql/minirun/part7/canondata/result.json2
-rw-r--r--yql/essentials/tests/sql/minirun/part8/canondata/result.json42
-rw-r--r--yql/essentials/tests/sql/sql2yql/canondata/result.json50
-rw-r--r--yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_blocks-agg_singular_type_key_/formatted.sql72
-rw-r--r--yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_blocks-agg_singular_type_key_optional_/formatted.sql72
-rw-r--r--yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_blocks-agg_singular_type_value_/formatted.sql33
-rw-r--r--yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_blocks-agg_singular_type_value_optional_/formatted.sql33
-rw-r--r--yql/essentials/tests/sql/suites/blocks/agg_singular_type_key.sql23
-rw-r--r--yql/essentials/tests/sql/suites/blocks/agg_singular_type_key_optional.sql24
-rw-r--r--yql/essentials/tests/sql/suites/blocks/agg_singular_type_value.sql26
-rw-r--r--yql/essentials/tests/sql/suites/blocks/agg_singular_type_value_optional.sql27
-rw-r--r--yql/essentials/types/binary_json/ut/entry_ut.cpp23
-rw-r--r--yql/essentials/types/binary_json/write.cpp39
-rw-r--r--yql/essentials/types/binary_json/write.h11
-rw-r--r--yql/essentials/udfs/language/yql/yql_language_udf.cpp38
-rw-r--r--yt/yql/providers/yt/codec/yt_arrow_converter.cpp4
-rw-r--r--yt/yql/providers/yt/gateway/qplayer/yql_yt_qplayer_gateway.cpp2
-rw-r--r--yt/yt/client/table_client/config.cpp3
-rw-r--r--yt/yt/client/table_client/config.h1
-rw-r--r--yt/yt/client/table_client/helpers.cpp9
-rw-r--r--yt/yt/client/table_client/helpers.h1
-rw-r--r--yt/yt/core/concurrency/fair_throttler.cpp114
-rw-r--r--yt/yt/core/concurrency/fair_throttler.h30
-rw-r--r--yt/yt/core/concurrency/public.h4
-rw-r--r--yt/yt/core/concurrency/unittests/fair_throttler_ut.cpp16
-rw-r--r--yt/yt/core/http/server.cpp43
-rw-r--r--yt/yt/core/http/server.h6
-rw-r--r--yt/yt/core/http/stream.cpp25
-rw-r--r--yt/yt/core/http/stream.h11
-rw-r--r--yt/yt/core/https/server.cpp6
-rw-r--r--yt/yt/core/https/server.h5
-rw-r--r--yt/yt/core/ytree/fluent.h3
-rw-r--r--yt/yt/core/ytree/unittests/yson_struct_update_ut.cpp8
-rw-r--r--yt/yt/core/ytree/yson_struct_update-inl.h66
-rw-r--r--yt/yt/core/ytree/yson_struct_update.h36
165 files changed, 2825 insertions, 2403 deletions
diff --git a/build/conf/autoincludes.json b/build/conf/autoincludes.json
index 3d47744839..c5db9dcd61 100644
--- a/build/conf/autoincludes.json
+++ b/build/conf/autoincludes.json
@@ -1,6 +1,7 @@
[
"devtools/ya",
"library/cpp/geo",
- "util"
+ "util",
+ "yql/essentials"
]
diff --git a/build/conf/java.conf b/build/conf/java.conf
index f76b0cfc90..8a06527ba7 100644
--- a/build/conf/java.conf
+++ b/build/conf/java.conf
@@ -404,7 +404,7 @@ macro _JAVA_SRCS(RESOURCES?"yes":"no", SRCDIR=".", PACKAGE_PREFIX="", EXCLUDE[],
SET(VAR_SALT $SRCDIR $Globs $EXCLUDE $PACKAGE_PREFIX $RESOURCES $FILES)
SET(JAR_SRCS_GLOB uniq_${hash:VAR_SALT})
_LATE_GLOB(${JAR_SRCS_GLOB} ${pre=${SRCDIR}/:Globs} EXCLUDE ${EXCLUDE})
- SET_APPEND(LINT_JAVA_SOURCES \${rootrel;input;ext=.java:${JAR_SRCS_GLOB}})
+ SET_APPEND(LINT_JAVA_SOURCES \${rootrel;ext=.java;input:${JAR_SRCS_GLOB}})
SET_APPEND(ALL_JAR_SOURCES --jsources ${BINDIR}/misc/${tolower:JAR_SRCS_GLOB}.src.txt --resources ${BINDIR}/misc/${tolower:JAR_SRCS_GLOB}.res.txt --srcdir ${quo:SRCDIR} \${input:${JAR_SRCS_GLOB}} ${pre=\$\{input\:\";suf=\"\}:FILES})
_FILL_JAR_COPY_RESOURCES_CMD(LINK_JAR_RESOURCES ${quo:SRCDIR} ${BINDIR}/cls ${PACKAGE_PREFIX} ${BINDIR}/misc/${tolower:JAR_SRCS_GLOB}.res.txt)
_FILL_JAR_COPY_RESOURCES_CMD(LINK_JAR_JSOURCES ${quo:SRCDIR} ${BINDIR}/src ${PACKAGE_PREFIX} ${BINDIR}/misc/${tolower:JAR_SRCS_GLOB}.src.txt)
@@ -503,7 +503,7 @@ macro JAR_ANNOTATION_PROCESSOR(Classes...) {
# tag:java-specific
macro _JAR_ANN_PROC_OPTS(Classes...) {
- .CMD=$_JAR_ANN_PROC_OPT_PREFIX ${join=,:Classes} $_USE_ANNOTATION_PROCESSOR_OPT
+ .CMD=$_JAR_ANN_PROC_OPT_PREFIX ${hideempty;join=,:Classes} $_USE_ANNOTATION_PROCESSOR_OPT
}
# tag:java-specific
@@ -531,7 +531,8 @@ macro _NOOP_MACRO(Args...) {
# tag:java-specific
module _JAR_BASE: _BARE_UNIT {
.NODE_TYPE=Bundle
- .CMD=TOUCH_UNIT
+ .CMD=$TOUCH_UNIT
+ .STRUCT_CMD=yes
.PEERDIR_POLICY=as_build_from
.FINAL_TARGET=no
.ALIASES=SRCS=_SRCS_NO_GLOBAL
@@ -581,7 +582,7 @@ JAR_RESOURCE_ID=
SRC_RESOURCE_ID=
FETCH_SRCS_JAR=
FETCH_TARGET_JAR=
-FETCH_CONTRIB_JAR=${hide:JAVA_FAKEID} $FETCH_TARGET_JAR $FETCH_SRCS_JAR
+FETCH_CONTRIB_JAR=${hide:JAVA_FAKEID} && $FETCH_TARGET_JAR && $FETCH_SRCS_JAR
# tag:java-specific
macro JAR_RESOURCE(Id) {
@@ -613,14 +614,14 @@ _JAVA_CONTRIB_SEM= \
# tag:java-specific
module JAVA_CONTRIB: _JAR_BASE {
- .CMD=FETCH_CONTRIB_JAR
+ .CMD=$FETCH_CONTRIB_JAR
.PEERDIR_POLICY=as_include
.SEM=_JAVA_CONTRIB_SEM
.FINAL_TARGET=yes
.GLOBAL=MAVEN_EXPORT_COORDS
when ($JAR_RESOURCE_ID) {
- FETCH_TARGET_JAR= && $_FETCH_CONTRIB($JAR_RESOURCE_ID ${BINDIR}/${MODULE_PREFIX}${REALPRJNAME}${MODULE_SUFFIX})
+ FETCH_TARGET_JAR= && $_FETCH_CONTRIB($JAR_RESOURCE_ID ${MODULE_PREFIX}${REALPRJNAME}${MODULE_SUFFIX})
}
otherwise {
when ($LOCAL_JAR_PATH) {
@@ -770,14 +771,14 @@ macro _ADD_OPTS_IF_NON_EMPTY(Opt, Args...) {
.CMD=${pre=$Opt :Args}
}
macro _ADD_GEN_POM_FROM_COORD_FILES_ARGS(Deps...) {
- .CMD=${pre=--deps-coords ;ext=.jar;suf=.mvn_coords:Deps}
+ .CMD=${pre=--deps-coords ;suf=.mvn_coords;ext=.jar:Deps}
}
MAVEN_BIN=$MAVEN_RESOURCE_GLOBAL/bin/mvn
MAVEN_EXPORT_OUT_DIR_FLAG=$_ADD_OPTS_IF_NON_EMPTY(--output-dir ${MAVEN_EXPORT_OUT_DIR})
MAVEN_EXPORT_SOURCE_DIRS=$_ADD_OPTS_IF_NON_EMPTY(--source-dirs ${ALL_SRCDIRS})
-MAVEN_EXPORT_DEPS_COORS=$_ADD_GEN_POM_FROM_COORD_FILES_ARGS(${MANAGED_PEERS_CLOSURE})
+MAVEN_EXPORT_DEPS_COORS=$_ADD_GEN_POM_FROM_COORD_FILES_ARGS($MANAGED_PEERS_CLOSURE)
MAVEN_EXPORT_OUT_DIR=
MAVEN_EXPORT=no
@@ -1010,7 +1011,7 @@ _BUILD_PROTO_JAR_SEM= \
### Reimplementation of the JAVA_LIBRARY with ymake.core.conf and ymake based dependency management
module JAR_LIBRARY: _COMPILABLE_JAR_BASE {
.EXTS=.jsrc .java .jar .mf .gentar .kt
- .CMD=LINK_JAR
+ .CMD=$LINK_JAR
.SEM=_BUILD_JAR_SEM
.FINAL_TARGET=yes
.ALIASES=JAVA_SRCS=FULL_JAVA_SRCS ANNOTATION_PROCESSOR=JAR_ANNOTATION_PROCESSOR
@@ -1047,7 +1048,7 @@ module JAR_LIBRARY: _COMPILABLE_JAR_BASE {
# For Kapt usage see: https://kotlinlang.org/docs/kapt.html#using-in-cli
# See for kapt.kotlin.generated: https://github.com/JetBrains/kotlin/blob/master/plugins/kapt3/kapt3-cli/testData/integration/kotlinFileGeneration/build.txt
_KAPT_OPTS=-Xplugin=${tool:"contrib/java/org/jetbrains/kotlin/kotlin-annotation-processing/1.9.24"} $KT_KAPT_PLUGIN_OPTS
- _RUN_KAPT=${YMAKE_PYTHON} ${input:"build/scripts/with_kapt_args.py"} ${pre=--ap-classpath :KT_KAPT_AP_CLASSPATH} -- $COMPILE_KT $_KAPT_OPTS
+ _RUN_KAPT=${YMAKE_PYTHON} ${input:"build/scripts/with_kapt_args.py"} --ap-classpath ${KT_KAPT_AP_CLASSPATH} -- $COMPILE_KT $_KAPT_OPTS
_APPEND_KAPT_GENERATED_SRCS=$YMAKE_PYTHON3 ${input:"build/scripts/resolve_java_srcs.py"} -d $KT_KAPT_SOURCES_DIR --include-patterns '**/*.java' '**/*.kt' --resolve-kotlin --append -s ${BINDIR}/all-java.srclst -k $KT_SRCLIST -r ${BINDIR}/not-used.txt
ALL_KT_COMMANDS+=&& $_RUN_KAPT && $_APPEND_KAPT_GENERATED_SRCS
@@ -1179,7 +1180,7 @@ module JAR_LIBRARY: _COMPILABLE_JAR_BASE {
# tag:java-specific
_SCRIPTGEN_FLAGS=
macro _GEN_JAVA_SCRIPT_IMPL(Out, Template, Props...) {
- .CMD=$SCRIPTGEN_RESOURCE_GLOBAL/scriptgen --java $JDK_RESOURCE/bin/java --output ${output:Out} --template ${input:Template} ${_SCRIPTGEN_FLAGS} -D JAR_NAME=${REALPRJNAME}.jar -D CLASSPATH=${join;pre="::";nopath;ext=.jar:MANAGED_PEERS_CLOSURE} -D PROJECT_DIR=${MODDIR} -D JAR_BASENAME=${REALPRJNAME} -D MAIN_CLASS=${_JAR_MAIN_CLASS} -D ENABLE_PREVIEW_VALUE=${ENABLE_PREVIEW_VALUE} $Props
+ .CMD=$SCRIPTGEN_RESOURCE_GLOBAL/scriptgen --java $JDK_RESOURCE/bin/java --output ${output:Out} --template ${input:Template} ${_SCRIPTGEN_FLAGS} -D JAR_NAME=${REALPRJNAME}.jar -D CLASSPATH=${join=;pre=\:\:;nopath;ext=.jar:MANAGED_PEERS_CLOSURE} -D PROJECT_DIR=${MODDIR} -D JAR_BASENAME=${REALPRJNAME} -D MAIN_CLASS=${_JAR_MAIN_CLASS} -D ENABLE_PREVIEW_VALUE=${ENABLE_PREVIEW_VALUE} $Props
}
# tag:java-specific
@@ -1202,12 +1203,17 @@ when ($HOST_OS_WINDOWS == "yes") {
GEN_JAVA_RUN_SH=$SCRIPTGEN_RESOURCE_GLOBAL/scriptgen --java $JDK_RESOURCE/bin/java --output ${output:_GEN_JAVA_RUN_SH_OUTPUT} \
-D GENERATE_DEFAULT_RUNNER=yes \
-D JAR_NAME=${REALPRJNAME}.jar \
- -D CLASSPATH=${join;pre="::";nopath:MANAGED_PEERS_CLOSURE} \
+ -D CLASSPATH=${join=;pre=\:\:;nopath:MANAGED_PEERS_CLOSURE} \
-D PROJECT_DIR=${REALPRJNAME} \
-D JAR_BASENAME=${REALPRJNAME} \
-D MAIN_CLASS=${_JAR_MAIN_CLASS} \
-D ENABLE_PREVIEW=${ENABLE_PREVIEW_VALUE}
GEN_RUN_CP=${WRITER_PY} --file ${BINDIR}/run-bf.txt -Q -m --ya-start-command-file ${qe;pre=$REALPRJNAME/;nopath:MANAGED_PEERS_CLOSURE} --ya-end-command-file && ${YMAKE_PYTHON} ${input:"build/scripts/make_manifest_from_bf.py"} ${BINDIR}/run-bf.txt ${TARGET}
+COLLECT_JAR_PROGRAM_CP__LATEOUT__=\
+ ${pre=$BINDIR/$REALPRJNAME/;nopath;ext=.jar:MANAGED_PEERS_CLOSURE} \
+ ${pre=$BINDIR/$REALPRJNAME/;nopath;ext=.so:MANAGED_PEERS_CLOSURE} \
+ ${pre=$BINDIR/$REALPRJNAME/;nopath;ext=.dll:MANAGED_PEERS_CLOSURE} \
+ ${pre=$BINDIR/$REALPRJNAME/;nopath;ext=.dylib:MANAGED_PEERS_CLOSURE}
COLLECT_JAR_PROGRAM_CP=$FS_TOOLS link_or_copy_to_dir \
--ya-start-command-file \
${ext=.jar:MANAGED_PEERS_CLOSURE} \
@@ -1217,10 +1223,7 @@ COLLECT_JAR_PROGRAM_CP=$FS_TOOLS link_or_copy_to_dir \
${_SOURCE_JARS} \
--ya-end-command-file \
${BINDIR}/${REALPRJNAME} \
- ${hide;late_out;pre=$BINDIR/$REALPRJNAME/;nopath;ext=.jar:MANAGED_PEERS_CLOSURE} \
- ${hide;late_out;pre=$BINDIR/$REALPRJNAME/;nopath;ext=.so:MANAGED_PEERS_CLOSURE} \
- ${hide;late_out;pre=$BINDIR/$REALPRJNAME/;nopath;ext=.dll:MANAGED_PEERS_CLOSURE} \
- ${hide;late_out;pre=$BINDIR/$REALPRJNAME/;nopath;ext=.dylib:MANAGED_PEERS_CLOSURE}
+ ${hide;late_out:COLLECT_JAR_PROGRAM_CP__LATEOUT__}
MAKE_JAR_PROGRAM_CPLST=${MAKE_JAVA_CLASSPATH_FILE} --from-args ${output;pre=$MODULE_PREFIX;suf=${MODULE_SUFFIX}.cplst:REALPRJNAME} --ya-start-command-file ${rootrel;pre=$BINDIR/$REALPRJNAME/;nopath;ext=.jar:MANAGED_PEERS_CLOSURE} ${_SOURCE_JARS_CPLIST} --ya-end-command-file
TAR_CLASSPATH= && $YMAKE_PYTHON ${input:"build/scripts/find_and_tar.py"} ${output;pre=$MODULE_PREFIX;suf=.tar:REALPRJNAME} ${cwd;pre=$BINDIR/:REALPRJNAME}
DO_TAR_CLASSPATH=
@@ -1258,7 +1261,7 @@ macro _MARK_JAVA_PROG_WITH_SOURCES(Args...) {
# tag:java-specific
module _JAR_RUNNABLE: _COMPILABLE_JAR_BASE {
.FINAL_TARGET=yes
- .CMD=LINK_JAR_PROGRAM
+ .CMD=$LINK_JAR_PROGRAM
.SEM=_SEM_IGNORED
.ALIASES=JAVA_SRCS=_MARK_JAVA_PROG_WITH_SOURCES
.ALLOWED=WITH_JDK GENERATE_SCRIPT
@@ -1299,7 +1302,7 @@ module _JAR_RUNNABLE: _COMPILABLE_JAR_BASE {
LINK_JAR_TEST=${hide:JAVA_FAKEID} ${WRITER_PY} --file ${BINDIR}/run-bf.txt -Q -m --ya-start-command-file ${ext=.jar:MANAGED_PEERS_CLOSURE} --ya-end-command-file && ${YMAKE_PYTHON} ${input:"build/scripts/make_manifest_from_bf.py"} ${BINDIR}/run-bf.txt ${TARGET} ${hide;kv:"p JT"}
module _JAR_TEST: _COMPILABLE_JAR_BASE {
.FINAL_TARGET=yes
- .CMD=LINK_JAR_TEST
+ .CMD=$LINK_JAR_TEST
.DEFAULT_NAME_GENERATOR=FullPath
CONSUME_NON_MANAGEABLE_PEERS=yes
diff --git a/build/conf/proto.conf b/build/conf/proto.conf
index 356293d9d9..f79cd7ebdb 100644
--- a/build/conf/proto.conf
+++ b/build/conf/proto.conf
@@ -508,7 +508,7 @@ otherwise {
KOTLIN_PROTO_FLAGS=
# tag:proto tag:java-specific
macro _JAVA_PROTO_CMD(File) {
- .CMD=${cwd;rootdir;input:File} $YMAKE_PYTHON ${input:"build/scripts/tared_protoc.py"} --tar-output ${output;norel;nopath;noext;suf=.jsrc:File} --protoc-out-dir $ARCADIA_BUILD_ROOT/java_out $JAVA_PROTOC -I=./$PROTO_NAMESPACE ${pre=-I=:_PROTO__INCLUDE} -I=$ARCADIA_ROOT --java_out=${_JAVA_PROTO_LITE_ARG}$ARCADIA_BUILD_ROOT/java_out ${KOTLIN_PROTO_FLAGS} $_PROTOC_FLAGS ${input;rootrel:File} ${hide;kv:"p PB"} ${hide;kv:"pc yellow"} $JAVA_PROTO_ARGS ${hide:PROTO_FAKEID}
+ .CMD=${cwd;rootdir;input:File} $YMAKE_PYTHON ${input:"build/scripts/tared_protoc.py"} --tar-output ${output;norel;nopath;noext;suf=.jsrc:File} --protoc-out-dir $ARCADIA_BUILD_ROOT/java_out $JAVA_PROTOC -I=./$PROTO_NAMESPACE ${pre=-I=:_PROTO__INCLUDE} -I=$ARCADIA_ROOT --java_out=${_JAVA_PROTO_LITE_ARG}$ARCADIA_BUILD_ROOT/java_out ${KOTLIN_PROTO_FLAGS} $_PROTOC_FLAGS ${input;rootrel:File} ${hide;kv:"p PB"} ${hide;kv:"pc yellow"} $JAVA_PROTO_ARGS ${hide:PROTO_FAKEID} ${hide:"UID_BANHAMMER"}
.SEM=proto_files ${input;rootrel:File} ${hide;output:File.jsrc}
}
diff --git a/build/export_generators/cmake/conanfile.py.jinja b/build/export_generators/cmake/conanfile.py.jinja
index ca78850911..13717d007d 100644
--- a/build/export_generators/cmake/conanfile.py.jinja
+++ b/build/export_generators/cmake/conanfile.py.jinja
@@ -33,11 +33,13 @@ class App(ConanFile):
{%- endif -%}
{%- if (has_conan_os_depends_requires) -%}
-{%- for conan_os_depend in conan.os_depends|selectattr('requires') %}
-{%- if (conan_os_depend.requires|length) %}
- if self.settings.os == "{{ conan_os_depend.os }}":
-{%- for conan_require in conan_os_depend.requires %}
- self.requires("{{ conan_require }}")
+{%- set oses = conan.os_depends|selectattr('os')|map(attribute='os')|unique -%}
+{%- for os in oses %}
+{%- set os_requires = conan.os_depends|selectattr('os', 'eq', os)|selectattr('requires')|map(attribute='requires')|sum|unique -%}
+{%- if (os_requires|length) %}
+ if self.settings.os == "{{ os }}":
+{%- for os_require in os_requires %}
+ self.requires("{{ os_require }}")
{%- endfor -%}
{%- endif -%}
{%- endfor -%}
@@ -55,11 +57,13 @@ class App(ConanFile):
{%- endif -%}
{%- if (has_conan_os_depends_tool_requires) -%}
-{%- for conan_os_depend in conan.os_depends|selectattr('tool_requires') %}
-{%- if (conan_os_depend.tool_requires|length) %}
- if self.settings.os == "{{ conan_os_depend.os }}":
-{%- for conan_tool_require in conan_os_depend.tool_requires %}
- self.tool_requires("{{ conan_tool_require }}")
+{%- set oses = conan.os_depends|selectattr('os')|map(attribute='os')|unique -%}
+{%- for os in oses %}
+{%- set os_tool_requires = conan.os_depends|selectattr('os', 'eq', os)|selectattr('tool_requires')|map(attribute='tool_requires')|sum|unique -%}
+{%- if (os_tool_requires|length) %}
+ if self.settings.os == "{{ os }}":
+{%- for os_tool_require in os_tool_requires %}
+ self.requires("{{ os_tool_require }}")
{%- endfor -%}
{%- endif -%}
{%- endfor -%}
diff --git a/build/external_resources/ymake/public.resources.json b/build/external_resources/ymake/public.resources.json
index 885ecc49de..2094162ad8 100644
--- a/build/external_resources/ymake/public.resources.json
+++ b/build/external_resources/ymake/public.resources.json
@@ -1,19 +1,19 @@
{
"by_platform": {
"darwin": {
- "uri": "sbr:8103757184"
+ "uri": "sbr:8157966268"
},
"darwin-arm64": {
- "uri": "sbr:8103755745"
+ "uri": "sbr:8157965432"
},
"linux": {
- "uri": "sbr:8103760334"
+ "uri": "sbr:8157967911"
},
"linux-aarch64": {
- "uri": "sbr:8103754551"
+ "uri": "sbr:8157964700"
},
"win32-clang-cl": {
- "uri": "sbr:8103758621"
+ "uri": "sbr:8157967266"
}
}
}
diff --git a/build/external_resources/ymake/resources.json b/build/external_resources/ymake/resources.json
index 934feca767..d52afb7ac7 100644
--- a/build/external_resources/ymake/resources.json
+++ b/build/external_resources/ymake/resources.json
@@ -1,19 +1,19 @@
{
"by_platform": {
"darwin": {
- "uri": "sbr:8103761804"
+ "uri": "sbr:8157959616"
},
"darwin-arm64": {
- "uri": "sbr:8103760168"
+ "uri": "sbr:8157958728"
},
"linux": {
- "uri": "sbr:8103765600"
+ "uri": "sbr:8157961256"
},
"linux-aarch64": {
- "uri": "sbr:8103758578"
+ "uri": "sbr:8157958024"
},
"win32-clang-cl": {
- "uri": "sbr:8103763594"
+ "uri": "sbr:8157960421"
}
}
}
diff --git a/build/mapping.conf.json b/build/mapping.conf.json
index 1e01a3d75c..51df82af27 100644
--- a/build/mapping.conf.json
+++ b/build/mapping.conf.json
@@ -509,6 +509,7 @@
"8029671029": "{registry_endpoint}/8029671029",
"8067063302": "{registry_endpoint}/8067063302",
"8119415565": "{registry_endpoint}/8119415565",
+ "8161441586": "{registry_endpoint}/8161441586",
"5486731632": "{registry_endpoint}/5486731632",
"5514350352": "{registry_endpoint}/5514350352",
"5514360398": "{registry_endpoint}/5514360398",
@@ -701,6 +702,7 @@
"8000013577": "{registry_endpoint}/8000013577",
"8069587979": "{registry_endpoint}/8069587979",
"8103757184": "{registry_endpoint}/8103757184",
+ "8157966268": "{registry_endpoint}/8157966268",
"5766171800": "{registry_endpoint}/5766171800",
"5805430761": "{registry_endpoint}/5805430761",
"5829025456": "{registry_endpoint}/5829025456",
@@ -768,6 +770,7 @@
"8000012780": "{registry_endpoint}/8000012780",
"8069587058": "{registry_endpoint}/8069587058",
"8103755745": "{registry_endpoint}/8103755745",
+ "8157965432": "{registry_endpoint}/8157965432",
"5766173070": "{registry_endpoint}/5766173070",
"5805432830": "{registry_endpoint}/5805432830",
"5829031598": "{registry_endpoint}/5829031598",
@@ -835,6 +838,7 @@
"8000014871": "{registry_endpoint}/8000014871",
"8069590186": "{registry_endpoint}/8069590186",
"8103760334": "{registry_endpoint}/8103760334",
+ "8157967911": "{registry_endpoint}/8157967911",
"5766171341": "{registry_endpoint}/5766171341",
"5805430188": "{registry_endpoint}/5805430188",
"5829023352": "{registry_endpoint}/5829023352",
@@ -902,6 +906,7 @@
"8000012216": "{registry_endpoint}/8000012216",
"8069586009": "{registry_endpoint}/8069586009",
"8103754551": "{registry_endpoint}/8103754551",
+ "8157964700": "{registry_endpoint}/8157964700",
"5766172695": "{registry_endpoint}/5766172695",
"5805432230": "{registry_endpoint}/5805432230",
"5829029743": "{registry_endpoint}/5829029743",
@@ -969,6 +974,7 @@
"8000014239": "{registry_endpoint}/8000014239",
"8069588665": "{registry_endpoint}/8069588665",
"8103758621": "{registry_endpoint}/8103758621",
+ "8157967266": "{registry_endpoint}/8157967266",
"4307890075": "{registry_endpoint}/4307890075",
"5517245192": "{registry_endpoint}/5517245192",
"4307901240": "{registry_endpoint}/4307901240",
@@ -1763,6 +1769,7 @@
"8029671029": "devtools/ya/test/programs/test_tool/bin/test_tool for linux",
"8067063302": "devtools/ya/test/programs/test_tool/bin/test_tool for linux",
"8119415565": "devtools/ya/test/programs/test_tool/bin/test_tool for linux",
+ "8161441586": "devtools/ya/test/programs/test_tool/bin/test_tool for linux",
"5486731632": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux",
"5514350352": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux",
"5514360398": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux",
@@ -1955,6 +1962,7 @@
"8000013577": "devtools/ymake/bin/ymake for darwin",
"8069587979": "devtools/ymake/bin/ymake for darwin",
"8103757184": "devtools/ymake/bin/ymake for darwin",
+ "8157966268": "devtools/ymake/bin/ymake for darwin",
"5766171800": "devtools/ymake/bin/ymake for darwin-arm64",
"5805430761": "devtools/ymake/bin/ymake for darwin-arm64",
"5829025456": "devtools/ymake/bin/ymake for darwin-arm64",
@@ -2022,6 +2030,7 @@
"8000012780": "devtools/ymake/bin/ymake for darwin-arm64",
"8069587058": "devtools/ymake/bin/ymake for darwin-arm64",
"8103755745": "devtools/ymake/bin/ymake for darwin-arm64",
+ "8157965432": "devtools/ymake/bin/ymake for darwin-arm64",
"5766173070": "devtools/ymake/bin/ymake for linux",
"5805432830": "devtools/ymake/bin/ymake for linux",
"5829031598": "devtools/ymake/bin/ymake for linux",
@@ -2089,6 +2098,7 @@
"8000014871": "devtools/ymake/bin/ymake for linux",
"8069590186": "devtools/ymake/bin/ymake for linux",
"8103760334": "devtools/ymake/bin/ymake for linux",
+ "8157967911": "devtools/ymake/bin/ymake for linux",
"5766171341": "devtools/ymake/bin/ymake for linux-aarch64",
"5805430188": "devtools/ymake/bin/ymake for linux-aarch64",
"5829023352": "devtools/ymake/bin/ymake for linux-aarch64",
@@ -2156,6 +2166,7 @@
"8000012216": "devtools/ymake/bin/ymake for linux-aarch64",
"8069586009": "devtools/ymake/bin/ymake for linux-aarch64",
"8103754551": "devtools/ymake/bin/ymake for linux-aarch64",
+ "8157964700": "devtools/ymake/bin/ymake for linux-aarch64",
"5766172695": "devtools/ymake/bin/ymake for win32-clang-cl",
"5805432230": "devtools/ymake/bin/ymake for win32-clang-cl",
"5829029743": "devtools/ymake/bin/ymake for win32-clang-cl",
@@ -2223,6 +2234,7 @@
"8000014239": "devtools/ymake/bin/ymake for win32-clang-cl",
"8069588665": "devtools/ymake/bin/ymake for win32-clang-cl",
"8103758621": "devtools/ymake/bin/ymake for win32-clang-cl",
+ "8157967266": "devtools/ymake/bin/ymake for win32-clang-cl",
"4307890075": "flake8_linter for linux",
"5517245192": "flake8_linter for linux",
"4307901240": "flake8_linter for linux-aarch64",
diff --git a/build/platform/test_tool/host.ya.make.inc b/build/platform/test_tool/host.ya.make.inc
index 0a710764cf..1d16478d48 100644
--- a/build/platform/test_tool/host.ya.make.inc
+++ b/build/platform/test_tool/host.ya.make.inc
@@ -1,12 +1,12 @@
IF (HOST_OS_DARWIN AND HOST_ARCH_X86_64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8119446934)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8161442120)
ELSEIF (HOST_OS_DARWIN AND HOST_ARCH_ARM64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8119444678)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8161441534)
ELSEIF (HOST_OS_LINUX AND HOST_ARCH_X86_64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8119452256)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8161443391)
ELSEIF (HOST_OS_LINUX AND HOST_ARCH_AARCH64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8119442724)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8161440859)
ELSEIF (HOST_OS_WINDOWS AND HOST_ARCH_X86_64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8119449312)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8161442654)
ENDIF()
diff --git a/build/platform/test_tool/host_os.ya.make.inc b/build/platform/test_tool/host_os.ya.make.inc
index 39a59b4039..3f8266caf3 100644
--- a/build/platform/test_tool/host_os.ya.make.inc
+++ b/build/platform/test_tool/host_os.ya.make.inc
@@ -1,12 +1,12 @@
IF (HOST_OS_DARWIN AND HOST_ARCH_X86_64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8119412037)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8161440522)
ELSEIF (HOST_OS_DARWIN AND HOST_ARCH_ARM64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8119409839)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8161440178)
ELSEIF (HOST_OS_LINUX AND HOST_ARCH_X86_64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8119415565)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8161441586)
ELSEIF (HOST_OS_LINUX AND HOST_ARCH_AARCH64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8119408227)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8161439551)
ELSEIF (HOST_OS_WINDOWS AND HOST_ARCH_X86_64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8119413751)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8161440986)
ENDIF()
diff --git a/build/plugins/_dart_fields.py b/build/plugins/_dart_fields.py
index e102154a34..6575f84ecf 100644
--- a/build/plugins/_dart_fields.py
+++ b/build/plugins/_dart_fields.py
@@ -670,7 +670,7 @@ class LintConfigs:
class LintExtraParams:
KEY = 'LINT-EXTRA-PARAMS'
- _CUSTOM_CLANG_FORMAT_BIN_ALLOWED_PATHS = ('ads', 'bigrt', 'grut')
+ _CUSTOM_CLANG_FORMAT_BIN_ALLOWED_PATHS = ('ads', 'bigrt', 'grut', 'yabs')
@classmethod
def from_macro_args(cls, unit, flat_args, spec_args):
@@ -1137,6 +1137,8 @@ class TestFiles:
# https://a.yandex-team.ru/arcadia/devtools/ya/test/dartfile/__init__.py?rev=r14292146#L10
KEY2 = 'FILES'
+ # XXX: this is a workaround to support very specific linting settings.
+ # Do not use it as a general mechanism!
_GRUT_PREFIX = 'grut'
_GRUT_INCLUDE_LINTER_TEST_PATHS = (
'grut/libs/bigrt/clients',
@@ -1151,6 +1153,36 @@ class TestFiles:
'grut/libs/shooter',
)
+ # XXX: this is a workaround to support very specific linting settings.
+ # Do not use it as a general mechanism!
+ _MAPS_RENDERER_PREFIX = 'maps/renderer'
+ _MAPS_RENDERER_INCLUDE_LINTER_TEST_PATHS = (
+ 'maps/renderer/cartograph',
+ 'maps/renderer/denormalization',
+ 'maps/renderer/libs/api',
+ 'maps/renderer/libs/data_sets/geojson_data_set',
+ 'maps/renderer/libs/data_sets/yt_data_set',
+ 'maps/renderer/libs/design',
+ 'maps/renderer/libs/geosx',
+ 'maps/renderer/libs/gltf',
+ 'maps/renderer/libs/golden',
+ 'maps/renderer/libs/hd3d',
+ 'maps/renderer/libs/image',
+ 'maps/renderer/libs/kv_storage',
+ 'maps/renderer/libs/marking',
+ 'maps/renderer/libs/mesh',
+ 'maps/renderer/libs/serializers',
+ 'maps/renderer/libs/style2',
+ 'maps/renderer/libs/style2_layer_bundle',
+ 'maps/renderer/libs/terrain',
+ 'maps/renderer/libs/vec',
+ 'maps/renderer/tilemill',
+ 'maps/renderer/tools/fontograph',
+ 'maps/renderer/tools/terrain_cli',
+ 'maps/renderer/tools/mapcheck2/lib',
+ 'maps/renderer/tools/mapcheck2/tests',
+ )
+
@classmethod
def value(cls, unit, flat_args, spec_args):
data_re = re.compile(r"sbr:/?/?(\d+)=?.*")
@@ -1251,6 +1283,14 @@ class TestFiles:
break
else:
raise DartValueError()
+
+ if upath.startswith(cls._MAPS_RENDERER_PREFIX):
+ for path in cls._MAPS_RENDERER_INCLUDE_LINTER_TEST_PATHS:
+ if os.path.commonpath([upath, path]) == path:
+ break
+ else:
+ raise DartValueError()
+
files_dart = _reference_group_var("ALL_SRCS", consts.STYLE_CPP_ALL_EXTS)
return {cls.KEY: files_dart, cls.KEY2: files_dart}
diff --git a/build/plugins/_requirements.py b/build/plugins/_requirements.py
index 40c50f8791..c358914e0e 100644
--- a/build/plugins/_requirements.py
+++ b/build/plugins/_requirements.py
@@ -4,6 +4,7 @@ import lib._metric_resolvers as mr
CANON_SB_VAULT_REGEX = re.compile(r"\w+=(value|file):[-\w]+:\w+")
CANON_YAV_REGEX = re.compile(r"\w+=(value|file):sec-[a-z0-9]+:\w+")
+PORTO_LAYERS_REGEX = re.compile(r"^\d+(,\d+)*$")
VALID_DNS_REQUIREMENTS = ("default", "local", "dns64")
VALID_NETWORK_REQUIREMENTS = ("full", "restricted")
@@ -87,6 +88,11 @@ def validate_yav_vault(name, value):
return "yav value '{}' should follow pattern <ENV_NAME>=<value|file>:<sec-id>:<key>".format(value)
+def validate_porto_layers(name, value):
+ if not PORTO_LAYERS_REGEX.match(value):
+ return "porto layers '{}' should follow pattern porto_layers=<layerId1>[,<layerIdN>]*".format(value)
+
+
def validate_numerical_requirement(name, value):
if mr.resolve_value(value) is None:
return "Cannot convert [[imp]]{}[[rst]] to the proper [[imp]]{}[[rst]] requirement value".format(value, name)
@@ -133,6 +139,7 @@ def validate_requirement(
):
req_checks = {
'container': validate_numerical_requirement,
+ 'porto_layers': validate_porto_layers,
'cpu': lambda n, v: validate_force_sandbox_requirement(
n, v, test_size, is_force_sandbox, in_autocheck, is_fuzzing, is_kvm, is_ytexec_run, check_cpu
),
@@ -166,7 +173,7 @@ def validate_requirement(
req_name, ", ".join(sorted(req_checks))
)
- if req_name in ('container', 'disk') and not is_force_sandbox:
+ if req_name in ('container', 'disk', 'porto_layers') and not is_force_sandbox:
return "Only [[imp]]LARGE[[rst]] tests without [[imp]]ya:force_distbuild[[rst]] tag can have [[imp]]{}[[rst]] requirement".format(
req_name
)
diff --git a/build/plugins/lib/nots/typescript/ts_config.py b/build/plugins/lib/nots/typescript/ts_config.py
index 608e9b8de2..435ff4e78b 100644
--- a/build/plugins/lib/nots/typescript/ts_config.py
+++ b/build/plugins/lib/nots/typescript/ts_config.py
@@ -64,7 +64,7 @@ class TsConfig(object):
def read(self):
try:
- with open(self.path, encoding="utf-8") as f:
+ with open(self.path) as f:
self.data = self.rj.load(f, parse_mode=(self.rj.PM_COMMENTS | self.rj.PM_TRAILING_COMMAS))
except Exception as e:
diff --git a/build/plugins/lib/test_const/__init__.py b/build/plugins/lib/test_const/__init__.py
index 293b514d01..1319ec0ead 100644
--- a/build/plugins/lib/test_const/__init__.py
+++ b/build/plugins/lib/test_const/__init__.py
@@ -231,6 +231,7 @@ class TestRequirements(Enum):
Dns = 'dns'
Kvm = 'kvm'
Network = 'network'
+ PortoLayers = 'porto_layers'
Ram = 'ram'
RamDisk = 'ram_disk'
SbVault = 'sb_vault'
@@ -450,6 +451,7 @@ class PythonLinterName(Enum):
class CppLinterName(Enum):
ClangFormat = "clang_format"
ClangFormatYT = "clang_format_yt"
+ ClangFormat15 = "clang_format_15"
class DefaultLinterConfig(Enum):
@@ -464,6 +466,7 @@ class LinterConfigsValidationRules(Enum):
LINTER_CONFIG_TYPES = {
CppLinterName.ClangFormat: (".clang-format",),
+ CppLinterName.ClangFormat15: (".clang-format",),
CppLinterName.ClangFormatYT: (".clang-format",),
PythonLinterName.Black: ("pyproject.toml",),
PythonLinterName.Ruff: ("pyproject.toml", "ruff.toml"),
diff --git a/build/plugins/pybuild.py b/build/plugins/pybuild.py
index 2a1add15ae..441579c561 100644
--- a/build/plugins/pybuild.py
+++ b/build/plugins/pybuild.py
@@ -170,6 +170,7 @@ def add_python_lint_checks(unit, py_ver, files):
"passport/backend/oauth/", # PASSP-35982
"sdg/sdc/contrib/", # SDC contrib
"sdg/sdc/third_party/", # SDC contrib
+ "smart_devices/third_party/", # smart_devices contrib
"yt/yt/", # YT-20053
"yt/python/", # YT-20053
"yt/python_py2/",
@@ -724,6 +725,8 @@ def onpy_register(unit, *args):
unit.oncflags(['-DPyInit_{}=PyInit_{}'.format(shortname, mangle(name))])
else:
unit.oncflags(['-Dinit{}=init{}'.format(shortname, mangle(name))])
+ # BOOST_PYTHON_MODULE case
+ unit.oncflags(['-Dinit_module_{}=init_module_{}'.format(shortname, mangle(name))])
def py_main(unit, arg):
diff --git a/build/plugins/ytest.py b/build/plugins/ytest.py
index 4ae288e062..937c049aff 100644
--- a/build/plugins/ytest.py
+++ b/build/plugins/ytest.py
@@ -268,8 +268,11 @@ def validate_test(unit, kw):
if in_autocheck and size == consts.TestSize.Large:
errors.append("LARGE test must have ya:fat tag")
- if consts.YaTestTags.Privileged in tags and 'container' not in requirements:
- errors.append("Only tests with 'container' requirement can have 'ya:privileged' tag")
+ if 'container' in requirements and 'porto_layers' in requirements:
+ errors.append("Only one of 'container', 'porto_layers' can be set, not both")
+
+ if consts.YaTestTags.Privileged in tags and 'container' not in requirements and 'porto_layers' not in requirements:
+ errors.append("Only tests with 'container' or 'porto_layers' requirement can have 'ya:privileged' tag")
if size not in size_timeout:
errors.append(
diff --git a/build/ymake.core.conf b/build/ymake.core.conf
index b96a5a412b..73e1c196cf 100644
--- a/build/ymake.core.conf
+++ b/build/ymake.core.conf
@@ -5906,3 +5906,7 @@ macro GENERATE_IMPLIB(Lib, Path, SONAME="") {
LINK_EXCLUDE_LIBRARIES($Lib)
}
+
+when ($OS_LINUX == "yes") {
+ YMAKE_USE_OBJCOPY=yes
+}
diff --git a/contrib/libs/cxxsupp/libcxx/.yandex_meta/build.ym b/contrib/libs/cxxsupp/libcxx/.yandex_meta/build.ym
index 23f291c8a4..85545f7c95 100644
--- a/contrib/libs/cxxsupp/libcxx/.yandex_meta/build.ym
+++ b/contrib/libs/cxxsupp/libcxx/.yandex_meta/build.ym
@@ -5,7 +5,6 @@
{% block keep_sources %}
.yandex_meta/scripts/sysincls.py
-glibcxx_eh_cxx17.cpp
include/__config_site
include/__config_epilogue.h
include/__memory/pointer_safety.h
@@ -114,12 +113,7 @@ ELSEIF (OS_IOS)
ELSEIF (OS_LINUX OR OS_DARWIN)
IF (ARCH_ARM7)
# libcxxrt support for ARM is currently broken, use libcxxabi instead
- # But allow switching back to glibcxx_static via -DCXX_RT=glibcxx_static
- DEFAULT(CXX_RT "libcxxabi")
- # ARM7 OS_SDK has old libstdc++ without aligned allocation support
- CFLAGS(
- GLOBAL -fno-aligned-new
- )
+ SET(CXX_RT "libcxxabi")
ELSE()
SET(CXX_RT "libcxxrt")
ENDIF()
@@ -156,13 +150,8 @@ ENDIF()
# * libcxxabi - https://github.com/llvm/llvm-project/tree/main/libcxxabi from Arcadia
# * libcxxabi_dynamic - https://github.com/llvm/llvm-project/tree/main/libcxxabi from SDK, dynamically linked
# * libcxxrt - https://github.com/libcxxrt/libcxxrt from Arcadia (with some parts hijacked from libcxxabi)
-# * glibcxx_static - https://github.com/gcc-mirror/gcc/tree/master/libstdc++-v3/libsupc++ from SDK, statically linked
# * msvcrt - Visual C++ runtime library from SDK, dynamically linked
-DISABLE(NEED_GLIBCXX_CXX17_SHIMS)
-
-DISABLE(NEED_CXX_RT_ADDINCL)
-
IF (CXX_RT == "libcxxrt")
PEERDIR(
contrib/libs/cxxsupp/libcxxabi-parts
@@ -175,20 +164,6 @@ IF (CXX_RT == "libcxxrt")
CFLAGS(
-DLIBCXXRT
)
- # These builtins are equivalent to clang -rtlib=compiler_rt and
- # are needed by potentially any code generated by clang.
- # With glibcxx runtime, builtins are provided by libgcc
-ELSEIF (CXX_RT == "glibcxx_static")
- LDFLAGS(
- -Wl,-Bstatic
- -lsupc++
- -lgcc
- -lgcc_eh
- -Wl,-Bdynamic
- )
- CXXFLAGS(-D__GLIBCXX__=1)
- ENABLE(NEED_GLIBCXX_CXX17_SHIMS)
- ENABLE(NEED_CXX_RT_ADDINCL)
ELSEIF (CXX_RT == "libcxxabi")
PEERDIR(
contrib/libs/cxxsupp/builtins
@@ -213,27 +188,6 @@ ELSE()
MESSAGE(FATAL_ERROR "Unexpected CXX_RT value: \${CXX_RT}")
ENDIF()
-IF (NEED_GLIBCXX_CXX17_SHIMS)
- IF (GCC)
- # Assume GCC is bundled with a modern enough version of C++ runtime
- ELSEIF (OS_SDK == "ubuntu-12" OR OS_SDK == "ubuntu-14" OR OS_SDK == "ubuntu-16")
- # Prior to ubuntu-18, system C++ runtime for C++17 is incomplete
- # and requires std::uncaught_exceptions() to be implemented.
- SRCS(
- glibcxx_eh_cxx17.cpp
- )
- ENDIF()
-ENDIF()
-
-IF (NEED_CXX_RT_ADDINCL)
- # FIXME:
- # This looks extremely weird and we have to use cxxabi.h from libsupc++ instead.
- # This ADDINCL is placed here just to fix the status quo
- ADDINCL(
- GLOBAL contrib/libs/cxxsupp/libcxxrt/include
- )
-ENDIF()
-
NO_UTIL()
NO_RUNTIME()
diff --git a/contrib/libs/cxxsupp/libcxx/glibcxx_eh_cxx17.cpp b/contrib/libs/cxxsupp/libcxx/glibcxx_eh_cxx17.cpp
deleted file mode 100644
index 5e5ad083ba..0000000000
--- a/contrib/libs/cxxsupp/libcxx/glibcxx_eh_cxx17.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-#include <cxxabi.h>
-
-/**
- * libc++ expects std::uncaught_exceptions() to be provided by C++ runtime library.
- *
- * GCC versions prior to GCC 6 did not provide this function yet, but it can be
- * implemented using its API.
- *
- * This implementation should cover ubuntu-12, ubuntu-14, ubuntu-16.
- */
-
-namespace std {
- int uncaught_exceptions() noexcept {
- const auto* globals{__cxxabiv1::__cxa_get_globals()};
- return static_cast<int>(globals->uncaughtExceptions);
- }
-}
diff --git a/contrib/libs/cxxsupp/libcxx/ya.make b/contrib/libs/cxxsupp/libcxx/ya.make
index 122c16d4f7..c4b545164e 100644
--- a/contrib/libs/cxxsupp/libcxx/ya.make
+++ b/contrib/libs/cxxsupp/libcxx/ya.make
@@ -36,12 +36,7 @@ ELSEIF (OS_IOS)
ELSEIF (OS_LINUX OR OS_DARWIN)
IF (ARCH_ARM7)
# libcxxrt support for ARM is currently broken, use libcxxabi instead
- # But allow switching back to glibcxx_static via -DCXX_RT=glibcxx_static
- DEFAULT(CXX_RT "libcxxabi")
- # ARM7 OS_SDK has old libstdc++ without aligned allocation support
- CFLAGS(
- GLOBAL -fno-aligned-new
- )
+ SET(CXX_RT "libcxxabi")
ELSE()
SET(CXX_RT "libcxxrt")
ENDIF()
@@ -74,13 +69,8 @@ ENDIF()
# * libcxxabi - https://github.com/llvm/llvm-project/tree/main/libcxxabi from Arcadia
# * libcxxabi_dynamic - https://github.com/llvm/llvm-project/tree/main/libcxxabi from SDK, dynamically linked
# * libcxxrt - https://github.com/libcxxrt/libcxxrt from Arcadia (with some parts hijacked from libcxxabi)
-# * glibcxx_static - https://github.com/gcc-mirror/gcc/tree/master/libstdc++-v3/libsupc++ from SDK, statically linked
# * msvcrt - Visual C++ runtime library from SDK, dynamically linked
-DISABLE(NEED_GLIBCXX_CXX17_SHIMS)
-
-DISABLE(NEED_CXX_RT_ADDINCL)
-
IF (CXX_RT == "libcxxrt")
PEERDIR(
contrib/libs/cxxsupp/libcxxabi-parts
@@ -93,20 +83,6 @@ IF (CXX_RT == "libcxxrt")
CFLAGS(
-DLIBCXXRT
)
- # These builtins are equivalent to clang -rtlib=compiler_rt and
- # are needed by potentially any code generated by clang.
- # With glibcxx runtime, builtins are provided by libgcc
-ELSEIF (CXX_RT == "glibcxx_static")
- LDFLAGS(
- -Wl,-Bstatic
- -lsupc++
- -lgcc
- -lgcc_eh
- -Wl,-Bdynamic
- )
- CXXFLAGS(-D__GLIBCXX__=1)
- ENABLE(NEED_GLIBCXX_CXX17_SHIMS)
- ENABLE(NEED_CXX_RT_ADDINCL)
ELSEIF (CXX_RT == "libcxxabi")
PEERDIR(
contrib/libs/cxxsupp/builtins
@@ -129,27 +105,6 @@ ELSE()
MESSAGE(FATAL_ERROR "Unexpected CXX_RT value: ${CXX_RT}")
ENDIF()
-IF (NEED_GLIBCXX_CXX17_SHIMS)
- IF (GCC)
- # Assume GCC is bundled with a modern enough version of C++ runtime
- ELSEIF (OS_SDK == "ubuntu-12" OR OS_SDK == "ubuntu-14" OR OS_SDK == "ubuntu-16")
- # Prior to ubuntu-18, system C++ runtime for C++17 is incomplete
- # and requires std::uncaught_exceptions() to be implemented.
- SRCS(
- glibcxx_eh_cxx17.cpp
- )
- ENDIF()
-ENDIF()
-
-IF (NEED_CXX_RT_ADDINCL)
- # FIXME:
- # This looks extremely weird and we have to use cxxabi.h from libsupc++ instead.
- # This ADDINCL is placed here just to fix the status quo
- ADDINCL(
- GLOBAL contrib/libs/cxxsupp/libcxxrt/include
- )
-ENDIF()
-
NO_UTIL()
NO_RUNTIME()
diff --git a/contrib/libs/poco/Foundation/include/Poco/BufferedStreamBuf.h b/contrib/libs/poco/Foundation/include/Poco/BufferedStreamBuf.h
index 3e39215262..182d8085e7 100644
--- a/contrib/libs/poco/Foundation/include/Poco/BufferedStreamBuf.h
+++ b/contrib/libs/poco/Foundation/include/Poco/BufferedStreamBuf.h
@@ -25,6 +25,10 @@
#include <iosfwd>
#include <ios>
+namespace DB
+{
+class ReadBufferFromIStream;
+}
namespace Poco {
@@ -124,6 +128,8 @@ protected:
}
private:
+ friend class DB::ReadBufferFromIStream;
+
virtual int readFromDevice(char_type* /*buffer*/, std::streamsize /*length*/)
{
return 0;
diff --git a/contrib/libs/re2/.yandex_meta/__init__.py b/contrib/libs/re2/.yandex_meta/__init__.py
index cd11be23f4..3e7fe27381 100644
--- a/contrib/libs/re2/.yandex_meta/__init__.py
+++ b/contrib/libs/re2/.yandex_meta/__init__.py
@@ -83,6 +83,8 @@ re2 = CMakeNinjaNixProject(
"include/re2": [
"re2/re2.h",
"re2/stringpiece.h",
+ "re2/regexp.h",
+ "re2/walker-inl.h",
],
"include/util": [
"util/logging.h",
diff --git a/contrib/libs/re2/include/re2/re2.h b/contrib/libs/re2/include/re2/re2.h
index 31cfa08363..a0c4744d8f 100644
--- a/contrib/libs/re2/include/re2/re2.h
+++ b/contrib/libs/re2/include/re2/re2.h
@@ -1 +1 @@
-#include "../../re2/re2.h" /* inclink generated by yamaker */
+#include "../../re2/re2.h" /* inclink generated by yamaker */ \ No newline at end of file
diff --git a/contrib/libs/re2/include/re2/regexp.h b/contrib/libs/re2/include/re2/regexp.h
new file mode 100644
index 0000000000..c1a566141c
--- /dev/null
+++ b/contrib/libs/re2/include/re2/regexp.h
@@ -0,0 +1 @@
+#include "../../re2/regexp.h" /* inclink generated by yamaker */
diff --git a/contrib/libs/re2/include/re2/walker-inl.h b/contrib/libs/re2/include/re2/walker-inl.h
new file mode 100644
index 0000000000..be1858437d
--- /dev/null
+++ b/contrib/libs/re2/include/re2/walker-inl.h
@@ -0,0 +1 @@
+#include "../../re2/walker-inl.h" /* inclink generated by yamaker */
diff --git a/contrib/python/psutil/py3/.dist-info/METADATA b/contrib/python/psutil/py3/.dist-info/METADATA
index eced53b9c3..685d2e23f3 100644
--- a/contrib/python/psutil/py3/.dist-info/METADATA
+++ b/contrib/python/psutil/py3/.dist-info/METADATA
@@ -1,7 +1,7 @@
Metadata-Version: 2.1
Name: psutil
-Version: 6.1.1
-Summary: Cross-platform lib for process and system monitoring in Python.
+Version: 7.0.0
+Summary: Cross-platform lib for process and system monitoring in Python. NOTE: the syntax of this script MUST be kept compatible with Python 2.7.
Home-page: https://github.com/giampaolo/psutil
Author: Giampaolo Rodola
Author-email: g.rodola@gmail.com
@@ -34,8 +34,6 @@ Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: POSIX :: SunOS/Solaris
Classifier: Operating System :: POSIX
Classifier: Programming Language :: C
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -52,12 +50,15 @@ Classifier: Topic :: System :: Networking
Classifier: Topic :: System :: Operating System
Classifier: Topic :: System :: Systems Administration
Classifier: Topic :: Utilities
-Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*
+Requires-Python: >=3.6
Description-Content-Type: text/x-rst
License-File: LICENSE
Provides-Extra: dev
+Requires-Dist: pytest ; extra == 'dev'
+Requires-Dist: pytest-xdist ; extra == 'dev'
+Requires-Dist: setuptools ; extra == 'dev'
Requires-Dist: abi3audit ; extra == 'dev'
-Requires-Dist: black ; extra == 'dev'
+Requires-Dist: black (==24.10.0) ; extra == 'dev'
Requires-Dist: check-manifest ; extra == 'dev'
Requires-Dist: coverage ; extra == 'dev'
Requires-Dist: packaging ; extra == 'dev'
@@ -82,7 +83,7 @@ Requires-Dist: setuptools ; extra == 'test'
| |downloads| |stars| |forks| |contributors| |coverage|
| |version| |py-versions| |packages| |license|
-| |github-actions-wheels| |github-actions-bsd| |appveyor| |doc| |twitter| |tidelift|
+| |github-actions-wheels| |github-actions-bsd| |doc| |twitter| |tidelift|
.. |downloads| image:: https://img.shields.io/pypi/dm/psutil.svg
:target: https://pepy.tech/project/psutil
@@ -108,10 +109,6 @@ Requires-Dist: setuptools ; extra == 'test'
:target: https://github.com/giampaolo/psutil/actions?query=workflow%3Absd-tests
:alt: FreeBSD, NetBSD, OpenBSD
-.. |appveyor| image:: https://img.shields.io/appveyor/build/giampaolo/psutil/master.svg?maxAge=3600&label=Windows%20(py2)
- :target: https://ci.appveyor.com/project/giampaolo/psutil
- :alt: Windows (Appveyor)
-
.. |coverage| image:: https://coveralls.io/repos/github/giampaolo/psutil/badge.svg?branch=master
:target: https://coveralls.io/github/giampaolo/psutil?branch=master
:alt: Test coverage (coverall.io)
@@ -177,8 +174,9 @@ psutil currently supports the following platforms:
- **Sun Solaris**
- **AIX**
-Supported Python versions are **2.7**, **3.6+** and
-`PyPy <http://pypy.org/>`__.
+Supported Python versions are cPython 3.6+ and `PyPy <https://pypy.org/>`__.
+Latest psutil version supporting Python 2.7 is
+`psutil 6.1.1 <https://pypi.org/project/psutil/6.1.1/>`__.
Funding
=======
diff --git a/contrib/python/psutil/py3/README.rst b/contrib/python/psutil/py3/README.rst
index 3fc6e601b1..16c756c50e 100644
--- a/contrib/python/psutil/py3/README.rst
+++ b/contrib/python/psutil/py3/README.rst
@@ -1,6 +1,6 @@
| |downloads| |stars| |forks| |contributors| |coverage|
| |version| |py-versions| |packages| |license|
-| |github-actions-wheels| |github-actions-bsd| |appveyor| |doc| |twitter| |tidelift|
+| |github-actions-wheels| |github-actions-bsd| |doc| |twitter| |tidelift|
.. |downloads| image:: https://img.shields.io/pypi/dm/psutil.svg
:target: https://pepy.tech/project/psutil
@@ -26,10 +26,6 @@
:target: https://github.com/giampaolo/psutil/actions?query=workflow%3Absd-tests
:alt: FreeBSD, NetBSD, OpenBSD
-.. |appveyor| image:: https://img.shields.io/appveyor/build/giampaolo/psutil/master.svg?maxAge=3600&label=Windows%20(py2)
- :target: https://ci.appveyor.com/project/giampaolo/psutil
- :alt: Windows (Appveyor)
-
.. |coverage| image:: https://coveralls.io/repos/github/giampaolo/psutil/badge.svg?branch=master
:target: https://coveralls.io/github/giampaolo/psutil?branch=master
:alt: Test coverage (coverall.io)
@@ -98,8 +94,9 @@ psutil currently supports the following platforms:
- **Sun Solaris**
- **AIX**
-Supported Python versions are **2.7**, **3.6+** and
-`PyPy <http://pypy.org/>`__.
+Supported Python versions are cPython 3.6+ and `PyPy <https://pypy.org/>`__.
+Latest psutil version supporting Python 2.7 is
+`psutil 6.1.1 <https://pypi.org/project/psutil/6.1.1/>`__.
Funding
=======
diff --git a/contrib/python/psutil/py3/patches/01-arcadia.patch b/contrib/python/psutil/py3/patches/01-arcadia.patch
index 54b53d1db5..6a0b3aff1d 100644
--- a/contrib/python/psutil/py3/patches/01-arcadia.patch
+++ b/contrib/python/psutil/py3/patches/01-arcadia.patch
@@ -1,17 +1,3 @@
---- contrib/python/psutil/py3/psutil/_pslinux.py (index)
-+++ contrib/python/psutil/py3/psutil/_pslinux.py (working tree)
-@@ -322,7 +322,10 @@ try:
- except ImportError:
- import ctypes
-
-- libc = ctypes.CDLL(None, use_errno=True)
-+ try:
-+ libc = ctypes.CDLL(None, use_errno=True)
-+ except:
-+ libc = None
-
- if hasattr(libc, "prlimit"):
-
--- contrib/python/psutil/py3/psutil/arch/windows/disk.c (index)
+++ contrib/python/psutil/py3/psutil/arch/windows/disk.c (working tree)
@@ -7,6 +7,7 @@
diff --git a/contrib/python/psutil/py3/psutil/__init__.py b/contrib/python/psutil/py3/psutil/__init__.py
index 5648339382..cf4a58057f 100644
--- a/contrib/python/psutil/py3/psutil/__init__.py
+++ b/contrib/python/psutil/py3/psutil/__init__.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -17,17 +15,16 @@ sensors) in Python. Supported platforms:
- Sun Solaris
- AIX
-Works with Python versions 2.7 and 3.6+.
+Supported Python versions are cPython 3.6+ and PyPy.
"""
-from __future__ import division
-
import collections
import contextlib
import datetime
import functools
import os
import signal
+import socket
import subprocess
import sys
import threading
@@ -54,16 +51,16 @@ from ._common import CONN_NONE
from ._common import CONN_SYN_RECV
from ._common import CONN_SYN_SENT
from ._common import CONN_TIME_WAIT
-from ._common import FREEBSD # NOQA
+from ._common import FREEBSD
from ._common import LINUX
from ._common import MACOS
-from ._common import NETBSD # NOQA
+from ._common import NETBSD
from ._common import NIC_DUPLEX_FULL
from ._common import NIC_DUPLEX_HALF
from ._common import NIC_DUPLEX_UNKNOWN
-from ._common import OPENBSD # NOQA
+from ._common import OPENBSD
from ._common import OSX # deprecated alias
-from ._common import POSIX # NOQA
+from ._common import POSIX
from ._common import POWER_TIME_UNKNOWN
from ._common import POWER_TIME_UNLIMITED
from ._common import STATUS_DEAD
@@ -88,11 +85,6 @@ from ._common import ZombieProcess
from ._common import debug
from ._common import memoize_when_activated
from ._common import wrap_numbers as _wrap_numbers
-from ._compat import PY3 as _PY3
-from ._compat import PermissionError
-from ._compat import ProcessLookupError
-from ._compat import SubprocessTimeoutExpired as _SubprocessTimeoutExpired
-from ._compat import long
if LINUX:
@@ -101,24 +93,24 @@ if LINUX:
PROCFS_PATH = "/proc"
from . import _pslinux as _psplatform
- from ._pslinux import IOPRIO_CLASS_BE # NOQA
- from ._pslinux import IOPRIO_CLASS_IDLE # NOQA
- from ._pslinux import IOPRIO_CLASS_NONE # NOQA
- from ._pslinux import IOPRIO_CLASS_RT # NOQA
+ from ._pslinux import IOPRIO_CLASS_BE # noqa: F401
+ from ._pslinux import IOPRIO_CLASS_IDLE # noqa: F401
+ from ._pslinux import IOPRIO_CLASS_NONE # noqa: F401
+ from ._pslinux import IOPRIO_CLASS_RT # noqa: F401
elif WINDOWS:
from . import _pswindows as _psplatform
- from ._psutil_windows import ABOVE_NORMAL_PRIORITY_CLASS # NOQA
- from ._psutil_windows import BELOW_NORMAL_PRIORITY_CLASS # NOQA
- from ._psutil_windows import HIGH_PRIORITY_CLASS # NOQA
- from ._psutil_windows import IDLE_PRIORITY_CLASS # NOQA
- from ._psutil_windows import NORMAL_PRIORITY_CLASS # NOQA
- from ._psutil_windows import REALTIME_PRIORITY_CLASS # NOQA
- from ._pswindows import CONN_DELETE_TCB # NOQA
- from ._pswindows import IOPRIO_HIGH # NOQA
- from ._pswindows import IOPRIO_LOW # NOQA
- from ._pswindows import IOPRIO_NORMAL # NOQA
- from ._pswindows import IOPRIO_VERYLOW # NOQA
+ from ._psutil_windows import ABOVE_NORMAL_PRIORITY_CLASS # noqa: F401
+ from ._psutil_windows import BELOW_NORMAL_PRIORITY_CLASS # noqa: F401
+ from ._psutil_windows import HIGH_PRIORITY_CLASS # noqa: F401
+ from ._psutil_windows import IDLE_PRIORITY_CLASS # noqa: F401
+ from ._psutil_windows import NORMAL_PRIORITY_CLASS # noqa: F401
+ from ._psutil_windows import REALTIME_PRIORITY_CLASS # noqa: F401
+ from ._pswindows import CONN_DELETE_TCB # noqa: F401
+ from ._pswindows import IOPRIO_HIGH # noqa: F401
+ from ._pswindows import IOPRIO_LOW # noqa: F401
+ from ._pswindows import IOPRIO_NORMAL # noqa: F401
+ from ._pswindows import IOPRIO_VERYLOW # noqa: F401
elif MACOS:
from . import _psosx as _psplatform
@@ -128,8 +120,8 @@ elif BSD:
elif SUNOS:
from . import _pssunos as _psplatform
- from ._pssunos import CONN_BOUND # NOQA
- from ._pssunos import CONN_IDLE # NOQA
+ from ._pssunos import CONN_BOUND # noqa: F401
+ from ._pssunos import CONN_IDLE # noqa: F401
# This is public writable API which is read from _pslinux.py and
# _pssunos.py via sys.modules.
@@ -143,7 +135,8 @@ elif AIX:
PROCFS_PATH = "/proc"
else: # pragma: no cover
- raise NotImplementedError('platform %s is not supported' % sys.platform)
+ msg = f"platform {sys.platform} is not supported"
+ raise NotImplementedError(msg)
# fmt: off
@@ -214,8 +207,8 @@ if hasattr(_psplatform.Process, "rlimit"):
AF_LINK = _psplatform.AF_LINK
__author__ = "Giampaolo Rodola'"
-__version__ = "6.1.1"
-version_info = tuple([int(num) for num in __version__.split('.')])
+__version__ = "7.0.0"
+version_info = tuple(int(num) for num in __version__.split('.'))
_timer = getattr(time, 'monotonic', time.time)
_TOTAL_PHYMEM = None
@@ -231,22 +224,19 @@ _SENTINEL = object()
if int(__version__.replace('.', '')) != getattr(
_psplatform.cext, 'version', None
):
- msg = "version conflict: %r C extension " % _psplatform.cext.__file__
+ msg = f"version conflict: {_psplatform.cext.__file__!r} C extension "
msg += "module was built for another version of psutil"
if hasattr(_psplatform.cext, 'version'):
- msg += " (%s instead of %s)" % (
- '.'.join([x for x in str(_psplatform.cext.version)]),
- __version__,
- )
+ v = ".".join(list(str(_psplatform.cext.version)))
+ msg += f" ({v} instead of {__version__})"
else:
- msg += " (different than %s)" % __version__
- msg += "; you may try to 'pip uninstall psutil', manually remove %s" % (
- getattr(
- _psplatform.cext,
- "__file__",
- "the existing psutil install directory",
- )
+ msg += f" (different than {__version__})"
+ what = getattr(
+ _psplatform.cext,
+ "__file__",
+ "the existing psutil install directory",
)
+ msg += f"; you may try to 'pip uninstall psutil', manually remove {what}"
msg += " or clean the virtual env somehow, then reinstall"
raise ImportError(msg)
@@ -282,12 +272,20 @@ def _pprint_secs(secs):
return datetime.datetime.fromtimestamp(secs).strftime(fmt)
+def _check_conn_kind(kind):
+ """Check net_connections()'s `kind` parameter."""
+ kinds = tuple(_common.conn_tmap)
+ if kind not in kinds:
+ msg = f"invalid kind argument {kind!r}; valid ones are: {kinds}"
+ raise ValueError(msg)
+
+
# =====================================================================
# --- Process class
# =====================================================================
-class Process(object): # noqa: UP004
+class Process:
"""Represents an OS process with the given PID.
If PID is omitted current process PID (os.getpid()) is used.
Raise NoSuchProcess if PID does not exist.
@@ -322,17 +320,14 @@ class Process(object): # noqa: UP004
if pid is None:
pid = os.getpid()
else:
- if not _PY3 and not isinstance(pid, (int, long)):
- msg = "pid must be an integer (got %r)" % pid
- raise TypeError(msg)
if pid < 0:
- msg = "pid must be a positive integer (got %s)" % pid
+ msg = f"pid must be a positive integer (got {pid})"
raise ValueError(msg)
try:
_psplatform.cext.check_pid_range(pid)
- except OverflowError:
- msg = "process PID out of range (got %s)" % pid
- raise NoSuchProcess(pid, msg=msg)
+ except OverflowError as err:
+ msg = "process PID out of range"
+ raise NoSuchProcess(pid, msg=msg) from err
self._pid = pid
self._name = None
@@ -365,9 +360,8 @@ class Process(object): # noqa: UP004
except NoSuchProcess:
if not _ignore_nsp:
msg = "process PID not found"
- raise NoSuchProcess(pid, msg=msg)
- else:
- self._gone = True
+ raise NoSuchProcess(pid, msg=msg) from None
+ self._gone = True
def _get_ident(self):
"""Return a (pid, uid) tuple which is supposed to identify a
@@ -419,10 +413,10 @@ class Process(object): # noqa: UP004
if self._create_time is not None:
info['started'] = _pprint_secs(self._create_time)
- return "%s.%s(%s)" % (
+ return "{}.{}({})".format(
self.__class__.__module__,
self.__class__.__name__,
- ", ".join(["%s=%r" % (k, v) for k, v in info.items()]),
+ ", ".join([f"{k}={v!r}" for k, v in info.items()]),
)
__repr__ = __str__
@@ -556,12 +550,12 @@ class Process(object): # noqa: UP004
valid_names = _as_dict_attrnames
if attrs is not None:
if not isinstance(attrs, (list, tuple, set, frozenset)):
- msg = "invalid attrs type %s" % type(attrs)
+ msg = f"invalid attrs type {type(attrs)}"
raise TypeError(msg)
attrs = set(attrs)
invalid_names = attrs - valid_names
if invalid_names:
- msg = "invalid attr name%s %s" % (
+ msg = "invalid attr name{} {}".format(
"s" if len(invalid_names) > 1 else "",
", ".join(map(repr, invalid_names)),
)
@@ -1049,7 +1043,7 @@ class Process(object): # noqa: UP004
"""
blocking = interval is not None and interval > 0.0
if interval is not None and interval < 0:
- msg = "interval is not positive (got %r)" % interval
+ msg = f"interval is not positive (got {interval!r})"
raise ValueError(msg)
num_cpus = cpu_count() or 1
@@ -1127,10 +1121,6 @@ class Process(object): # noqa: UP004
"""
return self._proc.memory_info()
- @_common.deprecated_method(replacement="memory_info")
- def memory_info_ex(self):
- return self.memory_info()
-
def memory_full_info(self):
"""This method returns the same information as memory_info(),
plus, on some platform (Linux, macOS, Windows), also provides
@@ -1159,9 +1149,9 @@ class Process(object): # noqa: UP004
"""
valid_types = list(_psplatform.pfullmem._fields)
if memtype not in valid_types:
- msg = "invalid memtype %r; valid types are %r" % (
- memtype,
- tuple(valid_types),
+ msg = (
+ f"invalid memtype {memtype!r}; valid types are"
+ f" {tuple(valid_types)!r}"
)
raise ValueError(msg)
fun = (
@@ -1178,7 +1168,7 @@ class Process(object): # noqa: UP004
# we should never get here
msg = (
"can't calculate process memory percent because total physical"
- " system memory is not positive (%r)" % (total_phymem)
+ f" system memory is not positive ({total_phymem!r})"
)
raise ValueError(msg)
return (value / float(total_phymem)) * 100
@@ -1203,11 +1193,11 @@ class Process(object): # noqa: UP004
path = tupl[2]
nums = tupl[3:]
try:
- d[path] = map(lambda x, y: x + y, d[path], nums)
+ d[path] = list(map(lambda x, y: x + y, d[path], nums))
except KeyError:
d[path] = nums
nt = _psplatform.pmmap_grouped
- return [nt(path, *d[path]) for path in d] # NOQA
+ return [nt(path, *d[path]) for path in d]
else:
nt = _psplatform.pmmap_ext
return [nt(*x) for x in it]
@@ -1241,6 +1231,7 @@ class Process(object): # noqa: UP004
| all | the sum of all the possible families and protocols |
+------------+----------------------------------------------------+
"""
+ _check_conn_kind(kind)
return self._proc.net_connections(kind)
@_common.deprecated_method(replacement="net_connections")
@@ -1254,7 +1245,9 @@ class Process(object): # noqa: UP004
def _send_signal(self, sig):
assert not self.pid < 0, self.pid
self._raise_if_pid_reused()
- if self.pid == 0:
+
+ pid, ppid, name = self.pid, self._ppid, self._name
+ if pid == 0:
# see "man 2 kill"
msg = (
"preventing sending signal to process with PID 0 as it "
@@ -1263,17 +1256,16 @@ class Process(object): # noqa: UP004
)
raise ValueError(msg)
try:
- os.kill(self.pid, sig)
- except ProcessLookupError:
- if OPENBSD and pid_exists(self.pid):
+ os.kill(pid, sig)
+ except ProcessLookupError as err:
+ if OPENBSD and pid_exists(pid):
# We do this because os.kill() lies in case of
# zombie processes.
- raise ZombieProcess(self.pid, self._name, self._ppid)
- else:
- self._gone = True
- raise NoSuchProcess(self.pid, self._name)
- except PermissionError:
- raise AccessDenied(self.pid, self._name)
+ raise ZombieProcess(pid, name, ppid) from err
+ self._gone = True
+ raise NoSuchProcess(pid, name) from err
+ except PermissionError as err:
+ raise AccessDenied(pid, name) from err
def send_signal(self, sig):
"""Send a signal *sig* to process pre-emptively checking
@@ -1358,11 +1350,12 @@ class Process(object): # noqa: UP004
# The valid attr names which can be processed by Process.as_dict().
# fmt: off
-_as_dict_attrnames = set(
- [x for x in dir(Process) if not x.startswith('_') and x not in
+_as_dict_attrnames = {
+ x for x in dir(Process) if not x.startswith("_") and x not in
{'send_signal', 'suspend', 'resume', 'terminate', 'kill', 'wait',
'is_running', 'as_dict', 'parent', 'parents', 'children', 'rlimit',
- 'memory_info_ex', 'connections', 'oneshot'}])
+ 'connections', 'oneshot'}
+}
# fmt: on
@@ -1439,16 +1432,13 @@ class Popen(Process):
try:
return object.__getattribute__(self.__subproc, name)
except AttributeError:
- msg = "%s instance has no attribute '%s'" % (
- self.__class__.__name__,
- name,
- )
- raise AttributeError(msg)
+ msg = f"{self.__class__!r} has no attribute {name!r}"
+ raise AttributeError(msg) from None
def wait(self, timeout=None):
if self.__subproc.returncode is not None:
return self.__subproc.returncode
- ret = super(Popen, self).wait(timeout) # noqa
+ ret = super().wait(timeout)
self.__subproc.returncode = ret
return ret
@@ -1525,7 +1515,7 @@ def process_iter(attrs=None, ad_value=None):
remove(pid)
while _pids_reused:
pid = _pids_reused.pop()
- debug("refreshing Process instance for reused PID %s" % pid)
+ debug(f"refreshing Process instance for reused PID {pid}")
remove(pid)
try:
ls = sorted(list(pmap.items()) + list(dict.fromkeys(new_pids).items()))
@@ -1542,7 +1532,7 @@ def process_iter(attrs=None, ad_value=None):
_pmap = pmap
-process_iter.cache_clear = lambda: _pmap.clear() # noqa
+process_iter.cache_clear = lambda: _pmap.clear() # noqa: PLW0108
process_iter.cache_clear.__doc__ = "Clear process_iter() internal cache."
@@ -1586,9 +1576,7 @@ def wait_procs(procs, timeout=None, callback=None):
def check_gone(proc, timeout):
try:
returncode = proc.wait(timeout=timeout)
- except TimeoutExpired:
- pass
- except _SubprocessTimeoutExpired:
+ except (TimeoutExpired, subprocess.TimeoutExpired):
pass
else:
if returncode is not None or not proc.is_running():
@@ -1599,12 +1587,12 @@ def wait_procs(procs, timeout=None, callback=None):
callback(proc)
if timeout is not None and not timeout >= 0:
- msg = "timeout must be a positive integer, got %s" % timeout
+ msg = f"timeout must be a positive integer, got {timeout}"
raise ValueError(msg)
gone = set()
alive = set(procs)
if callback is not None and not callable(callback):
- msg = "callback %r is not a callable" % callback
+ msg = f"callback {callback!r} is not a callable"
raise TypeError(msg)
if timeout is not None:
deadline = _timer() + timeout
@@ -1627,7 +1615,7 @@ def wait_procs(procs, timeout=None, callback=None):
check_gone(proc, timeout)
else:
check_gone(proc, max_timeout)
- alive = alive - gone # noqa PLR6104
+ alive = alive - gone # noqa: PLR6104
if alive:
# Last attempt over processes survived so far.
@@ -1646,7 +1634,7 @@ def wait_procs(procs, timeout=None, callback=None):
def cpu_count(logical=True):
"""Return the number of logical CPUs in the system (same as
- os.cpu_count() in Python 3.4).
+ os.cpu_count()).
If *logical* is False return the number of physical cores only
(e.g. hyper thread CPUs are excluded).
@@ -1804,7 +1792,7 @@ def cpu_percent(interval=None, percpu=False):
tid = threading.current_thread().ident
blocking = interval is not None and interval > 0.0
if interval is not None and interval < 0:
- msg = "interval is not positive (got %r)" % interval
+ msg = f"interval is not positive (got {interval})"
raise ValueError(msg)
def calculate(t1, t2):
@@ -1864,7 +1852,7 @@ def cpu_times_percent(interval=None, percpu=False):
tid = threading.current_thread().ident
blocking = interval is not None and interval > 0.0
if interval is not None and interval < 0:
- msg = "interval is not positive (got %r)" % interval
+ msg = f"interval is not positive (got {interval!r})"
raise ValueError(msg)
def calculate(t1, t2):
@@ -2202,6 +2190,7 @@ def net_connections(kind='inet'):
On macOS this function requires root privileges.
"""
+ _check_conn_kind(kind)
return _psplatform.net_connections(kind)
@@ -2223,35 +2212,46 @@ def net_if_addrs():
Note: you can have more than one address of the same family
associated with each interface.
"""
- has_enums = _PY3
- if has_enums:
- import socket
rawlist = _psplatform.net_if_addrs()
rawlist.sort(key=lambda x: x[1]) # sort by family
ret = collections.defaultdict(list)
for name, fam, addr, mask, broadcast, ptp in rawlist:
- if has_enums:
- try:
- fam = socket.AddressFamily(fam)
- except ValueError:
- if WINDOWS and fam == -1:
- fam = _psplatform.AF_LINK
- elif (
- hasattr(_psplatform, "AF_LINK")
- and fam == _psplatform.AF_LINK
- ):
- # Linux defines AF_LINK as an alias for AF_PACKET.
- # We re-set the family here so that repr(family)
- # will show AF_LINK rather than AF_PACKET
- fam = _psplatform.AF_LINK
+ try:
+ fam = socket.AddressFamily(fam)
+ except ValueError:
+ if WINDOWS and fam == -1:
+ fam = _psplatform.AF_LINK
+ elif (
+ hasattr(_psplatform, "AF_LINK") and fam == _psplatform.AF_LINK
+ ):
+ # Linux defines AF_LINK as an alias for AF_PACKET.
+ # We re-set the family here so that repr(family)
+ # will show AF_LINK rather than AF_PACKET
+ fam = _psplatform.AF_LINK
+
if fam == _psplatform.AF_LINK:
# The underlying C function may return an incomplete MAC
# address in which case we fill it with null bytes, see:
# https://github.com/giampaolo/psutil/issues/786
separator = ":" if POSIX else "-"
while addr.count(separator) < 5:
- addr += "%s00" % separator
- ret[name].append(_common.snicaddr(fam, addr, mask, broadcast, ptp))
+ addr += f"{separator}00"
+
+ nt = _common.snicaddr(fam, addr, mask, broadcast, ptp)
+
+ # On Windows broadcast is None, so we determine it via
+ # ipaddress module.
+ if WINDOWS and fam in {socket.AF_INET, socket.AF_INET6}:
+ try:
+ broadcast = _common.broadcast_addr(nt)
+ except Exception as err: # noqa: BLE001
+ debug(err)
+ else:
+ if broadcast is not None:
+ nt._replace(broadcast=broadcast)
+
+ ret[name].append(nt)
+
return dict(ret)
@@ -2404,83 +2404,4 @@ def _set_debug(value):
_psplatform.cext.set_debug(bool(value))
-def test(): # pragma: no cover
- from ._common import bytes2human
- from ._compat import get_terminal_size
-
- today_day = datetime.date.today()
- # fmt: off
- templ = "%-10s %5s %5s %7s %7s %5s %6s %6s %6s %s"
- attrs = ['pid', 'memory_percent', 'name', 'cmdline', 'cpu_times',
- 'create_time', 'memory_info', 'status', 'nice', 'username']
- print(templ % ("USER", "PID", "%MEM", "VSZ", "RSS", "NICE", # NOQA
- "STATUS", "START", "TIME", "CMDLINE"))
- # fmt: on
- for p in process_iter(attrs, ad_value=None):
- if p.info['create_time']:
- ctime = datetime.datetime.fromtimestamp(p.info['create_time'])
- if ctime.date() == today_day:
- ctime = ctime.strftime("%H:%M")
- else:
- ctime = ctime.strftime("%b%d")
- else:
- ctime = ''
- if p.info['cpu_times']:
- cputime = time.strftime(
- "%M:%S", time.localtime(sum(p.info['cpu_times']))
- )
- else:
- cputime = ''
-
- user = p.info['username'] or ''
- if not user and POSIX:
- try:
- user = p.uids()[0]
- except Error:
- pass
- if user and WINDOWS and '\\' in user:
- user = user.split('\\')[1]
- user = user[:9]
- vms = (
- bytes2human(p.info['memory_info'].vms)
- if p.info['memory_info'] is not None
- else ''
- )
- rss = (
- bytes2human(p.info['memory_info'].rss)
- if p.info['memory_info'] is not None
- else ''
- )
- memp = (
- round(p.info['memory_percent'], 1)
- if p.info['memory_percent'] is not None
- else ''
- )
- nice = int(p.info['nice']) if p.info['nice'] else ''
- if p.info['cmdline']:
- cmdline = ' '.join(p.info['cmdline'])
- else:
- cmdline = p.info['name']
- status = p.info['status'][:5] if p.info['status'] else ''
-
- line = templ % (
- user[:10],
- p.info['pid'],
- memp,
- vms,
- rss,
- nice,
- status,
- ctime,
- cputime,
- cmdline,
- )
- print(line[: get_terminal_size()[0]]) # NOQA
-
-
-del memoize_when_activated, division
-if sys.version_info[0] < 3:
- del num, x # noqa
-
-if __name__ == "__main__":
- test()
+del memoize_when_activated
diff --git a/contrib/python/psutil/py3/psutil/_common.py b/contrib/python/psutil/py3/psutil/_common.py
index 4b99b093e3..4096c0a18c 100644
--- a/contrib/python/psutil/py3/psutil/_common.py
+++ b/contrib/python/psutil/py3/psutil/_common.py
@@ -2,17 +2,14 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-"""Common objects shared by __init__.py and _ps*.py modules."""
+"""Common objects shared by __init__.py and _ps*.py modules.
-# Note: this module is imported by setup.py so it should not import
-# psutil or third-party modules.
-
-from __future__ import division
-from __future__ import print_function
+Note: this module is imported by setup.py, so it should not import
+psutil or third-party modules.
+"""
import collections
-import contextlib
-import errno
+import enum
import functools
import os
import socket
@@ -36,14 +33,6 @@ except ImportError:
AF_UNIX = None
-# can't take it from _common.py as this script is imported by setup.py
-PY3 = sys.version_info[0] >= 3
-if PY3:
- import enum
-else:
- enum = None
-
-
PSUTIL_DEBUG = bool(os.getenv('PSUTIL_DEBUG'))
_DEFAULT = object()
@@ -57,7 +46,7 @@ __all__ = [
'CONN_FIN_WAIT1', 'CONN_FIN_WAIT2', 'CONN_LAST_ACK', 'CONN_LISTEN',
'CONN_NONE', 'CONN_SYN_RECV', 'CONN_SYN_SENT', 'CONN_TIME_WAIT',
# net constants
- 'NIC_DUPLEX_FULL', 'NIC_DUPLEX_HALF', 'NIC_DUPLEX_UNKNOWN',
+ 'NIC_DUPLEX_FULL', 'NIC_DUPLEX_HALF', 'NIC_DUPLEX_UNKNOWN', # noqa: F822
# process status constants
'STATUS_DEAD', 'STATUS_DISK_SLEEP', 'STATUS_IDLE', 'STATUS_LOCKED',
'STATUS_RUNNING', 'STATUS_SLEEPING', 'STATUS_STOPPED', 'STATUS_SUSPENDED',
@@ -134,42 +123,29 @@ CONN_LISTEN = "LISTEN"
CONN_CLOSING = "CLOSING"
CONN_NONE = "NONE"
+
# net_if_stats()
-if enum is None:
+class NicDuplex(enum.IntEnum):
NIC_DUPLEX_FULL = 2
NIC_DUPLEX_HALF = 1
NIC_DUPLEX_UNKNOWN = 0
-else:
- class NicDuplex(enum.IntEnum):
- NIC_DUPLEX_FULL = 2
- NIC_DUPLEX_HALF = 1
- NIC_DUPLEX_UNKNOWN = 0
- globals().update(NicDuplex.__members__)
+globals().update(NicDuplex.__members__)
+
# sensors_battery()
-if enum is None:
+class BatteryTime(enum.IntEnum):
POWER_TIME_UNKNOWN = -1
POWER_TIME_UNLIMITED = -2
-else:
- class BatteryTime(enum.IntEnum):
- POWER_TIME_UNKNOWN = -1
- POWER_TIME_UNLIMITED = -2
- globals().update(BatteryTime.__members__)
+globals().update(BatteryTime.__members__)
# --- others
ENCODING = sys.getfilesystemencoding()
-if not PY3:
- ENCODING_ERRS = "replace"
-else:
- try:
- ENCODING_ERRS = sys.getfilesystemencodeerrors() # py 3.6
- except AttributeError:
- ENCODING_ERRS = "surrogateescape" if POSIX else "replace"
+ENCODING_ERRS = sys.getfilesystemencodeerrors()
# ===================================================================
@@ -273,7 +249,7 @@ if AF_INET6 is not None:
"udp6": ([AF_INET6], [SOCK_DGRAM]),
})
-if AF_UNIX is not None:
+if AF_UNIX is not None and not SUNOS:
conn_tmap.update({"unix": ([AF_UNIX], [SOCK_STREAM, SOCK_DGRAM])})
@@ -293,9 +269,7 @@ class Error(Exception):
info = collections.OrderedDict()
for name in attrs:
value = getattr(self, name, None)
- if value: # noqa
- info[name] = value
- elif name == "pid" and value == 0:
+ if value or (name == "pid" and value == 0):
info[name] = value
return info
@@ -303,8 +277,8 @@ class Error(Exception):
# invoked on `raise Error`
info = self._infodict(("pid", "ppid", "name"))
if info:
- details = "(%s)" % ", ".join(
- ["%s=%r" % (k, v) for k, v in info.items()]
+ details = "({})".format(
+ ", ".join([f"{k}={v!r}" for k, v in info.items()])
)
else:
details = None
@@ -313,8 +287,8 @@ class Error(Exception):
def __repr__(self):
# invoked on `repr(Error)`
info = self._infodict(("pid", "ppid", "name", "seconds", "msg"))
- details = ", ".join(["%s=%r" % (k, v) for k, v in info.items()])
- return "psutil.%s(%s)" % (self.__class__.__name__, details)
+ details = ", ".join([f"{k}={v!r}" for k, v in info.items()])
+ return f"psutil.{self.__class__.__name__}({details})"
class NoSuchProcess(Error):
@@ -380,7 +354,7 @@ class TimeoutExpired(Error):
self.seconds = seconds
self.pid = pid
self.name = name
- self.msg = "timeout after %s seconds" % seconds
+ self.msg = f"timeout after {seconds} seconds"
def __reduce__(self):
return (self.__class__, (self.seconds, self.pid, self.name))
@@ -391,26 +365,6 @@ class TimeoutExpired(Error):
# ===================================================================
-# This should be in _compat.py rather than here, but does not work well
-# with setup.py importing this module via a sys.path trick.
-if PY3:
- if isinstance(__builtins__, dict): # cpython
- exec_ = __builtins__["exec"]
- else: # pypy
- exec_ = getattr(__builtins__, "exec") # noqa
-
- exec_("""def raise_from(value, from_value):
- try:
- raise value from from_value
- finally:
- value = None
- """)
-else:
-
- def raise_from(value, from_value):
- raise value
-
-
def usage_percent(used, total, round_=None):
"""Calculate percentage usage of 'used' against 'total'."""
try:
@@ -456,7 +410,7 @@ def memoize(fun):
try:
ret = cache[key] = fun(*args, **kwargs)
except Exception as err: # noqa: BLE001
- raise raise_from(err, None)
+ raise err from None
return ret
def cache_clear():
@@ -505,14 +459,14 @@ def memoize_when_activated(fun):
try:
return fun(self)
except Exception as err: # noqa: BLE001
- raise raise_from(err, None)
+ raise err from None
except KeyError:
# case 3: we entered oneshot() ctx but there's no cache
# for this entry yet
try:
ret = fun(self)
except Exception as err: # noqa: BLE001
- raise raise_from(err, None)
+ raise err from None
try:
self._cache[fun] = ret
except AttributeError:
@@ -546,9 +500,9 @@ def isfile_strict(path):
"""
try:
st = os.stat(path)
- except OSError as err:
- if err.errno in {errno.EPERM, errno.EACCES}:
- raise
+ except PermissionError:
+ raise
+ except OSError:
return False
else:
return stat.S_ISREG(st.st_mode)
@@ -561,9 +515,9 @@ def path_exists_strict(path):
"""
try:
os.stat(path)
- except OSError as err:
- if err.errno in {errno.EPERM, errno.EACCES}:
- raise
+ except PermissionError:
+ raise
+ except OSError:
return False
else:
return True
@@ -575,11 +529,10 @@ def supports_ipv6():
if not socket.has_ipv6 or AF_INET6 is None:
return False
try:
- sock = socket.socket(AF_INET6, socket.SOCK_STREAM)
- with contextlib.closing(sock):
+ with socket.socket(AF_INET6, socket.SOCK_STREAM) as sock:
sock.bind(("::1", 0))
return True
- except socket.error:
+ except OSError:
return False
@@ -615,26 +568,20 @@ def sockfam_to_enum(num):
"""Convert a numeric socket family value to an IntEnum member.
If it's not a known member, return the numeric value itself.
"""
- if enum is None:
+ try:
+ return socket.AddressFamily(num)
+ except ValueError:
return num
- else: # pragma: no cover
- try:
- return socket.AddressFamily(num)
- except ValueError:
- return num
def socktype_to_enum(num):
"""Convert a numeric socket type value to an IntEnum member.
If it's not a known member, return the numeric value itself.
"""
- if enum is None:
+ try:
+ return socket.SocketKind(num)
+ except ValueError:
return num
- else: # pragma: no cover
- try:
- return socket.SocketKind(num)
- except ValueError:
- return num
def conn_to_ntuple(fd, fam, type_, laddr, raddr, status, status_map, pid=None):
@@ -656,15 +603,37 @@ def conn_to_ntuple(fd, fam, type_, laddr, raddr, status, status_map, pid=None):
return sconn(fd, fam, type_, laddr, raddr, status, pid)
+def broadcast_addr(addr):
+ """Given the address ntuple returned by ``net_if_addrs()``
+ calculates the broadcast address.
+ """
+ import ipaddress
+
+ if not addr.address or not addr.netmask:
+ return None
+ if addr.family == socket.AF_INET:
+ return str(
+ ipaddress.IPv4Network(
+ f"{addr.address}/{addr.netmask}", strict=False
+ ).broadcast_address
+ )
+ if addr.family == socket.AF_INET6:
+ return str(
+ ipaddress.IPv6Network(
+ f"{addr.address}/{addr.netmask}", strict=False
+ ).broadcast_address
+ )
+
+
def deprecated_method(replacement):
"""A decorator which can be used to mark a method as deprecated
'replcement' is the method name which will be called instead.
"""
def outer(fun):
- msg = "%s() is deprecated and will be removed; use %s() instead" % (
- fun.__name__,
- replacement,
+ msg = (
+ f"{fun.__name__}() is deprecated and will be removed; use"
+ f" {replacement}() instead"
)
if fun.__doc__ is None:
fun.__doc__ = msg
@@ -789,8 +758,6 @@ wrap_numbers.cache_info = _wn.cache_info
# is 8K. We use a bigger buffer (32K) in order to have more consistent
# results when reading /proc pseudo files on Linux, see:
# https://github.com/giampaolo/psutil/issues/2050
-# On Python 2 this also speeds up the reading of big files:
-# (namely /proc/{pid}/smaps and /proc/net/*):
# https://github.com/giampaolo/psutil/issues/708
FILE_READ_BUFFER_SIZE = 32 * 1024
@@ -800,17 +767,13 @@ def open_binary(fname):
def open_text(fname):
- """On Python 3 opens a file in text mode by using fs encoding and
- a proper en/decoding errors handler.
- On Python 2 this is just an alias for open(name, 'rt').
+ """Open a file in text mode by using the proper FS encoding and
+ en/decoding error handlers.
"""
- if not PY3:
- return open(fname, buffering=FILE_READ_BUFFER_SIZE)
-
# See:
# https://github.com/giampaolo/psutil/issues/675
# https://github.com/giampaolo/psutil/pull/733
- fobj = open(
+ fobj = open( # noqa: SIM115
fname,
buffering=FILE_READ_BUFFER_SIZE,
encoding=ENCODING,
@@ -842,7 +805,7 @@ def cat(fname, fallback=_DEFAULT, _open=open_text):
try:
with _open(fname) as f:
return f.read()
- except (IOError, OSError):
+ except OSError:
return fallback
@@ -852,7 +815,7 @@ def bcat(fname, fallback=_DEFAULT):
def bytes2human(n, format="%(value).1f%(symbol)s"):
- """Used by various scripts. See: http://goo.gl/zeJZl.
+ """Used by various scripts. See: https://code.activestate.com/recipes/578019-bytes-to-human-human-to-bytes-converter/?in=user-4178764.
>>> bytes2human(10000)
'9.8K'
@@ -875,15 +838,8 @@ def get_procfs_path():
return sys.modules['psutil'].PROCFS_PATH
-if PY3:
-
- def decode(s):
- return s.decode(encoding=ENCODING, errors=ENCODING_ERRS)
-
-else:
-
- def decode(s):
- return s
+def decode(s):
+ return s.decode(encoding=ENCODING, errors=ENCODING_ERRS)
# =====================================================================
@@ -927,13 +883,12 @@ def hilite(s, color=None, bold=False): # pragma: no cover
try:
color = colors[color]
except KeyError:
- raise ValueError(
- "invalid color %r; choose between %s" % (list(colors.keys()))
- )
+ msg = f"invalid color {color!r}; choose amongst {list(colors.keys())}"
+ raise ValueError(msg) from None
attr.append(color)
if bold:
attr.append('1')
- return '\x1b[%sm%s\x1b[0m' % (';'.join(attr), s)
+ return f"\x1b[{';'.join(attr)}m{s}\x1b[0m"
def print_color(
@@ -941,9 +896,9 @@ def print_color(
): # pragma: no cover
"""Print a colorized version of string."""
if not term_supports_colors():
- print(s, file=file) # NOQA
+ print(s, file=file)
elif POSIX:
- print(hilite(s, color, bold), file=file) # NOQA
+ print(hilite(s, color, bold), file=file)
else:
import ctypes
@@ -958,10 +913,11 @@ def print_color(
try:
color = colors[color]
except KeyError:
- raise ValueError(
- "invalid color %r; choose between %r"
- % (color, list(colors.keys()))
+ msg = (
+ f"invalid color {color!r}; choose between"
+ f" {list(colors.keys())!r}"
)
+ raise ValueError(msg) from None
if bold and color <= 7:
color += 8
@@ -970,7 +926,7 @@ def print_color(
handle = GetStdHandle(handle_id)
SetConsoleTextAttribute(handle, color)
try:
- print(s, file=file) # NOQA
+ print(s, file=file)
finally:
SetConsoleTextAttribute(handle, DEFAULT_COLOR)
@@ -984,11 +940,11 @@ def debug(msg):
inspect.currentframe().f_back
)
if isinstance(msg, Exception):
- if isinstance(msg, (OSError, IOError, EnvironmentError)):
+ if isinstance(msg, OSError):
# ...because str(exc) may contain info about the file name
- msg = "ignoring %s" % msg
+ msg = f"ignoring {msg}"
else:
- msg = "ignoring %r" % msg
- print( # noqa
- "psutil-debug [%s:%s]> %s" % (fname, lineno, msg), file=sys.stderr
+ msg = f"ignoring {msg!r}"
+ print( # noqa: T201
+ f"psutil-debug [{fname}:{lineno}]> {msg}", file=sys.stderr
)
diff --git a/contrib/python/psutil/py3/psutil/_compat.py b/contrib/python/psutil/py3/psutil/_compat.py
deleted file mode 100644
index 92e01713c3..0000000000
--- a/contrib/python/psutil/py3/psutil/_compat.py
+++ /dev/null
@@ -1,477 +0,0 @@
-# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Module which provides compatibility with older Python versions.
-This is more future-compatible rather than the opposite (prefer latest
-Python 3 way of doing things).
-"""
-
-import collections
-import contextlib
-import errno
-import functools
-import os
-import sys
-import types
-
-
-# fmt: off
-__all__ = [
- # constants
- "PY3",
- # builtins
- "long", "range", "super", "unicode", "basestring",
- # literals
- "b",
- # collections module
- "lru_cache",
- # shutil module
- "which", "get_terminal_size",
- # contextlib module
- "redirect_stderr",
- # python 3 exceptions
- "FileNotFoundError", "PermissionError", "ProcessLookupError",
- "InterruptedError", "ChildProcessError", "FileExistsError",
-]
-# fmt: on
-
-
-PY3 = sys.version_info[0] >= 3
-_SENTINEL = object()
-
-if PY3:
- long = int
- xrange = range
- unicode = str
- basestring = str
- range = range
-
- def b(s):
- return s.encode("latin-1")
-
-else:
- long = long
- range = xrange
- unicode = unicode
- basestring = basestring
-
- def b(s):
- return s
-
-
-# --- builtins
-
-
-# Python 3 super().
-# Taken from "future" package.
-# Credit: Ryan Kelly
-if PY3:
- super = super
-else:
- _builtin_super = super
-
- def super(type_=_SENTINEL, type_or_obj=_SENTINEL, framedepth=1):
- """Like Python 3 builtin super(). If called without any arguments
- it attempts to infer them at runtime.
- """
- if type_ is _SENTINEL:
- f = sys._getframe(framedepth)
- try:
- # Get the function's first positional argument.
- type_or_obj = f.f_locals[f.f_code.co_varnames[0]]
- except (IndexError, KeyError):
- msg = 'super() used in a function with no args'
- raise RuntimeError(msg)
- try:
- # Get the MRO so we can crawl it.
- mro = type_or_obj.__mro__
- except (AttributeError, RuntimeError):
- try:
- mro = type_or_obj.__class__.__mro__
- except AttributeError:
- msg = 'super() used in a non-newstyle class'
- raise RuntimeError(msg)
- for type_ in mro:
- # Find the class that owns the currently-executing method.
- for meth in type_.__dict__.values():
- # Drill down through any wrappers to the underlying func.
- # This handles e.g. classmethod() and staticmethod().
- try:
- while not isinstance(meth, types.FunctionType):
- if isinstance(meth, property):
- # Calling __get__ on the property will invoke
- # user code which might throw exceptions or
- # have side effects
- meth = meth.fget
- else:
- try:
- meth = meth.__func__
- except AttributeError:
- meth = meth.__get__(type_or_obj, type_)
- except (AttributeError, TypeError):
- continue
- if meth.func_code is f.f_code:
- break # found
- else:
- # Not found. Move onto the next class in MRO.
- continue
- break # found
- else:
- msg = 'super() called outside a method'
- raise RuntimeError(msg)
-
- # Dispatch to builtin super().
- if type_or_obj is not _SENTINEL:
- return _builtin_super(type_, type_or_obj)
- return _builtin_super(type_)
-
-
-# --- exceptions
-
-
-if PY3:
- FileNotFoundError = FileNotFoundError # NOQA
- PermissionError = PermissionError # NOQA
- ProcessLookupError = ProcessLookupError # NOQA
- InterruptedError = InterruptedError # NOQA
- ChildProcessError = ChildProcessError # NOQA
- FileExistsError = FileExistsError # NOQA
-else:
- # https://github.com/PythonCharmers/python-future/blob/exceptions/
- # src/future/types/exceptions/pep3151.py
- import platform
-
- def _instance_checking_exception(base_exception=Exception):
- def wrapped(instance_checker):
- class TemporaryClass(base_exception):
- def __init__(self, *args, **kwargs):
- if len(args) == 1 and isinstance(args[0], TemporaryClass):
- unwrap_me = args[0]
- for attr in dir(unwrap_me):
- if not attr.startswith('__'):
- setattr(self, attr, getattr(unwrap_me, attr))
- else:
- super(TemporaryClass, self).__init__( # noqa
- *args, **kwargs
- )
-
- class __metaclass__(type):
- def __instancecheck__(cls, inst):
- return instance_checker(inst)
-
- def __subclasscheck__(cls, classinfo):
- value = sys.exc_info()[1]
- return isinstance(value, cls)
-
- TemporaryClass.__name__ = instance_checker.__name__
- TemporaryClass.__doc__ = instance_checker.__doc__
- return TemporaryClass
-
- return wrapped
-
- @_instance_checking_exception(EnvironmentError)
- def FileNotFoundError(inst):
- return getattr(inst, 'errno', _SENTINEL) == errno.ENOENT
-
- @_instance_checking_exception(EnvironmentError)
- def ProcessLookupError(inst):
- return getattr(inst, 'errno', _SENTINEL) == errno.ESRCH
-
- @_instance_checking_exception(EnvironmentError)
- def PermissionError(inst):
- return getattr(inst, 'errno', _SENTINEL) in {errno.EACCES, errno.EPERM}
-
- @_instance_checking_exception(EnvironmentError)
- def InterruptedError(inst):
- return getattr(inst, 'errno', _SENTINEL) == errno.EINTR
-
- @_instance_checking_exception(EnvironmentError)
- def ChildProcessError(inst):
- return getattr(inst, 'errno', _SENTINEL) == errno.ECHILD
-
- @_instance_checking_exception(EnvironmentError)
- def FileExistsError(inst):
- return getattr(inst, 'errno', _SENTINEL) == errno.EEXIST
-
- if platform.python_implementation() != "CPython":
- try:
- raise OSError(errno.EEXIST, "perm")
- except FileExistsError:
- pass
- except OSError:
- msg = (
- "broken or incompatible Python implementation, see: "
- "https://github.com/giampaolo/psutil/issues/1659"
- )
- raise RuntimeError(msg)
-
-
-# --- stdlib additions
-
-
-# py 3.2 functools.lru_cache
-# Taken from: http://code.activestate.com/recipes/578078
-# Credit: Raymond Hettinger
-try:
- from functools import lru_cache
-except ImportError:
- try:
- from threading import RLock
- except ImportError:
- from dummy_threading import RLock
-
- _CacheInfo = collections.namedtuple(
- "CacheInfo", ["hits", "misses", "maxsize", "currsize"]
- )
-
- class _HashedSeq(list): # noqa: FURB189
- __slots__ = ('hashvalue',)
-
- def __init__(self, tup, hash=hash):
- self[:] = tup
- self.hashvalue = hash(tup)
-
- def __hash__(self):
- return self.hashvalue
-
- def _make_key(
- args,
- kwds,
- typed,
- kwd_mark=(_SENTINEL,),
- fasttypes=set((int, str, frozenset, type(None))), # noqa
- sorted=sorted,
- tuple=tuple,
- type=type,
- len=len,
- ):
- key = args
- if kwds:
- sorted_items = sorted(kwds.items())
- key += kwd_mark
- for item in sorted_items:
- key += item
- if typed:
- key += tuple(type(v) for v in args)
- if kwds:
- key += tuple(type(v) for k, v in sorted_items)
- elif len(key) == 1 and type(key[0]) in fasttypes:
- return key[0]
- return _HashedSeq(key)
-
- def lru_cache(maxsize=100, typed=False):
- """Least-recently-used cache decorator, see:
- http://docs.python.org/3/library/functools.html#functools.lru_cache.
- """
-
- def decorating_function(user_function):
- cache = {}
- stats = [0, 0]
- HITS, MISSES = 0, 1
- make_key = _make_key
- cache_get = cache.get
- _len = len
- lock = RLock()
- root = []
- root[:] = [root, root, None, None]
- nonlocal_root = [root]
- PREV, NEXT, KEY, RESULT = 0, 1, 2, 3
- if maxsize == 0:
-
- def wrapper(*args, **kwds):
- result = user_function(*args, **kwds)
- stats[MISSES] += 1
- return result
-
- elif maxsize is None:
-
- def wrapper(*args, **kwds):
- key = make_key(args, kwds, typed)
- result = cache_get(key, root)
- if result is not root:
- stats[HITS] += 1
- return result
- result = user_function(*args, **kwds)
- cache[key] = result
- stats[MISSES] += 1
- return result
-
- else:
-
- def wrapper(*args, **kwds):
- if kwds or typed:
- key = make_key(args, kwds, typed)
- else:
- key = args
- lock.acquire()
- try:
- link = cache_get(key)
- if link is not None:
- (root,) = nonlocal_root
- link_prev, link_next, key, result = link
- link_prev[NEXT] = link_next
- link_next[PREV] = link_prev
- last = root[PREV]
- last[NEXT] = root[PREV] = link
- link[PREV] = last
- link[NEXT] = root
- stats[HITS] += 1
- return result
- finally:
- lock.release()
- result = user_function(*args, **kwds)
- lock.acquire()
- try:
- (root,) = nonlocal_root
- if key in cache:
- pass
- elif _len(cache) >= maxsize:
- oldroot = root
- oldroot[KEY] = key
- oldroot[RESULT] = result
- root = nonlocal_root[0] = oldroot[NEXT]
- oldkey = root[KEY]
- root[KEY] = root[RESULT] = None
- del cache[oldkey]
- cache[key] = oldroot
- else:
- last = root[PREV]
- link = [last, root, key, result]
- last[NEXT] = root[PREV] = cache[key] = link
- stats[MISSES] += 1
- finally:
- lock.release()
- return result
-
- def cache_info():
- """Report cache statistics."""
- lock.acquire()
- try:
- return _CacheInfo(
- stats[HITS], stats[MISSES], maxsize, len(cache)
- )
- finally:
- lock.release()
-
- def cache_clear():
- """Clear the cache and cache statistics."""
- lock.acquire()
- try:
- cache.clear()
- root = nonlocal_root[0]
- root[:] = [root, root, None, None]
- stats[:] = [0, 0]
- finally:
- lock.release()
-
- wrapper.__wrapped__ = user_function
- wrapper.cache_info = cache_info
- wrapper.cache_clear = cache_clear
- return functools.update_wrapper(wrapper, user_function)
-
- return decorating_function
-
-
-# python 3.3
-try:
- from shutil import which
-except ImportError:
-
- def which(cmd, mode=os.F_OK | os.X_OK, path=None):
- """Given a command, mode, and a PATH string, return the path which
- conforms to the given mode on the PATH, or None if there is no such
- file.
-
- `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result
- of os.environ.get("PATH"), or can be overridden with a custom search
- path.
- """
-
- def _access_check(fn, mode):
- return (
- os.path.exists(fn)
- and os.access(fn, mode)
- and not os.path.isdir(fn)
- )
-
- if os.path.dirname(cmd):
- if _access_check(cmd, mode):
- return cmd
- return None
-
- if path is None:
- path = os.environ.get("PATH", os.defpath)
- if not path:
- return None
- path = path.split(os.pathsep)
-
- if sys.platform == "win32":
- if os.curdir not in path:
- path.insert(0, os.curdir)
-
- pathext = os.environ.get("PATHEXT", "").split(os.pathsep)
- if any(cmd.lower().endswith(ext.lower()) for ext in pathext):
- files = [cmd]
- else:
- files = [cmd + ext for ext in pathext]
- else:
- files = [cmd]
-
- seen = set()
- for dir in path:
- normdir = os.path.normcase(dir)
- if normdir not in seen:
- seen.add(normdir)
- for thefile in files:
- name = os.path.join(dir, thefile)
- if _access_check(name, mode):
- return name
- return None
-
-
-# python 3.3
-try:
- from shutil import get_terminal_size
-except ImportError:
-
- def get_terminal_size(fallback=(80, 24)):
- try:
- import fcntl
- import struct
- import termios
- except ImportError:
- return fallback
- else:
- try:
- # This should work on Linux.
- res = struct.unpack(
- 'hh', fcntl.ioctl(1, termios.TIOCGWINSZ, '1234')
- )
- return (res[1], res[0])
- except Exception: # noqa: BLE001
- return fallback
-
-
-# python 3.3
-try:
- from subprocess import TimeoutExpired as SubprocessTimeoutExpired
-except ImportError:
-
- class SubprocessTimeoutExpired(Exception):
- pass
-
-
-# python 3.5
-try:
- from contextlib import redirect_stderr
-except ImportError:
-
- @contextlib.contextmanager
- def redirect_stderr(new_target):
- original = sys.stderr
- try:
- sys.stderr = new_target
- yield new_target
- finally:
- sys.stderr = original
diff --git a/contrib/python/psutil/py3/psutil/_psaix.py b/contrib/python/psutil/py3/psutil/_psaix.py
index 2ccc638bce..ba2725fdc1 100644
--- a/contrib/python/psutil/py3/psutil/_psaix.py
+++ b/contrib/python/psutil/py3/psutil/_psaix.py
@@ -28,10 +28,6 @@ from ._common import conn_to_ntuple
from ._common import get_procfs_path
from ._common import memoize_when_activated
from ._common import usage_percent
-from ._compat import PY3
-from ._compat import FileNotFoundError
-from ._compat import PermissionError
-from ._compat import ProcessLookupError
__extra__all__ = ["PROCFS_PATH"]
@@ -148,12 +144,10 @@ def cpu_count_cores():
cmd = ["lsdev", "-Cc", "processor"]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
- if PY3:
- stdout, stderr = (
- x.decode(sys.stdout.encoding) for x in (stdout, stderr)
- )
+ stdout, stderr = (x.decode(sys.stdout.encoding) for x in (stdout, stderr))
if p.returncode != 0:
- raise RuntimeError("%r command error\n%s" % (cmd, stderr))
+ msg = f"{cmd!r} command error\n{stderr}"
+ raise RuntimeError(msg)
processors = stdout.strip().splitlines()
return len(processors) or None
@@ -211,12 +205,6 @@ def net_connections(kind, _pid=-1):
"""Return socket connections. If pid == -1 return system-wide
connections (as opposed to connections opened by one process only).
"""
- cmap = _common.conn_tmap
- if kind not in cmap:
- raise ValueError(
- "invalid %r kind argument; choose between %s"
- % (kind, ', '.join([repr(x) for x in cmap]))
- )
families, types = _common.conn_tmap[kind]
rawlist = cext.net_connections(_pid)
ret = []
@@ -243,7 +231,7 @@ def net_connections(kind, _pid=-1):
def net_if_stats():
"""Get NIC stats (isup, duplex, speed, mtu)."""
duplex_map = {"Full": NIC_DUPLEX_FULL, "Half": NIC_DUPLEX_HALF}
- names = set([x[0] for x in net_if_addrs()])
+ names = {x[0] for x in net_if_addrs()}
ret = {}
for name in names:
mtu = cext_posix.net_if_mtu(name)
@@ -260,10 +248,9 @@ def net_if_stats():
stderr=subprocess.PIPE,
)
stdout, stderr = p.communicate()
- if PY3:
- stdout, stderr = (
- x.decode(sys.stdout.encoding) for x in (stdout, stderr)
- )
+ stdout, stderr = (
+ x.decode(sys.stdout.encoding) for x in (stdout, stderr)
+ )
if p.returncode == 0:
re_result = re.search(
r"Running: (\d+) Mbps.*?(\w+) Duplex", stdout
@@ -330,18 +317,18 @@ def wrap_exceptions(fun):
@functools.wraps(fun)
def wrapper(self, *args, **kwargs):
+ pid, ppid, name = self.pid, self._ppid, self._name
try:
return fun(self, *args, **kwargs)
- except (FileNotFoundError, ProcessLookupError):
+ except (FileNotFoundError, ProcessLookupError) as err:
# ENOENT (no such file or directory) gets raised on open().
# ESRCH (no such process) can get raised on read() if
# process is gone in meantime.
- if not pid_exists(self.pid):
- raise NoSuchProcess(self.pid, self._name)
- else:
- raise ZombieProcess(self.pid, self._name, self._ppid)
- except PermissionError:
- raise AccessDenied(self.pid, self._name)
+ if not pid_exists(pid):
+ raise NoSuchProcess(pid, name) from err
+ raise ZombieProcess(pid, name, ppid) from err
+ except PermissionError as err:
+ raise AccessDenied(pid, name) from err
return wrapper
@@ -444,7 +431,7 @@ class Process:
# is no longer there.
if not retlist:
# will raise NSP if process is gone
- os.stat('%s/%s' % (self._procfs_path, self.pid))
+ os.stat(f"{self._procfs_path}/{self.pid}")
return retlist
@wrap_exceptions
@@ -457,7 +444,7 @@ class Process:
# is no longer there.
if not ret:
# will raise NSP if process is gone
- os.stat('%s/%s' % (self._procfs_path, self.pid))
+ os.stat(f"{self._procfs_path}/{self.pid}")
return ret
@wrap_exceptions
@@ -503,10 +490,10 @@ class Process:
def cwd(self):
procfs_path = self._procfs_path
try:
- result = os.readlink("%s/%s/cwd" % (procfs_path, self.pid))
+ result = os.readlink(f"{procfs_path}/{self.pid}/cwd")
return result.rstrip('/')
except FileNotFoundError:
- os.stat("%s/%s" % (procfs_path, self.pid)) # raise NSP or AD
+ os.stat(f"{procfs_path}/{self.pid}") # raise NSP or AD
return ""
@wrap_exceptions
@@ -533,10 +520,9 @@ class Process:
stderr=subprocess.PIPE,
)
stdout, stderr = p.communicate()
- if PY3:
- stdout, stderr = (
- x.decode(sys.stdout.encoding) for x in (stdout, stderr)
- )
+ stdout, stderr = (
+ x.decode(sys.stdout.encoding) for x in (stdout, stderr)
+ )
if "no such process" in stderr.lower():
raise NoSuchProcess(self.pid, self._name)
procfiles = re.findall(r"(\d+): S_IFREG.*name:(.*)\n", stdout)
@@ -554,7 +540,7 @@ class Process:
def num_fds(self):
if self.pid == 0: # no /proc/0/fd
return 0
- return len(os.listdir("%s/%s/fd" % (self._procfs_path, self.pid)))
+ return len(os.listdir(f"{self._procfs_path}/{self.pid}/fd"))
@wrap_exceptions
def num_ctx_switches(self):
@@ -570,10 +556,10 @@ class Process:
def io_counters(self):
try:
rc, wc, rb, wb = cext.proc_io_counters(self.pid)
- except OSError:
+ except OSError as err:
# if process is terminated, proc_io_counters returns OSError
# instead of NSP
if not pid_exists(self.pid):
- raise NoSuchProcess(self.pid, self._name)
+ raise NoSuchProcess(self.pid, self._name) from err
raise
return _common.pio(rc, wc, rb, wb)
diff --git a/contrib/python/psutil/py3/psutil/_psbsd.py b/contrib/python/psutil/py3/psutil/_psbsd.py
index 77b99c0fd8..13bd926fab 100644
--- a/contrib/python/psutil/py3/psutil/_psbsd.py
+++ b/contrib/python/psutil/py3/psutil/_psbsd.py
@@ -10,7 +10,7 @@ import functools
import os
from collections import defaultdict
from collections import namedtuple
-from xml.etree import ElementTree # noqa ICN001
+from xml.etree import ElementTree # noqa: ICN001
from . import _common
from . import _psposix
@@ -28,10 +28,6 @@ from ._common import debug
from ._common import memoize
from ._common import memoize_when_activated
from ._common import usage_percent
-from ._compat import FileNotFoundError
-from ._compat import PermissionError
-from ._compat import ProcessLookupError
-from ._compat import which
__extra__all__ = []
@@ -196,8 +192,8 @@ def virtual_memory():
# #2233), so zabbix seems to be wrong. Htop calculates it
# differently, and the used value seem more realistic, so let's
# match htop.
- # https://github.com/htop-dev/htop/blob/e7f447b/netbsd/NetBSDProcessList.c#L162 # noqa
- # https://github.com/zabbix/zabbix/blob/af5e0f8/src/libs/zbxsysinfo/netbsd/memory.c#L135 # noqa
+ # https://github.com/htop-dev/htop/blob/e7f447b/netbsd/NetBSDProcessList.c#L162
+ # https://github.com/zabbix/zabbix/blob/af5e0f8/src/libs/zbxsysinfo/netbsd/memory.c#L135
used = active + wired
avail = total - used
else:
@@ -206,7 +202,7 @@ def virtual_memory():
# * https://people.freebsd.org/~rse/dist/freebsd-memory
# * https://www.cyberciti.biz/files/scripts/freebsd-memory.pl.txt
# matches zabbix:
- # * https://github.com/zabbix/zabbix/blob/af5e0f8/src/libs/zbxsysinfo/freebsd/memory.c#L143 # noqa
+ # * https://github.com/zabbix/zabbix/blob/af5e0f8/src/libs/zbxsysinfo/freebsd/memory.c#L143
avail = inactive + cached + free
used = active + wired + cached
@@ -439,14 +435,8 @@ def net_if_stats():
def net_connections(kind):
"""System-wide network connections."""
- if kind not in _common.conn_tmap:
- raise ValueError(
- "invalid %r kind argument; choose between %s"
- % (kind, ', '.join([repr(x) for x in conn_tmap]))
- )
families, types = conn_tmap[kind]
ret = set()
-
if OPENBSD:
rawlist = cext.net_connections(-1, families, types)
elif NETBSD:
@@ -495,7 +485,7 @@ if FREEBSD:
current, high = cext.sensors_cpu_temperature(cpu)
if high <= 0:
high = None
- name = "Core %s" % cpu
+ name = f"Core {cpu}"
ret["coretemp"].append(
_common.shwtemp(name, current, high, high)
)
@@ -600,21 +590,18 @@ def wrap_exceptions(fun):
@functools.wraps(fun)
def wrapper(self, *args, **kwargs):
+ pid, ppid, name = self.pid, self._ppid, self._name
try:
return fun(self, *args, **kwargs)
- except ProcessLookupError:
- if is_zombie(self.pid):
- raise ZombieProcess(self.pid, self._name, self._ppid)
- else:
- raise NoSuchProcess(self.pid, self._name)
- except PermissionError:
- raise AccessDenied(self.pid, self._name)
- except OSError:
- if self.pid == 0:
- if 0 in pids():
- raise AccessDenied(self.pid, self._name)
- else:
- raise
+ except ProcessLookupError as err:
+ if is_zombie(pid):
+ raise ZombieProcess(pid, name, ppid) from err
+ raise NoSuchProcess(pid, name) from err
+ except PermissionError as err:
+ raise AccessDenied(pid, name) from err
+ except OSError as err:
+ if pid == 0 and 0 in pids():
+ raise AccessDenied(pid, name) from err
raise
return wrapper
@@ -623,18 +610,19 @@ def wrap_exceptions(fun):
@contextlib.contextmanager
def wrap_exceptions_procfs(inst):
"""Same as above, for routines relying on reading /proc fs."""
+ pid, name, ppid = inst.pid, inst._name, inst._ppid
try:
yield
- except (ProcessLookupError, FileNotFoundError):
+ except (ProcessLookupError, FileNotFoundError) as err:
# ENOENT (no such file or directory) gets raised on open().
# ESRCH (no such process) can get raised on read() if
# process is gone in meantime.
if is_zombie(inst.pid):
- raise ZombieProcess(inst.pid, inst._name, inst._ppid)
+ raise ZombieProcess(pid, name, ppid) from err
else:
- raise NoSuchProcess(inst.pid, inst._name)
- except PermissionError:
- raise AccessDenied(inst.pid, inst._name)
+ raise NoSuchProcess(pid, name) from err
+ except PermissionError as err:
+ raise AccessDenied(pid, name) from err
class Process:
@@ -683,16 +671,18 @@ class Process:
# /proc/0 dir exists but /proc/0/exe doesn't
return ""
with wrap_exceptions_procfs(self):
- return os.readlink("/proc/%s/exe" % self.pid)
+ return os.readlink(f"/proc/{self.pid}/exe")
else:
# OpenBSD: exe cannot be determined; references:
# https://chromium.googlesource.com/chromium/src/base/+/
# master/base_paths_posix.cc
# We try our best guess by using which against the first
# cmdline arg (may return None).
+ import shutil
+
cmdline = self.cmdline()
if cmdline:
- return which(cmdline[0]) or ""
+ return shutil.which(cmdline[0]) or ""
else:
return ""
@@ -709,15 +699,15 @@ class Process:
return cext.proc_cmdline(self.pid)
except OSError as err:
if err.errno == errno.EINVAL:
+ pid, name, ppid = self.pid, self._name, self._ppid
if is_zombie(self.pid):
- raise ZombieProcess(self.pid, self._name, self._ppid)
- elif not pid_exists(self.pid):
- raise NoSuchProcess(self.pid, self._name, self._ppid)
- else:
- # XXX: this happens with unicode tests. It means the C
- # routine is unable to decode invalid unicode chars.
- debug("ignoring %r and returning an empty list" % err)
- return []
+ raise ZombieProcess(pid, name, ppid) from err
+ if not pid_exists(self.pid):
+ raise NoSuchProcess(pid, name, ppid) from err
+ # XXX: this happens with unicode tests. It means the C
+ # routine is unable to decode invalid unicode chars.
+ debug(f"ignoring {err!r} and returning an empty list")
+ return []
else:
raise
else:
@@ -822,11 +812,6 @@ class Process:
@wrap_exceptions
def net_connections(self, kind='inet'):
- if kind not in conn_tmap:
- raise ValueError(
- "invalid %r kind argument; choose between %s"
- % (kind, ', '.join([repr(x) for x in conn_tmap]))
- )
families, types = conn_tmap[kind]
ret = []
@@ -945,12 +930,11 @@ class Process:
# Pre-emptively check if CPUs are valid because the C
# function has a weird behavior in case of invalid CPUs,
# see: https://github.com/giampaolo/psutil/issues/586
- allcpus = tuple(range(len(per_cpu_times())))
+ allcpus = set(range(len(per_cpu_times())))
for cpu in cpus:
if cpu not in allcpus:
- raise ValueError(
- "invalid CPU #%i (choose between %s)" % (cpu, allcpus)
- )
+ msg = f"invalid CPU {cpu!r} (choose between {allcpus})"
+ raise ValueError(msg)
try:
cext.proc_cpu_affinity_set(self.pid, cpus)
except OSError as err:
@@ -961,10 +945,11 @@ class Process:
if err.errno in {errno.EINVAL, errno.EDEADLK}:
for cpu in cpus:
if cpu not in allcpus:
- raise ValueError(
- "invalid CPU #%i (choose between %s)"
- % (cpu, allcpus)
+ msg = (
+ f"invalid CPU {cpu!r} (choose between"
+ f" {allcpus})"
)
+ raise ValueError(msg) from err
raise
@wrap_exceptions
@@ -977,9 +962,10 @@ class Process:
return cext.proc_getrlimit(self.pid, resource)
else:
if len(limits) != 2:
- raise ValueError(
- "second argument must be a (soft, hard) tuple, got %s"
- % repr(limits)
+ msg = (
+ "second argument must be a (soft, hard) tuple, got"
+ f" {limits!r}"
)
+ raise ValueError(msg)
soft, hard = limits
return cext.proc_setrlimit(self.pid, resource, soft, hard)
diff --git a/contrib/python/psutil/py3/psutil/_pslinux.py b/contrib/python/psutil/py3/psutil/_pslinux.py
index 3e7f3e402a..8cc64e9a10 100644
--- a/contrib/python/psutil/py3/psutil/_pslinux.py
+++ b/contrib/python/psutil/py3/psutil/_pslinux.py
@@ -4,15 +4,16 @@
"""Linux platform implementation."""
-from __future__ import division
import base64
import collections
+import enum
import errno
import functools
import glob
import os
import re
+import resource
import socket
import struct
import sys
@@ -24,6 +25,7 @@ from . import _common
from . import _psposix
from . import _psutil_linux as cext
from . import _psutil_posix as cext_posix
+from ._common import ENCODING
from ._common import NIC_DUPLEX_FULL
from ._common import NIC_DUPLEX_HALF
from ._common import NIC_DUPLEX_UNKNOWN
@@ -44,18 +46,6 @@ from ._common import parse_environ_block
from ._common import path_exists_strict
from ._common import supports_ipv6
from ._common import usage_percent
-from ._compat import PY3
-from ._compat import FileNotFoundError
-from ._compat import PermissionError
-from ._compat import ProcessLookupError
-from ._compat import b
-from ._compat import basestring
-
-
-if PY3:
- import enum
-else:
- enum = None
# fmt: off
@@ -69,6 +59,11 @@ __extra__all__ = [
"CONN_FIN_WAIT2", "CONN_TIME_WAIT", "CONN_CLOSE", "CONN_CLOSE_WAIT",
"CONN_LAST_ACK", "CONN_LISTEN", "CONN_CLOSING",
]
+
+if hasattr(resource, "prlimit"):
+ __extra__all__.extend(
+ [x for x in dir(cext) if x.startswith('RLIM') and x.isupper()]
+ )
# fmt: on
@@ -78,8 +73,8 @@ __extra__all__ = [
POWER_SUPPLY_PATH = "/sys/class/power_supply"
-HAS_PROC_SMAPS = os.path.exists('/proc/%s/smaps' % os.getpid())
-HAS_PROC_SMAPS_ROLLUP = os.path.exists('/proc/%s/smaps_rollup' % os.getpid())
+HAS_PROC_SMAPS = os.path.exists(f"/proc/{os.getpid()}/smaps")
+HAS_PROC_SMAPS_ROLLUP = os.path.exists(f"/proc/{os.getpid()}/smaps_rollup")
HAS_PROC_IO_PRIORITY = hasattr(cext, "proc_ioprio_get")
HAS_CPU_AFFINITY = hasattr(cext, "proc_cpu_affinity_get")
@@ -102,29 +97,21 @@ LITTLE_ENDIAN = sys.byteorder == 'little'
# * https://lkml.org/lkml/2015/8/17/234
DISK_SECTOR_SIZE = 512
-if enum is None:
- AF_LINK = socket.AF_PACKET
-else:
- AddressFamily = enum.IntEnum(
- 'AddressFamily', {'AF_LINK': int(socket.AF_PACKET)}
- )
- AF_LINK = AddressFamily.AF_LINK
+AddressFamily = enum.IntEnum(
+ 'AddressFamily', {'AF_LINK': int(socket.AF_PACKET)}
+)
+AF_LINK = AddressFamily.AF_LINK
+
# ioprio_* constants http://linux.die.net/man/2/ioprio_get
-if enum is None:
+class IOPriority(enum.IntEnum):
IOPRIO_CLASS_NONE = 0
IOPRIO_CLASS_RT = 1
IOPRIO_CLASS_BE = 2
IOPRIO_CLASS_IDLE = 3
-else:
- class IOPriority(enum.IntEnum):
- IOPRIO_CLASS_NONE = 0
- IOPRIO_CLASS_RT = 1
- IOPRIO_CLASS_BE = 2
- IOPRIO_CLASS_IDLE = 3
- globals().update(IOPriority.__members__)
+globals().update(IOPriority.__members__)
# See:
# https://github.com/torvalds/linux/blame/master/fs/proc/array.c
@@ -211,7 +198,7 @@ pcputimes = namedtuple('pcputimes',
def readlink(path):
"""Wrapper around os.readlink()."""
- assert isinstance(path, basestring), path
+ assert isinstance(path, str), path
path = os.readlink(path)
# readlink() might return paths containing null bytes ('\x00')
# resulting in "TypeError: must be encoded string without NULL
@@ -255,9 +242,9 @@ def is_storage_device(name):
name = name.replace('/', '!')
including_virtual = True
if including_virtual:
- path = "/sys/block/%s" % name
+ path = f"/sys/block/{name}"
else:
- path = "/sys/block/%s/device" % name
+ path = f"/sys/block/{name}/device"
return os.access(path, os.F_OK)
@@ -270,7 +257,7 @@ def set_scputimes_ntuple(procfs_path):
Used by cpu_times() function.
"""
global scputimes
- with open_binary('%s/stat' % procfs_path) as f:
+ with open_binary(f"{procfs_path}/stat") as f:
values = f.readline().split()[1:]
fields = ['user', 'nice', 'system', 'idle', 'iowait', 'irq', 'softirq']
vlen = len(values)
@@ -290,66 +277,11 @@ try:
set_scputimes_ntuple("/proc")
except Exception as err: # noqa: BLE001
# Don't want to crash at import time.
- debug("ignoring exception on import: %r" % err)
+ debug(f"ignoring exception on import: {err!r}")
scputimes = namedtuple('scputimes', 'user system idle')(0.0, 0.0, 0.0)
# =====================================================================
-# --- prlimit
-# =====================================================================
-
-# Backport of resource.prlimit() for Python 2. Originally this was done
-# in C, but CentOS-6 which we use to create manylinux wheels is too old
-# and does not support prlimit() syscall. As such the resulting wheel
-# would not include prlimit(), even when installed on newer systems.
-# This is the only part of psutil using ctypes.
-
-prlimit = None
-try:
- from resource import prlimit # python >= 3.4
-except ImportError:
- import ctypes
-
- try:
- libc = ctypes.CDLL(None, use_errno=True)
- except:
- libc = None
-
- if hasattr(libc, "prlimit"):
-
- def prlimit(pid, resource_, limits=None):
- class StructRlimit(ctypes.Structure):
- _fields_ = [
- ('rlim_cur', ctypes.c_longlong),
- ('rlim_max', ctypes.c_longlong),
- ]
-
- current = StructRlimit()
- if limits is None:
- # get
- ret = libc.prlimit(pid, resource_, None, ctypes.byref(current))
- else:
- # set
- new = StructRlimit()
- new.rlim_cur = limits[0]
- new.rlim_max = limits[1]
- ret = libc.prlimit(
- pid, resource_, ctypes.byref(new), ctypes.byref(current)
- )
-
- if ret != 0:
- errno_ = ctypes.get_errno()
- raise OSError(errno_, os.strerror(errno_))
- return (current.rlim_cur, current.rlim_max)
-
-
-if prlimit is not None:
- __extra__all__.extend(
- [x for x in dir(cext) if x.startswith('RLIM') and x.isupper()]
- )
-
-
-# =====================================================================
# --- system memory
# =====================================================================
@@ -392,14 +324,13 @@ def calculate_avail_vmem(mems):
slab_reclaimable = mems[b'SReclaimable:']
except KeyError as err:
debug(
- "%s is missing from /proc/meminfo; using an approximation for "
- "calculating available memory"
- % err.args[0]
+ f"{err.args[0]} is missing from /proc/meminfo; using an"
+ " approximation for calculating available memory"
)
return fallback
try:
- f = open_binary('%s/zoneinfo' % get_procfs_path())
- except IOError:
+ f = open_binary(f"{get_procfs_path()}/zoneinfo")
+ except OSError:
return fallback # kernel 2.6.13
watermark_low = 0
@@ -428,7 +359,7 @@ def virtual_memory():
"""
missing_fields = []
mems = {}
- with open_binary('%s/meminfo' % get_procfs_path()) as f:
+ with open_binary(f"{get_procfs_path()}/meminfo") as f:
for line in f:
fields = line.split()
mems[fields[0]] = int(fields[1]) * 1024
@@ -530,7 +461,7 @@ def virtual_memory():
# Warn about missing metrics which are set to 0.
if missing_fields:
- msg = "%s memory stats couldn't be determined and %s set to 0" % (
+ msg = "{} memory stats couldn't be determined and {} set to 0".format(
", ".join(missing_fields),
"was" if len(missing_fields) == 1 else "were",
)
@@ -554,7 +485,7 @@ def virtual_memory():
def swap_memory():
"""Return swap memory metrics."""
mems = {}
- with open_binary('%s/meminfo' % get_procfs_path()) as f:
+ with open_binary(f"{get_procfs_path()}/meminfo") as f:
for line in f:
fields = line.split()
mems[fields[0]] = int(fields[1]) * 1024
@@ -574,12 +505,12 @@ def swap_memory():
percent = usage_percent(used, total, round_=1)
# get pgin/pgouts
try:
- f = open_binary("%s/vmstat" % get_procfs_path())
- except IOError as err:
+ f = open_binary(f"{get_procfs_path()}/vmstat")
+ except OSError as err:
# see https://github.com/giampaolo/psutil/issues/722
msg = (
"'sin' and 'sout' swap memory stats couldn't "
- + "be determined and were set to 0 (%s)" % str(err)
+ f"be determined and were set to 0 ({err})"
)
warnings.warn(msg, RuntimeWarning, stacklevel=2)
sin = sout = 0
@@ -620,7 +551,7 @@ def cpu_times():
"""
procfs_path = get_procfs_path()
set_scputimes_ntuple(procfs_path)
- with open_binary('%s/stat' % procfs_path) as f:
+ with open_binary(f"{procfs_path}/stat") as f:
values = f.readline().split()
fields = values[1 : len(scputimes._fields) + 1]
fields = [float(x) / CLOCK_TICKS for x in fields]
@@ -634,7 +565,7 @@ def per_cpu_times():
procfs_path = get_procfs_path()
set_scputimes_ntuple(procfs_path)
cpus = []
- with open_binary('%s/stat' % procfs_path) as f:
+ with open_binary(f"{procfs_path}/stat") as f:
# get rid of the first line which refers to system wide CPU stats
f.readline()
for line in f:
@@ -654,7 +585,7 @@ def cpu_count_logical():
except ValueError:
# as a second fallback we try to parse /proc/cpuinfo
num = 0
- with open_binary('%s/cpuinfo' % get_procfs_path()) as f:
+ with open_binary(f"{get_procfs_path()}/cpuinfo") as f:
for line in f:
if line.lower().startswith(b'processor'):
num += 1
@@ -664,7 +595,7 @@ def cpu_count_logical():
# try to parse /proc/stat as a last resort
if num == 0:
search = re.compile(r'cpu\d')
- with open_text('%s/stat' % get_procfs_path()) as f:
+ with open_text(f"{get_procfs_path()}/stat") as f:
for line in f:
line = line.split(' ')[0]
if search.match(line):
@@ -697,7 +628,7 @@ def cpu_count_cores():
# Method #2
mapping = {}
current_info = {}
- with open_binary('%s/cpuinfo' % get_procfs_path()) as f:
+ with open_binary(f"{get_procfs_path()}/cpuinfo") as f:
for line in f:
line = line.strip().lower()
if not line:
@@ -720,7 +651,7 @@ def cpu_count_cores():
def cpu_stats():
"""Return various CPU stats as a named tuple."""
- with open_binary('%s/stat' % get_procfs_path()) as f:
+ with open_binary(f"{get_procfs_path()}/stat") as f:
ctx_switches = None
interrupts = None
soft_interrupts = None
@@ -745,12 +676,12 @@ def cpu_stats():
def _cpu_get_cpuinfo_freq():
"""Return current CPU frequency from cpuinfo if available."""
- ret = []
- with open_binary('%s/cpuinfo' % get_procfs_path()) as f:
- for line in f:
- if line.lower().startswith(b'cpu mhz'):
- ret.append(float(line.split(b':', 1)[1]))
- return ret
+ with open_binary(f"{get_procfs_path()}/cpuinfo") as f:
+ return [
+ float(line.split(b':', 1)[1])
+ for line in f
+ if line.lower().startswith(b'cpu mhz')
+ ]
if os.path.exists("/sys/devices/system/cpu/cpufreq/policy0") or os.path.exists(
@@ -781,9 +712,7 @@ if os.path.exists("/sys/devices/system/cpu/cpufreq/policy0") or os.path.exists(
# https://github.com/giampaolo/psutil/issues/1071
curr = bcat(pjoin(path, "cpuinfo_cur_freq"), fallback=None)
if curr is None:
- online_path = (
- "/sys/devices/system/cpu/cpu{}/online".format(i)
- )
+ online_path = f"/sys/devices/system/cpu/cpu{i}/online"
# if cpu core is offline, set to all zeroes
if cat(online_path, fallback=None) == "0\n":
ret.append(_common.scpufreq(0.0, 0.0, 0.0))
@@ -854,12 +783,12 @@ class NetConnections:
def get_proc_inodes(self, pid):
inodes = defaultdict(list)
- for fd in os.listdir("%s/%s/fd" % (self._procfs_path, pid)):
+ for fd in os.listdir(f"{self._procfs_path}/{pid}/fd"):
try:
- inode = readlink("%s/%s/fd/%s" % (self._procfs_path, pid, fd))
+ inode = readlink(f"{self._procfs_path}/{pid}/fd/{fd}")
except (FileNotFoundError, ProcessLookupError):
# ENOENT == file which is gone in the meantime;
- # os.stat('/proc/%s' % self.pid) will be done later
+ # os.stat(f"/proc/{self.pid}") will be done later
# to force NSP (if it's the case)
continue
except OSError as err:
@@ -917,8 +846,7 @@ class NetConnections:
# no end-points connected
if not port:
return ()
- if PY3:
- ip = ip.encode('ascii')
+ ip = ip.encode('ascii')
if family == socket.AF_INET:
# see: https://github.com/giampaolo/psutil/issues/201
if LITTLE_ENDIAN:
@@ -942,9 +870,8 @@ class NetConnections:
except ValueError:
# see: https://github.com/giampaolo/psutil/issues/623
if not supports_ipv6():
- raise _Ipv6UnsupportedError
- else:
- raise
+ raise _Ipv6UnsupportedError from None
+ raise
return _common.addr(ip, port)
@staticmethod
@@ -961,10 +888,11 @@ class NetConnections:
line.split()[:10]
)
except ValueError:
- raise RuntimeError(
- "error while parsing %s; malformed line %s %r"
- % (file, lineno, line)
+ msg = (
+ f"error while parsing {file}; malformed line"
+ f" {lineno} {line!r}"
)
+ raise RuntimeError(msg) from None
if inode in inodes:
# # We assume inet sockets are unique, so we error
# # out if there are multiple references to the
@@ -1002,11 +930,11 @@ class NetConnections:
if ' ' not in line:
# see: https://github.com/giampaolo/psutil/issues/766
continue
- raise RuntimeError(
- "error while parsing %s; malformed line %r"
- % (file, line)
+ msg = (
+ f"error while parsing {file}; malformed line {line!r}"
)
- if inode in inodes: # noqa
+ raise RuntimeError(msg) # noqa: B904
+ if inode in inodes: # noqa: SIM108
# With UNIX sockets we can have a single inode
# referencing many file descriptors.
pairs = inodes[inode]
@@ -1026,11 +954,6 @@ class NetConnections:
yield (fd, family, type_, path, raddr, status, pid)
def retrieve(self, kind, pid=None):
- if kind not in self.tmap:
- raise ValueError(
- "invalid %r kind argument; choose between %s"
- % (kind, ', '.join([repr(x) for x in self.tmap]))
- )
self._procfs_path = get_procfs_path()
if pid is not None:
inodes = self.get_proc_inodes(pid)
@@ -1041,7 +964,7 @@ class NetConnections:
inodes = self.get_all_inodes()
ret = set()
for proto_name, family, type_ in self.tmap[kind]:
- path = "%s/net/%s" % (self._procfs_path, proto_name)
+ path = f"{self._procfs_path}/net/{proto_name}"
if family in {socket.AF_INET, socket.AF_INET6}:
ls = self.process_inet(
path, family, type_, inodes, filter_pid=pid
@@ -1073,7 +996,7 @@ def net_io_counters():
"""Return network I/O statistics for every network interface
installed on the system as a dict of raw tuples.
"""
- with open_text("%s/net/dev" % get_procfs_path()) as f:
+ with open_text(f"{get_procfs_path()}/net/dev") as f:
lines = f.readlines()
retdict = {}
for line in lines[2:]:
@@ -1134,8 +1057,7 @@ def net_if_stats():
# https://github.com/giampaolo/psutil/issues/1279
if err.errno != errno.ENODEV:
raise
- else:
- debug(err)
+ debug(err)
else:
output_flags = ','.join(flags)
isup = 'running' in flags
@@ -1175,7 +1097,7 @@ def disk_io_counters(perdisk=False):
# See:
# https://www.kernel.org/doc/Documentation/iostats.txt
# https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats
- with open_text("%s/diskstats" % get_procfs_path()) as f:
+ with open_text(f"{get_procfs_path()}/diskstats") as f:
lines = f.readlines()
for line in lines:
fields = line.split()
@@ -1198,7 +1120,8 @@ def disk_io_counters(perdisk=False):
reads, rbytes, writes, wbytes = map(int, fields[3:])
rtime = wtime = reads_merged = writes_merged = busy_time = 0
else:
- raise ValueError("not sure how to interpret line %r" % line)
+ msg = f"not sure how to interpret line {line!r}"
+ raise ValueError(msg)
yield (name, reads, writes, rbytes, wbytes, rtime, wtime,
reads_merged, writes_merged, busy_time)
# fmt: on
@@ -1218,16 +1141,16 @@ def disk_io_counters(perdisk=False):
wtime, reads_merged, writes_merged, busy_time)
# fmt: on
- if os.path.exists('%s/diskstats' % get_procfs_path()):
+ if os.path.exists(f"{get_procfs_path()}/diskstats"):
gen = read_procfs()
elif os.path.exists('/sys/block'):
gen = read_sysfs()
else:
- raise NotImplementedError(
- "%s/diskstats nor /sys/block filesystem are available on this "
- "system"
- % get_procfs_path()
+ msg = (
+ f"{get_procfs_path()}/diskstats nor /sys/block are available on"
+ " this system"
)
+ raise NotImplementedError(msg)
retdict = {}
for entry in gen:
@@ -1273,7 +1196,7 @@ class RootFsDeviceFinder:
self.minor = os.minor(dev)
def ask_proc_partitions(self):
- with open_text("%s/partitions" % get_procfs_path()) as f:
+ with open_text(f"{get_procfs_path()}/partitions") as f:
for line in f.readlines()[2:]:
fields = line.split()
if len(fields) < 4: # just for extra safety
@@ -1283,19 +1206,19 @@ class RootFsDeviceFinder:
name = fields[3]
if major == self.major and minor == self.minor:
if name: # just for extra safety
- return "/dev/%s" % name
+ return f"/dev/{name}"
def ask_sys_dev_block(self):
- path = "/sys/dev/block/%s:%s/uevent" % (self.major, self.minor)
+ path = f"/sys/dev/block/{self.major}:{self.minor}/uevent"
with open_text(path) as f:
for line in f:
if line.startswith("DEVNAME="):
name = line.strip().rpartition("DEVNAME=")[2]
if name: # just for extra safety
- return "/dev/%s" % name
+ return f"/dev/{name}"
def ask_sys_class_block(self):
- needle = "%s:%s" % (self.major, self.minor)
+ needle = f"{self.major}:{self.minor}"
files = glob.iglob("/sys/class/block/*/dev")
for file in files:
try:
@@ -1307,24 +1230,24 @@ class RootFsDeviceFinder:
data = f.read().strip()
if data == needle:
name = os.path.basename(os.path.dirname(file))
- return "/dev/%s" % name
+ return f"/dev/{name}"
def find(self):
path = None
if path is None:
try:
path = self.ask_proc_partitions()
- except (IOError, OSError) as err:
+ except OSError as err:
debug(err)
if path is None:
try:
path = self.ask_sys_dev_block()
- except (IOError, OSError) as err:
+ except OSError as err:
debug(err)
if path is None:
try:
path = self.ask_sys_class_block()
- except (IOError, OSError) as err:
+ except OSError as err:
debug(err)
# We use exists() because the "/dev/*" part of the path is hard
# coded, so we want to be sure.
@@ -1337,7 +1260,7 @@ def disk_partitions(all=False):
fstypes = set()
procfs_path = get_procfs_path()
if not all:
- with open_text("%s/filesystems" % procfs_path) as f:
+ with open_text(f"{procfs_path}/filesystems") as f:
for line in f:
line = line.strip()
if not line.startswith("nodev"):
@@ -1352,7 +1275,7 @@ def disk_partitions(all=False):
if procfs_path == "/proc" and os.path.isfile('/etc/mtab'):
mounts_path = os.path.realpath("/etc/mtab")
else:
- mounts_path = os.path.realpath("%s/self/mounts" % procfs_path)
+ mounts_path = os.path.realpath(f"{procfs_path}/self/mounts")
retlist = []
partitions = cext.disk_partitions(mounts_path)
@@ -1395,7 +1318,7 @@ def sensors_temperatures():
# https://github.com/giampaolo/psutil/issues/971
# https://github.com/nicolargo/glances/issues/1060
basenames.extend(glob.glob('/sys/class/hwmon/hwmon*/device/temp*_*'))
- basenames = sorted(set([x.split('_')[0] for x in basenames]))
+ basenames = sorted({x.split('_')[0] for x in basenames})
# Only add the coretemp hwmon entries if they're not already in
# /sys/class/hwmon/
@@ -1404,7 +1327,7 @@ def sensors_temperatures():
basenames2 = glob.glob(
'/sys/devices/platform/coretemp.*/hwmon/hwmon*/temp*_*'
)
- repl = re.compile('/sys/devices/platform/coretemp.*/hwmon/')
+ repl = re.compile(r"/sys/devices/platform/coretemp.*/hwmon/")
for name in basenames2:
altname = repl.sub('/sys/class/hwmon/', name)
if altname not in basenames:
@@ -1416,7 +1339,7 @@ def sensors_temperatures():
current = float(bcat(path)) / 1000.0
path = os.path.join(os.path.dirname(base), 'name')
unit_name = cat(path).strip()
- except (IOError, OSError, ValueError):
+ except (OSError, ValueError):
# A lot of things can go wrong here, so let's just skip the
# whole entry. Sure thing is Linux's /sys/class/hwmon really
# is a stinky broken mess.
@@ -1455,15 +1378,15 @@ def sensors_temperatures():
current = float(bcat(path)) / 1000.0
path = os.path.join(base, 'type')
unit_name = cat(path).strip()
- except (IOError, OSError, ValueError) as err:
+ except (OSError, ValueError) as err:
debug(err)
continue
trip_paths = glob.glob(base + '/trip_point*')
- trip_points = set([
+ trip_points = {
'_'.join(os.path.basename(p).split('_')[0:3])
for p in trip_paths
- ])
+ }
critical = None
high = None
for trip_point in trip_points:
@@ -1511,11 +1434,11 @@ def sensors_fans():
# https://github.com/giampaolo/psutil/issues/971
basenames = glob.glob('/sys/class/hwmon/hwmon*/device/fan*_*')
- basenames = sorted(set([x.split('_')[0] for x in basenames]))
+ basenames = sorted({x.split("_")[0] for x in basenames})
for base in basenames:
try:
current = int(bcat(base + '_input'))
- except (IOError, OSError) as err:
+ except OSError as err:
debug(err)
continue
unit_name = cat(os.path.join(os.path.dirname(base), 'name')).strip()
@@ -1557,7 +1480,7 @@ def sensors_battery():
# Get the first available battery. Usually this is "BAT0", except
# some rare exceptions:
# https://github.com/giampaolo/psutil/issues/1238
- root = os.path.join(POWER_SUPPLY_PATH, sorted(bats)[0])
+ root = os.path.join(POWER_SUPPLY_PATH, min(bats))
# Base metrics.
energy_now = multi_bcat(root + "/energy_now", root + "/charge_now")
@@ -1634,14 +1557,15 @@ def users():
def boot_time():
"""Return the system boot time expressed in seconds since the epoch."""
global BOOT_TIME
- path = '%s/stat' % get_procfs_path()
+ path = f"{get_procfs_path()}/stat"
with open_binary(path) as f:
for line in f:
if line.startswith(b'btime'):
ret = float(line.strip().split()[1])
BOOT_TIME = ret
return ret
- raise RuntimeError("line 'btime' not found in %s" % path)
+ msg = f"line 'btime' not found in {path}"
+ raise RuntimeError(msg)
# =====================================================================
@@ -1651,7 +1575,8 @@ def boot_time():
def pids():
"""Returns a list of PIDs currently running on the system."""
- return [int(x) for x in os.listdir(b(get_procfs_path())) if x.isdigit()]
+ path = get_procfs_path().encode(ENCODING)
+ return [int(x) for x in os.listdir(path) if x.isdigit()]
def pid_exists(pid):
@@ -1673,7 +1598,7 @@ def pid_exists(pid):
# Note: already checked that this is faster than using a
# regular expr. Also (a lot) faster than doing
# 'return pid in pids()'
- path = "%s/%s/status" % (get_procfs_path(), pid)
+ path = f"{get_procfs_path()}/{pid}/status"
with open_binary(path) as f:
for line in f:
if line.startswith(b"Tgid:"):
@@ -1681,8 +1606,9 @@ def pid_exists(pid):
# If tgid and pid are the same then we're
# dealing with a process PID.
return tgid == pid
- raise ValueError("'Tgid' line not found in %s" % path)
- except (EnvironmentError, ValueError):
+ msg = f"'Tgid' line not found in {path}"
+ raise ValueError(msg)
+ except (OSError, ValueError):
return pid in pids()
@@ -1694,7 +1620,7 @@ def ppid_map():
procfs_path = get_procfs_path()
for pid in pids():
try:
- with open_binary("%s/%s/stat" % (procfs_path, pid)) as f:
+ with open_binary(f"{procfs_path}/{pid}/stat") as f:
data = f.read()
except (FileNotFoundError, ProcessLookupError):
# Note: we should be able to access /stat for all processes
@@ -1709,28 +1635,27 @@ def ppid_map():
def wrap_exceptions(fun):
- """Decorator which translates bare OSError and IOError exceptions
+ """Decorator which translates bare OSError and OSError exceptions
into NoSuchProcess and AccessDenied.
"""
@functools.wraps(fun)
def wrapper(self, *args, **kwargs):
+ pid, name = self.pid, self._name
try:
return fun(self, *args, **kwargs)
- except PermissionError:
- raise AccessDenied(self.pid, self._name)
- except ProcessLookupError:
+ except PermissionError as err:
+ raise AccessDenied(pid, name) from err
+ except ProcessLookupError as err:
self._raise_if_zombie()
- raise NoSuchProcess(self.pid, self._name)
- except FileNotFoundError:
+ raise NoSuchProcess(pid, name) from err
+ except FileNotFoundError as err:
self._raise_if_zombie()
# /proc/PID directory may still exist, but the files within
# it may not, indicating the process is gone, see:
# https://github.com/giampaolo/psutil/issues/2418
- if not os.path.exists(
- "%s/%s/stat" % (self._procfs_path, self.pid)
- ):
- raise NoSuchProcess(self.pid, self._name)
+ if not os.path.exists(f"{self._procfs_path}/{pid}/stat"):
+ raise NoSuchProcess(pid, name) from err
raise
return wrapper
@@ -1755,8 +1680,8 @@ class Process:
# it's empty. Instead of returning a "null" value we'll raise an
# exception.
try:
- data = bcat("%s/%s/stat" % (self._procfs_path, self.pid))
- except (IOError, OSError):
+ data = bcat(f"{self._procfs_path}/{self.pid}/stat")
+ except OSError:
return False
else:
rpar = data.rfind(b')')
@@ -1771,7 +1696,7 @@ class Process:
"""Raise NSP if the process disappeared on us."""
# For those C function who do not raise NSP, possibly returning
# incorrect or incomplete result.
- os.stat('%s/%s' % (self._procfs_path, self.pid))
+ os.stat(f"{self._procfs_path}/{self.pid}")
@wrap_exceptions
@memoize_when_activated
@@ -1784,7 +1709,7 @@ class Process:
The return value is cached in case oneshot() ctx manager is
in use.
"""
- data = bcat("%s/%s/stat" % (self._procfs_path, self.pid))
+ data = bcat(f"{self._procfs_path}/{self.pid}/stat")
# Process name is between parentheses. It can contain spaces and
# other parentheses. This is taken into account by looking for
# the first occurrence of "(" and the last occurrence of ")".
@@ -1819,13 +1744,13 @@ class Process:
The return value is cached in case oneshot() ctx manager is
in use.
"""
- with open_binary("%s/%s/status" % (self._procfs_path, self.pid)) as f:
+ with open_binary(f"{self._procfs_path}/{self.pid}/status") as f:
return f.read()
@wrap_exceptions
@memoize_when_activated
def _read_smaps_file(self):
- with open_binary("%s/%s/smaps" % (self._procfs_path, self.pid)) as f:
+ with open_binary(f"{self._procfs_path}/{self.pid}/smaps") as f:
return f.read().strip()
def oneshot_enter(self):
@@ -1840,28 +1765,25 @@ class Process:
@wrap_exceptions
def name(self):
- name = self._parse_stat_file()['name']
- if PY3:
- name = decode(name)
# XXX - gets changed later and probably needs refactoring
- return name
+ return decode(self._parse_stat_file()['name'])
@wrap_exceptions
def exe(self):
try:
- return readlink("%s/%s/exe" % (self._procfs_path, self.pid))
+ return readlink(f"{self._procfs_path}/{self.pid}/exe")
except (FileNotFoundError, ProcessLookupError):
self._raise_if_zombie()
# no such file error; might be raised also if the
# path actually exists for system processes with
# low pids (about 0-20)
- if os.path.lexists("%s/%s" % (self._procfs_path, self.pid)):
+ if os.path.lexists(f"{self._procfs_path}/{self.pid}"):
return ""
raise
@wrap_exceptions
def cmdline(self):
- with open_text("%s/%s/cmdline" % (self._procfs_path, self.pid)) as f:
+ with open_text(f"{self._procfs_path}/{self.pid}/cmdline") as f:
data = f.read()
if not data:
# may happen in case of zombie process
@@ -1887,7 +1809,7 @@ class Process:
@wrap_exceptions
def environ(self):
- with open_text("%s/%s/environ" % (self._procfs_path, self.pid)) as f:
+ with open_text(f"{self._procfs_path}/{self.pid}/environ") as f:
data = f.read()
return parse_environ_block(data)
@@ -1901,11 +1823,11 @@ class Process:
return None
# May not be available on old kernels.
- if os.path.exists('/proc/%s/io' % os.getpid()):
+ if os.path.exists(f"/proc/{os.getpid()}/io"):
@wrap_exceptions
def io_counters(self):
- fname = "%s/%s/io" % (self._procfs_path, self.pid)
+ fname = f"{self._procfs_path}/{self.pid}/io"
fields = {}
with open_binary(fname) as f:
for line in f:
@@ -1920,7 +1842,8 @@ class Process:
else:
fields[name] = int(value)
if not fields:
- raise RuntimeError("%s file was empty" % fname)
+ msg = f"{fname} file was empty"
+ raise RuntimeError(msg)
try:
return pio(
fields[b'syscr'], # read syscalls
@@ -1931,10 +1854,11 @@ class Process:
fields[b'wchar'], # write chars
)
except KeyError as err:
- raise ValueError(
- "%r field was not found in %s; found fields are %r"
- % (err.args[0], fname, fields)
+ msg = (
+ f"{err.args[0]!r} field was not found in {fname}; found"
+ f" fields are {fields!r}"
)
+ raise ValueError(msg) from None
@wrap_exceptions
def cpu_times(self):
@@ -1979,7 +1903,7 @@ class Process:
# | data | data + stack | drs | DATA |
# | dirty | dirty pages (unused in Linux 2.6) | dt | |
# ============================================================
- with open_binary("%s/%s/statm" % (self._procfs_path, self.pid)) as f:
+ with open_binary(f"{self._procfs_path}/{self.pid}/statm") as f:
vms, rss, shared, text, lib, data, dirty = (
int(x) * PAGESIZE for x in f.readline().split()[:7]
)
@@ -1998,7 +1922,7 @@ class Process:
# compared to /proc/pid/smaps_rollup.
uss = pss = swap = 0
with open_binary(
- "{}/{}/smaps_rollup".format(self._procfs_path, self.pid)
+ f"{self._procfs_path}/{self.pid}/smaps_rollup"
) as f:
for line in f:
if line.startswith(b"Private_"):
@@ -2023,8 +1947,6 @@ class Process:
# Note: using 3 regexes is faster than reading the file
# line by line.
- # XXX: on Python 3 the 2 regexes are 30% slower than on
- # Python 2 though. Figure out why.
#
# You might be tempted to calculate USS by subtracting
# the "shared" value from the "resident" value in
@@ -2062,7 +1984,7 @@ class Process:
def memory_maps(self):
"""Return process's mapped memory regions as a list of named
tuples. Fields are explained in 'man proc'; here is an updated
- (Apr 2012) version: http://goo.gl/fmebo.
+ (Apr 2012) version: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/proc.txt?id=b76437579d1344b612cf1851ae610c636cec7db0.
/proc/{PID}/smaps does not exist on kernels < 2.6.14 or if
CONFIG_MMU kernel configuration option is not enabled.
@@ -2083,11 +2005,8 @@ class Process:
if fields[0].startswith(b'VmFlags:'):
# see issue #369
continue
- else:
- raise ValueError(
- "don't know how to interpret line %r"
- % line
- )
+ msg = f"don't know how to interpret line {line!r}"
+ raise ValueError(msg) from None
yield (current_block.pop(), data)
data = self._read_smaps_file()
@@ -2109,8 +2028,7 @@ class Process:
if not path:
path = '[anon]'
else:
- if PY3:
- path = decode(path)
+ path = decode(path)
path = path.strip()
if path.endswith(' (deleted)') and not path_exists_strict(
path
@@ -2136,7 +2054,7 @@ class Process:
@wrap_exceptions
def cwd(self):
- return readlink("%s/%s/cwd" % (self._procfs_path, self.pid))
+ return readlink(f"{self._procfs_path}/{self.pid}/cwd")
@wrap_exceptions
def num_ctx_switches(
@@ -2145,34 +2063,29 @@ class Process:
data = self._read_status_file()
ctxsw = _ctxsw_re.findall(data)
if not ctxsw:
- raise NotImplementedError(
- "'voluntary_ctxt_switches' and 'nonvoluntary_ctxt_switches'"
- "lines were not found in %s/%s/status; the kernel is "
- "probably older than 2.6.23" % (self._procfs_path, self.pid)
+ msg = (
+ "'voluntary_ctxt_switches' and"
+ " 'nonvoluntary_ctxt_switches'lines were not found in"
+ f" {self._procfs_path}/{self.pid}/status; the kernel is"
+ " probably older than 2.6.23"
)
- else:
- return _common.pctxsw(int(ctxsw[0]), int(ctxsw[1]))
+ raise NotImplementedError(msg)
+ return _common.pctxsw(int(ctxsw[0]), int(ctxsw[1]))
@wrap_exceptions
def num_threads(self, _num_threads_re=re.compile(br'Threads:\t(\d+)')):
- # Note: on Python 3 using a re is faster than iterating over file
- # line by line. On Python 2 is the exact opposite, and iterating
- # over a file on Python 3 is slower than on Python 2.
+ # Using a re is faster than iterating over file line by line.
data = self._read_status_file()
return int(_num_threads_re.findall(data)[0])
@wrap_exceptions
def threads(self):
- thread_ids = os.listdir("%s/%s/task" % (self._procfs_path, self.pid))
+ thread_ids = os.listdir(f"{self._procfs_path}/{self.pid}/task")
thread_ids.sort()
retlist = []
hit_enoent = False
for thread_id in thread_ids:
- fname = "%s/%s/task/%s/stat" % (
- self._procfs_path,
- self.pid,
- thread_id,
- )
+ fname = f"{self._procfs_path}/{self.pid}/task/{thread_id}/stat"
try:
with open_binary(fname) as f:
st = f.read().strip()
@@ -2194,7 +2107,7 @@ class Process:
@wrap_exceptions
def nice_get(self):
- # with open_text('%s/%s/stat' % (self._procfs_path, self.pid)) as f:
+ # with open_text(f"{self._procfs_path}/{self.pid}/stat") as f:
# data = f.read()
# return int(data.split()[18])
@@ -2233,15 +2146,17 @@ class Process:
all_cpus = tuple(range(len(per_cpu_times())))
for cpu in cpus:
if cpu not in all_cpus:
- raise ValueError(
- "invalid CPU number %r; choose between %s"
- % (cpu, eligible_cpus)
+ msg = (
+ f"invalid CPU {cpu!r}; choose between"
+ f" {eligible_cpus!r}"
)
+ raise ValueError(msg) from None
if cpu not in eligible_cpus:
- raise ValueError(
- "CPU number %r is not eligible; choose "
- "between %s" % (cpu, eligible_cpus)
+ msg = (
+ f"CPU number {cpu} is not eligible; choose"
+ f" between {eligible_cpus}"
)
+ raise ValueError(msg) from err
raise
# only starting from kernel 2.6.13
@@ -2250,22 +2165,25 @@ class Process:
@wrap_exceptions
def ionice_get(self):
ioclass, value = cext.proc_ioprio_get(self.pid)
- if enum is not None:
- ioclass = IOPriority(ioclass)
+ ioclass = IOPriority(ioclass)
return _common.pionice(ioclass, value)
@wrap_exceptions
def ionice_set(self, ioclass, value):
if value is None:
value = 0
- if value and ioclass in {IOPRIO_CLASS_IDLE, IOPRIO_CLASS_NONE}:
- raise ValueError("%r ioclass accepts no value" % ioclass)
+ if value and ioclass in {
+ IOPriority.IOPRIO_CLASS_IDLE,
+ IOPriority.IOPRIO_CLASS_NONE,
+ }:
+ msg = f"{ioclass!r} ioclass accepts no value"
+ raise ValueError(msg)
if value < 0 or value > 7:
msg = "value not in 0-7 range"
raise ValueError(msg)
return cext.proc_ioprio_set(self.pid, ioclass, value)
- if prlimit is not None:
+ if hasattr(resource, "prlimit"):
@wrap_exceptions
def rlimit(self, resource_, limits=None):
@@ -2278,16 +2196,16 @@ class Process:
try:
if limits is None:
# get
- return prlimit(self.pid, resource_)
+ return resource.prlimit(self.pid, resource_)
else:
# set
if len(limits) != 2:
msg = (
"second argument must be a (soft, hard) "
- + "tuple, got %s" % repr(limits)
+ f"tuple, got {limits!r}"
)
raise ValueError(msg)
- prlimit(self.pid, resource_, limits)
+ resource.prlimit(self.pid, resource_, limits)
except OSError as err:
if err.errno == errno.ENOSYS:
# I saw this happening on Travis:
@@ -2298,18 +2216,17 @@ class Process:
@wrap_exceptions
def status(self):
letter = self._parse_stat_file()['status']
- if PY3:
- letter = letter.decode()
+ letter = letter.decode()
# XXX is '?' legit? (we're not supposed to return it anyway)
return PROC_STATUSES.get(letter, '?')
@wrap_exceptions
def open_files(self):
retlist = []
- files = os.listdir("%s/%s/fd" % (self._procfs_path, self.pid))
+ files = os.listdir(f"{self._procfs_path}/{self.pid}/fd")
hit_enoent = False
for fd in files:
- file = "%s/%s/fd/%s" % (self._procfs_path, self.pid, fd)
+ file = f"{self._procfs_path}/{self.pid}/fd/{fd}"
try:
path = readlink(file)
except (FileNotFoundError, ProcessLookupError):
@@ -2332,11 +2249,7 @@ class Process:
# absolute path though.
if path.startswith('/') and isfile_strict(path):
# Get file position and flags.
- file = "%s/%s/fdinfo/%s" % (
- self._procfs_path,
- self.pid,
- fd,
- )
+ file = f"{self._procfs_path}/{self.pid}/fdinfo/{fd}"
try:
with open_binary(file) as f:
pos = int(f.readline().split()[1])
@@ -2363,7 +2276,7 @@ class Process:
@wrap_exceptions
def num_fds(self):
- return len(os.listdir("%s/%s/fd" % (self._procfs_path, self.pid)))
+ return len(os.listdir(f"{self._procfs_path}/{self.pid}/fd"))
@wrap_exceptions
def ppid(self):
diff --git a/contrib/python/psutil/py3/psutil/_psosx.py b/contrib/python/psutil/py3/psutil/_psosx.py
index ed9b319de7..620497b30a 100644
--- a/contrib/python/psutil/py3/psutil/_psosx.py
+++ b/contrib/python/psutil/py3/psutil/_psosx.py
@@ -22,8 +22,6 @@ from ._common import isfile_strict
from ._common import memoize_when_activated
from ._common import parse_environ_block
from ._common import usage_percent
-from ._compat import PermissionError
-from ._compat import ProcessLookupError
__extra__all__ = []
@@ -114,8 +112,7 @@ def virtual_memory():
"""System virtual memory as a namedtuple."""
total, active, inactive, wired, free, speculative = cext.virtual_mem()
# This is how Zabbix calculate avail and used mem:
- # https://github.com/zabbix/zabbix/blob/trunk/src/libs/zbxsysinfo/
- # osx/memory.c
+ # https://github.com/zabbix/zabbix/blob/master/src/libs/zbxsysinfo/osx/memory.c
# Also see: https://github.com/giampaolo/psutil/issues/1277
avail = inactive + free
used = active + wired
@@ -345,15 +342,15 @@ def wrap_exceptions(fun):
@functools.wraps(fun)
def wrapper(self, *args, **kwargs):
+ pid, ppid, name = self.pid, self._ppid, self._name
try:
return fun(self, *args, **kwargs)
- except ProcessLookupError:
- if is_zombie(self.pid):
- raise ZombieProcess(self.pid, self._name, self._ppid)
- else:
- raise NoSuchProcess(self.pid, self._name)
- except PermissionError:
- raise AccessDenied(self.pid, self._name)
+ except ProcessLookupError as err:
+ if is_zombie(pid):
+ raise ZombieProcess(pid, name, ppid) from err
+ raise NoSuchProcess(pid, name) from err
+ except PermissionError as err:
+ raise AccessDenied(pid, name) from err
return wrapper
@@ -502,11 +499,6 @@ class Process:
@wrap_exceptions
def net_connections(self, kind='inet'):
- if kind not in conn_tmap:
- raise ValueError(
- "invalid %r kind argument; choose between %s"
- % (kind, ', '.join([repr(x) for x in conn_tmap]))
- )
families, types = conn_tmap[kind]
rawlist = cext.proc_net_connections(self.pid, families, types)
ret = []
diff --git a/contrib/python/psutil/py3/psutil/_psposix.py b/contrib/python/psutil/py3/psutil/_psposix.py
index 42bdfa7ef6..88703fdbd2 100644
--- a/contrib/python/psutil/py3/psutil/_psposix.py
+++ b/contrib/python/psutil/py3/psutil/_psposix.py
@@ -4,10 +4,10 @@
"""Routines common to all posix systems."""
+import enum
import glob
import os
import signal
-import sys
import time
from ._common import MACOS
@@ -15,25 +15,12 @@ from ._common import TimeoutExpired
from ._common import memoize
from ._common import sdiskusage
from ._common import usage_percent
-from ._compat import PY3
-from ._compat import ChildProcessError
-from ._compat import FileNotFoundError
-from ._compat import InterruptedError
-from ._compat import PermissionError
-from ._compat import ProcessLookupError
-from ._compat import unicode
if MACOS:
from . import _psutil_osx
-if PY3:
- import enum
-else:
- enum = None
-
-
__all__ = ['pid_exists', 'wait_pid', 'disk_usage', 'get_terminal_map']
@@ -59,23 +46,16 @@ def pid_exists(pid):
return True
-# Python 3.5 signals enum (contributed by me ^^):
-# https://bugs.python.org/issue21076
-if enum is not None and hasattr(signal, "Signals"):
- Negsignal = enum.IntEnum(
- 'Negsignal', dict([(x.name, -x.value) for x in signal.Signals])
- )
-
- def negsig_to_enum(num):
- """Convert a negative signal value to an enum."""
- try:
- return Negsignal(num)
- except ValueError:
- return num
+Negsignal = enum.IntEnum(
+ 'Negsignal', {x.name: -x.value for x in signal.Signals}
+)
-else: # pragma: no cover
- def negsig_to_enum(num):
+def negsig_to_enum(num):
+ """Convert a negative signal value to an enum."""
+ try:
+ return Negsignal(num)
+ except ValueError:
return num
@@ -139,7 +119,7 @@ def wait_pid(
# can't determine its exit status code.
while _pid_exists(pid):
interval = sleep(interval)
- return
+ return None
else:
if retpid == 0:
# WNOHANG flag was used and PID is still running.
@@ -171,7 +151,8 @@ def wait_pid(
# continue
else:
# Should never happen.
- raise ValueError("unknown process exit status %r" % status)
+ msg = f"unknown process exit status {status!r}"
+ raise ValueError(msg)
def disk_usage(path):
@@ -181,24 +162,7 @@ def disk_usage(path):
total and used disk space whereas "free" and "percent" represent
the "free" and "used percent" user disk space.
"""
- if PY3:
- st = os.statvfs(path)
- else: # pragma: no cover
- # os.statvfs() does not support unicode on Python 2:
- # - https://github.com/giampaolo/psutil/issues/416
- # - http://bugs.python.org/issue18695
- try:
- st = os.statvfs(path)
- except UnicodeEncodeError:
- if isinstance(path, unicode):
- try:
- path = path.encode(sys.getfilesystemencoding())
- except UnicodeEncodeError:
- pass
- st = os.statvfs(path)
- else:
- raise
-
+ st = os.statvfs(path)
# Total space which is only available to root (unless changed
# at system level).
total = st.f_blocks * st.f_frsize
diff --git a/contrib/python/psutil/py3/psutil/_pssunos.py b/contrib/python/psutil/py3/psutil/_pssunos.py
index a38d939d79..78d941cc5f 100644
--- a/contrib/python/psutil/py3/psutil/_pssunos.py
+++ b/contrib/python/psutil/py3/psutil/_pssunos.py
@@ -18,6 +18,7 @@ from . import _psposix
from . import _psutil_posix as cext_posix
from . import _psutil_sunos as cext
from ._common import AF_INET6
+from ._common import ENCODING
from ._common import AccessDenied
from ._common import NoSuchProcess
from ._common import ZombieProcess
@@ -28,11 +29,6 @@ from ._common import memoize_when_activated
from ._common import sockfam_to_enum
from ._common import socktype_to_enum
from ._common import usage_percent
-from ._compat import PY3
-from ._compat import FileNotFoundError
-from ._compat import PermissionError
-from ._compat import ProcessLookupError
-from ._compat import b
__extra__all__ = ["CONN_IDLE", "CONN_BOUND", "PROCFS_PATH"]
@@ -147,17 +143,17 @@ def swap_memory():
p = subprocess.Popen(
[
'/usr/bin/env',
- 'PATH=/usr/sbin:/sbin:%s' % os.environ['PATH'],
+ f"PATH=/usr/sbin:/sbin:{os.environ['PATH']}",
'swap',
'-l',
],
stdout=subprocess.PIPE,
)
stdout, _ = p.communicate()
- if PY3:
- stdout = stdout.decode(sys.stdout.encoding)
+ stdout = stdout.decode(sys.stdout.encoding)
if p.returncode != 0:
- raise RuntimeError("'swap -l' failed (retcode=%s)" % p.returncode)
+ msg = f"'swap -l' failed (retcode={p.returncode})"
+ raise RuntimeError(msg)
lines = stdout.strip().split('\n')[1:]
if not lines:
@@ -244,7 +240,7 @@ def disk_partitions(all=False):
continue
except OSError as err:
# https://github.com/giampaolo/psutil/issues/1674
- debug("skipping %r: %s" % (mountpoint, err))
+ debug(f"skipping {mountpoint!r}: {err}")
continue
ntuple = _common.sdiskpart(device, mountpoint, fstype, opts)
retlist.append(ntuple)
@@ -265,14 +261,6 @@ def net_connections(kind, _pid=-1):
connections (as opposed to connections opened by one process only).
Only INET sockets are returned (UNIX are not).
"""
- cmap = _common.conn_tmap.copy()
- if _pid == -1:
- cmap.pop('unix', 0)
- if kind not in cmap:
- raise ValueError(
- "invalid %r kind argument; choose between %s"
- % (kind, ', '.join([repr(x) for x in cmap]))
- )
families, types = _common.conn_tmap[kind]
rawlist = cext.net_connections(_pid)
ret = set()
@@ -346,7 +334,8 @@ def users():
def pids():
"""Returns a list of PIDs currently running on the system."""
- return [int(x) for x in os.listdir(b(get_procfs_path())) if x.isdigit()]
+ path = get_procfs_path().encode(ENCODING)
+ return [int(x) for x in os.listdir(path) if x.isdigit()]
def pid_exists(pid):
@@ -361,24 +350,23 @@ def wrap_exceptions(fun):
@functools.wraps(fun)
def wrapper(self, *args, **kwargs):
+ pid, ppid, name = self.pid, self._ppid, self._name
try:
return fun(self, *args, **kwargs)
- except (FileNotFoundError, ProcessLookupError):
+ except (FileNotFoundError, ProcessLookupError) as err:
# ENOENT (no such file or directory) gets raised on open().
# ESRCH (no such process) can get raised on read() if
# process is gone in meantime.
- if not pid_exists(self.pid):
- raise NoSuchProcess(self.pid, self._name)
- else:
- raise ZombieProcess(self.pid, self._name, self._ppid)
- except PermissionError:
- raise AccessDenied(self.pid, self._name)
- except OSError:
- if self.pid == 0:
+ if not pid_exists(pid):
+ raise NoSuchProcess(pid, name) from err
+ raise ZombieProcess(pid, name, ppid) from err
+ except PermissionError as err:
+ raise AccessDenied(pid, name) from err
+ except OSError as err:
+ if pid == 0:
if 0 in pids():
- raise AccessDenied(self.pid, self._name)
- else:
- raise
+ raise AccessDenied(pid, name) from err
+ raise
raise
return wrapper
@@ -399,7 +387,7 @@ class Process:
"""Raise NSP if the process disappeared on us."""
# For those C function who do not raise NSP, possibly returning
# incorrect or incomplete result.
- os.stat('%s/%s' % (self._procfs_path, self.pid))
+ os.stat(f"{self._procfs_path}/{self.pid}")
def oneshot_enter(self):
self._proc_name_and_args.cache_activate(self)
@@ -420,7 +408,7 @@ class Process:
@memoize_when_activated
def _proc_basic_info(self):
if self.pid == 0 and not os.path.exists(
- '%s/%s/psinfo' % (self._procfs_path, self.pid)
+ f"{self._procfs_path}/{self.pid}/psinfo"
):
raise AccessDenied(self.pid)
ret = cext.proc_basic_info(self.pid, self._procfs_path)
@@ -440,9 +428,7 @@ class Process:
@wrap_exceptions
def exe(self):
try:
- return os.readlink(
- "%s/%s/path/a.out" % (self._procfs_path, self.pid)
- )
+ return os.readlink(f"{self._procfs_path}/{self.pid}/path/a.out")
except OSError:
pass # continue and guess the exe name from the cmdline
# Will be guessed later from cmdline but we want to explicitly
@@ -539,9 +525,7 @@ class Process:
if tty != cext.PRNODEV:
for x in (0, 1, 2, 255):
try:
- return os.readlink(
- '%s/%d/path/%d' % (procfs_path, self.pid, x)
- )
+ return os.readlink(f"{procfs_path}/{self.pid}/path/{x}")
except FileNotFoundError:
hit_enoent = True
continue
@@ -553,12 +537,12 @@ class Process:
# /proc/PID/path/cwd may not be resolved by readlink() even if
# it exists (ls shows it). If that's the case and the process
# is still alive return None (we can return None also on BSD).
- # Reference: http://goo.gl/55XgO
+ # Reference: https://groups.google.com/g/comp.unix.solaris/c/tcqvhTNFCAs
procfs_path = self._procfs_path
try:
- return os.readlink("%s/%s/path/cwd" % (procfs_path, self.pid))
+ return os.readlink(f"{procfs_path}/{self.pid}/path/cwd")
except FileNotFoundError:
- os.stat("%s/%s" % (procfs_path, self.pid)) # raise NSP or AD
+ os.stat(f"{procfs_path}/{self.pid}") # raise NSP or AD
return ""
@wrap_exceptions
@@ -580,7 +564,7 @@ class Process:
def threads(self):
procfs_path = self._procfs_path
ret = []
- tids = os.listdir('%s/%d/lwp' % (procfs_path, self.pid))
+ tids = os.listdir(f"{procfs_path}/{self.pid}/lwp")
hit_enoent = False
for tid in tids:
tid = int(tid)
@@ -588,7 +572,7 @@ class Process:
utime, stime = cext.query_process_thread(
self.pid, tid, procfs_path
)
- except EnvironmentError as err:
+ except OSError as err:
if err.errno == errno.EOVERFLOW and not IS_64_BIT:
# We may get here if we attempt to query a 64bit process
# with a 32bit python.
@@ -615,8 +599,8 @@ class Process:
retlist = []
hit_enoent = False
procfs_path = self._procfs_path
- pathdir = '%s/%d/path' % (procfs_path, self.pid)
- for fd in os.listdir('%s/%d/fd' % (procfs_path, self.pid)):
+ pathdir = f"{procfs_path}/{self.pid}/path"
+ for fd in os.listdir(f"{procfs_path}/{self.pid}/fd"):
path = os.path.join(pathdir, fd)
if os.path.islink(path):
try:
@@ -640,16 +624,16 @@ class Process:
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
stdout, stderr = p.communicate()
- if PY3:
- stdout, stderr = (
- x.decode(sys.stdout.encoding) for x in (stdout, stderr)
- )
+ stdout, stderr = (
+ x.decode(sys.stdout.encoding) for x in (stdout, stderr)
+ )
if p.returncode != 0:
if 'permission denied' in stderr.lower():
raise AccessDenied(self.pid, self._name)
if 'no such process' in stderr.lower():
raise NoSuchProcess(self.pid, self._name)
- raise RuntimeError("%r command error\n%s" % (cmd, stderr))
+ msg = f"{cmd!r} command error\n{stderr}"
+ raise RuntimeError(msg)
lines = stdout.split('\n')[2:]
for i, line in enumerate(lines):
@@ -675,7 +659,7 @@ class Process:
# is no longer there.
if not ret:
# will raise NSP if process is gone
- os.stat('%s/%s' % (self._procfs_path, self.pid))
+ os.stat(f"{self._procfs_path}/{self.pid}")
# UNIX sockets
if kind in {'all', 'unix'}:
@@ -691,9 +675,8 @@ class Process:
@wrap_exceptions
def memory_maps(self):
def toaddr(start, end):
- return '%s-%s' % (
- hex(start)[2:].strip('L'),
- hex(end)[2:].strip('L'),
+ return "{}-{}".format(
+ hex(start)[2:].strip('L'), hex(end)[2:].strip('L')
)
procfs_path = self._procfs_path
@@ -718,9 +701,7 @@ class Process:
addr = toaddr(addr, addrsize)
if not name.startswith('['):
try:
- name = os.readlink(
- '%s/%s/path/%s' % (procfs_path, self.pid, name)
- )
+ name = os.readlink(f"{procfs_path}/{self.pid}/path/{name}")
except OSError as err:
if err.errno == errno.ENOENT:
# sometimes the link may not be resolved by
@@ -729,7 +710,7 @@ class Process:
# unresolved link path.
# This seems an inconsistency with /proc similar
# to: http://goo.gl/55XgO
- name = '%s/%s/path/%s' % (procfs_path, self.pid, name)
+ name = f"{procfs_path}/{self.pid}/path/{name}"
hit_enoent = True
else:
raise
@@ -740,7 +721,7 @@ class Process:
@wrap_exceptions
def num_fds(self):
- return len(os.listdir("%s/%s/fd" % (self._procfs_path, self.pid)))
+ return len(os.listdir(f"{self._procfs_path}/{self.pid}/fd"))
@wrap_exceptions
def num_ctx_switches(self):
diff --git a/contrib/python/psutil/py3/psutil/_psutil_common.c b/contrib/python/psutil/py3/psutil/_psutil_common.c
index 941f6bff1b..2a56ae0f4a 100644
--- a/contrib/python/psutil/py3/psutil/_psutil_common.c
+++ b/contrib/python/psutil/py3/psutil/_psutil_common.c
@@ -69,15 +69,6 @@ PyErr_SetExcFromWindowsErrWithFilenameObject(PyObject *type,
return PyErr_SetFromWindowsErrWithFilename(ierr, NULL);
}
#endif // !defined(PyErr_SetExcFromWindowsErrWithFilenameObject)
-
-
-// PyPy 2.7
-#if !defined(PyErr_SetFromWindowsErr)
-PyObject *
-PyErr_SetFromWindowsErr(int winerr) {
- return PyErr_SetFromWindowsErrWithFilename(winerr, "");
-}
-#endif // !defined(PyErr_SetFromWindowsErr)
#endif // defined(PSUTIL_WINDOWS) && defined(PYPY_VERSION)
diff --git a/contrib/python/psutil/py3/psutil/_psutil_common.h b/contrib/python/psutil/py3/psutil/_psutil_common.h
index 2cdfa9d4d6..024452630f 100644
--- a/contrib/python/psutil/py3/psutil/_psutil_common.h
+++ b/contrib/python/psutil/py3/psutil/_psutil_common.h
@@ -23,14 +23,6 @@ static const int PSUTIL_CONN_NONE = 128;
// --- Backward compatibility with missing Python.h APIs
// ====================================================================
-#if PY_MAJOR_VERSION < 3
- // On Python 2 we just return a plain byte string, which is never
- // supposed to raise decoding errors, see:
- // https://github.com/giampaolo/psutil/issues/1040
- #define PyUnicode_DecodeFSDefault PyString_FromString
- #define PyUnicode_DecodeFSDefaultAndSize PyString_FromStringAndSize
-#endif
-
#if defined(PSUTIL_WINDOWS) && defined(PYPY_VERSION)
#if !defined(PyErr_SetFromWindowsErrWithFilename)
PyObject *PyErr_SetFromWindowsErrWithFilename(int ierr,
@@ -45,7 +37,6 @@ static const int PSUTIL_CONN_NONE = 128;
// --- _Py_PARSE_PID
// SIZEOF_INT|LONG is missing on Linux + PyPy (only?).
-// SIZEOF_PID_T is missing on Windows + Python2.
// In this case we guess it from setup.py. It's not 100% bullet proof,
// If wrong we'll probably get compiler warnings.
// FWIW on all UNIX platforms I've seen pid_t is defined as an int.
@@ -60,8 +51,8 @@ static const int PSUTIL_CONN_NONE = 128;
#define SIZEOF_PID_T PSUTIL_SIZEOF_PID_T // set as a macro in setup.py
#endif
-// _Py_PARSE_PID is Python 3 only, but since it's private make sure it's
-// always present.
+// _Py_PARSE_PID was added in Python 3, but since it's private we make
+// sure it's always present.
#ifndef _Py_PARSE_PID
#if SIZEOF_PID_T == SIZEOF_INT
#define _Py_PARSE_PID "i"
@@ -75,14 +66,10 @@ static const int PSUTIL_CONN_NONE = 128;
#endif
#endif
-// Python 2 or PyPy on Windows
+// PyPy on Windows
#ifndef PyLong_FromPid
#if ((SIZEOF_PID_T == SIZEOF_INT) || (SIZEOF_PID_T == SIZEOF_LONG))
- #if PY_MAJOR_VERSION >= 3
- #define PyLong_FromPid PyLong_FromLong
- #else
- #define PyLong_FromPid PyInt_FromLong
- #endif
+ #define PyLong_FromPid PyLong_FromLong
#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
#define PyLong_FromPid PyLong_FromLongLong
#else
diff --git a/contrib/python/psutil/py3/psutil/_psutil_linux.c b/contrib/python/psutil/py3/psutil/_psutil_linux.c
index 46244c5792..fcd886bfb6 100644
--- a/contrib/python/psutil/py3/psutil/_psutil_linux.c
+++ b/contrib/python/psutil/py3/psutil/_psutil_linux.c
@@ -19,6 +19,13 @@
#include "arch/linux/proc.h"
#include "arch/linux/users.h"
+// May happen on old RedHat versions, see:
+// https://github.com/giampaolo/psutil/issues/607
+#ifndef DUPLEX_UNKNOWN
+ #define DUPLEX_UNKNOWN 0xff
+#endif
+
+#define INITERR return NULL
static PyMethodDef mod_methods[] = {
// --- per-process functions
@@ -41,40 +48,24 @@ static PyMethodDef mod_methods[] = {
{"set_debug", psutil_set_debug, METH_VARARGS},
{NULL, NULL, 0, NULL}
};
-// May happen on old RedHat versions, see:
-// https://github.com/giampaolo/psutil/issues/607
-#ifndef DUPLEX_UNKNOWN
- #define DUPLEX_UNKNOWN 0xff
-#endif
-
-#if PY_MAJOR_VERSION >= 3
- #define INITERR return NULL
- static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "_psutil_linux",
- NULL,
- -1,
- mod_methods,
- NULL,
- NULL,
- NULL,
- NULL
- };
+static struct PyModuleDef moduledef = {
+ PyModuleDef_HEAD_INIT,
+ "_psutil_linux",
+ NULL,
+ -1,
+ mod_methods,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
- PyObject *PyInit__psutil_linux(void)
-#else /* PY_MAJOR_VERSION */
- #define INITERR return
- void init_psutil_linux(void)
-#endif /* PY_MAJOR_VERSION */
-{
-#if PY_MAJOR_VERSION >= 3
+PyObject *
+PyInit__psutil_linux(void) {
PyObject *mod = PyModule_Create(&moduledef);
-#else
- PyObject *mod = Py_InitModule("_psutil_linux", mod_methods);
-#endif
if (mod == NULL)
INITERR;
@@ -91,7 +82,5 @@ static PyMethodDef mod_methods[] = {
if (mod == NULL)
INITERR;
-#if PY_MAJOR_VERSION >= 3
return mod;
-#endif
}
diff --git a/contrib/python/psutil/py3/psutil/_psutil_osx.c b/contrib/python/psutil/py3/psutil/_psutil_osx.c
index 09fa267a98..b16103379b 100644
--- a/contrib/python/psutil/py3/psutil/_psutil_osx.c
+++ b/contrib/python/psutil/py3/psutil/_psutil_osx.c
@@ -7,6 +7,7 @@
*/
#include <Python.h>
+#include <sys/time.h> // needed for old macOS versions
#include <sys/proc.h>
#include <netinet/tcp_fsm.h>
@@ -20,6 +21,8 @@
#include "arch/osx/sys.h"
+#define INITERR return NULL
+
static PyMethodDef mod_methods[] = {
// --- per-process functions
{"proc_cmdline", psutil_proc_cmdline, METH_VARARGS},
@@ -61,33 +64,22 @@ static PyMethodDef mod_methods[] = {
};
-#if PY_MAJOR_VERSION >= 3
- #define INITERR return NULL
-
- static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "_psutil_osx",
- NULL,
- -1,
- mod_methods,
- NULL,
- NULL,
- NULL,
- NULL
- };
-
- PyObject *PyInit__psutil_osx(void)
-#else /* PY_MAJOR_VERSION */
- #define INITERR return
-
- void init_psutil_osx(void)
-#endif /* PY_MAJOR_VERSION */
-{
-#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef moduledef = {
+ PyModuleDef_HEAD_INIT,
+ "_psutil_osx",
+ NULL,
+ -1,
+ mod_methods,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+
+PyObject *
+PyInit__psutil_osx(void) {
PyObject *mod = PyModule_Create(&moduledef);
-#else
- PyObject *mod = Py_InitModule("_psutil_osx", mod_methods);
-#endif
if (mod == NULL)
INITERR;
@@ -140,7 +132,5 @@ static PyMethodDef mod_methods[] = {
if (mod == NULL)
INITERR;
-#if PY_MAJOR_VERSION >= 3
return mod;
-#endif
}
diff --git a/contrib/python/psutil/py3/psutil/_psutil_posix.c b/contrib/python/psutil/py3/psutil/_psutil_posix.c
index 7e6eaac46c..de10f7854a 100644
--- a/contrib/python/psutil/py3/psutil/_psutil_posix.c
+++ b/contrib/python/psutil/py3/psutil/_psutil_posix.c
@@ -52,6 +52,9 @@
#include "_psutil_common.h"
+#define INITERR return NULL
+
+
// ====================================================================
// --- Utils
// ====================================================================
@@ -434,11 +437,7 @@ append_flag(PyObject *py_retlist, const char * flag_name)
{
PyObject *py_str = NULL;
-#if PY_MAJOR_VERSION >= 3
py_str = PyUnicode_FromString(flag_name);
-#else
- py_str = PyString_FromString(flag_name);
-#endif
if (! py_str)
return 0;
if (PyList_Append(py_retlist, py_str)) {
@@ -883,33 +882,21 @@ static PyMethodDef mod_methods[] = {
};
-#if PY_MAJOR_VERSION >= 3
- #define INITERR return NULL
-
- static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "_psutil_posix",
- NULL,
- -1,
- mod_methods,
- NULL,
- NULL,
- NULL,
- NULL
- };
-
- PyObject *PyInit__psutil_posix(void)
-#else /* PY_MAJOR_VERSION */
- #define INITERR return
+static struct PyModuleDef moduledef = {
+ PyModuleDef_HEAD_INIT,
+ "_psutil_posix",
+ NULL,
+ -1,
+ mod_methods,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
- void init_psutil_posix(void)
-#endif /* PY_MAJOR_VERSION */
-{
-#if PY_MAJOR_VERSION >= 3
+PyObject *
+PyInit__psutil_posix(void) {
PyObject *mod = PyModule_Create(&moduledef);
-#else
- PyObject *mod = Py_InitModule("_psutil_posix", mod_methods);
-#endif
if (mod == NULL)
INITERR;
@@ -1022,9 +1009,7 @@ static PyMethodDef mod_methods[] = {
if (mod == NULL)
INITERR;
-#if PY_MAJOR_VERSION >= 3
return mod;
-#endif
}
#ifdef __cplusplus
diff --git a/contrib/python/psutil/py3/psutil/_psutil_windows.c b/contrib/python/psutil/py3/psutil/_psutil_windows.c
index 0c221bdc23..0af18f3e26 100644
--- a/contrib/python/psutil/py3/psutil/_psutil_windows.c
+++ b/contrib/python/psutil/py3/psutil/_psutil_windows.c
@@ -34,6 +34,10 @@
#include "arch/windows/wmi.h"
+#define INITERROR return NULL
+#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
+
+
// ------------------------ Python init ---------------------------
static PyMethodDef
@@ -116,21 +120,15 @@ struct module_state {
PyObject *error;
};
-#if PY_MAJOR_VERSION >= 3
-#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
-#else
-#define GETSTATE(m) (&_state)
-static struct module_state _state;
-#endif
-
-#if PY_MAJOR_VERSION >= 3
-static int psutil_windows_traverse(PyObject *m, visitproc visit, void *arg) {
+static int
+psutil_windows_traverse(PyObject *m, visitproc visit, void *arg) {
Py_VISIT(GETSTATE(m)->error);
return 0;
}
-static int psutil_windows_clear(PyObject *m) {
+static int
+psutil_windows_clear(PyObject *m) {
Py_CLEAR(GETSTATE(m)->error);
return 0;
}
@@ -147,21 +145,12 @@ static struct PyModuleDef moduledef = {
NULL
};
-#define INITERROR return NULL
-
-PyMODINIT_FUNC PyInit__psutil_windows(void)
-#else
-#define INITERROR return
-void init_psutil_windows(void)
-#endif
-{
+PyMODINIT_FUNC
+PyInit__psutil_windows(void) {
struct module_state *st = NULL;
-#if PY_MAJOR_VERSION >= 3
+
PyObject *module = PyModule_Create(&moduledef);
-#else
- PyObject *module = Py_InitModule("_psutil_windows", PsutilMethods);
-#endif
if (module == NULL)
INITERROR;
@@ -283,7 +272,5 @@ void init_psutil_windows(void)
PyModule_AddIntConstant(
module, "WINDOWS_10", PSUTIL_WINDOWS_10);
-#if PY_MAJOR_VERSION >= 3
return module;
-#endif
}
diff --git a/contrib/python/psutil/py3/psutil/_pswindows.py b/contrib/python/psutil/py3/psutil/_pswindows.py
index e39ba711fa..e5af3c90f4 100644
--- a/contrib/python/psutil/py3/psutil/_pswindows.py
+++ b/contrib/python/psutil/py3/psutil/_pswindows.py
@@ -5,7 +5,7 @@
"""Windows platform implementation."""
import contextlib
-import errno
+import enum
import functools
import os
import signal
@@ -15,7 +15,6 @@ from collections import namedtuple
from . import _common
from ._common import ENCODING
-from ._common import ENCODING_ERRS
from ._common import AccessDenied
from ._common import NoSuchProcess
from ._common import TimeoutExpired
@@ -27,11 +26,6 @@ from ._common import memoize
from ._common import memoize_when_activated
from ._common import parse_environ_block
from ._common import usage_percent
-from ._compat import PY3
-from ._compat import long
-from ._compat import lru_cache
-from ._compat import range
-from ._compat import unicode
from ._psutil_windows import ABOVE_NORMAL_PRIORITY_CLASS
from ._psutil_windows import BELOW_NORMAL_PRIORITY_CLASS
from ._psutil_windows import HIGH_PRIORITY_CLASS
@@ -54,14 +48,10 @@ except ImportError as err:
msg = "this Windows version is too old (< Windows Vista); "
msg += "psutil 3.4.2 is the latest version which supports Windows "
msg += "2000, XP and 2003 server"
- raise RuntimeError(msg)
+ raise RuntimeError(msg) from err
else:
raise
-if PY3:
- import enum
-else:
- enum = None
# process priority constants, import from __init__.py:
# http://msdn.microsoft.com/en-us/library/ms686219(v=vs.85).aspx
@@ -88,11 +78,8 @@ CONN_DELETE_TCB = "DELETE_TCB"
ERROR_PARTIAL_COPY = 299
PYPY = '__pypy__' in sys.builtin_module_names
-if enum is None:
- AF_LINK = -1
-else:
- AddressFamily = enum.IntEnum('AddressFamily', {'AF_LINK': -1})
- AF_LINK = AddressFamily.AF_LINK
+AddressFamily = enum.IntEnum('AddressFamily', {'AF_LINK': -1})
+AF_LINK = AddressFamily.AF_LINK
TCP_STATUSES = {
cext.MIB_TCP_STATE_ESTAB: _common.CONN_ESTABLISHED,
@@ -110,32 +97,27 @@ TCP_STATUSES = {
cext.PSUTIL_CONN_NONE: _common.CONN_NONE,
}
-if enum is not None:
- class Priority(enum.IntEnum):
- ABOVE_NORMAL_PRIORITY_CLASS = ABOVE_NORMAL_PRIORITY_CLASS
- BELOW_NORMAL_PRIORITY_CLASS = BELOW_NORMAL_PRIORITY_CLASS
- HIGH_PRIORITY_CLASS = HIGH_PRIORITY_CLASS
- IDLE_PRIORITY_CLASS = IDLE_PRIORITY_CLASS
- NORMAL_PRIORITY_CLASS = NORMAL_PRIORITY_CLASS
- REALTIME_PRIORITY_CLASS = REALTIME_PRIORITY_CLASS
+class Priority(enum.IntEnum):
+ ABOVE_NORMAL_PRIORITY_CLASS = ABOVE_NORMAL_PRIORITY_CLASS
+ BELOW_NORMAL_PRIORITY_CLASS = BELOW_NORMAL_PRIORITY_CLASS
+ HIGH_PRIORITY_CLASS = HIGH_PRIORITY_CLASS
+ IDLE_PRIORITY_CLASS = IDLE_PRIORITY_CLASS
+ NORMAL_PRIORITY_CLASS = NORMAL_PRIORITY_CLASS
+ REALTIME_PRIORITY_CLASS = REALTIME_PRIORITY_CLASS
- globals().update(Priority.__members__)
-if enum is None:
+globals().update(Priority.__members__)
+
+
+class IOPriority(enum.IntEnum):
IOPRIO_VERYLOW = 0
IOPRIO_LOW = 1
IOPRIO_NORMAL = 2
IOPRIO_HIGH = 3
-else:
- class IOPriority(enum.IntEnum):
- IOPRIO_VERYLOW = 0
- IOPRIO_LOW = 1
- IOPRIO_NORMAL = 2
- IOPRIO_HIGH = 3
- globals().update(IOPriority.__members__)
+globals().update(IOPriority.__members__)
pinfo_map = dict(
num_handles=0,
@@ -199,7 +181,7 @@ pio = namedtuple('pio', ['read_count', 'write_count',
# =====================================================================
-@lru_cache(maxsize=512)
+@functools.lru_cache(maxsize=512)
def convert_dos_path(s):
r"""Convert paths using native DOS format like:
"\Device\HarddiskVolume1\Windows\systemew\file.txt"
@@ -212,18 +194,6 @@ def convert_dos_path(s):
return os.path.join(driveletter, remainder)
-def py2_strencode(s):
- """Encode a unicode string to a byte string by using the default fs
- encoding + "replace" error handler.
- """
- if PY3:
- return s
- if isinstance(s, str):
- return s
- else:
- return s.encode(ENCODING, ENCODING_ERRS)
-
-
@memoize
def getpagesize():
return cext.getpagesize()
@@ -282,7 +252,7 @@ disk_io_counters = cext.disk_io_counters
def disk_usage(path):
"""Return disk usage associated with path."""
- if PY3 and isinstance(path, bytes):
+ if isinstance(path, bytes):
# XXX: do we want to use "strict"? Probably yes, in order
# to fail immediately. After all we are accepting input here...
path = path.decode(ENCODING, errors="strict")
@@ -367,7 +337,7 @@ def getloadavg():
# Drop to 2 decimal points which is what Linux does
raw_loads = cext.getloadavg()
- return tuple([round(load, 2) for load in raw_loads])
+ return tuple(round(load, 2) for load in raw_loads)
# =====================================================================
@@ -379,11 +349,6 @@ def net_connections(kind, _pid=-1):
"""Return socket connections. If pid == -1 return system-wide
connections (as opposed to connections opened by one process only).
"""
- if kind not in conn_tmap:
- raise ValueError(
- "invalid %r kind argument; choose between %s"
- % (kind, ', '.join([repr(x) for x in conn_tmap]))
- )
families, types = conn_tmap[kind]
rawlist = cext.net_connections(_pid, families, types)
ret = set()
@@ -408,9 +373,6 @@ def net_if_stats():
ret = {}
rawdict = cext.net_if_stats()
for name, items in rawdict.items():
- if not PY3:
- assert isinstance(name, unicode), type(name)
- name = py2_strencode(name)
isup, duplex, speed, mtu = items
if hasattr(_common, 'NicDuplex'):
duplex = _common.NicDuplex(duplex)
@@ -422,18 +384,12 @@ def net_io_counters():
"""Return network I/O statistics for every network interface
installed on the system as a dict of raw tuples.
"""
- ret = cext.net_io_counters()
- return dict([(py2_strencode(k), v) for k, v in ret.items()])
+ return cext.net_io_counters()
def net_if_addrs():
"""Return the addresses associated to each NIC."""
- ret = []
- for items in cext.net_if_addrs():
- items = list(items)
- items[0] = py2_strencode(items[0])
- ret.append(items)
- return ret
+ return cext.net_if_addrs()
# =====================================================================
@@ -489,7 +445,6 @@ def users():
rawlist = cext.users()
for item in rawlist:
user, hostname, tstamp = item
- user = py2_strencode(user)
nt = _common.suser(user, None, hostname, tstamp, None)
retlist.append(nt)
return retlist
@@ -503,7 +458,7 @@ def users():
def win_service_iter():
"""Yields a list of WindowsService instances."""
for name, display_name in cext.winservice_enumerate():
- yield WindowsService(py2_strencode(name), py2_strencode(display_name))
+ yield WindowsService(name, display_name)
def win_service_get(name):
@@ -521,14 +476,11 @@ class WindowsService: # noqa: PLW1641
self._display_name = display_name
def __str__(self):
- details = "(name=%r, display_name=%r)" % (
- self._name,
- self._display_name,
- )
- return "%s%s" % (self.__class__.__name__, details)
+ details = f"(name={self._name!r}, display_name={self._display_name!r})"
+ return f"{self.__class__.__name__}{details}"
def __repr__(self):
- return "<%s at %s>" % (self.__str__(), id(self))
+ return f"<{self.__str__()} at {id(self)}>"
def __eq__(self, other):
# Test for equality with another WindosService object based
@@ -547,10 +499,10 @@ class WindowsService: # noqa: PLW1641
)
# XXX - update _self.display_name?
return dict(
- display_name=py2_strencode(display_name),
- binpath=py2_strencode(binpath),
- username=py2_strencode(username),
- start_type=py2_strencode(start_type),
+ display_name=display_name,
+ binpath=binpath,
+ username=username,
+ start_type=start_type,
)
def _query_status(self):
@@ -568,18 +520,18 @@ class WindowsService: # noqa: PLW1641
try:
yield
except OSError as err:
+ name = self._name
if is_permission_err(err):
msg = (
- "service %r is not querable (not enough privileges)"
- % self._name
+ f"service {name!r} is not querable (not enough privileges)"
)
- raise AccessDenied(pid=None, name=self._name, msg=msg)
+ raise AccessDenied(pid=None, name=name, msg=msg) from err
elif err.winerror in {
cext.ERROR_INVALID_NAME,
cext.ERROR_SERVICE_DOES_NOT_EXIST,
}:
- msg = "service %r does not exist" % self._name
- raise NoSuchProcess(pid=None, name=self._name, msg=msg)
+ msg = f"service {name!r} does not exist"
+ raise NoSuchProcess(pid=None, name=name, msg=msg) from err
else:
raise
@@ -628,7 +580,7 @@ class WindowsService: # noqa: PLW1641
def description(self):
"""Service long description."""
- return py2_strencode(cext.winservice_query_descr(self.name()))
+ return cext.winservice_query_descr(self.name())
# utils
@@ -696,12 +648,7 @@ ppid_map = cext.ppid_map # used internally by Process.children()
def is_permission_err(exc):
"""Return True if this is a permission error."""
assert isinstance(exc, OSError), exc
- if exc.errno in {errno.EPERM, errno.EACCES}:
- return True
- # On Python 2 OSError doesn't always have 'winerror'. Sometimes
- # it does, in which case the original exception was WindowsError
- # (which is a subclass of OSError).
- return getattr(exc, "winerror", -1) in {
+ return isinstance(exc, PermissionError) or exc.winerror in {
cext.ERROR_ACCESS_DENIED,
cext.ERROR_PRIVILEGE_NOT_HELD,
}
@@ -712,7 +659,7 @@ def convert_oserror(exc, pid=None, name=None):
assert isinstance(exc, OSError), exc
if is_permission_err(exc):
return AccessDenied(pid=pid, name=name)
- if exc.errno == errno.ESRCH:
+ if isinstance(exc, ProcessLookupError):
return NoSuchProcess(pid=pid, name=name)
raise exc
@@ -725,7 +672,7 @@ def wrap_exceptions(fun):
try:
return fun(self, *args, **kwargs)
except OSError as err:
- raise convert_oserror(err, pid=self.pid, name=self._name)
+ raise convert_oserror(err, pid=self.pid, name=self._name) from err
return wrapper
@@ -742,7 +689,7 @@ def retry_error_partial_copy(fun):
for _ in range(times): # retries for roughly 1 second
try:
return fun(self, *args, **kwargs)
- except WindowsError as _:
+ except OSError as _:
err = _
if err.winerror == ERROR_PARTIAL_COPY:
time.sleep(delay)
@@ -750,8 +697,8 @@ def retry_error_partial_copy(fun):
continue
raise
msg = (
- "{} retried {} times, converted to AccessDenied as it's still"
- "returning {}".format(fun, times, err)
+ f"{fun} retried {times} times, converted to AccessDenied as it's "
+ f"still returning {err}"
)
raise AccessDenied(pid=self.pid, name=self._name, msg=msg)
@@ -805,17 +752,15 @@ class Process:
if PYPY:
try:
exe = cext.proc_exe(self.pid)
- except WindowsError as err:
+ except OSError as err:
# 24 = ERROR_TOO_MANY_OPEN_FILES. Not sure why this happens
# (perhaps PyPy's JIT delaying garbage collection of files?).
if err.errno == 24:
- debug("%r translated into AccessDenied" % err)
- raise AccessDenied(self.pid, self._name)
+ debug(f"{err!r} translated into AccessDenied")
+ raise AccessDenied(self.pid, self._name) from err
raise
else:
exe = cext.proc_exe(self.pid)
- if not PY3:
- exe = py2_strencode(exe)
if exe.startswith('\\'):
return convert_dos_path(exe)
return exe # May be "Registry", "MemCompression", ...
@@ -827,32 +772,26 @@ class Process:
# PEB method detects cmdline changes but requires more
# privileges: https://github.com/giampaolo/psutil/pull/1398
try:
- ret = cext.proc_cmdline(self.pid, use_peb=True)
+ return cext.proc_cmdline(self.pid, use_peb=True)
except OSError as err:
if is_permission_err(err):
- ret = cext.proc_cmdline(self.pid, use_peb=False)
+ return cext.proc_cmdline(self.pid, use_peb=False)
else:
raise
else:
- ret = cext.proc_cmdline(self.pid, use_peb=True)
- if PY3:
- return ret
- else:
- return [py2_strencode(s) for s in ret]
+ return cext.proc_cmdline(self.pid, use_peb=True)
@wrap_exceptions
@retry_error_partial_copy
def environ(self):
- ustr = cext.proc_environ(self.pid)
- if ustr and not PY3:
- assert isinstance(ustr, unicode), type(ustr)
- return parse_environ_block(py2_strencode(ustr))
+ s = cext.proc_environ(self.pid)
+ return parse_environ_block(s)
def ppid(self):
try:
return ppid_map()[self.pid]
except KeyError:
- raise NoSuchProcess(self.pid, self._name)
+ raise NoSuchProcess(self.pid, self._name) from None
def _get_raw_meminfo(self):
try:
@@ -900,12 +839,10 @@ class Process:
except OSError as err:
# XXX - can't use wrap_exceptions decorator as we're
# returning a generator; probably needs refactoring.
- raise convert_oserror(err, self.pid, self._name)
+ raise convert_oserror(err, self.pid, self._name) from err
else:
for addr, perm, path, rss in raw:
path = convert_dos_path(path)
- if not PY3:
- path = py2_strencode(path)
addr = hex(addr)
yield (addr, perm, path, rss)
@@ -917,11 +854,7 @@ class Process:
def send_signal(self, sig):
if sig == signal.SIGTERM:
cext.proc_kill(self.pid)
- # py >= 2.7
- elif sig in {
- getattr(signal, "CTRL_C_EVENT", object()),
- getattr(signal, "CTRL_BREAK_EVENT", object()),
- }:
+ elif sig in {signal.CTRL_C_EVENT, signal.CTRL_BREAK_EVENT}:
os.kill(self.pid, sig)
else:
msg = (
@@ -946,9 +879,9 @@ class Process:
# May also be None if OpenProcess() failed with
# ERROR_INVALID_PARAMETER, meaning PID is already gone.
exit_code = cext.proc_wait(self.pid, cext_timeout)
- except cext.TimeoutExpired:
+ except cext.TimeoutExpired as err:
# WaitForSingleObject() returned WAIT_TIMEOUT. Just raise.
- raise TimeoutExpired(timeout, self.pid, self._name)
+ raise TimeoutExpired(timeout, self.pid, self._name) from err
except cext.TimeoutAbandoned:
# WaitForSingleObject() returned WAIT_ABANDONED, see:
# https://github.com/giampaolo/psutil/issues/1224
@@ -978,7 +911,7 @@ class Process:
if self.pid in {0, 4}:
return 'NT AUTHORITY\\SYSTEM'
domain, user = cext.proc_username(self.pid)
- return py2_strencode(domain) + '\\' + py2_strencode(user)
+ return f"{domain}\\{user}"
@wrap_exceptions
def create_time(self, fast_only=False):
@@ -1038,7 +971,7 @@ class Process:
# return a normalized pathname since the native C function appends
# "\\" at the and of the path
path = cext.proc_cwd(self.pid)
- return py2_strencode(os.path.normpath(path))
+ return os.path.normpath(path)
@wrap_exceptions
def open_files(self):
@@ -1050,12 +983,10 @@ class Process:
# Convert the first part in the corresponding drive letter
# (e.g. "C:\") by using Windows's QueryDosDevice()
raw_file_names = cext.proc_open_files(self.pid)
- for _file in raw_file_names:
- _file = convert_dos_path(_file)
- if isfile_strict(_file):
- if not PY3:
- _file = py2_strencode(_file)
- ntuple = _common.popenfile(_file, -1)
+ for file in raw_file_names:
+ file = convert_dos_path(file)
+ if isfile_strict(file):
+ ntuple = _common.popenfile(file, -1)
ret.add(ntuple)
return list(ret)
@@ -1066,8 +997,7 @@ class Process:
@wrap_exceptions
def nice_get(self):
value = cext.proc_priority_get(self.pid)
- if enum is not None:
- value = Priority(value)
+ value = Priority(value)
return value
@wrap_exceptions
@@ -1077,8 +1007,7 @@ class Process:
@wrap_exceptions
def ionice_get(self):
ret = cext.proc_io_priority_get(self.pid)
- if enum is not None:
- ret = IOPriority(ret)
+ ret = IOPriority(ret)
return ret
@wrap_exceptions
@@ -1087,12 +1016,13 @@ class Process:
msg = "value argument not accepted on Windows"
raise TypeError(msg)
if ioclass not in {
- IOPRIO_VERYLOW,
- IOPRIO_LOW,
- IOPRIO_NORMAL,
- IOPRIO_HIGH,
+ IOPriority.IOPRIO_VERYLOW,
+ IOPriority.IOPRIO_LOW,
+ IOPriority.IOPRIO_NORMAL,
+ IOPriority.IOPRIO_HIGH,
}:
- raise ValueError("%s is not a valid priority" % ioclass)
+ msg = f"{ioclass} is not a valid priority"
+ raise ValueError(msg)
cext.proc_io_priority_set(self.pid, ioclass)
@wrap_exceptions
@@ -1134,7 +1064,8 @@ class Process:
def cpu_affinity_set(self, value):
def to_bitmask(ls):
if not ls:
- raise ValueError("invalid argument %r" % ls)
+ msg = f"invalid argument {ls!r}"
+ raise ValueError(msg)
out = 0
for b in ls:
out |= 2**b
@@ -1146,12 +1077,11 @@ class Process:
allcpus = list(range(len(per_cpu_times())))
for cpu in value:
if cpu not in allcpus:
- if not isinstance(cpu, (int, long)):
- raise TypeError(
- "invalid CPU %r; an integer is required" % cpu
- )
- else:
- raise ValueError("invalid CPU %r" % cpu)
+ if not isinstance(cpu, int):
+ msg = f"invalid CPU {cpu!r}; an integer is required"
+ raise TypeError(msg)
+ msg = f"invalid CPU {cpu!r}"
+ raise ValueError(msg)
bitmask = to_bitmask(value)
cext.proc_cpu_affinity_set(self.pid, bitmask)
diff --git a/contrib/python/psutil/py3/psutil/arch/linux/proc.c b/contrib/python/psutil/py3/psutil/arch/linux/proc.c
index b58a3ce2a2..f8230ee75b 100644
--- a/contrib/python/psutil/py3/psutil/arch/linux/proc.c
+++ b/contrib/python/psutil/py3/psutil/arch/linux/proc.c
@@ -118,11 +118,7 @@ psutil_proc_cpu_affinity_get(PyObject *self, PyObject *args) {
cpucount_s = CPU_COUNT_S(setsize, mask);
for (cpu = 0, count = cpucount_s; count; cpu++) {
if (CPU_ISSET_S(cpu, setsize, mask)) {
-#if PY_MAJOR_VERSION >= 3
PyObject *cpu_num = PyLong_FromLong(cpu);
-#else
- PyObject *cpu_num = PyInt_FromLong(cpu);
-#endif
if (cpu_num == NULL)
goto error;
if (PyList_Append(py_list, cpu_num)) {
@@ -159,11 +155,7 @@ psutil_proc_cpu_affinity_set(PyObject *self, PyObject *args) {
if (!PySequence_Check(py_cpu_set)) {
return PyErr_Format(
PyExc_TypeError,
-#if PY_MAJOR_VERSION >= 3
"sequence argument expected, got %R", Py_TYPE(py_cpu_set)
-#else
- "sequence argument expected, got %s", Py_TYPE(py_cpu_set)->tp_name
-#endif
);
}
@@ -177,11 +169,7 @@ psutil_proc_cpu_affinity_set(PyObject *self, PyObject *args) {
if (!item) {
return NULL;
}
-#if PY_MAJOR_VERSION >= 3
long value = PyLong_AsLong(item);
-#else
- long value = PyInt_AsLong(item);
-#endif
Py_XDECREF(item);
if ((value == -1) || PyErr_Occurred()) {
if (!PyErr_Occurred())
diff --git a/contrib/python/psutil/py3/psutil/arch/osx/disk.c b/contrib/python/psutil/py3/psutil/arch/osx/disk.c
index d02cf794d5..e1a8f5a492 100644
--- a/contrib/python/psutil/py3/psutil/arch/osx/disk.c
+++ b/contrib/python/psutil/py3/psutil/arch/osx/disk.c
@@ -168,7 +168,6 @@ psutil_disk_usage_used(PyObject *self, PyObject *args) {
PyObject *py_mount_point_bytes = NULL;
char* mount_point;
-#if PY_MAJOR_VERSION >= 3
if (!PyArg_ParseTuple(args, "O&O", PyUnicode_FSConverter, &py_mount_point_bytes, &py_default_value)) {
return NULL;
}
@@ -177,11 +176,6 @@ psutil_disk_usage_used(PyObject *self, PyObject *args) {
Py_XDECREF(py_mount_point_bytes);
return NULL;
}
-#else
- if (!PyArg_ParseTuple(args, "sO", &mount_point, &py_default_value)) {
- return NULL;
- }
-#endif
#ifdef ATTR_VOL_SPACEUSED
/* Call getattrlist(ATTR_VOL_SPACEUSED) to get used space info. */
diff --git a/contrib/python/psutil/py3/psutil/arch/osx/mem.c b/contrib/python/psutil/py3/psutil/arch/osx/mem.c
index 53493065c2..8103876070 100644
--- a/contrib/python/psutil/py3/psutil/arch/osx/mem.c
+++ b/contrib/python/psutil/py3/psutil/arch/osx/mem.c
@@ -8,6 +8,9 @@
// from psutil/_psutil_osx.c in 2023. This is the GIT blame before the move:
// https://github.com/giampaolo/psutil/blame/efd7ed3/psutil/_psutil_osx.c
+// See:
+// https://github.com/apple-open-source/macos/blob/master/system_cmds/vm_stat/vm_stat.c
+
#include <Python.h>
#include <mach/host_info.h>
#include <sys/sysctl.h>
@@ -17,12 +20,12 @@
static int
-psutil_sys_vminfo(vm_statistics_data_t *vmstat) {
+psutil_sys_vminfo(vm_statistics64_t vmstat) {
kern_return_t ret;
- mach_msg_type_number_t count = sizeof(*vmstat) / sizeof(integer_t);
+ unsigned int count = HOST_VM_INFO64_COUNT;
mach_port_t mport = mach_host_self();
- ret = host_statistics(mport, HOST_VM_INFO, (host_info_t)vmstat, &count);
+ ret = host_statistics64(mport, HOST_VM_INFO64, (host_info64_t)vmstat, &count);
if (ret != KERN_SUCCESS) {
PyErr_Format(
PyExc_RuntimeError,
@@ -46,7 +49,7 @@ psutil_virtual_mem(PyObject *self, PyObject *args) {
int mib[2];
uint64_t total;
size_t len = sizeof(total);
- vm_statistics_data_t vm;
+ vm_statistics64_data_t vm;
long pagesize = psutil_getpagesize();
// physical mem
mib[0] = CTL_HW;
@@ -86,7 +89,7 @@ psutil_swap_mem(PyObject *self, PyObject *args) {
int mib[2];
size_t size;
struct xsw_usage totals;
- vm_statistics_data_t vmstat;
+ vm_statistics64_data_t vmstat;
long pagesize = psutil_getpagesize();
mib[0] = CTL_VM;
diff --git a/contrib/python/psutil/py3/psutil/arch/osx/proc.c b/contrib/python/psutil/py3/psutil/arch/osx/proc.c
index 136311ecee..681642c3ad 100644
--- a/contrib/python/psutil/py3/psutil/arch/osx/proc.c
+++ b/contrib/python/psutil/py3/psutil/arch/osx/proc.c
@@ -763,7 +763,7 @@ error:
/*
* Return process open files as a Python tuple.
* References:
- * - lsof source code: http://goo.gl/SYW79 and http://goo.gl/m78fd
+ * - lsof source code: https://github.com/apple-opensource/lsof/blob/28/lsof/dialects/darwin/libproc/dproc.c#L342
* - /usr/include/sys/proc_info.h
*/
PyObject *
@@ -854,7 +854,7 @@ error:
* Return process TCP and UDP connections as a list of tuples.
* Raises NSP in case of zombie process.
* References:
- * - lsof source code: http://goo.gl/SYW79 and http://goo.gl/wNrC0
+ * - lsof source code: https://github.com/apple-opensource/lsof/blob/28/lsof/dialects/darwin/libproc/dproc.c#L342
* - /usr/include/sys/proc_info.h
*/
PyObject *
diff --git a/contrib/python/psutil/py3/psutil/arch/windows/disk.c b/contrib/python/psutil/py3/psutil/arch/windows/disk.c
index 88469e3a61..d0405a98f8 100644
--- a/contrib/python/psutil/py3/psutil/arch/windows/disk.c
+++ b/contrib/python/psutil/py3/psutil/arch/windows/disk.c
@@ -45,33 +45,6 @@ PyObject *
psutil_disk_usage(PyObject *self, PyObject *args) {
BOOL retval;
ULARGE_INTEGER _, total, free;
-
-#if PY_MAJOR_VERSION <= 2
- char *path;
-
- if (PyArg_ParseTuple(args, "u", &path)) {
- Py_BEGIN_ALLOW_THREADS
- retval = GetDiskFreeSpaceExW((LPCWSTR)path, &_, &total, &free);
- Py_END_ALLOW_THREADS
- goto return_;
- }
-
- // on Python 2 we also want to accept plain strings other
- // than Unicode
- PyErr_Clear(); // drop the argument parsing error
- if (PyArg_ParseTuple(args, "s", &path)) {
- Py_BEGIN_ALLOW_THREADS
- retval = GetDiskFreeSpaceEx(path, &_, &total, &free);
- Py_END_ALLOW_THREADS
- goto return_;
- }
-
- return NULL;
-
-return_:
- if (retval == 0)
- return PyErr_SetFromWindowsErrWithFilename(0, path);
-#else
PyObject *py_path;
wchar_t *path;
@@ -92,7 +65,7 @@ return_:
if (retval == 0)
return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, 0, py_path);
-#endif
+
return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
}
diff --git a/contrib/python/psutil/py3/psutil/arch/windows/net.c b/contrib/python/psutil/py3/psutil/arch/windows/net.c
index 8d8f7d1c0a..9a5634b069 100644
--- a/contrib/python/psutil/py3/psutil/arch/windows/net.c
+++ b/contrib/python/psutil/py3/psutil/arch/windows/net.c
@@ -255,21 +255,14 @@ psutil_net_if_addrs(PyObject *self, PyObject *args) {
continue;
}
-#if PY_MAJOR_VERSION >= 3
py_address = PyUnicode_FromString(buff_addr);
-#else
- py_address = PyString_FromString(buff_addr);
-#endif
if (py_address == NULL)
goto error;
if (netmaskIntRet != NULL) {
-#if PY_MAJOR_VERSION >= 3
py_netmask = PyUnicode_FromString(buff_netmask);
-#else
- py_netmask = PyString_FromString(buff_netmask);
-#endif
- } else {
+ }
+ else {
Py_INCREF(Py_None);
py_netmask = Py_None;
}
diff --git a/contrib/python/psutil/py3/psutil/arch/windows/proc.c b/contrib/python/psutil/py3/psutil/arch/windows/proc.c
index 05fb502557..41fa9dda68 100644
--- a/contrib/python/psutil/py3/psutil/arch/windows/proc.c
+++ b/contrib/python/psutil/py3/psutil/arch/windows/proc.c
@@ -192,11 +192,7 @@ psutil_proc_wait(PyObject *self, PyObject *args) {
CloseHandle(hProcess);
-#if PY_MAJOR_VERSION >= 3
return PyLong_FromLong((long) ExitCode);
-#else
- return PyInt_FromLong((long) ExitCode);
-#endif
}
diff --git a/contrib/python/psutil/py3/ya.make b/contrib/python/psutil/py3/ya.make
index c81c1dffb8..fd48170ac2 100644
--- a/contrib/python/psutil/py3/ya.make
+++ b/contrib/python/psutil/py3/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(6.1.1)
+VERSION(7.0.0)
LICENSE(BSD-3-Clause)
@@ -27,7 +27,7 @@ NO_CHECK_IMPORTS(
NO_UTIL()
CFLAGS(
- -DPSUTIL_VERSION=611
+ -DPSUTIL_VERSION=700
)
SRCS(
@@ -125,7 +125,6 @@ PY_SRCS(
TOP_LEVEL
psutil/__init__.py
psutil/_common.py
- psutil/_compat.py
psutil/_psaix.py
psutil/_psbsd.py
psutil/_pslinux.py
diff --git a/contrib/python/simplejson/py2/.dist-info/METADATA b/contrib/python/simplejson/py2/.dist-info/METADATA
index 84d46e5eca..9a1e6c550b 100644
--- a/contrib/python/simplejson/py2/.dist-info/METADATA
+++ b/contrib/python/simplejson/py2/.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: simplejson
-Version: 3.19.3
+Version: 3.20.1
Summary: Simple, fast, extensible JSON encoder/decoder for Python
Home-page: https://github.com/simplejson/simplejson
Author: Bob Ippolito
diff --git a/contrib/python/simplejson/py2/simplejson/__init__.py b/contrib/python/simplejson/py2/simplejson/__init__.py
index d3ff141d00..8bb46f15ed 100644
--- a/contrib/python/simplejson/py2/simplejson/__init__.py
+++ b/contrib/python/simplejson/py2/simplejson/__init__.py
@@ -118,7 +118,7 @@ Serializing multiple objects to JSON lines (newline-delimited JSON)::
"""
from __future__ import absolute_import
-__version__ = '3.19.3'
+__version__ = '3.20.1'
__all__ = [
'dump', 'dumps', 'load', 'loads',
'JSONDecoder', 'JSONDecodeError', 'JSONEncoder',
diff --git a/contrib/python/simplejson/py2/simplejson/_speedups.c b/contrib/python/simplejson/py2/simplejson/_speedups.c
index bd56b4dc87..4133b9bc76 100644
--- a/contrib/python/simplejson/py2/simplejson/_speedups.c
+++ b/contrib/python/simplejson/py2/simplejson/_speedups.c
@@ -10,11 +10,13 @@
#define JSON_UNICHR Py_UCS4
#define JSON_InternFromString PyUnicode_InternFromString
#define PyString_GET_SIZE PyUnicode_GET_LENGTH
+#define JSON_StringCheck PyUnicode_Check
#define PY2_UNUSED
#define PY3_UNUSED UNUSED
#else /* PY_MAJOR_VERSION >= 3 */
#define PY2_UNUSED UNUSED
#define PY3_UNUSED
+#define JSON_StringCheck(obj) (PyString_Check(obj) || PyUnicode_Check(obj))
#define PyBytes_Check PyString_Check
#define PyUnicode_READY(obj) 0
#define PyUnicode_KIND(obj) (sizeof(Py_UNICODE))
@@ -3034,25 +3036,29 @@ encoder_listencode_dict(PyEncoderObject *s, JSON_Accu *rval, PyObject *dct, Py_s
if (value == NULL)
goto bail;
- encoded = PyDict_GetItem(s->key_memo, key);
- if (encoded != NULL) {
- Py_INCREF(encoded);
- } else {
- kstr = encoder_stringify_key(s, key);
- if (kstr == NULL)
- goto bail;
- else if (kstr == Py_None) {
- /* skipkeys */
- Py_DECREF(item);
- Py_DECREF(kstr);
- continue;
- }
+ kstr = encoder_stringify_key(s, key);
+ if (kstr == NULL)
+ goto bail;
+ else if (kstr == Py_None) {
+ /* skipkeys */
+ Py_DECREF(item);
+ Py_DECREF(kstr);
+ continue;
}
if (idx) {
if (JSON_Accu_Accumulate(rval, s->item_separator))
goto bail;
}
- if (encoded == NULL) {
+ /*
+ * Only cache the encoding of string keys. False and True are
+ * indistinguishable from 0 and 1 in a dictionary lookup and there
+ * may be other quirks with user defined subclasses.
+ */
+ encoded = PyDict_GetItem(s->key_memo, kstr);
+ if (encoded != NULL) {
+ Py_INCREF(encoded);
+ Py_CLEAR(kstr);
+ } else {
encoded = encoder_encode_string(s, kstr);
Py_CLEAR(kstr);
if (encoded == NULL)
diff --git a/contrib/python/simplejson/py2/simplejson/tests/test_dump.py b/contrib/python/simplejson/py2/simplejson/tests/test_dump.py
index eff24c299c..5628489f26 100644
--- a/contrib/python/simplejson/py2/simplejson/tests/test_dump.py
+++ b/contrib/python/simplejson/py2/simplejson/tests/test_dump.py
@@ -73,6 +73,12 @@ class TestDump(TestCase):
{True: False, False: True}, sort_keys=True),
'{"false": true, "true": false}')
self.assertEqual(
+ # load first because the keys are not sorted
+ json.loads(json.dumps({'k1': {False: 5}, 'k2': {0: 5}})),
+ {'k1': {'false': 5}, 'k2': {'0': 5}},
+ )
+
+ self.assertEqual(
json.dumps(
{2: 3.0,
4.0: long_type(5),
diff --git a/contrib/python/simplejson/py2/ya.make b/contrib/python/simplejson/py2/ya.make
index 7397dd761d..f565e0ee79 100644
--- a/contrib/python/simplejson/py2/ya.make
+++ b/contrib/python/simplejson/py2/ya.make
@@ -2,7 +2,7 @@
PY2_LIBRARY()
-VERSION(3.19.3)
+VERSION(3.20.1)
LICENSE(MIT)
diff --git a/contrib/python/simplejson/py3/.dist-info/METADATA b/contrib/python/simplejson/py3/.dist-info/METADATA
index 689e566f7f..bee5586b12 100644
--- a/contrib/python/simplejson/py3/.dist-info/METADATA
+++ b/contrib/python/simplejson/py3/.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: simplejson
-Version: 3.19.3
+Version: 3.20.1
Summary: Simple, fast, extensible JSON encoder/decoder for Python
Home-page: https://github.com/simplejson/simplejson
Author: Bob Ippolito
diff --git a/contrib/python/simplejson/py3/simplejson/__init__.py b/contrib/python/simplejson/py3/simplejson/__init__.py
index d3ff141d00..8bb46f15ed 100644
--- a/contrib/python/simplejson/py3/simplejson/__init__.py
+++ b/contrib/python/simplejson/py3/simplejson/__init__.py
@@ -118,7 +118,7 @@ Serializing multiple objects to JSON lines (newline-delimited JSON)::
"""
from __future__ import absolute_import
-__version__ = '3.19.3'
+__version__ = '3.20.1'
__all__ = [
'dump', 'dumps', 'load', 'loads',
'JSONDecoder', 'JSONDecodeError', 'JSONEncoder',
diff --git a/contrib/python/simplejson/py3/simplejson/_speedups.c b/contrib/python/simplejson/py3/simplejson/_speedups.c
index bd56b4dc87..4133b9bc76 100644
--- a/contrib/python/simplejson/py3/simplejson/_speedups.c
+++ b/contrib/python/simplejson/py3/simplejson/_speedups.c
@@ -10,11 +10,13 @@
#define JSON_UNICHR Py_UCS4
#define JSON_InternFromString PyUnicode_InternFromString
#define PyString_GET_SIZE PyUnicode_GET_LENGTH
+#define JSON_StringCheck PyUnicode_Check
#define PY2_UNUSED
#define PY3_UNUSED UNUSED
#else /* PY_MAJOR_VERSION >= 3 */
#define PY2_UNUSED UNUSED
#define PY3_UNUSED
+#define JSON_StringCheck(obj) (PyString_Check(obj) || PyUnicode_Check(obj))
#define PyBytes_Check PyString_Check
#define PyUnicode_READY(obj) 0
#define PyUnicode_KIND(obj) (sizeof(Py_UNICODE))
@@ -3034,25 +3036,29 @@ encoder_listencode_dict(PyEncoderObject *s, JSON_Accu *rval, PyObject *dct, Py_s
if (value == NULL)
goto bail;
- encoded = PyDict_GetItem(s->key_memo, key);
- if (encoded != NULL) {
- Py_INCREF(encoded);
- } else {
- kstr = encoder_stringify_key(s, key);
- if (kstr == NULL)
- goto bail;
- else if (kstr == Py_None) {
- /* skipkeys */
- Py_DECREF(item);
- Py_DECREF(kstr);
- continue;
- }
+ kstr = encoder_stringify_key(s, key);
+ if (kstr == NULL)
+ goto bail;
+ else if (kstr == Py_None) {
+ /* skipkeys */
+ Py_DECREF(item);
+ Py_DECREF(kstr);
+ continue;
}
if (idx) {
if (JSON_Accu_Accumulate(rval, s->item_separator))
goto bail;
}
- if (encoded == NULL) {
+ /*
+ * Only cache the encoding of string keys. False and True are
+ * indistinguishable from 0 and 1 in a dictionary lookup and there
+ * may be other quirks with user defined subclasses.
+ */
+ encoded = PyDict_GetItem(s->key_memo, kstr);
+ if (encoded != NULL) {
+ Py_INCREF(encoded);
+ Py_CLEAR(kstr);
+ } else {
encoded = encoder_encode_string(s, kstr);
Py_CLEAR(kstr);
if (encoded == NULL)
diff --git a/contrib/python/simplejson/py3/simplejson/tests/test_dump.py b/contrib/python/simplejson/py3/simplejson/tests/test_dump.py
index eff24c299c..5628489f26 100644
--- a/contrib/python/simplejson/py3/simplejson/tests/test_dump.py
+++ b/contrib/python/simplejson/py3/simplejson/tests/test_dump.py
@@ -73,6 +73,12 @@ class TestDump(TestCase):
{True: False, False: True}, sort_keys=True),
'{"false": true, "true": false}')
self.assertEqual(
+ # load first because the keys are not sorted
+ json.loads(json.dumps({'k1': {False: 5}, 'k2': {0: 5}})),
+ {'k1': {'false': 5}, 'k2': {'0': 5}},
+ )
+
+ self.assertEqual(
json.dumps(
{2: 3.0,
4.0: long_type(5),
diff --git a/contrib/python/simplejson/py3/ya.make b/contrib/python/simplejson/py3/ya.make
index 7537b289e7..1d192847a5 100644
--- a/contrib/python/simplejson/py3/ya.make
+++ b/contrib/python/simplejson/py3/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(3.19.3)
+VERSION(3.20.1)
LICENSE(MIT)
diff --git a/library/cpp/http/simple/http_client.cpp b/library/cpp/http/simple/http_client.cpp
index 2be5a14582..6fb0475539 100644
--- a/library/cpp/http/simple/http_client.cpp
+++ b/library/cpp/http/simple/http_client.cpp
@@ -195,28 +195,28 @@ void TSimpleHttpClient::EnableVerificationForHttps() {
HttpsVerification = true;
}
-void TSimpleHttpClient::DoGet(const TStringBuf relativeUrl, IOutputStream* output, const THeaders& headers, NThreading::TCancellationToken cancellation) const {
+void TSimpleHttpClient::DoGet(const TStringBuf relativeUrl, IOutputStream* output, const THeaders& headers, THttpHeaders* outHeaders, NThreading::TCancellationToken cancellation) const {
TKeepAliveHttpClient cl = CreateClient();
- TKeepAliveHttpClient::THttpCode code = cl.DoGet(relativeUrl, output, headers, nullptr, std::move(cancellation));
+ TKeepAliveHttpClient::THttpCode code = cl.DoGet(relativeUrl, output, headers, outHeaders, std::move(cancellation));
Y_ENSURE(cl.GetHttpInput());
ProcessResponse(relativeUrl, *cl.GetHttpInput(), output, code);
}
-void TSimpleHttpClient::DoPost(const TStringBuf relativeUrl, TStringBuf body, IOutputStream* output, const THashMap<TString, TString>& headers, NThreading::TCancellationToken cancellation) const {
+void TSimpleHttpClient::DoPost(const TStringBuf relativeUrl, TStringBuf body, IOutputStream* output, const THashMap<TString, TString>& headers, THttpHeaders* outHeaders, NThreading::TCancellationToken cancellation) const {
TKeepAliveHttpClient cl = CreateClient();
- TKeepAliveHttpClient::THttpCode code = cl.DoPost(relativeUrl, body, output, headers, nullptr, std::move(cancellation));
+ TKeepAliveHttpClient::THttpCode code = cl.DoPost(relativeUrl, body, output, headers, outHeaders, std::move(cancellation));
Y_ENSURE(cl.GetHttpInput());
ProcessResponse(relativeUrl, *cl.GetHttpInput(), output, code);
}
-void TSimpleHttpClient::DoPostRaw(const TStringBuf relativeUrl, const TStringBuf rawRequest, IOutputStream* output, NThreading::TCancellationToken cancellation) const {
+void TSimpleHttpClient::DoPostRaw(const TStringBuf relativeUrl, const TStringBuf rawRequest, IOutputStream* output, THttpHeaders* outHeaders, NThreading::TCancellationToken cancellation) const {
TKeepAliveHttpClient cl = CreateClient();
- TKeepAliveHttpClient::THttpCode code = cl.DoRequestRaw(rawRequest, output, nullptr, std::move(cancellation));
+ TKeepAliveHttpClient::THttpCode code = cl.DoRequestRaw(rawRequest, output, outHeaders, std::move(cancellation));
Y_ENSURE(cl.GetHttpInput());
ProcessResponse(relativeUrl, *cl.GetHttpInput(), output, code);
diff --git a/library/cpp/http/simple/http_client.h b/library/cpp/http/simple/http_client.h
index 86a8cb4e99..3860862698 100644
--- a/library/cpp/http/simple/http_client.h
+++ b/library/cpp/http/simple/http_client.h
@@ -172,13 +172,13 @@ public:
void EnableVerificationForHttps();
- void DoGet(const TStringBuf relativeUrl, IOutputStream* output, const THeaders& headers = THeaders(), NThreading::TCancellationToken cancellation = NThreading::TCancellationToken::Default()) const;
+ void DoGet(const TStringBuf relativeUrl, IOutputStream* output, const THeaders& headers = THeaders(), THttpHeaders* outHeaders = nullptr, NThreading::TCancellationToken cancellation = NThreading::TCancellationToken::Default()) const;
// builds post request from headers and body
- void DoPost(const TStringBuf relativeUrl, TStringBuf body, IOutputStream* output, const THeaders& headers = THeaders(), NThreading::TCancellationToken cancellation = NThreading::TCancellationToken::Default()) const;
+ void DoPost(const TStringBuf relativeUrl, TStringBuf body, IOutputStream* output, const THeaders& headers = THeaders(), THttpHeaders* outHeaders = nullptr, NThreading::TCancellationToken cancellation = NThreading::TCancellationToken::Default()) const;
// requires already well-formed post request
- void DoPostRaw(const TStringBuf relativeUrl, TStringBuf rawRequest, IOutputStream* output, NThreading::TCancellationToken cancellation = NThreading::TCancellationToken::Default()) const;
+ void DoPostRaw(const TStringBuf relativeUrl, TStringBuf rawRequest, IOutputStream* output, THttpHeaders* outHeaders = nullptr, NThreading::TCancellationToken cancellation = NThreading::TCancellationToken::Default()) const;
virtual ~TSimpleHttpClient();
diff --git a/library/cpp/monlib/encode/buffered/buffered_encoder_base.cpp b/library/cpp/monlib/encode/buffered/buffered_encoder_base.cpp
index 87c832d642..c0449a10ff 100644
--- a/library/cpp/monlib/encode/buffered/buffered_encoder_base.cpp
+++ b/library/cpp/monlib/encode/buffered/buffered_encoder_base.cpp
@@ -144,6 +144,12 @@ void TBufferedEncoderBase::OnLogHistogram(TInstant time, TLogHistogramSnapshotPt
metric.TimeSeries.Add(time, s.Get());
}
+void TBufferedEncoderBase::OnMemOnly(bool isMemOnly) {
+ State_.Expect(TEncoderState::EState::METRIC);
+ TMetric& metric = Metrics_.back();
+ metric.IsMemOnly = isMemOnly;
+}
+
TString TBufferedEncoderBase::FormatLabels(const TPooledLabels& labels) const {
auto formattedLabels = TVector<TString>(Reserve(labels.size() + CommonLabels_.size()));
auto addLabel = [&](const TPooledLabel& l) {
diff --git a/library/cpp/monlib/encode/buffered/buffered_encoder_base.h b/library/cpp/monlib/encode/buffered/buffered_encoder_base.h
index fe3714e58f..dab5671ad4 100644
--- a/library/cpp/monlib/encode/buffered/buffered_encoder_base.h
+++ b/library/cpp/monlib/encode/buffered/buffered_encoder_base.h
@@ -37,6 +37,8 @@ public:
void OnSummaryDouble(TInstant time, ISummaryDoubleSnapshotPtr snapshot) override;
void OnLogHistogram(TInstant, TLogHistogramSnapshotPtr) override;
+ void OnMemOnly(bool isMemOnly) override;
+
protected:
using TPooledStr = TStringPoolBuilder::TValue;
@@ -80,6 +82,7 @@ protected:
EMetricType MetricType = EMetricType::UNKNOWN;
TPooledLabels Labels;
TMetricTimeSeries TimeSeries;
+ bool IsMemOnly;
};
protected:
diff --git a/library/cpp/monlib/encode/fake/fake.cpp b/library/cpp/monlib/encode/fake/fake.cpp
index 69d691361a..e3db20cbd1 100644
--- a/library/cpp/monlib/encode/fake/fake.cpp
+++ b/library/cpp/monlib/encode/fake/fake.cpp
@@ -43,6 +43,9 @@ namespace NMonitoring {
void Close() override {
}
+
+ void OnMemOnly(bool) override {
+ }
};
IMetricEncoderPtr EncoderFake() {
diff --git a/library/cpp/monlib/encode/protobuf/protobuf_encoder.cpp b/library/cpp/monlib/encode/protobuf/protobuf_encoder.cpp
index 2d11b9d5ba..2cffda13ac 100644
--- a/library/cpp/monlib/encode/protobuf/protobuf_encoder.cpp
+++ b/library/cpp/monlib/encode/protobuf/protobuf_encoder.cpp
@@ -227,6 +227,11 @@ namespace NMonitoring {
FillLogHistogram(*snapshot, point->MutableLogHistogram());
}
+ void OnMemOnly(bool isMemOnly) override {
+ Y_ENSURE(Sample_, "metric not started");
+ Sample_->SetIsMemOnly(isMemOnly);
+ }
+
void Close() override {
}
diff --git a/library/cpp/monlib/encode/protobuf/protos/samples.proto b/library/cpp/monlib/encode/protobuf/protos/samples.proto
index 371f4181d2..a3ca917221 100644
--- a/library/cpp/monlib/encode/protobuf/protos/samples.proto
+++ b/library/cpp/monlib/encode/protobuf/protos/samples.proto
@@ -59,7 +59,7 @@ message TPoint {
message TSingleSample {
repeated TLabel Labels = 1;
EMetricType MetricType = 2;
-
+ bool IsMemOnly = 10;
// inlined TPoint
uint64 Time = 3;
oneof Value {
@@ -76,6 +76,7 @@ message TMultiSample {
repeated TLabel Labels = 1;
EMetricType MetricType = 2;
repeated TPoint Points = 3;
+ bool IsMemOnly = 4;
}
message TSingleSamplesList {
diff --git a/library/cpp/monlib/encode/spack/spack_v1_decoder.cpp b/library/cpp/monlib/encode/spack/spack_v1_decoder.cpp
index 384ef456dd..a236bb9a50 100644
--- a/library/cpp/monlib/encode/spack/spack_v1_decoder.cpp
+++ b/library/cpp/monlib/encode/spack/spack_v1_decoder.cpp
@@ -107,15 +107,15 @@ namespace NMonitoring {
c->OnMetricBegin(metricType);
- // TODO: use it
- ReadFixed<ui8>(); // skip flags byte
+ // (5.2) flags byte
+ c->OnMemOnly(ReadFixed<ui8>() & 0x01);
auto metricNameValueIndex = std::numeric_limits<ui32>::max();
if (Header_.Version >= SV1_02) {
metricNameValueIndex = ReadVarint();
}
- // (5.2) labels
+ // (5.3) labels
ui32 labelsCount = ReadVarint();
DECODE_ENSURE(Header_.Version >= SV1_02 || labelsCount > 0, "metric #" << i << " has no labels");
c->OnLabelsBegin();
@@ -125,7 +125,7 @@ namespace NMonitoring {
ReadLabels(labelNames, labelValues, labelsCount, c);
c->OnLabelsEnd();
- // (5.3) values
+ // (5.4) values
switch (valueType) {
case EValueType::NONE:
break;
diff --git a/library/cpp/monlib/encode/spack/spack_v1_encoder.cpp b/library/cpp/monlib/encode/spack/spack_v1_encoder.cpp
index 7e13c3292b..70c5bba551 100644
--- a/library/cpp/monlib/encode/spack/spack_v1_encoder.cpp
+++ b/library/cpp/monlib/encode/spack/spack_v1_encoder.cpp
@@ -68,6 +68,10 @@ namespace NMonitoring {
TBufferedEncoderBase::OnLogHistogram(time, snapshot);
}
+ void OnMemOnly(bool isMemOnly) override {
+ TBufferedEncoderBase::OnMemOnly(isMemOnly);
+ }
+
void Close() override {
if (Closed_) {
return;
@@ -128,8 +132,8 @@ namespace NMonitoring {
ui8 typesByte = PackTypes(metric);
Out_->Write(&typesByte, sizeof(typesByte));
- // TODO: implement
- ui8 flagsByte = 0x00;
+ // (5.2) flags byte
+ ui8 flagsByte = metric.IsMemOnly & 0x01;
Out_->Write(&flagsByte, sizeof(flagsByte));
// v1.2 format addition — metric name
@@ -143,10 +147,10 @@ namespace NMonitoring {
WriteVarUInt32(Out_, it->Value->Index);
}
- // (5.2) labels
+ // (5.3) labels
WriteLabels(metric.Labels, MetricName_);
- // (5.3) values
+ // (5.4) values
switch (metric.TimeSeries.Size()) {
case 0:
break;
diff --git a/library/cpp/monlib/encode/spack/spack_v1_ut.cpp b/library/cpp/monlib/encode/spack/spack_v1_ut.cpp
index fe778eb7e0..bbc3b8712b 100644
--- a/library/cpp/monlib/encode/spack/spack_v1_ut.cpp
+++ b/library/cpp/monlib/encode/spack/spack_v1_ut.cpp
@@ -104,7 +104,7 @@ Y_UNIT_TEST_SUITE(TSpackTest) {
ui8 expectedMetric1[] = {
0x0C, // types (RATE | NONE) (fixed ui8)
- 0x00, // flags (fixed ui8)
+ 0x01, // flags (fixed ui8)
0x01, // metric labels count (varint)
0x00, // label name index (varint)
0x01, // label value index (varint)
@@ -282,6 +282,7 @@ Y_UNIT_TEST_SUITE(TSpackTest) {
e->OnLabelsBegin();
e->OnLabel("name", "q1");
e->OnLabelsEnd();
+ e->OnMemOnly(true);
}
e->OnMetricEnd();
}
@@ -513,12 +514,14 @@ Y_UNIT_TEST_SUITE(TSpackTest) {
{
const NProto::TMultiSample& s = samples.GetSamples(0);
UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::RATE);
+ UNIT_ASSERT_EQUAL(s.GetIsMemOnly(), true);
UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1);
AssertLabelEqual(s.GetLabels(0), "name", "q1");
}
{
const NProto::TMultiSample& s = samples.GetSamples(1);
UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::COUNTER);
+ UNIT_ASSERT_EQUAL(s.GetIsMemOnly(), false);
UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1);
AssertLabelEqual(s.GetLabels(0), "name", "q2");
@@ -528,6 +531,7 @@ Y_UNIT_TEST_SUITE(TSpackTest) {
{
const NProto::TMultiSample& s = samples.GetSamples(2);
UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::COUNTER);
+ UNIT_ASSERT_EQUAL(s.GetIsMemOnly(), false);
UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1);
AssertLabelEqual(s.GetLabels(0), "name", "q3");
@@ -537,6 +541,7 @@ Y_UNIT_TEST_SUITE(TSpackTest) {
{
const NProto::TMultiSample& s = samples.GetSamples(3);
UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE);
+ UNIT_ASSERT_EQUAL(s.GetIsMemOnly(), false);
UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1);
AssertLabelEqual(s.GetLabels(0), "name", "answer");
@@ -547,6 +552,7 @@ Y_UNIT_TEST_SUITE(TSpackTest) {
{
const NProto::TMultiSample& s = samples.GetSamples(4);
UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::HISTOGRAM);
+ UNIT_ASSERT_EQUAL(s.GetIsMemOnly(), false);
UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1);
AssertLabelEqual(s.GetLabels(0), "name", "responseTimeMillis");
@@ -570,6 +576,7 @@ Y_UNIT_TEST_SUITE(TSpackTest) {
{
const NProto::TMultiSample& s = samples.GetSamples(5);
UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::IGAUGE);
+ UNIT_ASSERT_EQUAL(s.GetIsMemOnly(), false);
UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1);
AssertLabelEqual(s.GetLabels(0), "name", "bytes");
@@ -579,6 +586,7 @@ Y_UNIT_TEST_SUITE(TSpackTest) {
{
const NProto::TMultiSample& s = samples.GetSamples(6);
UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::DSUMMARY);
+ UNIT_ASSERT_EQUAL(s.GetIsMemOnly(), false);
UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1);
AssertLabelEqual(s.GetLabels(0), "name", "temperature");
@@ -601,6 +609,7 @@ Y_UNIT_TEST_SUITE(TSpackTest) {
{
const NProto::TMultiSample& s = samples.GetSamples(7);
UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::LOGHISTOGRAM);
+ UNIT_ASSERT_EQUAL(s.GetIsMemOnly(), false);
UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1);
AssertLabelEqual(s.GetLabels(0), "name", "ms");
diff --git a/library/cpp/monlib/metrics/metric_consumer.h b/library/cpp/monlib/metrics/metric_consumer.h
index f7a727585a..1152b51c4a 100644
--- a/library/cpp/monlib/metrics/metric_consumer.h
+++ b/library/cpp/monlib/metrics/metric_consumer.h
@@ -33,6 +33,10 @@ namespace NMonitoring {
virtual void OnHistogram(TInstant time, IHistogramSnapshotPtr snapshot) = 0;
virtual void OnLogHistogram(TInstant time, TLogHistogramSnapshotPtr snapshot) = 0;
virtual void OnSummaryDouble(TInstant time, ISummaryDoubleSnapshotPtr snapshot) = 0;
+
+ virtual void OnMemOnly(bool isMemOnly) {
+ Y_UNUSED(isMemOnly);
+ }
};
using IMetricConsumerPtr = THolder<IMetricConsumer>;
diff --git a/library/cpp/monlib/metrics/metric_registry.cpp b/library/cpp/monlib/metrics/metric_registry.cpp
index c747ae2b74..245f65702d 100644
--- a/library/cpp/monlib/metrics/metric_registry.cpp
+++ b/library/cpp/monlib/metrics/metric_registry.cpp
@@ -11,16 +11,17 @@ namespace NMonitoring {
}
template <typename TLabelsConsumer>
- void ConsumeMetric(TInstant time, IMetricConsumer* consumer, IMetric* metric, TLabelsConsumer&& labelsConsumer) {
+ void ConsumeMetric(TInstant time, IMetricConsumer* consumer, IMetric* metric, TLabelsConsumer&& labelsConsumer, TMetricOpts opts = {}) {
consumer->OnMetricBegin(metric->Type());
// (1) add labels
consumer->OnLabelsBegin();
labelsConsumer();
consumer->OnLabelsEnd();
-
// (2) add time and value
metric->Accept(time, consumer);
+ // (3) add flag
+ consumer->OnMemOnly(opts.MemOnly);
consumer->OnMetricEnd();
}
}
@@ -55,104 +56,177 @@ namespace NMonitoring {
}
TGauge* TMetricRegistry::Gauge(TLabels labels) {
- return Metric<TGauge, EMetricType::GAUGE>(std::move(labels));
+ return GaugeWithOpts(std::move(labels));
+ }
+ TGauge* TMetricRegistry::GaugeWithOpts(TLabels labels, TMetricOpts opts) {
+ return Metric<TGauge, EMetricType::GAUGE>(std::move(labels), std::move(opts));
}
TGauge* TMetricRegistry::Gauge(ILabelsPtr labels) {
- return Metric<TGauge, EMetricType::GAUGE>(std::move(labels));
+ return GaugeWithOpts(std::move(labels));
+ }
+ TGauge* TMetricRegistry::GaugeWithOpts(ILabelsPtr labels, TMetricOpts opts) {
+ return Metric<TGauge, EMetricType::GAUGE>(std::move(labels), std::move(opts));
}
TLazyGauge* TMetricRegistry::LazyGauge(TLabels labels, std::function<double()> supplier) {
- return Metric<TLazyGauge, EMetricType::GAUGE>(std::move(labels), std::move(supplier));
+ return LazyGaugeWithOpts(std::move(labels), std::move(supplier));
+ }
+ TLazyGauge* TMetricRegistry::LazyGaugeWithOpts(TLabels labels, std::function<double()> supplier, TMetricOpts opts) {
+ return Metric<TLazyGauge, EMetricType::GAUGE>(std::move(labels),std::move(opts), std::move(supplier));
}
TLazyGauge* TMetricRegistry::LazyGauge(ILabelsPtr labels, std::function<double()> supplier) {
- return Metric<TLazyGauge, EMetricType::GAUGE>(std::move(labels), std::move(supplier));
+ return LazyGaugeWithOpts(std::move(labels), std::move(supplier));
+ }
+ TLazyGauge* TMetricRegistry::LazyGaugeWithOpts(ILabelsPtr labels, std::function<double()> supplier, TMetricOpts opts) {
+ return Metric<TLazyGauge, EMetricType::GAUGE>(std::move(labels), std::move(opts), std::move(supplier));
}
TIntGauge* TMetricRegistry::IntGauge(TLabels labels) {
- return Metric<TIntGauge, EMetricType::IGAUGE>(std::move(labels));
+ return IntGaugeWithOpts(std::move(labels));
+ }
+ TIntGauge* TMetricRegistry::IntGaugeWithOpts(TLabels labels, TMetricOpts opts) {
+ return Metric<TIntGauge, EMetricType::IGAUGE>(std::move(labels), std::move(opts));
}
TIntGauge* TMetricRegistry::IntGauge(ILabelsPtr labels) {
- return Metric<TIntGauge, EMetricType::IGAUGE>(std::move(labels));
+ return IntGaugeWithOpts(std::move(labels));
+ }
+ TIntGauge* TMetricRegistry::IntGaugeWithOpts(ILabelsPtr labels, TMetricOpts opts) {
+ return Metric<TIntGauge, EMetricType::IGAUGE>(std::move(labels), std::move(opts));
}
TLazyIntGauge* TMetricRegistry::LazyIntGauge(TLabels labels, std::function<i64()> supplier) {
- return Metric<TLazyIntGauge, EMetricType::IGAUGE>(std::move(labels), std::move(supplier));
+ return LazyIntGaugeWithOpts(std::move(labels), std::move(supplier));
+ }
+ TLazyIntGauge* TMetricRegistry::LazyIntGaugeWithOpts(TLabels labels, std::function<i64()> supplier, TMetricOpts opts) {
+ return Metric<TLazyIntGauge, EMetricType::IGAUGE>(std::move(labels), std::move(opts), std::move(supplier));
}
TLazyIntGauge* TMetricRegistry::LazyIntGauge(ILabelsPtr labels, std::function<i64()> supplier) {
- return Metric<TLazyIntGauge, EMetricType::IGAUGE>(std::move(labels), std::move(supplier));
+ return LazyIntGaugeWithOpts(std::move(labels), std::move(supplier));
+ }
+ TLazyIntGauge* TMetricRegistry::LazyIntGaugeWithOpts(ILabelsPtr labels, std::function<i64()> supplier, TMetricOpts opts) {
+ return Metric<TLazyIntGauge, EMetricType::IGAUGE>(std::move(labels), std::move(opts), std::move(supplier));
}
TCounter* TMetricRegistry::Counter(TLabels labels) {
- return Metric<TCounter, EMetricType::COUNTER>(std::move(labels));
+ return CounterWithOpts(std::move(labels));
+ }
+ TCounter* TMetricRegistry::CounterWithOpts(TLabels labels, TMetricOpts opts) {
+ return Metric<TCounter, EMetricType::COUNTER>(std::move(labels), std::move(opts));
}
TCounter* TMetricRegistry::Counter(ILabelsPtr labels) {
- return Metric<TCounter, EMetricType::COUNTER>(std::move(labels));
+ return CounterWithOpts(std::move(labels));
+ }
+ TCounter* TMetricRegistry::CounterWithOpts(ILabelsPtr labels, TMetricOpts opts) {
+ return Metric<TCounter, EMetricType::COUNTER>(std::move(labels), std::move(opts));
}
TLazyCounter* TMetricRegistry::LazyCounter(TLabels labels, std::function<ui64()> supplier) {
- return Metric<TLazyCounter, EMetricType::COUNTER>(std::move(labels), std::move(supplier));
+ return LazyCounterWithOpts(std::move(labels), std::move(supplier));
+ }
+ TLazyCounter* TMetricRegistry::LazyCounterWithOpts(TLabels labels, std::function<ui64()> supplier, TMetricOpts opts) {
+ return Metric<TLazyCounter, EMetricType::COUNTER>(std::move(labels), std::move(opts), std::move(supplier));
}
TLazyCounter* TMetricRegistry::LazyCounter(ILabelsPtr labels, std::function<ui64()> supplier) {
- return Metric<TLazyCounter, EMetricType::COUNTER>(std::move(labels), std::move(supplier));
+ return LazyCounterWithOpts(std::move(labels), std::move(supplier));
+ }
+ TLazyCounter* TMetricRegistry::LazyCounterWithOpts(ILabelsPtr labels, std::function<ui64()> supplier, TMetricOpts opts) {
+ return Metric<TLazyCounter, EMetricType::COUNTER>(std::move(labels), std::move(opts), std::move(supplier));
}
TRate* TMetricRegistry::Rate(TLabels labels) {
- return Metric<TRate, EMetricType::RATE>(std::move(labels));
+ return RateWithOpts(std::move(labels));
+ }
+ TRate* TMetricRegistry::RateWithOpts(TLabels labels, TMetricOpts opts) {
+ return Metric<TRate, EMetricType::RATE>(std::move(labels), std::move(opts));
}
TRate* TMetricRegistry::Rate(ILabelsPtr labels) {
- return Metric<TRate, EMetricType::RATE>(std::move(labels));
+ return RateWithOpts(std::move(labels));
+ }
+ TRate* TMetricRegistry::RateWithOpts(ILabelsPtr labels, TMetricOpts opts) {
+ return Metric<TRate, EMetricType::RATE>(std::move(labels), std::move(opts));
}
TLazyRate* TMetricRegistry::LazyRate(TLabels labels, std::function<ui64()> supplier) {
- return Metric<TLazyRate, EMetricType::RATE>(std::move(labels), std::move(supplier));
+ return LazyRateWithOpts(std::move(labels), std::move(supplier));
+ }
+ TLazyRate* TMetricRegistry::LazyRateWithOpts(TLabels labels, std::function<ui64()> supplier, TMetricOpts opts) {
+ return Metric<TLazyRate, EMetricType::RATE>(std::move(labels), std::move(opts), std::move(supplier));
}
TLazyRate* TMetricRegistry::LazyRate(ILabelsPtr labels, std::function<ui64()> supplier) {
- return Metric<TLazyRate, EMetricType::RATE>(std::move(labels), std::move(supplier));
+ return LazyRateWithOpts(std::move(labels), std::move(supplier));
+ }
+ TLazyRate* TMetricRegistry::LazyRateWithOpts(ILabelsPtr labels, std::function<ui64()> supplier, TMetricOpts opts) {
+ return Metric<TLazyRate, EMetricType::RATE>(std::move(labels), std::move(opts), std::move(supplier));
}
THistogram* TMetricRegistry::HistogramCounter(TLabels labels, IHistogramCollectorPtr collector) {
- return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(collector), false);
+ return HistogramCounterWithOpts(std::move(labels), std::move(collector));
+ }
+ THistogram* TMetricRegistry::HistogramCounterWithOpts(TLabels labels, IHistogramCollectorPtr collector, TMetricOpts opts) {
+ return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(opts), std::move(collector), false);
}
THistogram* TMetricRegistry::HistogramCounter(ILabelsPtr labels, IHistogramCollectorPtr collector) {
- return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(collector), false);
+ return HistogramCounterWithOpts(std::move(labels), std::move(collector));
+ }
+ THistogram* TMetricRegistry::HistogramCounterWithOpts(ILabelsPtr labels, IHistogramCollectorPtr collector, TMetricOpts opts) {
+ return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(opts), std::move(collector), false);
}
THistogram* TMetricRegistry::HistogramCounter(TLabels labels, std::function<IHistogramCollectorPtr()> supplier) {
- return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(supplier), false);
+ return HistogramCounterWithOpts(std::move(labels), std::move(supplier));
+ }
+ THistogram* TMetricRegistry::HistogramCounterWithOpts(TLabels labels, std::function<IHistogramCollectorPtr()> supplier, TMetricOpts opts) {
+ return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(opts), std::move(supplier), false);
}
THistogram* TMetricRegistry::HistogramCounter(ILabelsPtr labels, std::function<IHistogramCollectorPtr()> supplier) {
- return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(supplier), false);
+ return HistogramCounterWithOpts(std::move(labels), std::move(supplier));
+ }
+ THistogram* TMetricRegistry::HistogramCounterWithOpts(ILabelsPtr labels, std::function<IHistogramCollectorPtr()> supplier, TMetricOpts opts) {
+ return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(opts), std::move(supplier), false);
}
THistogram* TMetricRegistry::HistogramRate(TLabels labels, IHistogramCollectorPtr collector) {
- return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(collector), true);
+ return HistogramRateWithOpts(std::move(labels), std::move(collector));
+ }
+ THistogram* TMetricRegistry::HistogramRateWithOpts(TLabels labels, IHistogramCollectorPtr collector, TMetricOpts opts) {
+ return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(opts), std::move(collector), true);
}
THistogram* TMetricRegistry::HistogramRate(ILabelsPtr labels, IHistogramCollectorPtr collector) {
- return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(collector), true);
+ return HistogramRateWithOpts(std::move(labels), std::move(collector));
+ }
+ THistogram* TMetricRegistry::HistogramRateWithOpts(ILabelsPtr labels, IHistogramCollectorPtr collector, TMetricOpts opts) {
+ return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(opts), std::move(collector), true);
}
THistogram* TMetricRegistry::HistogramRate(TLabels labels, std::function<IHistogramCollectorPtr()> supplier) {
- return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(supplier), true);
+ return HistogramRateWithOpts(std::move(labels), std::move(supplier));
+ }
+ THistogram* TMetricRegistry::HistogramRateWithOpts(TLabels labels, std::function<IHistogramCollectorPtr()> supplier, TMetricOpts opts) {
+ return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(opts), std::move(supplier), true);
}
THistogram* TMetricRegistry::HistogramRate(ILabelsPtr labels, std::function<IHistogramCollectorPtr()> supplier) {
- return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(supplier), true);
+ return HistogramRateWithOpts(std::move(labels), std::move(supplier));
+ }
+ THistogram* TMetricRegistry::HistogramRateWithOpts(ILabelsPtr labels, std::function<IHistogramCollectorPtr()> supplier, TMetricOpts opts) {
+ return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(opts), std::move(supplier), true);
}
void TMetricRegistry::Reset() {
TWriteGuard g{*Lock_};
- for (auto& [label, metric] : Metrics_) {
+ for (auto& [label, metricValue] : Metrics_) {
+ auto metric = metricValue.Metric;
switch (metric->Type()) {
case EMetricType::GAUGE:
static_cast<TGauge*>(metric.Get())->Set(.0);
@@ -184,16 +258,19 @@ namespace NMonitoring {
}
template <typename TMetric, EMetricType type, typename TLabelsType, typename... Args>
- TMetric* TMetricRegistry::Metric(TLabelsType&& labels, Args&&... args) {
+ TMetric* TMetricRegistry::Metric(TLabelsType&& labels, TMetricOpts&& opts, Args&&... args) {
{
TReadGuard g{*Lock_};
auto it = Metrics_.find(labels);
if (it != Metrics_.end()) {
- Y_ENSURE(it->second->Type() == type, "cannot create metric " << labels
+ Y_ENSURE(it->second.Metric->Type() == type, "cannot create metric " << labels
<< " with type " << MetricTypeToStr(type)
- << ", because registry already has same metric with type " << MetricTypeToStr(it->second->Type()));
- return static_cast<TMetric*>(it->second.Get());
+ << ", because registry already has same metric with type " << MetricTypeToStr(it->second.Metric->Type()));
+ Y_ENSURE(it->second.Opts.MemOnly == opts.MemOnly,"cannot create metric " << labels
+ << " with memOnly=" << opts.MemOnly
+ << ", because registry already has same metric with memOnly=" << it->second.Opts.MemOnly);
+ return static_cast<TMetric*>(it->second.Metric.Get());
}
}
@@ -202,14 +279,15 @@ namespace NMonitoring {
TWriteGuard g{*Lock_};
// decltype(Metrics_)::iterator breaks build on windows
- THashMap<ILabelsPtr, IMetricPtr>::iterator it;
+ THashMap<ILabelsPtr, TMetricValue>::iterator it;
+ TMetricValue metricValue = {metric, opts};
if constexpr (!std::is_convertible_v<TLabelsType, ILabelsPtr>) {
- it = Metrics_.emplace(new TLabels{std::forward<TLabelsType>(labels)}, std::move(metric)).first;
+ it = Metrics_.emplace(new TLabels{std::forward<TLabelsType>(labels)}, std::move(metricValue)).first;
} else {
- it = Metrics_.emplace(std::forward<TLabelsType>(labels), std::move(metric)).first;
+ it = Metrics_.emplace(std::forward<TLabelsType>(labels), std::move(metricValue)).first;
}
- return static_cast<TMetric*>(it->second.Get());
+ return static_cast<TMetric*>(it->second.Metric.Get());
}
}
@@ -227,7 +305,7 @@ namespace NMonitoring {
consumer->OnLabelsEnd();
}
- TVector<std::pair<ILabelsPtr, IMetricPtr>> tmpMetrics;
+ TVector<std::pair<ILabelsPtr, TMetricValue>> tmpMetrics;
{
TReadGuard g{*Lock_};
@@ -239,10 +317,17 @@ namespace NMonitoring {
for (const auto& it: tmpMetrics) {
ILabels* labels = it.first.Get();
- IMetric* metric = it.second.Get();
- ConsumeMetric(time, consumer, metric, [&]() {
- ConsumeLabels(consumer, *labels);
- });
+ IMetric* metric = it.second.Metric.Get();
+ TMetricOpts opts = it.second.Opts;
+ ConsumeMetric(
+ time,
+ consumer,
+ metric,
+ [&]() {
+ ConsumeLabels(consumer, *labels);
+ },
+ opts
+ );
}
consumer->OnStreamEnd();
@@ -253,11 +338,18 @@ namespace NMonitoring {
for (const auto& it: Metrics_) {
ILabels* labels = it.first.Get();
- IMetric* metric = it.second.Get();
- ConsumeMetric(time, consumer, metric, [&]() {
- ConsumeLabels(consumer, CommonLabels_);
- ConsumeLabels(consumer, *labels);
- });
+ IMetric* metric = it.second.Metric.Get();
+ TMetricOpts opts = it.second.Opts;
+ ConsumeMetric(
+ time,
+ consumer,
+ metric,
+ [&]() {
+ ConsumeLabels(consumer, CommonLabels_);
+ ConsumeLabels(consumer, *labels);
+ },
+ opts
+ );
}
}
}
diff --git a/library/cpp/monlib/metrics/metric_registry.h b/library/cpp/monlib/metrics/metric_registry.h
index 7b3a7aab70..f60467cf91 100644
--- a/library/cpp/monlib/metrics/metric_registry.h
+++ b/library/cpp/monlib/metrics/metric_registry.h
@@ -9,35 +9,109 @@
namespace NMonitoring {
+
+ struct TMetricOpts {
+ bool MemOnly = false;
+ };
+
class IMetricFactory {
public:
virtual ~IMetricFactory() = default;
virtual IGauge* Gauge(ILabelsPtr labels) = 0;
+ virtual IGauge* GaugeWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) {
+ Y_UNUSED(opts);
+ return Gauge(std::move(labels));
+ }
+
virtual ILazyGauge* LazyGauge(ILabelsPtr labels, std::function<double()> supplier) = 0;
+ virtual ILazyGauge* LazyGaugeWithOpts(ILabelsPtr labels, std::function<double()> supplier, TMetricOpts opts = {}) {
+ Y_UNUSED(opts);
+ return LazyGauge(std::move(labels), std::move(supplier));
+ }
+
virtual IIntGauge* IntGauge(ILabelsPtr labels) = 0;
+ virtual IIntGauge* IntGaugeWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) {
+ Y_UNUSED(opts);
+ return IntGauge(std::move(labels));
+ }
virtual ILazyIntGauge* LazyIntGauge(ILabelsPtr labels, std::function<i64()> supplier) = 0;
+ virtual ILazyIntGauge* LazyIntGaugeWithOpts(ILabelsPtr labels, std::function<i64()> supplier, TMetricOpts opts = {}) {
+ Y_UNUSED(opts);
+ return LazyIntGauge(std::move(labels), std::move(supplier));
+ }
+
virtual ICounter* Counter(ILabelsPtr labels) = 0;
+ virtual ICounter* CounterWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) {
+ Y_UNUSED(opts);
+ return Counter(std::move(labels));
+ }
+
virtual ILazyCounter* LazyCounter(ILabelsPtr labels, std::function<ui64()> supplier) = 0;
+ virtual ILazyCounter* LazyCounterWithOpts(ILabelsPtr labels, std::function<ui64()> supplier, TMetricOpts opts = {}) {
+ Y_UNUSED(opts);
+ return LazyCounter(std::move(labels), std::move(supplier));
+ }
virtual IRate* Rate(ILabelsPtr labels) = 0;
+ virtual IRate* RateWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) {
+ Y_UNUSED(opts);
+ return Rate(std::move(labels));
+ }
+
virtual ILazyRate* LazyRate(ILabelsPtr labels, std::function<ui64()> supplier) = 0;
+ virtual ILazyRate* LazyRateWithOpts(ILabelsPtr labels, std::function<ui64()> supplier, TMetricOpts opts = {}) {
+ Y_UNUSED(opts);
+ return LazyRate(std::move(labels), std::move(supplier));
+ }
virtual IHistogram* HistogramCounter(
ILabelsPtr labels,
IHistogramCollectorPtr collector) = 0;
+ virtual IHistogram* HistogramCounterWithOpts(
+ ILabelsPtr labels,
+ IHistogramCollectorPtr collector,
+ TMetricOpts opts = {})
+ {
+ Y_UNUSED(opts);
+ return HistogramCounter(std::move(labels), std::move(collector));
+ }
virtual IHistogram* HistogramRate(
ILabelsPtr labels,
IHistogramCollectorPtr collector) = 0;
+ virtual IHistogram* HistogramRateWithOpts(
+ ILabelsPtr labels,
+ IHistogramCollectorPtr collector,
+ TMetricOpts opts = {})
+ {
+ Y_UNUSED(opts);
+ return HistogramRate(std::move(labels), std::move(collector));
+ }
virtual IHistogram* HistogramCounter(
ILabelsPtr labels,
std::function<IHistogramCollectorPtr()> makeHistogramCollector) = 0;
+ virtual IHistogram* HistogramCounterWithOpts(
+ ILabelsPtr labels,
+ std::function<IHistogramCollectorPtr()> makeHistogramCollector,
+ TMetricOpts opts = {})
+ {
+ Y_UNUSED(opts);
+ return HistogramCounter(std::move(labels), std::move(makeHistogramCollector));
+ }
virtual IHistogram* HistogramRate(
ILabelsPtr labels,
std::function<IHistogramCollectorPtr()> makeHistogramCollector) = 0;
+ virtual IHistogram* HistogramRateWithOpts(
+ ILabelsPtr labels,
+ std::function<IHistogramCollectorPtr()> makeHistogramCollector,
+ TMetricOpts opts = {})
+ {
+ Y_UNUSED(opts);
+ return HistogramRate(std::move(labels), std::move(makeHistogramCollector));
+ }
};
class IMetricSupplier {
@@ -79,29 +153,53 @@ namespace NMonitoring {
static std::shared_ptr<TMetricRegistry> SharedInstance();
TGauge* Gauge(TLabels labels);
+ TGauge* GaugeWithOpts(TLabels labels, TMetricOpts opts = {});
TLazyGauge* LazyGauge(TLabels labels, std::function<double()> supplier);
+ TLazyGauge* LazyGaugeWithOpts(TLabels labels, std::function<double()> supplier, TMetricOpts opts = {});
TIntGauge* IntGauge(TLabels labels);
+ TIntGauge* IntGaugeWithOpts(TLabels labels, TMetricOpts opts = {});
TLazyIntGauge* LazyIntGauge(TLabels labels, std::function<i64()> supplier);
+ TLazyIntGauge* LazyIntGaugeWithOpts(TLabels labels, std::function<i64()> supplier, TMetricOpts opts = {});
TCounter* Counter(TLabels labels);
+ TCounter* CounterWithOpts(TLabels labels, TMetricOpts opts = {});
TLazyCounter* LazyCounter(TLabels labels, std::function<ui64()> supplier);
+ TLazyCounter* LazyCounterWithOpts(TLabels labels, std::function<ui64()> supplier, TMetricOpts opts = {});
TRate* Rate(TLabels labels);
+ TRate* RateWithOpts(TLabels labels, TMetricOpts opts = {});
TLazyRate* LazyRate(TLabels labels, std::function<ui64()> supplier);
+ TLazyRate* LazyRateWithOpts(TLabels labels, std::function<ui64()> supplier, TMetricOpts opts = {});
THistogram* HistogramCounter(
TLabels labels,
IHistogramCollectorPtr collector);
+ THistogram* HistogramCounterWithOpts(
+ TLabels labels,
+ IHistogramCollectorPtr collector,
+ TMetricOpts opts = {});
THistogram* HistogramRate(
TLabels labels,
IHistogramCollectorPtr collector);
+ THistogram* HistogramRateWithOpts(
+ TLabels labels,
+ IHistogramCollectorPtr collector,
+ TMetricOpts opts = {});
THistogram* HistogramCounter(
TLabels labels,
std::function<IHistogramCollectorPtr()> makeHistogramCollector);
+ THistogram* HistogramCounterWithOpts(
+ TLabels labels,
+ std::function<IHistogramCollectorPtr()> makeHistogramCollector,
+ TMetricOpts opts = {});
THistogram* HistogramRate(
TLabels labels,
std::function<IHistogramCollectorPtr()> makeHistogramCollector);
+ THistogram* HistogramRateWithOpts(
+ TLabels labels,
+ std::function<IHistogramCollectorPtr()> makeHistogramCollector,
+ TMetricOpts opts = {});
/**
* Set all registered metrics to zero
@@ -123,36 +221,65 @@ namespace NMonitoring {
private:
TGauge* Gauge(ILabelsPtr labels) override;
+ TGauge* GaugeWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) override;
TLazyGauge* LazyGauge(ILabelsPtr labels, std::function<double()> supplier) override;
+ TLazyGauge* LazyGaugeWithOpts(ILabelsPtr labels, std::function<double()> supplier, TMetricOpts opts = {}) override;
TIntGauge* IntGauge(ILabelsPtr labels) override;
+ TIntGauge* IntGaugeWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) override;
TLazyIntGauge* LazyIntGauge(ILabelsPtr labels, std::function<i64()> supplier) override;
+ TLazyIntGauge* LazyIntGaugeWithOpts(ILabelsPtr labels, std::function<i64()> supplier, TMetricOpts opts = {}) override;
TCounter* Counter(ILabelsPtr labels) override;
+ TCounter* CounterWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) override;
TLazyCounter* LazyCounter(ILabelsPtr labels, std::function<ui64()> supplier) override;
+ TLazyCounter* LazyCounterWithOpts(ILabelsPtr labels, std::function<ui64()> supplier, TMetricOpts opts = {}) override;
TRate* Rate(ILabelsPtr labels) override;
+ TRate* RateWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) override;
TLazyRate* LazyRate(ILabelsPtr labels, std::function<ui64()> supplier) override;
+ TLazyRate* LazyRateWithOpts(ILabelsPtr labels, std::function<ui64()> supplier, TMetricOpts opts = {}) override;
THistogram* HistogramCounter(
ILabelsPtr labels,
IHistogramCollectorPtr collector) override;
+ THistogram* HistogramCounterWithOpts(
+ ILabelsPtr labels,
+ IHistogramCollectorPtr collector,
+ TMetricOpts opts = {}) override;
THistogram* HistogramRate(
ILabelsPtr labels,
IHistogramCollectorPtr collector) override;
+ THistogram* HistogramRateWithOpts(
+ ILabelsPtr labels,
+ IHistogramCollectorPtr collector,
+ TMetricOpts opts = {}) override;
THistogram* HistogramCounter(
ILabelsPtr labels,
std::function<IHistogramCollectorPtr()> makeHistogramCollector) override;
+ THistogram* HistogramCounterWithOpts(
+ ILabelsPtr labels,
+ std::function<IHistogramCollectorPtr()> makeHistogramCollector,
+ TMetricOpts opts = {}) override;
THistogram* HistogramRate(
ILabelsPtr labels,
std::function<IHistogramCollectorPtr()> makeHistogramCollector) override;
+ THistogram* HistogramRateWithOpts(
+ ILabelsPtr labels,
+ std::function<IHistogramCollectorPtr()> makeHistogramCollector,
+ TMetricOpts opts = {}) override;
+
+ struct TMetricValue {
+ IMetricPtr Metric;
+ TMetricOpts Opts;
+ };
private:
THolder<TRWMutex> Lock_ = MakeHolder<TRWMutex>();
- THashMap<ILabelsPtr, IMetricPtr> Metrics_;
+ THashMap<ILabelsPtr, TMetricValue> Metrics_;
template <typename TMetric, EMetricType type, typename TLabelsType, typename... Args>
- TMetric* Metric(TLabelsType&& labels, Args&&... args);
+ TMetric* Metric(TLabelsType&& labels, TMetricOpts&& opts, Args&&... args);
TLabels CommonLabels_;
};
diff --git a/library/cpp/monlib/metrics/metric_registry_ut.cpp b/library/cpp/monlib/metrics/metric_registry_ut.cpp
index 802c423264..89e6d56146 100644
--- a/library/cpp/monlib/metrics/metric_registry_ut.cpp
+++ b/library/cpp/monlib/metrics/metric_registry_ut.cpp
@@ -396,4 +396,76 @@ Y_UNIT_TEST_SUITE(TMetricRegistryTest) {
UNIT_ASSERT(commonLabels[0].GetName() == "common");
UNIT_ASSERT(commonLabels[0].GetValue() == "label");
}
+
+ Y_UNIT_TEST(MemOnlyMetric) {
+ TMetricRegistry registry;
+ i64 int_val = 0;
+ double double_val = 0;
+
+ registry.GaugeWithOpts({{"some", "gauge"}}, {true});
+ UNIT_ASSERT_EXCEPTION(registry.Gauge({{"some", "gauge"}}), yexception);
+
+ registry.LazyGaugeWithOpts(
+ {{"some", "lazy_gauge"}},
+ [&double_val](){return double_val;},
+ {true});
+ UNIT_ASSERT_EXCEPTION(
+ registry.LazyGauge(
+ {{"some", "lazy_gauge"}},
+ [&double_val](){return double_val;}),
+ yexception);
+
+ registry.IntGaugeWithOpts({{"some", "int_gauge"}}, {true});
+ UNIT_ASSERT_EXCEPTION(registry.IntGauge({{"some", "int_gauge"}}), yexception);
+
+ registry.LazyIntGaugeWithOpts(
+ {{"some", "lazy_int_gauge"}},
+ [&int_val](){return int_val;},
+ {true});
+ UNIT_ASSERT_EXCEPTION(
+ registry.LazyIntGauge(
+ {{"some", "lazy_int_gauge"}},
+ [&int_val](){return int_val;}),
+ yexception);
+
+ registry.CounterWithOpts({{"some", "counter"}}, {true});
+ UNIT_ASSERT_EXCEPTION(registry.Counter({{"some", "counter"}}), yexception);
+
+ registry.LazyCounterWithOpts({{"some", "lazy_counter"}}, [&int_val](){return int_val;}, {true});
+ UNIT_ASSERT_EXCEPTION(
+ registry.LazyCounter(
+ {{"some", "lazy_counter"}},
+ [&int_val](){return int_val;}),
+ yexception);
+
+ registry.RateWithOpts({{"some", "rate"}}, {true});
+ UNIT_ASSERT_EXCEPTION(registry.Rate({{"some", "rate"}}), yexception);
+
+ registry.LazyRateWithOpts({{"some", "lazy_rate"}}, [&double_val](){return double_val;}, {true});
+ UNIT_ASSERT_EXCEPTION(
+ registry.LazyRate(
+ {{"some", "lazy_rate"}},
+ [&double_val](){return double_val;}),
+ yexception);
+
+ registry.HistogramCounterWithOpts(
+ {{"some", "histogram_counter"}},
+ ExplicitHistogram({1, 5, 15, 20, 25}),
+ {true});
+ UNIT_ASSERT_EXCEPTION(
+ registry.HistogramCounter(
+ {{"some", "histogram_counter"}},
+ ExplicitHistogram({1, 5, 15, 20, 25})),
+ yexception);
+
+ registry.HistogramRateWithOpts(
+ {{"some", "histogram_rate"}},
+ ExponentialHistogram(5, 2),
+ {true});
+ UNIT_ASSERT_EXCEPTION(
+ registry.HistogramRate(
+ {{"some", "histogram_rate"}},
+ ExponentialHistogram(5, 2)),
+ yexception);
+ }
}
diff --git a/library/cpp/monlib/metrics/metric_sub_registry.h b/library/cpp/monlib/metrics/metric_sub_registry.h
index d1860c00a9..c3481f338f 100644
--- a/library/cpp/monlib/metrics/metric_sub_registry.h
+++ b/library/cpp/monlib/metrics/metric_sub_registry.h
@@ -33,61 +33,110 @@ public:
AddCommonLabels(labels.Get());
return DelegatePtr_->Gauge(std::move(labels));
}
+ IGauge* GaugeWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) override {
+ AddCommonLabels(labels.Get());
+ return DelegatePtr_->GaugeWithOpts(std::move(labels), std::move(opts));
+ }
ILazyGauge* LazyGauge(ILabelsPtr labels, std::function<double()> supplier) override {
AddCommonLabels(labels.Get());
return DelegatePtr_->LazyGauge(std::move(labels), std::move(supplier));
}
+ ILazyGauge* LazyGaugeWithOpts(ILabelsPtr labels, std::function<double()> supplier, TMetricOpts opts = {}) override {
+ AddCommonLabels(labels.Get());
+ return DelegatePtr_->LazyGaugeWithOpts(std::move(labels), std::move(supplier), std::move(opts));
+ }
IIntGauge* IntGauge(ILabelsPtr labels) override {
AddCommonLabels(labels.Get());
return DelegatePtr_->IntGauge(std::move(labels));
}
+ IIntGauge* IntGaugeWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) override {
+ AddCommonLabels(labels.Get());
+ return DelegatePtr_->IntGaugeWithOpts(std::move(labels), std::move(opts));
+ }
ILazyIntGauge* LazyIntGauge(ILabelsPtr labels, std::function<i64()> supplier) override {
AddCommonLabels(labels.Get());
return DelegatePtr_->LazyIntGauge(std::move(labels), std::move(supplier));
}
+ ILazyIntGauge* LazyIntGaugeWithOpts(ILabelsPtr labels, std::function<i64()> supplier, TMetricOpts opts = {}) override {
+ AddCommonLabels(labels.Get());
+ return DelegatePtr_->LazyIntGaugeWithOpts(std::move(labels), std::move(supplier), std::move(opts));
+ }
ICounter* Counter(ILabelsPtr labels) override {
AddCommonLabels(labels.Get());
return DelegatePtr_->Counter(std::move(labels));
}
+ ICounter* CounterWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) override {
+ AddCommonLabels(labels.Get());
+ return DelegatePtr_->CounterWithOpts(std::move(labels), std::move(opts));
+ }
ILazyCounter* LazyCounter(ILabelsPtr labels, std::function<ui64()> supplier) override {
AddCommonLabels(labels.Get());
return DelegatePtr_->LazyCounter(std::move(labels), std::move(supplier));
}
+ ILazyCounter* LazyCounterWithOpts(ILabelsPtr labels, std::function<ui64()> supplier, TMetricOpts opts = {}) override {
+ AddCommonLabels(labels.Get());
+ return DelegatePtr_->LazyCounterWithOpts(std::move(labels), std::move(supplier), std::move(opts));
+ }
IRate* Rate(ILabelsPtr labels) override {
AddCommonLabels(labels.Get());
return DelegatePtr_->Rate(std::move(labels));
}
+ IRate* RateWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) override {
+ AddCommonLabels(labels.Get());
+ return DelegatePtr_->RateWithOpts(std::move(labels), std::move(opts));
+ }
+
ILazyRate* LazyRate(ILabelsPtr labels, std::function<ui64()> supplier) override {
AddCommonLabels(labels.Get());
return DelegatePtr_->LazyRate(std::move(labels), std::move(supplier));
}
+ ILazyRate* LazyRateWithOpts(ILabelsPtr labels, std::function<ui64()> supplier, TMetricOpts opts = {}) override {
+ AddCommonLabels(labels.Get());
+ return DelegatePtr_->LazyRateWithOpts(std::move(labels), std::move(supplier), std::move(opts));
+ }
IHistogram* HistogramCounter(ILabelsPtr labels, IHistogramCollectorPtr collector) override {
AddCommonLabels(labels.Get());
return DelegatePtr_->HistogramCounter(std::move(labels), std::move(collector));
}
+ IHistogram* HistogramCounterWithOpts(ILabelsPtr labels, IHistogramCollectorPtr collector, TMetricOpts opts = {}) override {
+ AddCommonLabels(labels.Get());
+ return DelegatePtr_->HistogramCounterWithOpts(std::move(labels), std::move(collector), std::move(opts));
+ }
IHistogram* HistogramRate(ILabelsPtr labels, IHistogramCollectorPtr collector) override {
AddCommonLabels(labels.Get());
return DelegatePtr_->HistogramRate(std::move(labels), std::move(collector));
}
+ IHistogram* HistogramRateWithOpts(ILabelsPtr labels, IHistogramCollectorPtr collector, TMetricOpts opts = {}) override {
+ AddCommonLabels(labels.Get());
+ return DelegatePtr_->HistogramRateWithOpts(std::move(labels), std::move(collector), std::move(opts));
+ }
IHistogram* HistogramCounter(ILabelsPtr labels, std::function<IHistogramCollectorPtr()> collector) override {
AddCommonLabels(labels.Get());
return DelegatePtr_->HistogramCounter(std::move(labels), std::move(collector));
}
+ IHistogram* HistogramCounterWithOpts(ILabelsPtr labels, std::function<IHistogramCollectorPtr()> collector, TMetricOpts opts = {}) override {
+ AddCommonLabels(labels.Get());
+ return DelegatePtr_->HistogramCounterWithOpts(std::move(labels), std::move(collector), std::move(opts));
+ }
IHistogram* HistogramRate(ILabelsPtr labels, std::function<IHistogramCollectorPtr()> collector) override {
AddCommonLabels(labels.Get());
return DelegatePtr_->HistogramRate(std::move(labels), std::move(collector));
}
+ IHistogram* HistogramRateWithOpts(ILabelsPtr labels, std::function<IHistogramCollectorPtr()> collector, TMetricOpts opts) override {
+ AddCommonLabels(labels.Get());
+ return DelegatePtr_->HistogramRateWithOpts(std::move(labels), std::move(collector), std::move(opts));
+ }
void Accept(TInstant time, IMetricConsumer* consumer) const override {
DelegatePtr_->Accept(time, consumer);
diff --git a/library/cpp/yt/memory/non_null_ptr-inl.h b/library/cpp/yt/memory/non_null_ptr-inl.h
index a14b1e9302..d4d00c5549 100644
--- a/library/cpp/yt/memory/non_null_ptr-inl.h
+++ b/library/cpp/yt/memory/non_null_ptr-inl.h
@@ -1,6 +1,6 @@
#pragma once
#ifndef NON_NULL_PTR_H_
-#error "Direct inclusion of this file is not allowed, include helpers.h"
+#error "Direct inclusion of this file is not allowed, include non_null_ptr.h"
// For the sake of sane code completion.
#include "non_null_ptr.h"
#endif
diff --git a/library/cpp/yt/memory/poison-inl.h b/library/cpp/yt/memory/poison-inl.h
new file mode 100644
index 0000000000..c7563565a8
--- /dev/null
+++ b/library/cpp/yt/memory/poison-inl.h
@@ -0,0 +1,60 @@
+#pragma once
+#ifndef POISON_INL_H_
+#error "Direct inclusion of this file is not allowed, include poison.h"
+// For the sake of sane code completion.
+#include "poison.h"
+#endif
+
+#include <util/system/compiler.h>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+#if defined(_asan_enabled_)
+
+extern "C" {
+void __asan_poison_memory_region(void const volatile *addr, size_t size);
+void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
+} // extern "C"
+
+Y_FORCE_INLINE void PoisonMemory(TMutableRef ref)
+{
+ __asan_poison_memory_region(ref.data(), ref.size());
+}
+
+Y_FORCE_INLINE void UnpoisonMemory(TMutableRef ref)
+{
+ __asan_unpoison_memory_region(ref.data(), ref.size());
+}
+
+#elif defined(_msan_enabled_)
+
+extern "C" {
+void __msan_unpoison(const volatile void* a, size_t size);
+void __msan_poison(const volatile void* a, size_t size);
+} // extern "C"
+
+Y_FORCE_INLINE void PoisonMemory(TMutableRef ref)
+{
+ __msan_poison(ref.data(), ref.size());
+}
+
+Y_FORCE_INLINE void UnpoisonMemory(TMutableRef ref)
+{
+ __msan_unpoison(ref.data(), ref.size());
+}
+
+#elif defined(NDEBUG)
+
+Y_FORCE_INLINE void PoisonMemory(TMutableRef /*ref*/)
+{ }
+
+Y_FORCE_INLINE void UnpoisonMemory(TMutableRef /*ref*/)
+{ }
+
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/memory/poison.cpp b/library/cpp/yt/memory/poison.cpp
new file mode 100644
index 0000000000..bc4bcad4e0
--- /dev/null
+++ b/library/cpp/yt/memory/poison.cpp
@@ -0,0 +1,64 @@
+#include "poison.h"
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace {
+
+template <char Byte0, char Byte1, char Byte2, char Byte3, char Byte4, char Byte5, char Byte6, char Byte7>
+void ClobberMemory(char* __restrict__ ptr, size_t size)
+{
+ while (size >= 8) {
+ *ptr++ = Byte0;
+ *ptr++ = Byte1;
+ *ptr++ = Byte2;
+ *ptr++ = Byte3;
+ *ptr++ = Byte4;
+ *ptr++ = Byte5;
+ *ptr++ = Byte6;
+ *ptr++ = Byte7;
+ size -= 8;
+ }
+
+ switch (size) {
+ case 7:
+ *ptr++ = Byte0;
+ [[fallthrough]];
+ case 6:
+ *ptr++ = Byte1;
+ [[fallthrough]];
+ case 5:
+ *ptr++ = Byte2;
+ [[fallthrough]];
+ case 4:
+ *ptr++ = Byte3;
+ [[fallthrough]];
+ case 3:
+ *ptr++ = Byte4;
+ [[fallthrough]];
+ case 2:
+ *ptr++ = Byte5;
+ [[fallthrough]];
+ case 1:
+ *ptr++ = Byte6;
+ }
+}
+
+} // namespace
+
+#if !defined(NDEBUG) && !defined(_asan_enabled_) && !defined(_msan_enabled_)
+void PoisonMemory(TMutableRef ref)
+{
+ ClobberMemory<'d', 'e', 'a', 'd', 'b', 'e', 'e', 'f'>(ref.data(), ref.size());
+}
+
+void UnpoisonMemory(TMutableRef ref)
+{
+ ClobberMemory<'c', 'a', 'f', 'e', 'b', 'a', 'b', 'e'>(ref.data(), ref.size());
+}
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/memory/poison.h b/library/cpp/yt/memory/poison.h
new file mode 100644
index 0000000000..9519f3da10
--- /dev/null
+++ b/library/cpp/yt/memory/poison.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "ref.h"
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+//! In release builds, does nothing.
+//! In checked builds, clobbers memory with garbage pattern.
+//! In sanitized builds, invokes sanitizer poisoning.
+void PoisonMemory(TMutableRef ref);
+
+//! In release builds, does nothing.
+//! In checked builds, clobbers memory with (another) garbage pattern.
+//! In sanitized builds, invokes sanitizer unpoisoning.
+void UnpoisonMemory(TMutableRef ref);
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
+
+#define POISON_INL_H_
+#include "poison-inl.h"
+#undef POISON_INL_H_
diff --git a/library/cpp/yt/memory/range.h b/library/cpp/yt/memory/range.h
index 420ee9b429..84ea2e7758 100644
--- a/library/cpp/yt/memory/range.h
+++ b/library/cpp/yt/memory/range.h
@@ -354,12 +354,23 @@ public:
: TRange<T>(elements)
{ }
+ using TRange<T>::Data;
using TRange<T>::Begin;
using TRange<T>::End;
using TRange<T>::Front;
using TRange<T>::Back;
using TRange<T>::operator[];
+ T* Data() const
+ {
+ return const_cast<T*>(this->Data_);
+ }
+
+ T* data() const
+ {
+ return Data();
+ }
+
iterator Begin() const
{
return const_cast<T*>(this->Data_);
diff --git a/library/cpp/yt/memory/ya.make b/library/cpp/yt/memory/ya.make
index 5397dccf32..d0c377cf3d 100644
--- a/library/cpp/yt/memory/ya.make
+++ b/library/cpp/yt/memory/ya.make
@@ -16,6 +16,7 @@ SRCS(
chunked_output_stream.cpp
memory_tag.cpp
new.cpp
+ poison.cpp
ref.cpp
ref_tracked.cpp
safe_memory_reader.cpp
diff --git a/tools/cpp_style_checker/__main__.py b/tools/cpp_style_checker/__main__.py
index ab8534a0ad..089d9fa079 100644
--- a/tools/cpp_style_checker/__main__.py
+++ b/tools/cpp_style_checker/__main__.py
@@ -5,7 +5,7 @@ import subprocess
import time
import yaml
-from build.plugins.lib.test_const import CLANG_FORMAT_RESOURCE
+from build.plugins.lib.test_const import CLANG_FORMAT_RESOURCE, CLANG_FORMAT_15_RESOURCE
from library.python.testing.custom_linter_util import linter_params, reporter
from library.python.testing.style import rules
@@ -16,6 +16,8 @@ def main():
if 'clang_format_bin' in params.extra_params:
# custom clang-format
clang_format_binary = params.depends[params.extra_params['clang_format_bin']]
+ elif 'use_clang_format_15' in params.extra_params:
+ clang_format_binary = os.path.join(params.global_resources[CLANG_FORMAT_15_RESOURCE], 'clang-format-15')
else:
clang_format_binary = os.path.join(params.global_resources[CLANG_FORMAT_RESOURCE], 'clang-format')
diff --git a/ya b/ya
index ccffcc2eec..f2ed38dc5e 100755
--- a/ya
+++ b/ya
@@ -39,33 +39,33 @@ REGISTRY_ENDPOINT = os.environ.get("YA_REGISTRY_ENDPOINT", "https://devtools-reg
PLATFORM_MAP = {
"data": {
"darwin": {
- "md5": "ed34b869e3a766cccca99388465df834",
+ "md5": "0a246880109da2b6d775b5daeb6bb2f2",
"urls": [
- f"{REGISTRY_ENDPOINT}/8119502178"
+ f"{REGISTRY_ENDPOINT}/8161454854"
]
},
"darwin-arm64": {
- "md5": "a1cacfea98f9894d5581fe46b4eb27f8",
+ "md5": "4f2cf03181b6f11f9fa5e70319233ec7",
"urls": [
- f"{REGISTRY_ENDPOINT}/8119500148"
+ f"{REGISTRY_ENDPOINT}/8161452021"
]
},
"linux-aarch64": {
- "md5": "76e502fc5106cd60cfaeaf54fc61c44d",
+ "md5": "bdf485f4384d5c49d076cd6f51549c52",
"urls": [
- f"{REGISTRY_ENDPOINT}/8119498515"
+ f"{REGISTRY_ENDPOINT}/8161449965"
]
},
"win32-clang-cl": {
- "md5": "9d94a672b39ef7d913f5743fd901592f",
+ "md5": "e243509e7283a639cb34c83349e128be",
"urls": [
- f"{REGISTRY_ENDPOINT}/8119504001"
+ f"{REGISTRY_ENDPOINT}/8161456097"
]
},
"linux": {
- "md5": "7222ec6e66035ce9e75c26df1aad868a",
+ "md5": "e4a4799a1caa797935daf3013bebe4e2",
"urls": [
- f"{REGISTRY_ENDPOINT}/8119506702"
+ f"{REGISTRY_ENDPOINT}/8161456791"
]
}
}
diff --git a/ydb/ci/rightlib.txt b/ydb/ci/rightlib.txt
index b7b70c3a1b..1298102d24 100644
--- a/ydb/ci/rightlib.txt
+++ b/ydb/ci/rightlib.txt
@@ -1 +1 @@
-6678165e016ba474f1b8dd6d49af92b0d46350b9
+0ae3f82349eeb4f353c62dd726e4ba06bbc837f9
diff --git a/yql/essentials/core/facade/yql_facade.cpp b/yql/essentials/core/facade/yql_facade.cpp
index f8d9c28ba1..547c3a292e 100644
--- a/yql/essentials/core/facade/yql_facade.cpp
+++ b/yql/essentials/core/facade/yql_facade.cpp
@@ -691,6 +691,7 @@ void TProgram::HandleTranslationSettings(NSQLTranslation::TTranslationSettings&
loadedSettings.V0WarnAsError = NSQLTranslation::ISqlFeaturePolicy::Make(dataNode["V0WarnAsError"].AsBool());
loadedSettings.DqDefaultAuto = NSQLTranslation::ISqlFeaturePolicy::Make(dataNode["DqDefaultAuto"].AsBool());
loadedSettings.BlockDefaultAuto = NSQLTranslation::ISqlFeaturePolicy::Make(dataNode["BlockDefaultAuto"].AsBool());
+ loadedSettings.IsReplay = true;
currentSettings = &loadedSettings;
}
}
diff --git a/yql/essentials/linters.make.inc b/yql/essentials/linters.make.inc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/yql/essentials/linters.make.inc
diff --git a/yql/essentials/minikql/aligned_page_pool.cpp b/yql/essentials/minikql/aligned_page_pool.cpp
index 04aab1bd8a..bcbb3edd11 100644
--- a/yql/essentials/minikql/aligned_page_pool.cpp
+++ b/yql/essentials/minikql/aligned_page_pool.cpp
@@ -783,6 +783,40 @@ void* GetAlignedPage(ui64 size) {
}
template<typename TMmap>
+void* GetAlignedPage() {
+ const auto size = TAlignedPagePool::POOL_PAGE_SIZE;
+ auto& globalPool = TGlobalPools<TMmap, false>::Instance();
+
+ if (auto* page = globalPool.Get(0).GetPage()) {
+ return page;
+ }
+
+ auto allocSize = size * 2;
+ void* unalignedPtr = globalPool.DoMmap(allocSize);
+ if (Y_UNLIKELY(MAP_FAILED == unalignedPtr)) {
+ TStringStream mmaps;
+ const auto lastError = LastSystemError();
+ if (lastError == ENOMEM) {
+ mmaps << GetMemoryMapsString();
+ }
+
+ ythrow yexception() << "Mmap failed to allocate " << allocSize << " bytes: "
+ << LastSystemErrorText(lastError) << mmaps.Str();
+ }
+
+ void* page = AlignUp(unalignedPtr, size);
+
+ // Unmap unaligned prefix before offset and tail after aligned page
+ const size_t offset = (intptr_t)page - (intptr_t)unalignedPtr;
+ if (Y_UNLIKELY(offset)) {
+ globalPool.DoMunmap(unalignedPtr, offset);
+ globalPool.DoMunmap((ui8*)page + size, size - offset);
+ }
+
+ return page;
+}
+
+template<typename TMmap>
void ReleaseAlignedPage(void* mem, ui64 size) {
size = AlignUp(size, SYS_PAGE_SIZE);
if (size < TAlignedPagePool::POOL_PAGE_SIZE) {
@@ -801,6 +835,11 @@ void ReleaseAlignedPage(void* mem, ui64 size) {
}
template<typename TMmap>
+void ReleaseAlignedPage(void* ptr) {
+ TGlobalPools<TMmap, false>::Instance().PushPage(0, ptr);
+}
+
+template<typename TMmap>
i64 GetTotalMmapedBytes() {
return TGlobalPools<TMmap, true>::Instance().GetTotalMmappedBytes() + TGlobalPools<TMmap, false>::Instance().GetTotalMmappedBytes();
}
@@ -822,10 +861,18 @@ template void* GetAlignedPage<>(ui64);
template void* GetAlignedPage<TFakeAlignedMmap>(ui64);
template void* GetAlignedPage<TFakeUnalignedMmap>(ui64);
+template void* GetAlignedPage<>();
+template void* GetAlignedPage<TFakeAlignedMmap>();
+template void* GetAlignedPage<TFakeUnalignedMmap>();
+
template void ReleaseAlignedPage<>(void*,ui64);
template void ReleaseAlignedPage<TFakeAlignedMmap>(void*,ui64);
template void ReleaseAlignedPage<TFakeUnalignedMmap>(void*,ui64);
+template void ReleaseAlignedPage<>(void*);
+template void ReleaseAlignedPage<TFakeAlignedMmap>(void*);
+template void ReleaseAlignedPage<TFakeUnalignedMmap>(void*);
+
size_t GetMemoryMapsCount() {
size_t lineCount = 0;
TString line;
diff --git a/yql/essentials/minikql/aligned_page_pool.h b/yql/essentials/minikql/aligned_page_pool.h
index 4a5b1d2e55..511b99b4d7 100644
--- a/yql/essentials/minikql/aligned_page_pool.h
+++ b/yql/essentials/minikql/aligned_page_pool.h
@@ -309,9 +309,15 @@ template<typename TMmap = TSystemMmap>
void* GetAlignedPage(ui64 size);
template<typename TMmap = TSystemMmap>
+void* GetAlignedPage();
+
+template<typename TMmap = TSystemMmap>
void ReleaseAlignedPage(void* mem, ui64 size);
template<typename TMmap = TSystemMmap>
+void ReleaseAlignedPage(void* mem);
+
+template<typename TMmap = TSystemMmap>
i64 GetTotalMmapedBytes();
template<typename TMmap = TSystemMmap>
i64 GetTotalFreeListBytes();
diff --git a/yql/essentials/minikql/comp_nodes/mkql_apply.cpp b/yql/essentials/minikql/comp_nodes/mkql_apply.cpp
index 180a38176b..60fbe82ad4 100644
--- a/yql/essentials/minikql/comp_nodes/mkql_apply.cpp
+++ b/yql/essentials/minikql/comp_nodes/mkql_apply.cpp
@@ -206,9 +206,8 @@ private:
}
IComputationNode* WrapApply(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- const bool withPos = callable.GetType()->GetName() == "Apply2";
- const ui32 deltaArgs = withPos ? 3 : 0;
- MKQL_ENSURE(callable.GetInputsCount() >= 2 + deltaArgs, "Expected at least " << (2 + deltaArgs) << " arguments");
+ MKQL_ENSURE(callable.GetInputsCount() >= 5, "Expected at least 5 arguments");
+ constexpr size_t posArgs = 3;
const auto function = callable.GetInput(0);
MKQL_ENSURE(!function.IsImmediate() && function.GetNode()->GetType()->IsCallable(),
@@ -218,11 +217,11 @@ IComputationNode* WrapApply(TCallable& callable, const TComputationNodeFactoryCo
const auto returnType = functionCallable->GetType()->GetReturnType();
MKQL_ENSURE(returnType->IsCallable(), "Expected callable as return type");
- const TStringBuf file = withPos ? AS_VALUE(TDataLiteral, callable.GetInput(2))->AsValue().AsStringRef() : NUdf::TStringRef();
- const ui32 row = withPos ? AS_VALUE(TDataLiteral, callable.GetInput(3))->AsValue().Get<ui32>() : 0;
- const ui32 column = withPos ? AS_VALUE(TDataLiteral, callable.GetInput(4))->AsValue().Get<ui32>() : 0;
+ const TStringBuf file = AS_VALUE(TDataLiteral, callable.GetInput(2))->AsValue().AsStringRef();
+ const ui32 row = AS_VALUE(TDataLiteral, callable.GetInput(3))->AsValue().Get<ui32>();
+ const ui32 column = AS_VALUE(TDataLiteral, callable.GetInput(4))->AsValue().Get<ui32>();
- const ui32 inputsCount = callable.GetInputsCount() - deltaArgs;
+ const ui32 inputsCount = callable.GetInputsCount() - posArgs;
const ui32 argsCount = inputsCount - 2;
const ui32 dependentCount = AS_VALUE(TDataLiteral, callable.GetInput(1))->AsValue().Get<ui32>();
@@ -235,11 +234,11 @@ IComputationNode* WrapApply(TCallable& callable, const TComputationNodeFactoryCo
TComputationNodePtrVector argNodes(callableType->GetArgumentsCount() + dependentCount);
for (ui32 i = 2; i < 2 + usedArgs; ++i) {
- argNodes[i - 2] = LocateNode(ctx.NodeLocator, callable, i + deltaArgs);
+ argNodes[i - 2] = LocateNode(ctx.NodeLocator, callable, i + posArgs);
}
for (ui32 i = 2 + usedArgs; i < inputsCount; ++i) {
- argNodes[callableType->GetArgumentsCount() + i - 2 - usedArgs] = LocateNode(ctx.NodeLocator, callable, i + deltaArgs);
+ argNodes[callableType->GetArgumentsCount() + i - 2 - usedArgs] = LocateNode(ctx.NodeLocator, callable, i + posArgs);
}
auto functionNode = LocateNode(ctx.NodeLocator, callable, 0);
diff --git a/yql/essentials/minikql/comp_nodes/mkql_dictitems.cpp b/yql/essentials/minikql/comp_nodes/mkql_dictitems.cpp
index 8790089972..295bee402b 100644
--- a/yql/essentials/minikql/comp_nodes/mkql_dictitems.cpp
+++ b/yql/essentials/minikql/comp_nodes/mkql_dictitems.cpp
@@ -277,24 +277,9 @@ private:
}
IComputationNode* WrapDictItems(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 1 || callable.GetInputsCount() == 2, "Expected one or two args");
+ MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected one arg");
const auto node = LocateNode(ctx.NodeLocator, callable, 0);
-
- if (1U == callable.GetInputsCount()) {
- return new TDictItemsWrapper(ctx.Mutables, node);
- }
-
- const auto mode = AS_VALUE(TDataLiteral, callable.GetInput(1))->AsValue().Get<ui32>();
- switch (static_cast<EDictItems>(mode)) {
- case EDictItems::Both:
- return new TDictItemsWrapper(ctx.Mutables, node);
- case EDictItems::Keys:
- return new TDictHalfsWrapper<true>(ctx.Mutables, node);
- case EDictItems::Payloads:
- return new TDictHalfsWrapper<false>(ctx.Mutables, node);
- default:
- Y_ABORT("Unknown mode: %" PRIu32, mode);
- }
+ return new TDictItemsWrapper(ctx.Mutables, node);
}
IComputationNode* WrapDictKeys(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
diff --git a/yql/essentials/minikql/comp_nodes/mkql_factory.cpp b/yql/essentials/minikql/comp_nodes/mkql_factory.cpp
index 3b2119ba21..c6b198463b 100644
--- a/yql/essentials/minikql/comp_nodes/mkql_factory.cpp
+++ b/yql/essentials/minikql/comp_nodes/mkql_factory.cpp
@@ -219,7 +219,6 @@ struct TCallableComputationNodeBuilderFuncMapFiller {
{"Invoke", &WrapInvoke},
{"Udf", &WrapUdf},
{"ScriptUdf", &WrapScriptUdf},
- {"Apply", &WrapApply},
{"Apply2", &WrapApply},
{"Callable", &WrapCallable},
{"Size", &WrapSize},
diff --git a/yql/essentials/minikql/comp_nodes/mkql_replicate.cpp b/yql/essentials/minikql/comp_nodes/mkql_replicate.cpp
index 81996e07bf..2adac528b9 100644
--- a/yql/essentials/minikql/comp_nodes/mkql_replicate.cpp
+++ b/yql/essentials/minikql/comp_nodes/mkql_replicate.cpp
@@ -227,20 +227,17 @@ private:
}
IComputationNode* WrapReplicate(TCallable& callable, const TComputationNodeFactoryContext& ctx) {
- MKQL_ENSURE(callable.GetInputsCount() == 2 || callable.GetInputsCount() == 5, "Expected 2 or 5 args");
+ MKQL_ENSURE(callable.GetInputsCount() == 5, "Expected 5 args");
const auto countType = AS_TYPE(TDataType, callable.GetInput(1));
MKQL_ENSURE(countType->GetSchemeType() == NUdf::TDataType<ui64>::Id, "Expected ui64");
const auto list = LocateNode(ctx.NodeLocator, callable, 0);
const auto count = LocateNode(ctx.NodeLocator, callable, 1);
- NUdf::TSourcePosition pos;
- if (callable.GetInputsCount() == 5) {
- const TStringBuf file = AS_VALUE(TDataLiteral, callable.GetInput(2))->AsValue().AsStringRef();
- const ui32 row = AS_VALUE(TDataLiteral, callable.GetInput(3))->AsValue().Get<ui32>();
- const ui32 column = AS_VALUE(TDataLiteral, callable.GetInput(4))->AsValue().Get<ui32>();
- pos = NUdf::TSourcePosition(row, column, file);
- }
+ const TStringBuf file = AS_VALUE(TDataLiteral, callable.GetInput(2))->AsValue().AsStringRef();
+ const ui32 row = AS_VALUE(TDataLiteral, callable.GetInput(3))->AsValue().Get<ui32>();
+ const ui32 column = AS_VALUE(TDataLiteral, callable.GetInput(4))->AsValue().Get<ui32>();
+ const NUdf::TSourcePosition pos = NUdf::TSourcePosition(row, column, file);
return new TReplicateWrapper(ctx.Mutables, list, count, pos);
}
diff --git a/yql/essentials/minikql/comp_nodes/ut/mkql_chopper_ut.cpp b/yql/essentials/minikql/comp_nodes/ut/mkql_chopper_ut.cpp
index 8e314cfb9e..811927b14c 100644
--- a/yql/essentials/minikql/comp_nodes/ut/mkql_chopper_ut.cpp
+++ b/yql/essentials/minikql/comp_nodes/ut/mkql_chopper_ut.cpp
@@ -297,7 +297,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLChopperStreamTest) {
UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|0|0|");
}
}
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 9u
+
Y_UNIT_TEST_SUITE(TMiniKQLChopperFlowTest) {
Y_UNIT_TEST_LLVM(TestEmpty) {
TSetup<LLVM> setup;
@@ -482,6 +482,6 @@ Y_UNIT_TEST_SUITE(TMiniKQLChopperFlowTest) {
UNIT_ASSERT_VALUES_EQUAL(TStringBuf(result.AsStringRef()), "|0|0|0|0|0|");
}
}
-#endif
+
} // NMiniKQL
} // NKikimr
diff --git a/yql/essentials/minikql/comp_nodes/ut/mkql_combine_ut.cpp b/yql/essentials/minikql/comp_nodes/ut/mkql_combine_ut.cpp
index 55cea5f9fa..ab80f54e00 100644
--- a/yql/essentials/minikql/comp_nodes/ut/mkql_combine_ut.cpp
+++ b/yql/essentials/minikql/comp_nodes/ut/mkql_combine_ut.cpp
@@ -799,7 +799,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLCombineStreamPerfTest) {
Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
}
}
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 3u
+
Y_UNIT_TEST_SUITE(TMiniKQLCombineFlowTest) {
Y_UNIT_TEST_LLVM(TestFullCombineWithOptOut) {
TSetup<LLVM> setup(GetNodeFactory());
@@ -1530,6 +1530,6 @@ Y_UNIT_TEST_SUITE(TMiniKQLCombineFlowPerfTest) {
Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
}
}
-#endif
+
} // NMiniKQL
} // NKikimr
diff --git a/yql/essentials/minikql/comp_nodes/ut/mkql_flatmap_ut.cpp b/yql/essentials/minikql/comp_nodes/ut/mkql_flatmap_ut.cpp
index 12c11e4813..e8282e94d7 100644
--- a/yql/essentials/minikql/comp_nodes/ut/mkql_flatmap_ut.cpp
+++ b/yql/essentials/minikql/comp_nodes/ut/mkql_flatmap_ut.cpp
@@ -522,7 +522,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLFlatMapTest) {
UNIT_ASSERT(!iterator.Next(item));
UNIT_ASSERT(!iterator.Next(item));
}
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
+
Y_UNIT_TEST_LLVM(TestNarrowWithList) {
TSetup<LLVM> setup;
TProgramBuilder& pb = *setup.PgmBuilder;
@@ -846,7 +846,6 @@ Y_UNIT_TEST_SUITE(TMiniKQLFlatMapTest) {
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
}
-#endif
}
}
diff --git a/yql/essentials/minikql/comp_nodes/ut/mkql_join_ut.cpp b/yql/essentials/minikql/comp_nodes/ut/mkql_join_ut.cpp
index d404644972..3731ff1539 100644
--- a/yql/essentials/minikql/comp_nodes/ut/mkql_join_ut.cpp
+++ b/yql/essentials/minikql/comp_nodes/ut/mkql_join_ut.cpp
@@ -116,7 +116,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLCommonJoinCoreTupleTest) {
UNIT_ASSERT(!iterator.Next(item));
}
}
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
+
Y_UNIT_TEST_SUITE(TMiniKQLCommonJoinCoreWideTest) {
Y_UNIT_TEST_LLVM(Inner) {
TSetup<LLVM> setup;
@@ -323,7 +323,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLCommonJoinCoreWideTest) {
UNIT_ASSERT(!iterator.Next(item));
}
}
-#endif
+
}
}
diff --git a/yql/essentials/minikql/comp_nodes/ut/mkql_map_join_ut.cpp b/yql/essentials/minikql/comp_nodes/ut/mkql_map_join_ut.cpp
index e68d4bd46e..fe734804ea 100644
--- a/yql/essentials/minikql/comp_nodes/ut/mkql_map_join_ut.cpp
+++ b/yql/essentials/minikql/comp_nodes/ut/mkql_map_join_ut.cpp
@@ -585,7 +585,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLMapJoinCoreTest) {
}
}
}
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
+
Y_UNIT_TEST_SUITE(TMiniKQLWideMapJoinCoreTest) {
Y_UNIT_TEST_LLVM(TestInner) {
for (ui32 pass = 0; pass < 1; ++pass) {
@@ -1144,7 +1144,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLWideMapJoinCoreTest) {
}
}
}
-#endif
+
}
}
diff --git a/yql/essentials/minikql/comp_nodes/ut/mkql_multimap_ut.cpp b/yql/essentials/minikql/comp_nodes/ut/mkql_multimap_ut.cpp
index 5dcb30db2e..d6735151f6 100644
--- a/yql/essentials/minikql/comp_nodes/ut/mkql_multimap_ut.cpp
+++ b/yql/essentials/minikql/comp_nodes/ut/mkql_multimap_ut.cpp
@@ -121,7 +121,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLMultiMapTest) {
UNIT_ASSERT(!iterator.Next(item));
UNIT_ASSERT(!iterator.Next(item));
}
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
+
Y_UNIT_TEST_LLVM(TestFlattenByNarrow) {
TSetup<LLVM> setup;
TProgramBuilder& pb = *setup.PgmBuilder;
@@ -164,7 +164,6 @@ Y_UNIT_TEST_SUITE(TMiniKQLMultiMapTest) {
UNIT_ASSERT(!iterator.Next(item));
UNIT_ASSERT(!iterator.Next(item));
}
-#endif
}
}
diff --git a/yql/essentials/minikql/comp_nodes/ut/mkql_wide_chopper_ut.cpp b/yql/essentials/minikql/comp_nodes/ut/mkql_wide_chopper_ut.cpp
index 554dd8a3d3..95ce34a54c 100644
--- a/yql/essentials/minikql/comp_nodes/ut/mkql_wide_chopper_ut.cpp
+++ b/yql/essentials/minikql/comp_nodes/ut/mkql_wide_chopper_ut.cpp
@@ -3,7 +3,7 @@
namespace NKikimr {
namespace NMiniKQL {
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
+
Y_UNIT_TEST_SUITE(TMiniKQLWideChopperTest) {
Y_UNIT_TEST_LLVM(TestConcatKeyToItems) {
TSetup<LLVM> setup;
@@ -468,7 +468,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLWideChopperTest) {
UNIT_ASSERT(!iterator.Next(item));
}
}
-#endif
+
}
}
diff --git a/yql/essentials/minikql/comp_nodes/ut/mkql_wide_combine_ut.cpp b/yql/essentials/minikql/comp_nodes/ut/mkql_wide_combine_ut.cpp
index 55cb6babbf..4e4d13163c 100644
--- a/yql/essentials/minikql/comp_nodes/ut/mkql_wide_combine_ut.cpp
+++ b/yql/essentials/minikql/comp_nodes/ut/mkql_wide_combine_ut.cpp
@@ -155,7 +155,6 @@ void CheckIfStreamHasExpectedStringValues(const NUdf::TUnboxedValue& streamValue
} // unnamed
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
Y_UNIT_TEST_SUITE(TMiniKQLWideCombinerTest) {
Y_UNIT_TEST_LLVM(TestLongStringsRefCounting) {
TSetup<LLVM> setup;
@@ -1065,7 +1064,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLWideCombinerPerfTest) {
Cerr << "Runtime is " << t2 - t1 << " vs C++ " << cppTime << Endl;
}
}
-#endif
+
#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 29u
Y_UNIT_TEST_SUITE(TMiniKQLWideLastCombinerTest) {
Y_UNIT_TEST_LLVM_SPILLING(TestLongStringsRefCounting) {
diff --git a/yql/essentials/minikql/comp_nodes/ut/mkql_wide_condense_ut.cpp b/yql/essentials/minikql/comp_nodes/ut/mkql_wide_condense_ut.cpp
index b231df462b..1313812732 100644
--- a/yql/essentials/minikql/comp_nodes/ut/mkql_wide_condense_ut.cpp
+++ b/yql/essentials/minikql/comp_nodes/ut/mkql_wide_condense_ut.cpp
@@ -3,7 +3,7 @@
namespace NKikimr {
namespace NMiniKQL {
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
+
Y_UNIT_TEST_SUITE(TMiniKQLWideCondense1Test) {
Y_UNIT_TEST_LLVM(TestConcatItemsToKey) {
TSetup<LLVM> setup;
@@ -167,7 +167,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLWideCondense1Test) {
UNIT_ASSERT(!iterator.Next(item));
}
}
-#endif
+
}
}
diff --git a/yql/essentials/minikql/comp_nodes/ut/mkql_wide_filter_ut.cpp b/yql/essentials/minikql/comp_nodes/ut/mkql_wide_filter_ut.cpp
index 15c8516089..fd7b3f2f23 100644
--- a/yql/essentials/minikql/comp_nodes/ut/mkql_wide_filter_ut.cpp
+++ b/yql/essentials/minikql/comp_nodes/ut/mkql_wide_filter_ut.cpp
@@ -3,7 +3,7 @@
namespace NKikimr {
namespace NMiniKQL {
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
+
Y_UNIT_TEST_SUITE(TMiniKQLWideFilterTest) {
Y_UNIT_TEST_LLVM(TestPredicateExpression) {
TSetup<LLVM> setup;
@@ -381,6 +381,6 @@ Y_UNIT_TEST_SUITE(TMiniKQLWideFilterTest) {
UNIT_ASSERT(!iterator.Next(item));
}
}
-#endif
+
}
}
diff --git a/yql/essentials/minikql/comp_nodes/ut/mkql_wide_map_ut.cpp b/yql/essentials/minikql/comp_nodes/ut/mkql_wide_map_ut.cpp
index d1afec27f4..97c7d82d7b 100644
--- a/yql/essentials/minikql/comp_nodes/ut/mkql_wide_map_ut.cpp
+++ b/yql/essentials/minikql/comp_nodes/ut/mkql_wide_map_ut.cpp
@@ -3,7 +3,7 @@
namespace NKikimr {
namespace NMiniKQL {
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
+
Y_UNIT_TEST_SUITE(TMiniKQLWideMapTest) {
Y_UNIT_TEST_LLVM(TestSimpleSwap) {
TSetup<LLVM> setup;
@@ -330,6 +330,6 @@ Y_UNIT_TEST_SUITE(TMiniKQLWideMapTest) {
UNIT_ASSERT(!iterator.Next(item));
}
}
-#endif
+
}
}
diff --git a/yql/essentials/minikql/comp_nodes/ut/mkql_wide_nodes_ut.cpp b/yql/essentials/minikql/comp_nodes/ut/mkql_wide_nodes_ut.cpp
index 093810f0bc..1cbe7d774b 100644
--- a/yql/essentials/minikql/comp_nodes/ut/mkql_wide_nodes_ut.cpp
+++ b/yql/essentials/minikql/comp_nodes/ut/mkql_wide_nodes_ut.cpp
@@ -3,7 +3,7 @@
namespace NKikimr {
namespace NMiniKQL {
-#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
+
Y_UNIT_TEST_SUITE(TMiniKQLWideNodesTest) {
// TDOD: fixme
#if 0
@@ -119,6 +119,6 @@ Y_UNIT_TEST_SUITE(TMiniKQLWideNodesTest) {
}
}
-#endif
+
}
}
diff --git a/yql/essentials/minikql/computation/mkql_block_reader.cpp b/yql/essentials/minikql/computation/mkql_block_reader.cpp
index 4e2060e739..5886e121c4 100644
--- a/yql/essentials/minikql/computation/mkql_block_reader.cpp
+++ b/yql/essentials/minikql/computation/mkql_block_reader.cpp
@@ -162,6 +162,19 @@ private:
i32 TypeLen = 0;
};
+class TSingularTypeItemConverter: public IBlockItemConverter {
+public:
+ NUdf::TUnboxedValuePod MakeValue(TBlockItem item, const THolderFactory& holderFactory) const final {
+ Y_UNUSED(item, holderFactory);
+ return NUdf::TUnboxedValuePod::Zero();
+ }
+
+ TBlockItem MakeItem(const NUdf::TUnboxedValuePod& value) const final {
+ Y_UNUSED(value);
+ return TBlockItem::Zero();
+ }
+};
+
template <bool Nullable>
class TTupleBlockItemConverter : public IBlockItemConverter {
public:
@@ -285,6 +298,7 @@ struct TConverterTraits {
using TExtOptional = TExternalOptionalBlockItemConverter;
template<typename TTzDate, bool Nullable>
using TTzDateConverter = TTzDateBlockItemConverter<TTzDate, Nullable>;
+ using TSingularType = TSingularTypeItemConverter;
constexpr static bool PassType = false;
@@ -325,6 +339,10 @@ struct TConverterTraits {
return std::make_unique<TTzDateConverter<TTzDate, false>>();
}
}
+
+ static std::unique_ptr<TResult> MakeSingular() {
+ return std::make_unique<TSingularType>();
+ }
};
} // namespace
diff --git a/yql/essentials/minikql/computation/mkql_block_transport.cpp b/yql/essentials/minikql/computation/mkql_block_transport.cpp
index a03a5027e8..766df54889 100644
--- a/yql/essentials/minikql/computation/mkql_block_transport.cpp
+++ b/yql/essentials/minikql/computation/mkql_block_transport.cpp
@@ -13,7 +13,7 @@ namespace {
using NYql::TChunkedBuffer;
TChunkedBuffer MakeChunkedBufferAndUntrack(const std::shared_ptr<const arrow::Buffer>& owner, const char* data, size_t size) {
- MKQLArrowUntrack(owner->data());
+ MKQLArrowUntrack(owner->data(), owner->capacity());
return TChunkedBuffer(TStringBuf{data, size}, owner);
}
@@ -429,6 +429,49 @@ private:
const std::unique_ptr<TBlockDeserializerBase> Inner_;
};
+class TSingularTypeBlockSerializer final: public IBlockSerializer {
+private:
+ size_t ArrayMetadataCount() const final {
+ return 0;
+ }
+
+ void StoreMetadata(const arrow::ArrayData& data, const IBlockSerializer::TMetadataSink& metaSink) const final {
+ Y_UNUSED(data, metaSink);
+ }
+
+ void StoreArray(const arrow::ArrayData& data, TChunkedBuffer& dst) const final {
+ Y_UNUSED(data, dst);
+ }
+};
+
+class TSingularTypeBlockDeserializer final: public TBlockDeserializerBase {
+private:
+ void DoLoadMetadata(const TMetadataSource& metaSource) final {
+ Y_UNUSED(metaSource);
+ }
+
+ std::shared_ptr<arrow::ArrayData> DoMakeDefaultValue(const std::shared_ptr<arrow::Buffer>& nulls, i64 nullsCount, ui64 blockLen, ui64 offset) const final {
+ Y_UNUSED(offset);
+ Y_ENSURE(nullsCount == 0);
+ Y_ENSURE(!nulls || nulls->size() == 0);
+ return arrow::NullArray(blockLen).data();
+ }
+
+ std::shared_ptr<arrow::ArrayData> DoLoadArray(TChunkedBuffer& src, const std::shared_ptr<arrow::Buffer>& nulls, i64 nullsCount, ui64 blockLen, ui64 offset) final {
+ Y_UNUSED(offset, src);
+ Y_ENSURE(nullsCount == 0);
+ Y_ENSURE(!nulls || nulls->size() == 0);
+ return arrow::NullArray(blockLen).data();
+ }
+
+ bool IsNullable() const final {
+ return false;
+ }
+
+ void DoResetMetadata() final {
+ }
+};
+
template<bool Nullable, typename TDerived>
class TTupleBlockSerializerBase : public IBlockSerializer {
size_t ArrayMetadataCount() const final {
@@ -632,7 +675,7 @@ struct TSerializerTraits {
using TExtOptional = TExtOptionalBlockSerializer;
template<typename TTzDateType, bool Nullable>
using TTzDate = TTzDateBlockSerializer<TTzDateType, Nullable>;
-
+ using TSingularType = TSingularTypeBlockSerializer;
constexpr static bool PassType = false;
static std::unique_ptr<TResult> MakePg(const NUdf::TPgTypeDescription& desc, const NUdf::IPgBuilder* pgBuilder) {
@@ -648,6 +691,10 @@ struct TSerializerTraits {
ythrow yexception() << "Serializer not implemented for block resources";
}
+ static std::unique_ptr<TResult> MakeSingular() {
+ return std::make_unique<TSingularType>();
+ }
+
template<typename TTzDateType>
static std::unique_ptr<TResult> MakeTzDate(bool isOptional) {
if (isOptional) {
@@ -670,6 +717,7 @@ struct TDeserializerTraits {
using TExtOptional = TExtOptionalBlockDeserializer;
template<typename TTzDateType, bool Nullable>
using TTzDate = TTzDateBlockDeserializer<TTzDateType, Nullable>;
+ using TSingularType = TSingularTypeBlockDeserializer;
constexpr static bool PassType = false;
@@ -686,6 +734,10 @@ struct TDeserializerTraits {
ythrow yexception() << "Deserializer not implemented for block resources";
}
+ static std::unique_ptr<TResult> MakeSingular() {
+ return std::make_unique<TSingularType>();
+ }
+
template<typename TTzDateType>
static std::unique_ptr<TResult> MakeTzDate(bool isOptional) {
if (isOptional) {
diff --git a/yql/essentials/minikql/computation/mkql_block_trimmer.cpp b/yql/essentials/minikql/computation/mkql_block_trimmer.cpp
index b53a3890a4..0b53f91452 100644
--- a/yql/essentials/minikql/computation/mkql_block_trimmer.cpp
+++ b/yql/essentials/minikql/computation/mkql_block_trimmer.cpp
@@ -98,6 +98,17 @@ public:
}
};
+class TSingularBlockTrimmer: public TBlockTrimmerBase {
+public:
+ TSingularBlockTrimmer(arrow::MemoryPool* pool)
+ : TBlockTrimmerBase(pool) {
+ }
+
+ std::shared_ptr<arrow::ArrayData> Trim(const std::shared_ptr<arrow::ArrayData>& array) override {
+ return array;
+ }
+};
+
template<typename TStringType, bool Nullable>
class TStringBlockTrimmer : public TBlockTrimmerBase {
using TOffset = typename TStringType::offset_type;
@@ -217,6 +228,7 @@ struct TTrimmerTraits {
using TResource = TResourceBlockTrimmer<Nullable>;
template<typename TTzDate, bool Nullable>
using TTzDateReader = TTzDateBlockTrimmer<TTzDate, Nullable>;
+ using TSingular = TSingularBlockTrimmer;
constexpr static bool PassType = false;
@@ -237,6 +249,10 @@ struct TTrimmerTraits {
}
}
+ static TResult::TPtr MakeSingular(arrow::MemoryPool* pool) {
+ return std::make_unique<TSingular>(pool);
+ }
+
template<typename TTzDate>
static TResult::TPtr MakeTzDate(bool isOptional, arrow::MemoryPool* pool) {
if (isOptional) {
diff --git a/yql/essentials/minikql/computation/mkql_computation_node_pack_ut.cpp b/yql/essentials/minikql/computation/mkql_computation_node_pack_ut.cpp
index b689e4cf8b..cbff1c5722 100644
--- a/yql/essentials/minikql/computation/mkql_computation_node_pack_ut.cpp
+++ b/yql/essentials/minikql/computation/mkql_computation_node_pack_ut.cpp
@@ -674,6 +674,8 @@ protected:
auto tzDateType = PgmBuilder.NewDataType(NUdf::EDataSlot::TzDate);
auto blockTzDateType = PgmBuilder.NewBlockType(tzDateType, TBlockType::EShape::Many);
+ auto nullType = PgmBuilder.NewNullType();
+ auto blockNullType = PgmBuilder.NewBlockType(nullType, TBlockType::EShape::Many);
auto rowType =
legacyStruct
@@ -683,11 +685,12 @@ protected:
{"_yql_block_length", scalarUi64Type},
{"a", scalarOptStrType},
{"b", blockOptTupleOptUi32StrType},
- {"c", blockTzDateType}
+ {"c", blockTzDateType},
+ {"nill", blockNullType},
})
: PgmBuilder.NewMultiType(
{blockUi32Type, blockOptStrType, scalarOptStrType,
- blockOptTupleOptUi32StrType, blockTzDateType, scalarUi64Type});
+ blockOptTupleOptUi32StrType, blockTzDateType, blockNullType, scalarUi64Type});
ui64 blockLen = 1000;
UNIT_ASSERT_LE(offset + len, blockLen);
@@ -696,6 +699,8 @@ protected:
auto builder2 = MakeArrayBuilder(TTypeInfoHelper(), optStrType, *ArrowPool_, CalcBlockLen(CalcMaxBlockItemSize(optStrType)), nullptr);
auto builder3 = MakeArrayBuilder(TTypeInfoHelper(), optTupleOptUi32StrType, *ArrowPool_, CalcBlockLen(CalcMaxBlockItemSize(optTupleOptUi32StrType)), nullptr);
auto builder4 = MakeArrayBuilder(TTypeInfoHelper(), tzDateType, *ArrowPool_, CalcBlockLen(CalcMaxBlockItemSize(tzDateType)), nullptr);
+ auto builder5 = MakeArrayBuilder(TTypeInfoHelper(), nullType, *ArrowPool_, CalcBlockLen(CalcMaxBlockItemSize(nullType)), nullptr);
+
for (ui32 i = 0; i < blockLen; ++i) {
TBlockItem b1(i);
@@ -712,6 +717,7 @@ protected:
TBlockItem tzDate {i};
tzDate.SetTimezoneId(i % 100);
builder4->Add(tzDate);
+ builder5->Add(TBlockItem::Zero());
}
std::string_view testScalarString = "foobar";
@@ -725,12 +731,14 @@ protected:
datums.emplace_back(arrow::Datum(std::make_shared<arrow::BinaryScalar>(strbuf)));
datums.emplace_back(builder3->Build(true));
datums.emplace_back(builder4->Build(true));
+ datums.emplace_back(builder5->Build(true));
} else {
datums.emplace_back(builder1->Build(true));
datums.emplace_back(builder2->Build(true));
datums.emplace_back(arrow::Datum(std::make_shared<arrow::BinaryScalar>(strbuf)));
datums.emplace_back(builder3->Build(true));
datums.emplace_back(builder4->Build(true));
+ datums.emplace_back(builder5->Build(true));
datums.emplace_back(arrow::Datum(std::make_shared<arrow::UInt64Scalar>(blockLen)));
}
@@ -785,6 +793,7 @@ protected:
auto reader2 = MakeBlockReader(TTypeInfoHelper(), optStrType);
auto reader3 = MakeBlockReader(TTypeInfoHelper(), optTupleOptUi32StrType);
auto reader4 = MakeBlockReader(TTypeInfoHelper(), tzDateType);
+ auto reader5 = MakeBlockReader(TTypeInfoHelper(), nullType);
for (ui32 i = offset; i < len; ++i) {
TBlockItem b1 = reader1->GetItem(*TArrowBlock::From(unpackedColumns[0]).GetDatum().array(), i - offset);
@@ -814,6 +823,8 @@ protected:
TBlockItem b4 = reader4->GetItem(*TArrowBlock::From(unpackedColumns[legacyStruct ? 5 : 4]).GetDatum().array(), i - offset);
UNIT_ASSERT(b4.Get<ui16>() == i);
UNIT_ASSERT(b4.GetTimezoneId() == (i % 100));
+ TBlockItem b5 = reader5->GetItem(*TArrowBlock::From(unpackedColumns[legacyStruct ? 6 : 5]).GetDatum().array(), i - offset);
+ UNIT_ASSERT(b5);
}
}
}
diff --git a/yql/essentials/minikql/mkql_alloc.cpp b/yql/essentials/minikql/mkql_alloc.cpp
index 963f46a67e..8446522eda 100644
--- a/yql/essentials/minikql/mkql_alloc.cpp
+++ b/yql/essentials/minikql/mkql_alloc.cpp
@@ -7,6 +7,8 @@ namespace NKikimr {
namespace NMiniKQL {
+constexpr ui64 ArrowSizeForArena = (TAllocState::POOL_PAGE_SIZE >> 2);
+
Y_POD_THREAD(TAllocState*) TlsAllocState;
TAllocPageHeader TAllocState::EmptyPageHeader = { 0, 0, 0, 0, nullptr, nullptr };
@@ -94,6 +96,10 @@ void TAllocState::KillAllBoxed() {
OffloadedBlocksRoot.InitLinks();
}
+ if (CurrentArrowPages) {
+ MKQLArrowFree(CurrentArrowPages, 0);
+ CurrentArrowPages = nullptr;
+ }
CleanupArrowList(&ArrowBlocksRoot);
#ifndef NDEBUG
@@ -253,7 +259,49 @@ void TPagedArena::Clear() noexcept {
}
}
+void* MKQLArrowAllocateOnArena(ui64 size) {
+ TAllocState* state = TlsAllocState;
+ Y_ENSURE(state);
+
+ auto alignedSize = AlignUp(size, ArrowAlignment);
+ auto& page = state->CurrentArrowPages;
+
+ if (Y_UNLIKELY(!page || page->Offset + alignedSize > page->Size)) {
+ const auto pageSize = TAllocState::POOL_PAGE_SIZE;
+
+ if (state->EnableArrowTracking) {
+ state->OffloadAlloc(pageSize);
+ }
+
+ if (page) {
+ MKQLArrowFree(page, 0);
+ }
+
+ page = (TMkqlArrowHeader*)GetAlignedPage();
+ page->Offset = sizeof(TMkqlArrowHeader);
+ page->Size = pageSize;
+ page->UseCount = 1;
+
+ if (state->EnableArrowTracking) {
+ page->Entry.Link(&state->ArrowBlocksRoot);
+ Y_ENSURE(state->ArrowBuffers.insert(page).second);
+ } else {
+ page->Entry.Clear();
+ }
+ }
+
+ void* ptr = (ui8*)page + page->Offset;
+ page->Offset += alignedSize;
+ ++page->UseCount;
+
+ return ptr;
+}
+
void* MKQLArrowAllocate(ui64 size) {
+ if (size <= ArrowSizeForArena) {
+ return MKQLArrowAllocateOnArena(size);
+ }
+
TAllocState* state = TlsAllocState;
Y_ENSURE(state);
auto fullSize = size + sizeof(TMkqlArrowHeader);
@@ -276,6 +324,9 @@ void* MKQLArrowAllocate(ui64 size) {
#endif
auto* header = (TMkqlArrowHeader*)ptr;
+ header->Offset = 0;
+ header->UseCount = 0;
+
if (state->EnableArrowTracking) {
header->Entry.Link(&state->ArrowBlocksRoot);
Y_ENSURE(state->ArrowBuffers.insert(header + 1).second);
@@ -294,7 +345,31 @@ void* MKQLArrowReallocate(const void* mem, ui64 prevSize, ui64 size) {
return res;
}
+void MKQLArrowFreeOnArena(const void* ptr) {
+ auto* page = (TMkqlArrowHeader*)TAllocState::GetPageStart(ptr);
+ if (page->UseCount.fetch_sub(1) == 1) {
+ if (!page->Entry.IsUnlinked()) {
+ TAllocState* state = TlsAllocState;
+ Y_ENSURE(state);
+ state->OffloadFree(page->Size);
+ page->Entry.Unlink();
+
+ auto it = state->ArrowBuffers.find(page);
+ Y_ENSURE(it != state->ArrowBuffers.end());
+ state->ArrowBuffers.erase(it);
+ }
+
+ ReleaseAlignedPage(page);
+ }
+
+ return;
+}
+
void MKQLArrowFree(const void* mem, ui64 size) {
+ if (size <= ArrowSizeForArena) {
+ return MKQLArrowFreeOnArena(mem);
+ }
+
auto fullSize = size + sizeof(TMkqlArrowHeader);
auto header = ((TMkqlArrowHeader*)mem) - 1;
if (!header->Entry.IsUnlinked()) {
@@ -318,19 +393,37 @@ void MKQLArrowFree(const void* mem, ui64 size) {
ReleaseAlignedPage(header, fullSize);
}
-void MKQLArrowUntrack(const void* mem) {
+void MKQLArrowUntrack(const void* mem, ui64 size) {
TAllocState* state = TlsAllocState;
Y_ENSURE(state);
if (!state->EnableArrowTracking) {
return;
}
+ if (size <= ArrowSizeForArena) {
+ auto* page = (TMkqlArrowHeader*)TAllocState::GetPageStart(mem);
+
+ auto it = state->ArrowBuffers.find(page);
+ if (it == state->ArrowBuffers.end()) {
+ return;
+ }
+
+ if (!page->Entry.IsUnlinked()) {
+ page->Entry.Unlink(); // unlink page immediately so we don't accidentally free untracked memory within `TAllocState`
+ state->ArrowBuffers.erase(it);
+ state->OffloadFree(page->Size);
+ }
+
+ return;
+ }
+
auto it = state->ArrowBuffers.find(mem);
if (it == state->ArrowBuffers.end()) {
return;
}
- auto header = ((TMkqlArrowHeader*)mem) - 1;
+ auto* header = ((TMkqlArrowHeader*)mem) - 1;
+ Y_ENSURE(header->UseCount == 0);
if (!header->Entry.IsUnlinked()) {
header->Entry.Unlink();
auto fullSize = header->Size + sizeof(TMkqlArrowHeader);
diff --git a/yql/essentials/minikql/mkql_alloc.h b/yql/essentials/minikql/mkql_alloc.h
index abcb6cc73d..24bbbb8e9e 100644
--- a/yql/essentials/minikql/mkql_alloc.h
+++ b/yql/essentials/minikql/mkql_alloc.h
@@ -41,6 +41,8 @@ constexpr ui32 MaxPageUserData = TAlignedPagePool::POOL_PAGE_SIZE - sizeof(TAllo
static_assert(sizeof(TAllocPageHeader) % MKQL_ALIGNMENT == 0, "Incorrect size of header");
+struct TMkqlArrowHeader;
+
struct TAllocState : public TAlignedPagePool
{
struct TListEntry {
@@ -90,6 +92,7 @@ struct TAllocState : public TAlignedPagePool
TListEntry GlobalPAllocList;
TListEntry* CurrentPAllocList;
TListEntry ArrowBlocksRoot;
+ TMkqlArrowHeader* CurrentArrowPages = nullptr; // page arena for small arrow allocations
std::unordered_set<const void*> ArrowBuffers;
bool EnableArrowTracking = true;
@@ -186,7 +189,9 @@ constexpr size_t ArrowAlignment = 64;
struct TMkqlArrowHeader {
TAllocState::TListEntry Entry;
ui64 Size;
- char Padding[ArrowAlignment - sizeof(TAllocState::TListEntry) - sizeof(ui64)];
+ ui64 Offset;
+ std::atomic<ui64> UseCount;
+ char Padding[ArrowAlignment - sizeof(TAllocState::TListEntry) - sizeof(ui64) - sizeof(ui64) - sizeof(std::atomic<ui64>)];
};
static_assert(sizeof(TMkqlArrowHeader) == ArrowAlignment);
@@ -441,7 +446,7 @@ inline void MKQLUnregisterObject(NUdf::TBoxedValue* value) noexcept {
void* MKQLArrowAllocate(ui64 size);
void* MKQLArrowReallocate(const void* mem, ui64 prevSize, ui64 size);
void MKQLArrowFree(const void* mem, ui64 size);
-void MKQLArrowUntrack(const void* mem);
+void MKQLArrowUntrack(const void* mem, ui64 size);
template <const EMemorySubPool MemoryPoolExt = EMemorySubPool::Default>
struct TWithMiniKQLAlloc {
diff --git a/yql/essentials/minikql/mkql_program_builder.cpp b/yql/essentials/minikql/mkql_program_builder.cpp
index b139c24058..e03a5e3b28 100644
--- a/yql/essentials/minikql/mkql_program_builder.cpp
+++ b/yql/essentials/minikql/mkql_program_builder.cpp
@@ -20,6 +20,8 @@ using namespace std::string_view_literals;
namespace NKikimr {
namespace NMiniKQL {
+static_assert(RuntimeVersion >= 20);
+
namespace {
struct TDataFunctionFlags {
@@ -403,10 +405,6 @@ TRuntimeNode TProgramBuilder::Arg(TType* type) const {
}
TRuntimeNode TProgramBuilder::WideFlowArg(TType* type) const {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
TCallableBuilder builder(Env, __func__, type, true);
return TRuntimeNode(builder.Build(), false);
}
@@ -973,10 +971,6 @@ TRuntimeNode TProgramBuilder::ToList(TRuntimeNode optional) {
}
TRuntimeNode TProgramBuilder::Iterable(TZeroLambda lambda) {
- if constexpr (RuntimeVersion < 19U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
const auto itemArg = Arg(NewNull().GetStaticType());
auto lambdaRes = lambda();
const auto resultType = NewListType(AS_TYPE(TStreamType, lambdaRes.GetStaticType())->GetItemType());
@@ -1397,9 +1391,6 @@ TRuntimeNode TProgramBuilder::Iterator(TRuntimeNode list, const TArrayRef<const
TRuntimeNode TProgramBuilder::EmptyIterator(TType* streamType) {
MKQL_ENSURE(streamType->IsStream() || streamType->IsFlow(), "Expected stream or flow.");
- if (RuntimeVersion < 7U && streamType->IsFlow()) {
- return ToFlow(EmptyIterator(NewStreamType(AS_TYPE(TFlowType, streamType)->GetItemType())));
- }
TCallableBuilder callableBuilder(Env, __func__, streamType);
return TRuntimeNode(callableBuilder.Build(), false);
}
@@ -1435,11 +1426,6 @@ TRuntimeNode TProgramBuilder::LazyList(TRuntimeNode list) {
TRuntimeNode TProgramBuilder::ForwardList(TRuntimeNode stream) {
const auto type = stream.GetStaticType();
MKQL_ENSURE(type->IsStream() || type->IsFlow(), "Expected flow or stream.");
- if constexpr (RuntimeVersion < 10U) {
- if (type->IsFlow()) {
- return ForwardList(FromFlow(stream));
- }
- }
TCallableBuilder callableBuilder(Env, __func__, NewListType(type->IsFlow() ? AS_TYPE(TFlowType, stream)->GetItemType() : AS_TYPE(TStreamType, stream)->GetItemType()));
callableBuilder.Add(stream);
return TRuntimeNode(callableBuilder.Build(), false);
@@ -2054,29 +2040,7 @@ TRuntimeNode TProgramBuilder::Lookup(TRuntimeNode dict, TRuntimeNode key) {
return TRuntimeNode(callableBuilder.Build(), false);
}
-TRuntimeNode TProgramBuilder::DictItems(TRuntimeNode dict, EDictItems mode) {
- const auto dictTypeChecked = AS_TYPE(TDictType, dict.GetStaticType());
- TType* itemType;
- switch (mode) {
- case EDictItems::Both: {
- const std::array<TType*, 2U> tupleTypes = {{ dictTypeChecked->GetKeyType(), dictTypeChecked->GetPayloadType() }};
- itemType = NewTupleType(tupleTypes);
- break;
- }
- case EDictItems::Keys: itemType = dictTypeChecked->GetKeyType(); break;
- case EDictItems::Payloads: itemType = dictTypeChecked->GetPayloadType(); break;
- }
-
- TCallableBuilder callableBuilder(Env, __func__, NewListType(itemType));
- callableBuilder.Add(dict);
- callableBuilder.Add(NewDataLiteral((ui32)mode));
- return TRuntimeNode(callableBuilder.Build(), false);
-}
-
TRuntimeNode TProgramBuilder::DictItems(TRuntimeNode dict) {
- if constexpr (RuntimeVersion < 6U) {
- return DictItems(dict, EDictItems::Both);
- }
const auto dictTypeChecked = AS_TYPE(TDictType, dict.GetStaticType());
const auto itemType = NewTupleType({ dictTypeChecked->GetKeyType(), dictTypeChecked->GetPayloadType() });
TCallableBuilder callableBuilder(Env, __func__, NewListType(itemType));
@@ -2085,9 +2049,6 @@ TRuntimeNode TProgramBuilder::DictItems(TRuntimeNode dict) {
}
TRuntimeNode TProgramBuilder::DictKeys(TRuntimeNode dict) {
- if constexpr (RuntimeVersion < 6U) {
- return DictItems(dict, EDictItems::Keys);
- }
const auto dictTypeChecked = AS_TYPE(TDictType, dict.GetStaticType());
TCallableBuilder callableBuilder(Env, __func__, NewListType(dictTypeChecked->GetKeyType()));
callableBuilder.Add(dict);
@@ -2095,9 +2056,6 @@ TRuntimeNode TProgramBuilder::DictKeys(TRuntimeNode dict) {
}
TRuntimeNode TProgramBuilder::DictPayloads(TRuntimeNode dict) {
- if constexpr (RuntimeVersion < 6U) {
- return DictItems(dict, EDictItems::Payloads);
- }
const auto dictTypeChecked = AS_TYPE(TDictType, dict.GetStaticType());
TCallableBuilder callableBuilder(Env, __func__, NewListType(dictTypeChecked->GetPayloadType()));
callableBuilder.Add(dict);
@@ -3019,10 +2977,6 @@ TRuntimeNode TProgramBuilder::SourceOf(TType* returnType) {
}
TRuntimeNode TProgramBuilder::Source() {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
TCallableBuilder callableBuilder(Env, __func__, NewFlowType(NewMultiType({})));
return TRuntimeNode(callableBuilder.Build(), false);
}
@@ -3197,9 +3151,7 @@ TRuntimeNode TProgramBuilder::QueueCreate(TRuntimeNode initCapacity, TRuntimeNod
auto resType = AS_TYPE(TResourceType, returnType);
const auto tag = resType->GetTag();
- if (initCapacity.GetStaticType()->IsVoid()) {
- MKQL_ENSURE(RuntimeVersion >= 13, "Unbounded queue is not supported in runtime version " << RuntimeVersion);
- } else {
+ if (!initCapacity.GetStaticType()->IsVoid()) {
auto initCapacityType = AS_TYPE(TDataType, initCapacity);
MKQL_ENSURE(initCapacityType->GetSchemeType() == NUdf::TDataType<ui64>::Id, "init capcity must be ui64");
}
@@ -3253,8 +3205,6 @@ TRuntimeNode TProgramBuilder::QueuePeek(TRuntimeNode resource, TRuntimeNode inde
}
TRuntimeNode TProgramBuilder::QueueRange(TRuntimeNode resource, TRuntimeNode begin, TRuntimeNode end, const TArrayRef<const TRuntimeNode>& dependentNodes, TType* returnType) {
- MKQL_ENSURE(RuntimeVersion >= 14, "QueueRange is not supported in runtime version " << RuntimeVersion);
-
MKQL_ENSURE(returnType->IsList(), "Expected list type as result of QueueRange");
auto resType = AS_TYPE(TResourceType, resource);
@@ -3291,8 +3241,6 @@ TRuntimeNode TProgramBuilder::PreserveStream(TRuntimeNode stream, TRuntimeNode q
}
TRuntimeNode TProgramBuilder::Seq(const TArrayRef<const TRuntimeNode>& args, TType* returnType) {
- MKQL_ENSURE(RuntimeVersion >= 15, "Seq is not supported in runtime version " << RuntimeVersion);
-
TCallableBuilder callableBuilder(Env, __func__, returnType);
for (auto node : args) {
callableBuilder.Add(node);
@@ -3738,16 +3686,6 @@ TRuntimeNode TProgramBuilder::BuildFlatMap(const std::string_view& callableName,
TRuntimeNode TProgramBuilder::MultiMap(TRuntimeNode list, const TExpandLambda& handler)
{
- if constexpr (RuntimeVersion < 16U) {
- const auto single = [=](TRuntimeNode item) -> TRuntimeNode {
- const auto newList = handler(item);
- const auto retItemType = newList.front().GetStaticType();
- MKQL_ENSURE(retItemType->IsSameType(*newList.back().GetStaticType()), "Must be same type.");
- return NewList(retItemType, newList);
- };
- return OrderedFlatMap(list, single);
- }
-
const auto listType = list.GetStaticType();
MKQL_ENSURE(listType->IsFlow() || listType->IsList(), "Expected flow, list, stream or optional");
@@ -3770,10 +3708,6 @@ TRuntimeNode TProgramBuilder::MultiMap(TRuntimeNode list, const TExpandLambda& h
}
TRuntimeNode TProgramBuilder::NarrowMultiMap(TRuntimeNode flow, const TWideLambda& handler) {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
const auto wideComponents = GetWideComponents(AS_TYPE(TFlowType, flow.GetStaticType()));
TRuntimeNode::TList itemArgs;
@@ -3795,10 +3729,6 @@ TRuntimeNode TProgramBuilder::NarrowMultiMap(TRuntimeNode flow, const TWideLambd
}
TRuntimeNode TProgramBuilder::ExpandMap(TRuntimeNode flow, const TExpandLambda& handler) {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
const auto itemType = AS_TYPE(TFlowType, flow.GetStaticType())->GetItemType();
const auto itemArg = Arg(itemType);
const auto newItems = handler(itemArg);
@@ -3815,10 +3745,6 @@ TRuntimeNode TProgramBuilder::ExpandMap(TRuntimeNode flow, const TExpandLambda&
}
TRuntimeNode TProgramBuilder::WideMap(TRuntimeNode flow, const TWideLambda& handler) {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
const auto wideComponents = GetWideComponents(AS_TYPE(TFlowType, flow.GetStaticType()));
TRuntimeNode::TList itemArgs;
@@ -3875,10 +3801,6 @@ TRuntimeNode TProgramBuilder::WideChain1Map(TRuntimeNode flow, const TWideLambda
}
TRuntimeNode TProgramBuilder::NarrowMap(TRuntimeNode flow, const TNarrowLambda& handler) {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
const auto wideComponents = GetWideComponents(AS_TYPE(TFlowType, flow.GetStaticType()));
TRuntimeNode::TList itemArgs;
@@ -3896,10 +3818,6 @@ TRuntimeNode TProgramBuilder::NarrowMap(TRuntimeNode flow, const TNarrowLambda&
}
TRuntimeNode TProgramBuilder::NarrowFlatMap(TRuntimeNode flow, const TNarrowLambda& handler) {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
const auto wideComponents = GetWideComponents(AS_TYPE(TFlowType, flow.GetStaticType()));
TRuntimeNode::TList itemArgs;
@@ -3931,10 +3849,6 @@ TRuntimeNode TProgramBuilder::NarrowFlatMap(TRuntimeNode flow, const TNarrowLamb
}
TRuntimeNode TProgramBuilder::BuildWideFilter(const std::string_view& callableName, TRuntimeNode flow, const TNarrowLambda& handler) {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
const auto wideComponents = GetWideComponents(AS_TYPE(TFlowType, flow.GetStaticType()));
TRuntimeNode::TList itemArgs;
@@ -4019,10 +3933,6 @@ TRuntimeNode TProgramBuilder::BuildFilter(const std::string_view& callableName,
TRuntimeNode TProgramBuilder::BuildFilter(const std::string_view& callableName, TRuntimeNode list, TRuntimeNode limit, const TUnaryLambda& handler, TType* resultType)
{
- if constexpr (RuntimeVersion < 4U) {
- return Take(BuildFilter(callableName, list, handler, resultType), limit);
- }
-
const auto listType = list.GetStaticType();
MKQL_ENSURE(listType->IsFlow() || listType->IsList() || listType->IsStream(), "Expected flow, list or stream.");
MKQL_ENSURE(limit.GetStaticType()->IsData(), "Expected data");
@@ -4322,15 +4232,12 @@ TRuntimeNode TProgramBuilder::Apply(TRuntimeNode callableNode, const TArrayRef<c
<< " with static " << arg.GetStaticType()->GetKindAsStr());
}
- TCallableBuilder callableBuilder(Env, RuntimeVersion >= 8 ? "Apply2" : "Apply", callableType->GetReturnType());
+ TCallableBuilder callableBuilder(Env, "Apply2", callableType->GetReturnType());
callableBuilder.Add(callableNode);
callableBuilder.Add(NewDataLiteral<ui32>(dependentCount));
-
- if constexpr (RuntimeVersion >= 8) {
- callableBuilder.Add(NewDataLiteral<NUdf::EDataSlot::String>(file));
- callableBuilder.Add(NewDataLiteral(row));
- callableBuilder.Add(NewDataLiteral(column));
- }
+ callableBuilder.Add(NewDataLiteral<NUdf::EDataSlot::String>(file));
+ callableBuilder.Add(NewDataLiteral(row));
+ callableBuilder.Add(NewDataLiteral(column));
for (const auto& arg: args) {
callableBuilder.Add(arg);
@@ -4365,12 +4272,11 @@ TRuntimeNode TProgramBuilder::Callable(TType* callableType, const TArrayLambda&
}
TRuntimeNode TProgramBuilder::NewNull() {
- if (!UseNullType || RuntimeVersion < 11) {
- TCallableBuilder callableBuilder(Env, "Null", NewOptionalType(Env.GetVoidLazy()->GetType()));
- return TRuntimeNode(callableBuilder.Build(), false);
- } else {
+ if (UseNullType) {
return TRuntimeNode(Env.GetNullLazy(), true);
}
+ TCallableBuilder callableBuilder(Env, "Null", NewOptionalType(Env.GetVoidLazy()->GetType()));
+ return TRuntimeNode(callableBuilder.Build(), false);
}
TRuntimeNode TProgramBuilder::Concat(TRuntimeNode data1, TRuntimeNode data2) {
@@ -4403,18 +4309,10 @@ TRuntimeNode TProgramBuilder::RFind(TRuntimeNode haystack, TRuntimeNode needle,
}
TRuntimeNode TProgramBuilder::StartsWith(TRuntimeNode string, TRuntimeNode prefix) {
- if constexpr (RuntimeVersion < 19U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
return DataCompare(__func__, string, prefix);
}
TRuntimeNode TProgramBuilder::EndsWith(TRuntimeNode string, TRuntimeNode suffix) {
- if constexpr (RuntimeVersion < 19U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
return DataCompare(__func__, string, suffix);
}
@@ -4746,10 +4644,6 @@ TRuntimeNode TProgramBuilder::CommonJoinCore(TRuntimeNode flow, EJoinKind joinKi
ui64 memLimit, std::optional<ui32> sortedTableOrder,
EAnyJoinSettings anyJoinSettings, const ui32 tableIndexField, TType* returnType) {
- if constexpr (RuntimeVersion < 17U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
MKQL_ENSURE(leftColumns.size() % 2U == 0U, "Expected even count");
MKQL_ENSURE(rightColumns.size() % 2U == 0U, "Expected even count");
@@ -4796,10 +4690,6 @@ TRuntimeNode TProgramBuilder::CommonJoinCore(TRuntimeNode flow, EJoinKind joinKi
}
TRuntimeNode TProgramBuilder::WideCombiner(TRuntimeNode flow, i64 memLimit, const TWideLambda& extractor, const TBinaryWideLambda& init, const TTernaryWideLambda& update, const TBinaryWideLambda& finish) {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
if (memLimit < 0) {
if constexpr (RuntimeVersion < 46U) {
THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__ << " with limit " << memLimit;
@@ -4934,10 +4824,6 @@ TRuntimeNode TProgramBuilder::WideLastCombinerWithSpilling(TRuntimeNode flow, co
}
TRuntimeNode TProgramBuilder::WideCondense1(TRuntimeNode flow, const TWideLambda& init, const TWideSwitchLambda& switcher, const TBinaryWideLambda& update, bool useCtx) {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
const auto wideComponents = GetWideComponents(AS_TYPE(TFlowType, flow.GetStaticType()));
TRuntimeNode::TList itemArgs;
@@ -4983,10 +4869,6 @@ TRuntimeNode TProgramBuilder::CombineCore(TRuntimeNode stream,
const TBinaryLambda& finish,
ui64 memLimit)
{
- if constexpr (RuntimeVersion < 3U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
const bool isStream = stream.GetStaticType()->IsStream();
const auto itemType = isStream ? AS_TYPE(TStreamType, stream)->GetItemType() : AS_TYPE(TFlowType, stream)->GetItemType();
@@ -5037,10 +4919,6 @@ TRuntimeNode TProgramBuilder::GroupingCore(TRuntimeNode stream,
const TUnaryLambda& keyExtractor,
const TUnaryLambda& handler)
{
- if (handler && RuntimeVersion < 20U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__ << " with handler";
- }
-
auto itemType = AS_TYPE(TStreamType, stream)->GetItemType();
TRuntimeNode keyExtractorItemArg = Arg(itemType);
@@ -5084,13 +4962,6 @@ TRuntimeNode TProgramBuilder::Chopper(TRuntimeNode flow, const TUnaryLambda& key
const auto flowType = flow.GetStaticType();
MKQL_ENSURE(flowType->IsFlow() || flowType->IsStream(), "Expected flow or stream.");
-
- if constexpr (RuntimeVersion < 9U) {
- return FlatMap(GroupingCore(flow, groupSwitch, keyExtractor),
- [&](TRuntimeNode item) -> TRuntimeNode { return groupHandler(Nth(item, 0U), Nth(item, 1U)); }
- );
- }
-
const bool isStream = flowType->IsStream();
const auto itemType = isStream ? AS_TYPE(TStreamType, flow)->GetItemType() : AS_TYPE(TFlowType, flow)->GetItemType();
@@ -5119,10 +4990,6 @@ TRuntimeNode TProgramBuilder::Chopper(TRuntimeNode flow, const TUnaryLambda& key
TRuntimeNode TProgramBuilder::WideChopper(TRuntimeNode flow, const TWideLambda& extractor, const TWideSwitchLambda& groupSwitch,
const std::function<TRuntimeNode (TRuntimeNode::TList, TRuntimeNode)>& groupHandler
) {
- if constexpr (RuntimeVersion < 18U) {
- THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
- }
-
const auto wideComponents = GetWideComponents(AS_TYPE(TFlowType, flow.GetStaticType()));
TRuntimeNode::TList itemArgs, keyArgs;
@@ -5564,11 +5431,9 @@ TRuntimeNode TProgramBuilder::Replicate(TRuntimeNode item, TRuntimeNode count, c
TCallableBuilder callableBuilder(Env, __func__, listType);
callableBuilder.Add(item);
callableBuilder.Add(count);
- if constexpr (RuntimeVersion >= 2) {
- callableBuilder.Add(NewDataLiteral<NUdf::EDataSlot::String>(file));
- callableBuilder.Add(NewDataLiteral(row));
- callableBuilder.Add(NewDataLiteral(column));
- }
+ callableBuilder.Add(NewDataLiteral<NUdf::EDataSlot::String>(file));
+ callableBuilder.Add(NewDataLiteral(row));
+ callableBuilder.Add(NewDataLiteral(column));
return TRuntimeNode(callableBuilder.Build(), false);
}
diff --git a/yql/essentials/minikql/mkql_type_builder.cpp b/yql/essentials/minikql/mkql_type_builder.cpp
index d1df31a97d..231231eee7 100644
--- a/yql/essentials/minikql/mkql_type_builder.cpp
+++ b/yql/essentials/minikql/mkql_type_builder.cpp
@@ -1522,6 +1522,17 @@ bool ConvertArrowTypeImpl(NUdf::EDataSlot slot, std::shared_ptr<arrow::DataType>
}
}
+inline bool IsSingularType(const TType* type) {
+ return type->IsNull() ||
+ type->IsVoid() ||
+ type->IsEmptyDict() ||
+ type->IsEmptyList();
+}
+
+inline bool NeedWrapWithExternalOptional(const TType* type) {
+ return type->IsPg() || IsSingularType(type);
+}
+
bool ConvertArrowTypeImpl(TType* itemType, std::shared_ptr<arrow::DataType>& type, const TArrowConvertFailedCallback& onFail, bool output) {
bool isOptional;
auto unpacked = UnpackOptional(itemType, isOptional);
@@ -1534,8 +1545,7 @@ bool ConvertArrowTypeImpl(TType* itemType, std::shared_ptr<arrow::DataType>& typ
return false;
}
- if (unpacked->IsOptional() || isOptional && unpacked->IsPg()) {
- // at least 2 levels of optionals
+ if (unpacked->IsOptional() || isOptional && NeedWrapWithExternalOptional(unpacked)) {
ui32 nestLevel = 0;
auto currentType = itemType;
auto previousType = itemType;
@@ -1545,12 +1555,11 @@ bool ConvertArrowTypeImpl(TType* itemType, std::shared_ptr<arrow::DataType>& typ
currentType = AS_TYPE(TOptionalType, currentType)->GetItemType();
} while (currentType->IsOptional());
- if (currentType->IsPg()) {
+ if (NeedWrapWithExternalOptional(currentType)) {
previousType = currentType;
++nestLevel;
}
- // previousType is always Optional
std::shared_ptr<arrow::DataType> innerArrowType;
if (!ConvertArrowTypeImpl(previousType, innerArrowType, onFail, output)) {
return false;
@@ -1618,6 +1627,11 @@ bool ConvertArrowTypeImpl(TType* itemType, std::shared_ptr<arrow::DataType>& typ
return true;
}
+ if (IsSingularType(unpacked)) {
+ type = arrow::null();
+ return true;
+ }
+
if (!unpacked->IsData()) {
if (onFail) {
onFail(unpacked);
@@ -2479,6 +2493,10 @@ size_t CalcMaxBlockItemSize(const TType* type) {
return sizeof(NYql::NUdf::TUnboxedValue);
}
+ if (IsSingularType(type)) {
+ return 0;
+ }
+
if (type->IsData()) {
auto slot = *AS_TYPE(TDataType, type)->GetDataSlot();
switch (slot) {
@@ -2552,6 +2570,7 @@ struct TComparatorTraits {
using TExtOptional = NUdf::TExternalOptionalBlockItemComparator;
template <typename T, bool Nullable>
using TTzDateComparator = NUdf::TTzDateBlockItemComparator<T, Nullable>;
+ using TSingularType = NUdf::TSingularTypeBlockItemComparator;
constexpr static bool PassType = false;
@@ -2565,6 +2584,10 @@ struct TComparatorTraits {
ythrow yexception() << "Comparator not implemented for block resources: ";
}
+ static std::unique_ptr<TResult> MakeSingular() {
+ return std::make_unique<TSingularType>();
+ }
+
template<typename TTzDate>
static std::unique_ptr<TResult> MakeTzDate(bool isOptional) {
if (isOptional) {
@@ -2586,6 +2609,7 @@ struct THasherTraits {
using TExtOptional = NUdf::TExternalOptionalBlockItemHasher;
template <typename T, bool Nullable>
using TTzDateHasher = NYql::NUdf::TTzDateBlockItemHasher<T, Nullable>;
+ using TSingularType = NUdf::TSingularTypeBlockItemHaser;
constexpr static bool PassType = false;
@@ -2607,6 +2631,10 @@ struct THasherTraits {
return std::make_unique<TTzDateHasher<TTzDate, false>>();
}
}
+
+ static std::unique_ptr<TResult> MakeSingular() {
+ return std::make_unique<TSingularType>();
+ }
};
NUdf::IBlockItemComparator::TPtr TBlockTypeHelper::MakeComparator(NUdf::TType* type) const {
@@ -2622,12 +2650,11 @@ TType* TTypeBuilder::NewVoidType() const {
}
TType* TTypeBuilder::NewNullType() const {
- if (!UseNullType || RuntimeVersion < 11) {
- TCallableBuilder callableBuilder(Env, "Null", NewOptionalType(NewVoidType()));
- return TRuntimeNode(callableBuilder.Build(), false).GetStaticType();
- } else {
+ if (UseNullType) {
return TRuntimeNode(Env.GetNullLazy(), true).GetStaticType();
}
+ TCallableBuilder callableBuilder(Env, "Null", NewOptionalType(NewVoidType()));
+ return TRuntimeNode(callableBuilder.Build(), false).GetStaticType();
}
TType* TTypeBuilder::NewEmptyStructType() const {
diff --git a/yql/essentials/providers/common/mkql/yql_provider_mkql.cpp b/yql/essentials/providers/common/mkql/yql_provider_mkql.cpp
index 123b59cc04..983bf85542 100644
--- a/yql/essentials/providers/common/mkql/yql_provider_mkql.cpp
+++ b/yql/essentials/providers/common/mkql/yql_provider_mkql.cpp
@@ -2236,22 +2236,12 @@ TMkqlCommonCallableCompiler::TShared::TShared() {
AddCallable("EmptyList", [](const TExprNode& node, TMkqlBuildContext& ctx) {
Y_UNUSED(node);
- if (RuntimeVersion < 11) {
- return ctx.ProgramBuilder.NewEmptyList(ctx.ProgramBuilder.NewVoid().GetStaticType());
- } else {
- return TRuntimeNode(ctx.ProgramBuilder.GetTypeEnvironment().GetEmptyListLazy(), true);
- }
+ return TRuntimeNode(ctx.ProgramBuilder.GetTypeEnvironment().GetEmptyListLazy(), true);
});
AddCallable("EmptyDict", [](const TExprNode& node, TMkqlBuildContext& ctx) {
Y_UNUSED(node);
- if (RuntimeVersion < 11) {
- auto voidType = ctx.ProgramBuilder.NewVoid().GetStaticType();
- auto dictType = ctx.ProgramBuilder.NewDictType(voidType, voidType, false);
- return ctx.ProgramBuilder.NewDict(dictType, {});
- } else {
- return TRuntimeNode(ctx.ProgramBuilder.GetTypeEnvironment().GetEmptyDictLazy(), true);
- }
+ return TRuntimeNode(ctx.ProgramBuilder.GetTypeEnvironment().GetEmptyDictLazy(), true);
});
AddCallable("SourceOf", [](const TExprNode& node, TMkqlBuildContext& ctx) {
diff --git a/yql/essentials/providers/common/mkql/yql_type_mkql.cpp b/yql/essentials/providers/common/mkql/yql_type_mkql.cpp
index cb001c847b..372ba7a98e 100644
--- a/yql/essentials/providers/common/mkql/yql_type_mkql.cpp
+++ b/yql/essentials/providers/common/mkql/yql_type_mkql.cpp
@@ -184,20 +184,10 @@ NKikimr::NMiniKQL::TType* BuildTypeImpl(const TTypeAnnotationNode& annotation, c
}
case ETypeAnnotationKind::EmptyList: {
- if (NKikimr::NMiniKQL::RuntimeVersion < 11) {
- auto voidType = typeBuilder.NewVoidType();
- return typeBuilder.NewListType(voidType);
- }
-
return typeBuilder.GetTypeEnvironment().GetTypeOfEmptyListLazy();
}
case ETypeAnnotationKind::EmptyDict: {
- if constexpr(NKikimr::NMiniKQL::RuntimeVersion < 11) {
- auto voidType = typeBuilder.NewVoidType();
- return typeBuilder.NewDictType(voidType, voidType, false);
- }
-
return typeBuilder.GetTypeEnvironment().GetTypeOfEmptyDictLazy();
}
diff --git a/yql/essentials/providers/common/schema/mkql/yql_mkql_schema.cpp b/yql/essentials/providers/common/schema/mkql/yql_mkql_schema.cpp
index c172a0a09f..8273070925 100644
--- a/yql/essentials/providers/common/schema/mkql/yql_mkql_schema.cpp
+++ b/yql/essentials/providers/common/schema/mkql/yql_mkql_schema.cpp
@@ -192,17 +192,9 @@ struct TRuntimeTypeLoader {
return Builder.GetTypeEnvironment().GetTypeOfTypeLazy();
}
TMaybe<TType> LoadEmptyListType(ui32 /*level*/) {
- if (NKikimr::NMiniKQL::RuntimeVersion < 11) {
- return Builder.NewListType(Builder.NewVoid().GetStaticType());
- }
-
return Builder.GetTypeEnvironment().GetTypeOfEmptyListLazy();
}
TMaybe<TType> LoadEmptyDictType(ui32 /*level*/) {
- if (NKikimr::NMiniKQL::RuntimeVersion < 11) {
- return Builder.NewDictType(Builder.NewVoid().GetStaticType(), Builder.NewVoid().GetStaticType(), false);
- }
-
return Builder.GetTypeEnvironment().GetTypeOfEmptyDictLazy();
}
TMaybe<TType> LoadDataType(const TString& dataType, ui32 /*level*/) {
diff --git a/yql/essentials/public/issue/yql_warning.cpp b/yql/essentials/public/issue/yql_warning.cpp
index 881e63e95f..6364025ff3 100644
--- a/yql/essentials/public/issue/yql_warning.cpp
+++ b/yql/essentials/public/issue/yql_warning.cpp
@@ -31,6 +31,10 @@ TWarningRule::EParseResult TWarningRule::ParseFrom(const TString& codePattern, c
return EParseResult::PARSE_OK;
}
+TWarningPolicy::TWarningPolicy(bool isReplay)
+ : IsReplay(isReplay)
+{}
+
void TWarningPolicy::AddRule(const TWarningRule& rule)
{
TString pattern = rule.GetPattern();
@@ -38,6 +42,10 @@ void TWarningPolicy::AddRule(const TWarningRule& rule)
return;
}
+ if (pattern == "*" && IsReplay) {
+ return;
+ }
+
Rules.push_back(rule);
EWarningAction action = rule.GetAction();
diff --git a/yql/essentials/public/issue/yql_warning.h b/yql/essentials/public/issue/yql_warning.h
index d1d6a90922..7c3939d1d3 100644
--- a/yql/essentials/public/issue/yql_warning.h
+++ b/yql/essentials/public/issue/yql_warning.h
@@ -34,6 +34,8 @@ using TWarningRules = TVector<TWarningRule>;
class TWarningPolicy {
public:
+ TWarningPolicy(bool isReplay = false);
+
void AddRule(const TWarningRule& rule);
EWarningAction GetAction(TIssueCode code) const;
@@ -43,6 +45,7 @@ public:
void Clear();
private:
+ const bool IsReplay;
TWarningRules Rules;
EWarningAction BaseAction = EWarningAction::DEFAULT;
THashMap<TIssueCode, EWarningAction> Overrides;
diff --git a/yql/essentials/public/udf/arrow/block_builder.h b/yql/essentials/public/udf/arrow/block_builder.h
index 92f4f7e123..baac1842b9 100644
--- a/yql/essentials/public/udf/arrow/block_builder.h
+++ b/yql/essentials/public/udf/arrow/block_builder.h
@@ -10,6 +10,7 @@
#include <yql/essentials/public/udf/udf_value_builder.h>
#include <yql/essentials/public/udf/udf_type_inspection.h>
+#include <arrow/array/array_base.h>
#include <arrow/datum.h>
#include <arrow/c/bridge.h>
@@ -1358,6 +1359,53 @@ private:
std::unique_ptr<TTypedBufferBuilder<ui8>> NullBuilder;
};
+class TSingularBlockBuilder final: public TArrayBuilderBase {
+public:
+ TSingularBlockBuilder(const TType* type, const ITypeInfoHelper& typeInfoHelper, arrow::MemoryPool& pool,
+ size_t maxLen, const TParams& params = {})
+ : TArrayBuilderBase(typeInfoHelper, type, pool, maxLen, params) {
+ Reserve();
+ }
+
+ void DoAdd(NUdf::TUnboxedValuePod value) final {
+ Y_UNUSED(value);
+ }
+
+ void DoAdd(TBlockItem value) final {
+ Y_UNUSED(value);
+ }
+
+ void DoAdd(TInputBuffer& input) final {
+ Y_UNUSED(input.PopChar());
+ }
+
+ void DoAddDefault() final {}
+
+ void DoAddMany(const arrow::ArrayData& array, const ui8* sparseBitmap, size_t popCount) final {
+ Y_UNUSED(array, sparseBitmap, popCount);
+ }
+
+ void DoAddMany(const arrow::ArrayData& array, ui64 beginIndex, size_t count) final {
+ Y_UNUSED(array, beginIndex, count);
+ }
+
+ void DoAddMany(const arrow::ArrayData& array, const ui64* indexes, size_t count) final {
+ Y_UNUSED(array, indexes, count);
+ }
+
+ TBlockArrayTree::Ptr DoBuildTree(bool finish) final {
+ TBlockArrayTree::Ptr result = std::make_shared<TBlockArrayTree>();
+ Y_UNUSED(finish);
+ result->Payload.push_back(arrow::NullArray(GetCurrLen()).data());
+ return result;
+ }
+
+private:
+ size_t DoReserve() final {
+ return 0;
+ }
+};
+
using TArrayBuilderParams = TArrayBuilderBase::TParams;
struct TBuilderTraits {
@@ -1373,6 +1421,7 @@ struct TBuilderTraits {
using TResource = TResourceArrayBuilder<Nullable>;
template<typename TTzDate, bool Nullable>
using TTzDateReader = TTzDateArrayBuilder<TTzDate, Nullable>;
+ using TSingular = TSingularBlockBuilder;
constexpr static bool PassType = true;
@@ -1412,6 +1461,10 @@ struct TBuilderTraits {
return std::make_unique<TTzDateReader<TTzDate, false>>(type, typeInfoHelper, pool, maxLen, params);
}
}
+
+ static std::unique_ptr<TResult> MakeSingular(const TType* type, const ITypeInfoHelper& typeInfoHelper, arrow::MemoryPool& pool, size_t maxLen, const TArrayBuilderParams& params) {
+ return std::make_unique<TSingular>(type, typeInfoHelper, pool, maxLen, params);
+ }
};
inline std::unique_ptr<IArrayBuilder> MakeArrayBuilder(
diff --git a/yql/essentials/public/udf/arrow/block_item.h b/yql/essentials/public/udf/arrow/block_item.h
index 2f9784cd3c..79686b3094 100644
--- a/yql/essentials/public/udf/arrow/block_item.h
+++ b/yql/essentials/public/udf/arrow/block_item.h
@@ -166,6 +166,18 @@ public:
return &Raw;
}
+ static inline TBlockItem Void() {
+ TBlockItem v;
+ v.Raw.Simple.Meta = static_cast<ui8>(EMarkers::Embedded);
+ return v;
+ }
+
+ static inline TBlockItem Zero() {
+ TBlockItem v;
+ v.Raw.Simple.Meta = static_cast<ui8>(EMarkers::Embedded);
+ return v;
+ }
+
inline const void* GetRawPtr() const
{
return &Raw;
diff --git a/yql/essentials/public/udf/arrow/block_item_comparator.h b/yql/essentials/public/udf/arrow/block_item_comparator.h
index e185b63f66..ad803799c6 100644
--- a/yql/essentials/public/udf/arrow/block_item_comparator.h
+++ b/yql/essentials/public/udf/arrow/block_item_comparator.h
@@ -169,6 +169,24 @@ public:
}
};
+class TSingularTypeBlockItemComparator: public TBlockItemComparatorBase<TSingularTypeBlockItemComparator, /*Nullable=*/false> {
+public:
+ i64 DoCompare(TBlockItem lhs, TBlockItem rhs) const {
+ Y_UNUSED(lhs, rhs);
+ return 0;
+ }
+
+ bool DoEquals(TBlockItem lhs, TBlockItem rhs) const {
+ Y_UNUSED(lhs, rhs);
+ return true;
+ }
+
+ bool DoLess(TBlockItem lhs, TBlockItem rhs) const {
+ Y_UNUSED(lhs, rhs);
+ return false;
+ }
+};
+
template<typename TTzType, bool Nullable>
class TTzDateBlockItemComparator : public TBlockItemComparatorBase<TTzDateBlockItemComparator<TTzType, Nullable>, Nullable> {
using TLayout = typename TDataType<TTzType>::TLayout;
diff --git a/yql/essentials/public/udf/arrow/block_item_hasher.h b/yql/essentials/public/udf/arrow/block_item_hasher.h
index 3f77e27b6f..9108d7b06e 100644
--- a/yql/essentials/public/udf/arrow/block_item_hasher.h
+++ b/yql/essentials/public/udf/arrow/block_item_hasher.h
@@ -76,6 +76,14 @@ public:
}
};
+class TSingularTypeBlockItemHaser : public TBlockItemHasherBase<TSingularTypeBlockItemHaser, /*Nullable=*/false> {
+public:
+ ui64 DoHash(TBlockItem value) const {
+ Y_UNUSED(value);
+ return 0;
+ }
+};
+
template <bool Nullable>
class TTupleBlockItemHasher : public TBlockItemHasherBase<TTupleBlockItemHasher<Nullable>, Nullable> {
public:
diff --git a/yql/essentials/public/udf/arrow/block_reader.h b/yql/essentials/public/udf/arrow/block_reader.h
index 05dd3ce440..6652df2ac6 100644
--- a/yql/essentials/public/udf/arrow/block_reader.h
+++ b/yql/essentials/public/udf/arrow/block_reader.h
@@ -424,6 +424,48 @@ private:
TFixedSizeBlockReader<ui16, /* Nullable */false> TimezoneReader_;
};
+// NOTE: For any singular type we use arrow::null() data type.
+// This data type DOES NOT support bit mask so for optional type
+// we have to use |TExternalOptional| wrapper.
+class TSingularTypeBlockReader: public IBlockReader {
+public:
+ TSingularTypeBlockReader() = default;
+
+ ~TSingularTypeBlockReader() override = default;
+
+ TBlockItem GetItem(const arrow::ArrayData& data, size_t index) override {
+ Y_UNUSED(data, index);
+ return TBlockItem::Zero();
+ }
+
+ TBlockItem GetScalarItem(const arrow::Scalar& scalar) override {
+ Y_UNUSED(scalar);
+ return TBlockItem::Zero();
+ }
+
+ ui64 GetDataWeight(const arrow::ArrayData& data) const override {
+ Y_UNUSED(data);
+ return 0;
+ }
+
+ ui64 GetDataWeight(TBlockItem item) const override {
+ Y_UNUSED(item);
+ return 0;
+ }
+
+ ui64 GetDefaultValueWeight() const override {
+ return 0;
+ }
+
+ void SaveItem(const arrow::ArrayData& data, size_t index, TOutputBuffer& out) const override {
+ Y_UNUSED(index, data, out);
+ }
+
+ void SaveScalarItem(const arrow::Scalar& scalar, TOutputBuffer& out) const override {
+ Y_UNUSED(scalar, out);
+ }
+};
+
class TExternalOptionalBlockReader final : public IBlockReader {
public:
TExternalOptionalBlockReader(std::unique_ptr<IBlockReader>&& inner)
@@ -498,6 +540,7 @@ struct TReaderTraits {
using TResource = TResourceBlockReader<Nullable>;
template<typename TTzDate, bool Nullable>
using TTzDateReader = TTzDateBlockReader<TTzDate, Nullable>;
+ using TSingularType = TSingularTypeBlockReader;
constexpr static bool PassType = false;
@@ -518,6 +561,10 @@ struct TReaderTraits {
}
}
+ static std::unique_ptr<TResult> MakeSingular() {
+ return std::make_unique<TSingularType>();
+ }
+
template<typename TTzDate>
static std::unique_ptr<TResult> MakeTzDate(bool isOptional) {
if (isOptional) {
@@ -595,6 +642,10 @@ inline void UpdateBlockItemSerializeProps(const ITypeInfoHelper& typeInfoHelper,
return;
}
+ if (IsSingularType(typeInfoHelper, type)) {
+ return;
+ }
+
Y_ENSURE(false, "Unsupported type");
}
diff --git a/yql/essentials/public/udf/arrow/dispatch_traits.h b/yql/essentials/public/udf/arrow/dispatch_traits.h
index 88c303cc87..87c25b93f5 100644
--- a/yql/essentials/public/udf/arrow/dispatch_traits.h
+++ b/yql/essentials/public/udf/arrow/dispatch_traits.h
@@ -1,5 +1,6 @@
#pragma once
+#include <yql/essentials/public/udf/arrow/util.h>
#include <yql/essentials/public/udf/udf_type_inspection.h>
#include <yql/essentials/public/udf/udf_value_builder.h>
@@ -85,8 +86,7 @@ std::unique_ptr<typename TTraits::TResult> DispatchByArrowTraits(const ITypeInfo
TOptionalTypeInspector unpackedOpt(typeInfoHelper, unpacked);
TPgTypeInspector unpackedPg(typeInfoHelper, unpacked);
- if (unpackedOpt || typeOpt && unpackedPg) {
- // at least 2 levels of optionals
+ if (unpackedOpt || (typeOpt && NeedWrapWithExternalOptional(typeInfoHelper, unpacked))) {
ui32 nestLevel = 0;
auto currentType = type;
auto previousType = type;
@@ -103,7 +103,7 @@ std::unique_ptr<typename TTraits::TResult> DispatchByArrowTraits(const ITypeInfo
}
}
- if (TPgTypeInspector(typeInfoHelper, currentType)) {
+ if (NeedWrapWithExternalOptional(typeInfoHelper, currentType)) {
previousType = currentType;
++nestLevel;
}
@@ -118,8 +118,7 @@ std::unique_ptr<typename TTraits::TResult> DispatchByArrowTraits(const ITypeInfo
}
return reader;
- }
- else {
+ } else {
type = unpacked;
}
@@ -230,6 +229,15 @@ std::unique_ptr<typename TTraits::TResult> DispatchByArrowTraits(const ITypeInfo
}
}
+ if (IsSingularType(typeInfoHelper, type)) {
+ Y_ENSURE(!isOptional, "Optional data types are not supported directly for singular type. Please use TExternalOptional wrapper.");
+ if constexpr (TTraits::PassType) {
+ return TTraits::MakeSingular(type, std::forward<TArgs>(args)...);
+ } else {
+ return TTraits::MakeSingular(std::forward<TArgs>(args)...);
+ }
+ }
+
Y_ENSURE(false, "Unsupported type");
}
diff --git a/yql/essentials/public/udf/arrow/ut/array_builder_ut.cpp b/yql/essentials/public/udf/arrow/ut/array_builder_ut.cpp
index bbb4c134c8..d0851c5e86 100644
--- a/yql/essentials/public/udf/arrow/ut/array_builder_ut.cpp
+++ b/yql/essentials/public/udf/arrow/ut/array_builder_ut.cpp
@@ -220,6 +220,46 @@ Y_UNIT_TEST_SUITE(TArrayBuilderTest) {
UNIT_ASSERT_VALUES_EQUAL(item2AfterRead.GetStringRefFromValue(), "234");
}
+ Y_UNIT_TEST(TestSingularTypeValueBuilderReader) {
+ TArrayBuilderTestData data;
+ const auto nullType = data.PgmBuilder.NewNullType();
+
+ std::shared_ptr<arrow::ArrayData> arrayData = arrow::NullArray{42}.data();
+ IArrayBuilder::TArrayDataItem arrayDataItem = {.Data = arrayData.get(), .StartOffset = 0};
+ {
+ const auto arrayBuilder = MakeArrayBuilder(NMiniKQL::TTypeInfoHelper(), nullType, *data.ArrowPool, MAX_BLOCK_SIZE, /*pgBuilder=*/nullptr);
+ // Check builder.
+ arrayBuilder->Add(TUnboxedValuePod::Zero());
+ arrayBuilder->Add(TBlockItem::Zero());
+ arrayBuilder->Add(TBlockItem::Zero(), 4);
+ TInputBuffer inputBuffer("Just arbitrary string");
+ arrayBuilder->Add(inputBuffer);
+ arrayBuilder->AddMany(*arrayData, /*popCount=*/3u, /*sparseBitmat=*/nullptr, /*bitmapSize=*/arrayData->length);
+ arrayBuilder->AddMany(&arrayDataItem, /*arrayCount=*/1, /*beginIndex=*/1, /*count=*/3u);
+ std::vector<ui64> indexes = {1, 5, 7, 10};
+ arrayBuilder->AddMany(&arrayDataItem, /*arrayCount=*/1, /*beginIndex=*/indexes.data(), /*count=*/4u);
+ UNIT_ASSERT_VALUES_EQUAL(arrayBuilder->Build(true).array()->length, 1 + 1 + 4 + 1 + 3 + 3 + 4);
+ }
+
+ {
+ // Check reader.
+ const auto blockReader = MakeBlockReader(NMiniKQL::TTypeInfoHelper(), nullType);
+
+ UNIT_ASSERT(blockReader->GetItem(*arrayData, 0));
+ UNIT_ASSERT(blockReader->GetScalarItem(arrow::Scalar(arrow::null())));
+ UNIT_ASSERT_EQUAL(blockReader->GetDataWeight(*arrayData), 0);
+ UNIT_ASSERT_EQUAL(blockReader->GetDataWeight(TBlockItem::Zero()), 0);
+ UNIT_ASSERT_EQUAL(blockReader->GetDefaultValueWeight(), 0);
+ UNIT_ASSERT_EQUAL(blockReader->GetDefaultValueWeight(), 0);
+
+ TOutputBuffer outputBuffer;
+ blockReader->SaveItem(*arrayData, 1, outputBuffer);
+ UNIT_ASSERT(outputBuffer.Finish().empty());
+ blockReader->SaveScalarItem(arrow::Scalar(arrow::null()), outputBuffer);
+ UNIT_ASSERT(outputBuffer.Finish().empty());
+ }
+ }
+
Y_UNIT_TEST(TestBuilderAllocatedSize) {
TArrayBuilderTestData data;
const auto optStringType = data.PgmBuilder.NewDataType(NUdf::EDataSlot::String, true);
diff --git a/yql/essentials/public/udf/arrow/util.h b/yql/essentials/public/udf/arrow/util.h
index f7bdb715f9..e899af26af 100644
--- a/yql/essentials/public/udf/arrow/util.h
+++ b/yql/essentials/public/udf/arrow/util.h
@@ -12,6 +12,9 @@
#include <functional>
+#include <yql/essentials/public/udf/udf_type_inspection.h>
+#include <yql/essentials/public/udf/udf_types.h>
+
namespace NYql {
namespace NUdf {
@@ -236,5 +239,17 @@ inline void ZeroMemoryContext(void* ptr) {
SetMemoryContext(ptr, nullptr);
}
+inline bool IsSingularType(const ITypeInfoHelper& typeInfoHelper, const TType* type) {
+ auto kind = typeInfoHelper.GetTypeKind(type);
+ return kind == ETypeKind::Null ||
+ kind == ETypeKind::Void ||
+ kind == ETypeKind::EmptyDict ||
+ kind == ETypeKind::EmptyList;
+}
+
+inline bool NeedWrapWithExternalOptional(const ITypeInfoHelper& typeInfoHelper, const TType* type) {
+ return TPgTypeInspector(typeInfoHelper, type) || IsSingularType(typeInfoHelper, type);
+}
+
} // namespace NUdf
} // namespace NYql
diff --git a/yql/essentials/sql/settings/translation_settings.h b/yql/essentials/sql/settings/translation_settings.h
index 8c6e716343..98d537038e 100644
--- a/yql/essentials/sql/settings/translation_settings.h
+++ b/yql/essentials/sql/settings/translation_settings.h
@@ -129,6 +129,7 @@ namespace NSQLTranslation {
NYql::IAutoParamBuilderFactory* AutoParamBuilderFactory = nullptr;
bool EmitReadsForExists = false;
bool AlwaysAllowExports = false;
+ bool IsReplay = false;
};
bool ParseTranslationSettings(const TString& query, NSQLTranslation::TTranslationSettings& settings, NYql::TIssues& issues);
diff --git a/yql/essentials/sql/v1/context.cpp b/yql/essentials/sql/v1/context.cpp
index 9790e931dc..b72c673b0e 100644
--- a/yql/essentials/sql/v1/context.cpp
+++ b/yql/essentials/sql/v1/context.cpp
@@ -100,6 +100,7 @@ TContext::TContext(const TLexers& lexers, const TParsers& parsers,
, HasPendingErrors(false)
, DqEngineEnable(Settings.DqDefaultAuto->Allow())
, AnsiQuotedIdentifiers(settings.AnsiLexer)
+ , WarningPolicy(settings.IsReplay)
, BlockEngineEnable(Settings.BlockDefaultAuto->Allow())
{
for (auto lib : settings.Libraries) {
diff --git a/yql/essentials/tests/sql/minirun/part0/canondata/result.json b/yql/essentials/tests/sql/minirun/part0/canondata/result.json
index 3c1aa86fec..ffeebb57cc 100644
--- a/yql/essentials/tests/sql/minirun/part0/canondata/result.json
+++ b/yql/essentials/tests/sql/minirun/part0/canondata/result.json
@@ -275,6 +275,27 @@
"uri": "https://{canondata_backend}/1936842/8073eb626dd657fcbe20d34185c363a1a18c3e7c/resource.tar.gz#test.test_blocks-agg_all_mixed_distinct-default.txt-Results_/results.txt"
}
],
+ "test.test[blocks-agg_singular_type_key_optional-default.txt-Debug]": [
+ {
+ "checksum": "71ee94512d6ef28833fb6df3bace7b53",
+ "size": 2727,
+ "uri": "https://{canondata_backend}/1925842/7e03c084910acb6d9d50a1f7dc65eda3cdac3b45/resource.tar.gz#test.test_blocks-agg_singular_type_key_optional-default.txt-Debug_/opt.yql"
+ }
+ ],
+ "test.test[blocks-agg_singular_type_key_optional-default.txt-Peephole]": [
+ {
+ "checksum": "db2e4bd6530b31b6efceb77a4a184b4e",
+ "size": 6606,
+ "uri": "https://{canondata_backend}/1925842/7e03c084910acb6d9d50a1f7dc65eda3cdac3b45/resource.tar.gz#test.test_blocks-agg_singular_type_key_optional-default.txt-Peephole_/opt.yql"
+ }
+ ],
+ "test.test[blocks-agg_singular_type_key_optional-default.txt-Results]": [
+ {
+ "checksum": "4b79ad0d41612ad09d735f34513ee6ff",
+ "size": 7301,
+ "uri": "https://{canondata_backend}/1925842/7e03c084910acb6d9d50a1f7dc65eda3cdac3b45/resource.tar.gz#test.test_blocks-agg_singular_type_key_optional-default.txt-Results_/results.txt"
+ }
+ ],
"test.test[blocks-and-default.txt-Debug]": [
{
"checksum": "47525fa40526e04498f0c41e6bc48f59",
diff --git a/yql/essentials/tests/sql/minirun/part2/canondata/result.json b/yql/essentials/tests/sql/minirun/part2/canondata/result.json
index 48c0652311..73ff7dcd87 100644
--- a/yql/essentials/tests/sql/minirun/part2/canondata/result.json
+++ b/yql/essentials/tests/sql/minirun/part2/canondata/result.json
@@ -258,6 +258,27 @@
"uri": "https://{canondata_backend}/1937150/3d01c6ab2777fc3b99338655d39a5bcbb1ac89c3/resource.tar.gz#test.test_blocks-agg_by_key_only_distinct-default.txt-Results_/results.txt"
}
],
+ "test.test[blocks-agg_singular_type_value_optional-default.txt-Debug]": [
+ {
+ "checksum": "06774e6dab64198fc6cc5d173b0bba26",
+ "size": 2781,
+ "uri": "https://{canondata_backend}/1781765/b8d92d6ccf46e436b2e5b3b70ab511bab6d820b0/resource.tar.gz#test.test_blocks-agg_singular_type_value_optional-default.txt-Debug_/opt.yql"
+ }
+ ],
+ "test.test[blocks-agg_singular_type_value_optional-default.txt-Peephole]": [
+ {
+ "checksum": "d22ed37889eea3b41eadb6164bf6d017",
+ "size": 3113,
+ "uri": "https://{canondata_backend}/1781765/b8d92d6ccf46e436b2e5b3b70ab511bab6d820b0/resource.tar.gz#test.test_blocks-agg_singular_type_value_optional-default.txt-Peephole_/opt.yql"
+ }
+ ],
+ "test.test[blocks-agg_singular_type_value_optional-default.txt-Results]": [
+ {
+ "checksum": "98fbeb83e5295954045efa6fd159626f",
+ "size": 5301,
+ "uri": "https://{canondata_backend}/1781765/b8d92d6ccf46e436b2e5b3b70ab511bab6d820b0/resource.tar.gz#test.test_blocks-agg_singular_type_value_optional-default.txt-Results_/results.txt"
+ }
+ ],
"test.test[blocks-exists-default.txt-Debug]": [
{
"checksum": "a871029504a6d3f1c07342493b86d28d",
diff --git a/yql/essentials/tests/sql/minirun/part7/canondata/result.json b/yql/essentials/tests/sql/minirun/part7/canondata/result.json
index 399f6d226b..d018f1582d 100644
--- a/yql/essentials/tests/sql/minirun/part7/canondata/result.json
+++ b/yql/essentials/tests/sql/minirun/part7/canondata/result.json
@@ -220,7 +220,7 @@
{
"checksum": "02e80809d3cbf91101d09d4ac1e87aa0",
"size": 623,
- "uri": "https://{canondata_backend}/1917492/b01930df0710eb10e4ce2d35cddca6be33ac8a9f/resource.tar.gz#test.test_blocks-as_tuple-default.txt-Peephole_/opt.yql"
+ "uri": "https://{canondata_backend}/1130705/f9eb075ce8fc54a57832e4ee918669601325c133/resource.tar.gz#test.test_blocks-as_tuple-default.txt-Peephole_/opt.yql"
}
],
"test.test[blocks-as_tuple-default.txt-Results]": [
diff --git a/yql/essentials/tests/sql/minirun/part8/canondata/result.json b/yql/essentials/tests/sql/minirun/part8/canondata/result.json
index 6d3cbc281d..94d8c6547e 100644
--- a/yql/essentials/tests/sql/minirun/part8/canondata/result.json
+++ b/yql/essentials/tests/sql/minirun/part8/canondata/result.json
@@ -352,6 +352,48 @@
"uri": "https://{canondata_backend}/1031349/4d0c6ce1905689c65e264d15d770d36efcd9426f/resource.tar.gz#test.test_binding-named_expr_input-default.txt-Results_/results.txt"
}
],
+ "test.test[blocks-agg_singular_type_key-default.txt-Debug]": [
+ {
+ "checksum": "b97d36400fafea8f8f6670954d7ac139",
+ "size": 2685,
+ "uri": "https://{canondata_backend}/1936273/07450a3416f3c728f9a8a8fdde6e5f5a0ca2d9a6/resource.tar.gz#test.test_blocks-agg_singular_type_key-default.txt-Debug_/opt.yql"
+ }
+ ],
+ "test.test[blocks-agg_singular_type_key-default.txt-Peephole]": [
+ {
+ "checksum": "f77f6136a2995c5b0e0ae3ed00274d36",
+ "size": 6564,
+ "uri": "https://{canondata_backend}/1936273/07450a3416f3c728f9a8a8fdde6e5f5a0ca2d9a6/resource.tar.gz#test.test_blocks-agg_singular_type_key-default.txt-Peephole_/opt.yql"
+ }
+ ],
+ "test.test[blocks-agg_singular_type_key-default.txt-Results]": [
+ {
+ "checksum": "e2233558149bd3009f7f16412bf4838a",
+ "size": 6117,
+ "uri": "https://{canondata_backend}/1936273/07450a3416f3c728f9a8a8fdde6e5f5a0ca2d9a6/resource.tar.gz#test.test_blocks-agg_singular_type_key-default.txt-Results_/results.txt"
+ }
+ ],
+ "test.test[blocks-agg_singular_type_value-default.txt-Debug]": [
+ {
+ "checksum": "4733abf71c9c62e30af77c6490d59334",
+ "size": 2358,
+ "uri": "https://{canondata_backend}/1130705/a25045513209436069d9f9a29831b732c13e1675/resource.tar.gz#test.test_blocks-agg_singular_type_value-default.txt-Debug_/opt.yql"
+ }
+ ],
+ "test.test[blocks-agg_singular_type_value-default.txt-Peephole]": [
+ {
+ "checksum": "b34c4e8ca42e6232ef03f2ffeb05fd83",
+ "size": 3013,
+ "uri": "https://{canondata_backend}/1130705/a25045513209436069d9f9a29831b732c13e1675/resource.tar.gz#test.test_blocks-agg_singular_type_value-default.txt-Peephole_/opt.yql"
+ }
+ ],
+ "test.test[blocks-agg_singular_type_value-default.txt-Results]": [
+ {
+ "checksum": "4718805e72274809e4ac6c07ee8dfd7d",
+ "size": 3489,
+ "uri": "https://{canondata_backend}/1130705/a25045513209436069d9f9a29831b732c13e1675/resource.tar.gz#test.test_blocks-agg_singular_type_value-default.txt-Results_/results.txt"
+ }
+ ],
"test.test[blocks-and_scalar-default.txt-Debug]": [
{
"checksum": "e5ccc5c53756e09ded8e82b6d662e5e9",
diff --git a/yql/essentials/tests/sql/sql2yql/canondata/result.json b/yql/essentials/tests/sql/sql2yql/canondata/result.json
index f345b0e389..0c9c63e161 100644
--- a/yql/essentials/tests/sql/sql2yql/canondata/result.json
+++ b/yql/essentials/tests/sql/sql2yql/canondata/result.json
@@ -1378,6 +1378,34 @@
"uri": "https://{canondata_backend}/1917492/7dd4bc86433f6173a26b62397e1ef41fa9471945/resource.tar.gz#test_sql2yql.test_blocks-agg_by_key_only_distinct_/sql.yql"
}
],
+ "test_sql2yql.test[blocks-agg_singular_type_key]": [
+ {
+ "checksum": "7cae7f556775597a0b451a875e77a1df",
+ "size": 7636,
+ "uri": "https://{canondata_backend}/1784117/5ff6ff6c0808bf39612567f492af1bc2db36da20/resource.tar.gz#test_sql2yql.test_blocks-agg_singular_type_key_/sql.yql"
+ }
+ ],
+ "test_sql2yql.test[blocks-agg_singular_type_key_optional]": [
+ {
+ "checksum": "a3f91d7949791561f4972eafc1610499",
+ "size": 7678,
+ "uri": "https://{canondata_backend}/1781765/9e1dc7f8aa95db55a59c09f397a0634224d08363/resource.tar.gz#test_sql2yql.test_blocks-agg_singular_type_key_optional_/sql.yql"
+ }
+ ],
+ "test_sql2yql.test[blocks-agg_singular_type_value]": [
+ {
+ "checksum": "cd58c3714a9d215fd1f4bea4e36f37a2",
+ "size": 3634,
+ "uri": "https://{canondata_backend}/1781765/9e1dc7f8aa95db55a59c09f397a0634224d08363/resource.tar.gz#test_sql2yql.test_blocks-agg_singular_type_value_/sql.yql"
+ }
+ ],
+ "test_sql2yql.test[blocks-agg_singular_type_value_optional]": [
+ {
+ "checksum": "5ae70db766241594bfea9edd5e5dec34",
+ "size": 3676,
+ "uri": "https://{canondata_backend}/1781765/0dce37dc71c65fe553d73ed7cf98a62bdee9ddee/resource.tar.gz#test_sql2yql.test_blocks-agg_singular_type_value_optional_/sql.yql"
+ }
+ ],
"test_sql2yql.test[blocks-and]": [
{
"checksum": "e22a52b51ef20174c3b832acb09df01b",
@@ -1410,7 +1438,7 @@
{
"checksum": "601f02d489707b615a9ff16a4fe1d3f5",
"size": 1304,
- "uri": "https://{canondata_backend}/1900335/c447765ddbde200b8fe3ee8091f4d625b36b6bc6/resource.tar.gz#test_sql2yql.test_blocks-as_tuple_/sql.yql"
+ "uri": "https://{canondata_backend}/1784826/bb2033aff3202d2b68e04361e6d1bacbf4cbbed6/resource.tar.gz#test_sql2yql.test_blocks-as_tuple_/sql.yql"
}
],
"test_sql2yql.test[blocks-coalesce]": [
@@ -8299,6 +8327,26 @@
"uri": "file://test_sql_format.test_blocks-agg_by_key_only_distinct_/formatted.sql"
}
],
+ "test_sql_format.test[blocks-agg_singular_type_key]": [
+ {
+ "uri": "file://test_sql_format.test_blocks-agg_singular_type_key_/formatted.sql"
+ }
+ ],
+ "test_sql_format.test[blocks-agg_singular_type_key_optional]": [
+ {
+ "uri": "file://test_sql_format.test_blocks-agg_singular_type_key_optional_/formatted.sql"
+ }
+ ],
+ "test_sql_format.test[blocks-agg_singular_type_value]": [
+ {
+ "uri": "file://test_sql_format.test_blocks-agg_singular_type_value_/formatted.sql"
+ }
+ ],
+ "test_sql_format.test[blocks-agg_singular_type_value_optional]": [
+ {
+ "uri": "file://test_sql_format.test_blocks-agg_singular_type_value_optional_/formatted.sql"
+ }
+ ],
"test_sql_format.test[blocks-and]": [
{
"uri": "file://test_sql_format.test_blocks-and_/formatted.sql"
diff --git a/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_blocks-agg_singular_type_key_/formatted.sql b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_blocks-agg_singular_type_key_/formatted.sql
new file mode 100644
index 0000000000..fd6c96da8f
--- /dev/null
+++ b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_blocks-agg_singular_type_key_/formatted.sql
@@ -0,0 +1,72 @@
+PRAGMA config.flags('PeepholeFlags', 'UseAggPhases');
+
+$n = 3;
+
+$data = ListMap(
+ ListFromRange(1, $n), ($x) -> (
+ <|
+ idx: $x,
+ empty_list: [],
+ empty_dict: {},
+ nil: NULL,
+ val: $x + 5,
+ vid: Void(),
+ emtpy_tuple: AsTuple(),
+ empty_struct: AsStruct()
+ |>
+ )
+);
+
+SELECT
+ empty_list,
+ SOME(idx)
+FROM
+ as_table($data)
+GROUP BY
+ empty_list
+;
+
+SELECT
+ empty_dict,
+ SOME(idx)
+FROM
+ as_table($data)
+GROUP BY
+ empty_dict
+;
+
+SELECT
+ nil,
+ SOME(idx)
+FROM
+ as_table($data)
+GROUP BY
+ nil
+;
+
+SELECT
+ vid,
+ SOME(idx)
+FROM
+ as_table($data)
+GROUP BY
+ vid
+;
+
+SELECT
+ emtpy_tuple,
+ SOME(idx)
+FROM
+ as_table($data)
+GROUP BY
+ emtpy_tuple
+;
+
+SELECT
+ empty_struct,
+ SOME(idx)
+FROM
+ as_table($data)
+GROUP BY
+ empty_struct
+;
diff --git a/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_blocks-agg_singular_type_key_optional_/formatted.sql b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_blocks-agg_singular_type_key_optional_/formatted.sql
new file mode 100644
index 0000000000..401f8117f5
--- /dev/null
+++ b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_blocks-agg_singular_type_key_optional_/formatted.sql
@@ -0,0 +1,72 @@
+PRAGMA config.flags('PeepholeFlags', 'UseAggPhases');
+
+$n = 3;
+
+$data = ListMap(
+ ListFromRange(1, $n), ($x) -> (
+ <|
+ idx: $x,
+ empty_list: Just([]),
+ empty_dict: Just({}),
+ nil: Just(NULL),
+ val: $x + 5,
+ vid: Just(Void()),
+ emtpy_tuple: Just(AsTuple()),
+ empty_struct: Just(AsStruct())
+ |>
+ )
+);
+
+SELECT
+ empty_list,
+ SOME(idx)
+FROM
+ as_table($data)
+GROUP BY
+ empty_list
+;
+
+SELECT
+ empty_dict,
+ SOME(idx)
+FROM
+ as_table($data)
+GROUP BY
+ empty_dict
+;
+
+SELECT
+ nil,
+ SOME(idx)
+FROM
+ as_table($data)
+GROUP BY
+ nil
+;
+
+SELECT
+ vid,
+ SOME(idx)
+FROM
+ as_table($data)
+GROUP BY
+ vid
+;
+
+SELECT
+ emtpy_tuple,
+ SOME(idx)
+FROM
+ as_table($data)
+GROUP BY
+ emtpy_tuple
+;
+
+SELECT
+ empty_struct,
+ SOME(idx)
+FROM
+ as_table($data)
+GROUP BY
+ empty_struct
+;
diff --git a/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_blocks-agg_singular_type_value_/formatted.sql b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_blocks-agg_singular_type_value_/formatted.sql
new file mode 100644
index 0000000000..f8836f06f6
--- /dev/null
+++ b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_blocks-agg_singular_type_value_/formatted.sql
@@ -0,0 +1,33 @@
+PRAGMA config.flags('PeepholeFlags', 'UseAggPhases');
+
+$n = 3;
+
+$data = ListMap(
+ ListFromRange(1, $n), ($x) -> (
+ <|
+ idx: $x,
+ empty_list: [],
+ empty_dict: {},
+ nil: NULL,
+ val: $x + 5,
+ vid: Void(),
+ emtpy_tuple: AsTuple(),
+ empty_struct: AsStruct()
+ |>
+ )
+);
+
+SELECT
+ idx,
+ SOME(empty_dict),
+ SOME(empty_list),
+ SOME(nil),
+ SOME(empty_dict),
+ SOME(vid),
+ SOME(emtpy_tuple),
+ SOME(empty_struct),
+FROM
+ as_table($data)
+GROUP BY
+ idx
+;
diff --git a/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_blocks-agg_singular_type_value_optional_/formatted.sql b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_blocks-agg_singular_type_value_optional_/formatted.sql
new file mode 100644
index 0000000000..258de29fb0
--- /dev/null
+++ b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_blocks-agg_singular_type_value_optional_/formatted.sql
@@ -0,0 +1,33 @@
+PRAGMA config.flags('PeepholeFlags', 'UseAggPhases');
+
+$n = 3;
+
+$data = ListMap(
+ ListFromRange(1, $n), ($x) -> (
+ <|
+ idx: $x,
+ empty_list: Just([]),
+ empty_dict: Just({}),
+ nil: Just(NULL),
+ val: $x + 5,
+ vid: Just(Void()),
+ emtpy_tuple: Just(AsTuple()),
+ empty_struct: Just(AsStruct())
+ |>
+ )
+);
+
+SELECT
+ idx,
+ SOME(empty_dict),
+ SOME(empty_list),
+ SOME(nil),
+ SOME(empty_dict),
+ SOME(vid),
+ SOME(emtpy_tuple),
+ SOME(empty_struct),
+FROM
+ as_table($data)
+GROUP BY
+ idx
+;
diff --git a/yql/essentials/tests/sql/suites/blocks/agg_singular_type_key.sql b/yql/essentials/tests/sql/suites/blocks/agg_singular_type_key.sql
new file mode 100644
index 0000000000..34c1f31962
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/blocks/agg_singular_type_key.sql
@@ -0,0 +1,23 @@
+PRAGMA config.flags('PeepholeFlags', 'UseAggPhases');
+
+$n = 3;
+$data = ListMap(ListFromRange(1, $n), ($x) -> (<|idx: $x,
+ empty_list: [],
+ empty_dict: {},
+ nil: NULL,
+ val: $x + 5,
+ vid: Void(),
+ emtpy_tuple: AsTuple(),
+ empty_struct: AsStruct()|>));
+
+SELECT empty_list, SOME(idx) FROM as_table($data) GROUP BY empty_list;
+
+SELECT empty_dict, SOME(idx) FROM as_table($data) GROUP BY empty_dict;
+
+SELECT nil, SOME(idx) FROM as_table($data) GROUP BY nil;
+
+SELECT vid, SOME(idx) FROM as_table($data) GROUP BY vid;
+
+SELECT emtpy_tuple, SOME(idx) FROM as_table($data) GROUP BY emtpy_tuple;
+
+SELECT empty_struct, SOME(idx) FROM as_table($data) GROUP BY empty_struct;
diff --git a/yql/essentials/tests/sql/suites/blocks/agg_singular_type_key_optional.sql b/yql/essentials/tests/sql/suites/blocks/agg_singular_type_key_optional.sql
new file mode 100644
index 0000000000..0b86e48184
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/blocks/agg_singular_type_key_optional.sql
@@ -0,0 +1,24 @@
+PRAGMA config.flags('PeepholeFlags', 'UseAggPhases');
+
+$n = 3;
+
+$data = ListMap(ListFromRange(1, $n), ($x) -> (<|idx: $x,
+ empty_list: Just([]),
+ empty_dict: Just({}),
+ nil: Just(NULL),
+ val: $x + 5,
+ vid: Just(Void()),
+ emtpy_tuple: Just(AsTuple()),
+ empty_struct: Just(AsStruct())|>));
+
+SELECT empty_list, SOME(idx) FROM as_table($data) GROUP BY empty_list;
+
+SELECT empty_dict, SOME(idx) FROM as_table($data) GROUP BY empty_dict;
+
+SELECT nil, SOME(idx) FROM as_table($data) GROUP BY nil;
+
+SELECT vid, SOME(idx) FROM as_table($data) GROUP BY vid;
+
+SELECT emtpy_tuple, SOME(idx) FROM as_table($data) GROUP BY emtpy_tuple;
+
+SELECT empty_struct, SOME(idx) FROM as_table($data) GROUP BY empty_struct;
diff --git a/yql/essentials/tests/sql/suites/blocks/agg_singular_type_value.sql b/yql/essentials/tests/sql/suites/blocks/agg_singular_type_value.sql
new file mode 100644
index 0000000000..ac290e2d25
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/blocks/agg_singular_type_value.sql
@@ -0,0 +1,26 @@
+PRAGMA config.flags('PeepholeFlags', 'UseAggPhases');
+
+$n = 3;
+$data = ListMap(ListFromRange(1, $n), ($x) -> (<|idx: $x,
+ empty_list: [],
+ empty_dict: {},
+ nil: NULL,
+ val: $x + 5,
+ vid: Void(),
+ emtpy_tuple: AsTuple(),
+ empty_struct: AsStruct()|>));
+
+SELECT
+ idx,
+ SOME(empty_dict),
+ SOME(empty_list),
+ SOME(nil),
+ SOME(empty_dict),
+ SOME(vid),
+ SOME(emtpy_tuple),
+ SOME(empty_struct),
+FROM
+ as_table($data)
+GROUP BY
+ idx
+;
diff --git a/yql/essentials/tests/sql/suites/blocks/agg_singular_type_value_optional.sql b/yql/essentials/tests/sql/suites/blocks/agg_singular_type_value_optional.sql
new file mode 100644
index 0000000000..3214db1049
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/blocks/agg_singular_type_value_optional.sql
@@ -0,0 +1,27 @@
+PRAGMA config.flags('PeepholeFlags', 'UseAggPhases');
+
+$n = 3;
+$data = ListMap(ListFromRange(1, $n), ($x) -> (<|idx: $x,
+ empty_list: Just([]),
+ empty_dict: Just({}),
+ nil: Just(NULL),
+ val: $x + 5,
+ vid: Just(Void()),
+ emtpy_tuple: Just(AsTuple()),
+ empty_struct: Just(AsStruct())|>));
+
+SELECT
+ idx,
+ SOME(empty_dict),
+ SOME(empty_list),
+ SOME(nil),
+ SOME(empty_dict),
+ SOME(vid),
+ SOME(emtpy_tuple),
+ SOME(empty_struct),
+FROM
+ as_table($data)
+GROUP BY
+ idx
+;
+
diff --git a/yql/essentials/types/binary_json/ut/entry_ut.cpp b/yql/essentials/types/binary_json/ut/entry_ut.cpp
index 0f099ed59d..247fc5034c 100644
--- a/yql/essentials/types/binary_json/ut/entry_ut.cpp
+++ b/yql/essentials/types/binary_json/ut/entry_ut.cpp
@@ -17,6 +17,7 @@ public:
UNIT_TEST(TestGetContainer);
UNIT_TEST(TestGetString);
UNIT_TEST(TestGetNumber);
+ UNIT_TEST(TestOutOfBounds);
UNIT_TEST_SUITE_END();
void TestGetType() {
@@ -93,6 +94,28 @@ public:
UNIT_ASSERT_VALUES_EQUAL(container.GetElement(0).GetNumber(), testCase.second);
}
}
+
+ void TestOutOfBounds() {
+ const TVector<std::pair<TString, double>> testCases = {
+ { "1e100000000", std::numeric_limits<double>::infinity() },
+ { "-1e100000000", -std::numeric_limits<double>::infinity() },
+ { "1.797693135e+308", std::numeric_limits<double>::infinity() },
+ { "-1.797693135e+308", -std::numeric_limits<double>::infinity() },
+ };
+
+ for (const auto& testCase : testCases) {
+ UNIT_ASSERT(std::holds_alternative<TString>(SerializeToBinaryJson(testCase.first)));
+ }
+
+ for (const auto& testCase : testCases) {
+ const auto binaryJson = std::get<TBinaryJson>(SerializeToBinaryJson(testCase.first, true));
+ const auto reader = TBinaryJsonReader::Make(binaryJson);
+ const auto container = reader->GetRootCursor();
+
+ UNIT_ASSERT_VALUES_EQUAL(container.GetElement(0).GetNumber(), testCase.second);
+ }
+ }
};
UNIT_TEST_SUITE_REGISTRATION(TBinaryJsonEntryTest);
+
diff --git a/yql/essentials/types/binary_json/write.cpp b/yql/essentials/types/binary_json/write.cpp
index 28dffea9db..39cd05949d 100644
--- a/yql/essentials/types/binary_json/write.cpp
+++ b/yql/essentials/types/binary_json/write.cpp
@@ -13,6 +13,8 @@
#include <util/generic/set.h>
#include <util/generic/stack.h>
#include <util/generic/vector.h>
+#include <yql/essentials/minikql/dom/node.h>
+#include <yql/essentials/utils/parse_double.h>
#include <cmath>
@@ -415,9 +417,8 @@ private:
*/
class TBinaryJsonCallbacks : public TJsonCallbacks {
public:
- TBinaryJsonCallbacks(bool throwException)
- : TJsonCallbacks(/* throwException */ throwException)
- {
+ TBinaryJsonCallbacks(bool throwException, bool allowInf)
+ : TJsonCallbacks(/* throwException */ throwException), AllowInf(allowInf) {
}
bool OnNull() override {
@@ -445,7 +446,7 @@ public:
}
bool OnDouble(double value) override {
- if (Y_UNLIKELY(std::isinf(value))) {
+ if (Y_UNLIKELY(std::isinf(value) && !AllowInf)) {
if (ThrowException) {
ythrow yexception() << "JSON number is infinite";
} else {
@@ -492,6 +493,7 @@ public:
private:
TJsonIndex Json;
+ bool AllowInf;
};
void DomToJsonIndex(const NUdf::TUnboxedValue& value, TBinaryJsonCallbacks& callbacks) {
@@ -573,8 +575,14 @@ template <typename TOnDemandValue>
switch (value.get_number_type()) {
case simdjson::builtin::number_type::floating_point_number: {
double v;
- RETURN_IF_NOT_SUCCESS(value.get(v));
- callbacks.OnDouble(v);
+ if (const auto& error = value.get(v); Y_UNLIKELY(error != simdjson::SUCCESS)) {
+ if (!NYql::TryDoubleFromString((std::string_view)value.raw_json_token(), v)) {
+ return error;
+ }
+ };
+ if (Y_UNLIKELY(!callbacks.OnDouble(v))) {
+ return simdjson::error_code::NUMBER_ERROR;
+ }
break;
}
case simdjson::builtin::number_type::signed_integer: {
@@ -592,7 +600,9 @@ template <typename TOnDemandValue>
case simdjson::builtin::number_type::big_integer:
double v;
RETURN_IF_NOT_SUCCESS(value.get(v));
- callbacks.OnDouble(v);
+ if (Y_UNLIKELY(!callbacks.OnDouble(v))) {
+ return simdjson::error_code::NUMBER_ERROR;
+ }
break;
}
break;
@@ -600,7 +610,7 @@ template <typename TOnDemandValue>
case simdjson::ondemand::json_type::null: {
auto is_null = value.is_null();
RETURN_IF_NOT_SUCCESS(is_null.error());
- if (Y_UNLIKELY(!is_null.value_unsafe())) {
+ if (Y_UNLIKELY(!is_null.value_unsafe())) {
return simdjson::error_code::N_ATOM_ERROR;
}
callbacks.OnNull();
@@ -644,7 +654,7 @@ template <typename TOnDemandValue>
}
// unused, left for performance comparison
-[[maybe_unused]] [[nodiscard]] simdjson::error_code SimdJsonToJsonIndexImpl(const simdjson::dom::element& value, TBinaryJsonCallbacks& callbacks) {
+[[nodiscard]] [[maybe_unused]] simdjson::error_code SimdJsonToJsonIndexImpl(const simdjson::dom::element& value, TBinaryJsonCallbacks& callbacks) {
#define RETURN_IF_NOT_SUCCESS(status) \
if (Y_UNLIKELY(status != simdjson::SUCCESS)) { \
return status; \
@@ -715,9 +725,9 @@ template <typename TOnDemandValue>
}
}
-std::variant<TBinaryJson, TString> SerializeToBinaryJsonImpl(const TStringBuf json) {
+std::variant<TBinaryJson, TString> SerializeToBinaryJsonImpl(const TStringBuf json, bool allowInf) {
std::variant<TBinaryJson, TString> res;
- TBinaryJsonCallbacks callbacks(/* throwException */ false);
+ TBinaryJsonCallbacks callbacks(/* throwException */ false, allowInf);
const simdjson::padded_string paddedJson(json);
simdjson::ondemand::parser parser;
try {
@@ -739,15 +749,16 @@ std::variant<TBinaryJson, TString> SerializeToBinaryJsonImpl(const TStringBuf js
return res;
}
-std::variant<TBinaryJson, TString> SerializeToBinaryJson(const TStringBuf json) {
- return SerializeToBinaryJsonImpl(json);
+std::variant<TBinaryJson, TString> SerializeToBinaryJson(const TStringBuf json, bool allowInf) {
+ return SerializeToBinaryJsonImpl(json, allowInf);
}
TBinaryJson SerializeToBinaryJson(const NUdf::TUnboxedValue& value) {
- TBinaryJsonCallbacks callbacks(/* throwException */ false);
+ TBinaryJsonCallbacks callbacks(/* throwException */ false, /* allowInf */ false);
DomToJsonIndex(value, callbacks);
TBinaryJsonSerializer serializer(std::move(callbacks).GetResult());
return std::move(serializer).Serialize();
}
}
+
diff --git a/yql/essentials/types/binary_json/write.h b/yql/essentials/types/binary_json/write.h
index c4f8f89d2d..61dea9bfb4 100644
--- a/yql/essentials/types/binary_json/write.h
+++ b/yql/essentials/types/binary_json/write.h
@@ -2,23 +2,24 @@
#include "format.h"
-#include <yql/essentials/minikql/dom/node.h>
-
#include <util/generic/maybe.h>
#include <variant>
+namespace NYql::NUdf {
+class TUnboxedValue;
+};
+
namespace NKikimr::NBinaryJson {
/**
* @brief Translates textual JSON into BinaryJson
*/
-std::variant<TBinaryJson, TString> SerializeToBinaryJson(const TStringBuf json);
+std::variant<TBinaryJson, TString> SerializeToBinaryJson(const TStringBuf json, bool allowInf = false);
/**
* @brief Translates DOM layout from `yql/library/dom` library into BinaryJson
*/
-TBinaryJson SerializeToBinaryJson(const NUdf::TUnboxedValue& value);
-
+TBinaryJson SerializeToBinaryJson(const NYql::NUdf::TUnboxedValue& value);
}
diff --git a/yql/essentials/udfs/language/yql/yql_language_udf.cpp b/yql/essentials/udfs/language/yql/yql_language_udf.cpp
index 356ecfade3..ab1090a108 100644
--- a/yql/essentials/udfs/language/yql/yql_language_udf.cpp
+++ b/yql/essentials/udfs/language/yql/yql_language_udf.cpp
@@ -1,10 +1,13 @@
#include <yql/essentials/public/udf/udf_helpers.h>
+#include <yql/essentials/sql/v1/context.h>
+#include <yql/essentials/sql/v1/sql_translation.h>
#include <yql/essentials/sql/v1/lexer/antlr4/lexer.h>
#include <yql/essentials/sql/v1/lexer/antlr4_ansi/lexer.h>
#include <yql/essentials/sql/v1/proto_parser/proto_parser.h>
#include <yql/essentials/sql/v1/proto_parser/antlr4/proto_parser.h>
#include <yql/essentials/sql/v1/proto_parser/antlr4_ansi/proto_parser.h>
+#include <yql/essentials/parser/proto_ast/gen/v1_proto_split/SQLv1Parser.pb.main.h>
#include <yql/essentials/sql/v1/format/sql_format.h>
#include <yql/essentials/sql/settings/translation_settings.h>
#include <library/cpp/protobuf/util/simple_reflection.h>
@@ -12,18 +15,34 @@
using namespace NYql;
using namespace NKikimr::NUdf;
using namespace NSQLTranslation;
+using namespace NSQLTranslationV1;
+using namespace NSQLv1Generated;
+
+class TRuleFreqTranslation : public TSqlTranslation
+{
+public:
+ TRuleFreqTranslation(TContext& ctx)
+ : TSqlTranslation(ctx, ctx.Settings.Mode)
+ {}
+};
class TRuleFreqVisitor {
public:
- TRuleFreqVisitor() {
+ TRuleFreqVisitor(TContext& ctx)
+ : Translation(ctx)
+ {
}
void Visit(const NProtoBuf::Message& msg) {
const NProtoBuf::Descriptor* descr = msg.GetDescriptor();
- if (descr->name() == "TToken") {
+ if (descr == TToken::GetDescriptor()) {
return;
}
+ if (descr == TRule_use_stmt::GetDescriptor()) {
+ VisitUseStmt(dynamic_cast<const TRule_use_stmt&>(msg));
+ }
+
TStringBuf fullName = descr->full_name();
fullName.SkipPrefix("NSQLv1Generated.");
for (int i = 0; i < descr->field_count(); ++i) {
@@ -51,6 +70,17 @@ public:
}
private:
+ void VisitUseStmt(const TRule_use_stmt& msg) {
+ const auto& cluster = msg.GetRule_cluster_expr2();
+ if (cluster.GetBlock2().Alt_case() == TRule_cluster_expr::TBlock2::kAlt1) {
+ const auto& val = cluster.GetBlock2().GetAlt1().GetRule_pure_column_or_named1();
+ if (val.Alt_case() == TRule_pure_column_or_named::kAltPureColumnOrNamed2) {
+ const auto& id = val.GetAlt_pure_column_or_named2().GetRule_an_id1();
+ Freqs[std::make_pair("USE", Id(id, Translation))] += 1;
+ }
+ }
+ }
+
void VisitAllFields(const NProtoBuf::Message& msg, const NProtoBuf::Descriptor* descr) {
for (int i = 0; i < descr->field_count(); ++i) {
const NProtoBuf::FieldDescriptor* fd = descr->field(i);
@@ -64,6 +94,7 @@ private:
}
THashMap<std::pair<TString, TString>, ui64> Freqs;
+ TRuleFreqTranslation Translation;
};
SIMPLE_UDF(TObfuscate, TOptional<char*>(TAutoMap<char*>)) {
@@ -125,7 +156,8 @@ SIMPLE_UDF(TRuleFreq, TOptional<TRuleFreqResult>(TAutoMap<char*>)) {
return {};
}
- TRuleFreqVisitor visitor;
+ TContext ctx(lexers, parsers, settings, {}, issues, query);
+ TRuleFreqVisitor visitor(ctx);
visitor.Visit(*msg);
auto listBuilder = valueBuilder->NewListBuilder();
diff --git a/yt/yql/providers/yt/codec/yt_arrow_converter.cpp b/yt/yql/providers/yt/codec/yt_arrow_converter.cpp
index 7d85493324..29bfc40ad9 100644
--- a/yt/yql/providers/yt/codec/yt_arrow_converter.cpp
+++ b/yt/yql/providers/yt/codec/yt_arrow_converter.cpp
@@ -471,6 +471,10 @@ struct TComplexTypeYsonReaderTraits {
ythrow yexception() << "Complex type Yson reader not implemented for block resources";
}
+ static std::unique_ptr<TResult> MakeSingular() {
+ ythrow yexception() << "Complex type Yson reader not implemented for singular types.";
+ }
+
template<typename TTzDate>
static std::unique_ptr<TResult> MakeTzDate(bool isOptional) {
if (isOptional) {
diff --git a/yt/yql/providers/yt/gateway/qplayer/yql_yt_qplayer_gateway.cpp b/yt/yql/providers/yt/gateway/qplayer/yql_yt_qplayer_gateway.cpp
index 3a9bd3272b..f1f70ad43b 100644
--- a/yt/yql/providers/yt/gateway/qplayer/yql_yt_qplayer_gateway.cpp
+++ b/yt/yql/providers/yt/gateway/qplayer/yql_yt_qplayer_gateway.cpp
@@ -247,7 +247,7 @@ public:
}
}
}
- data.WriteLock = options.ReadOnly() ? false : valueNode["WriteLock"].AsBool();
+ data.WriteLock = valueNode["WriteLock"].AsBool();
res.Data.push_back(data);
}
diff --git a/yt/yt/client/table_client/config.cpp b/yt/yt/client/table_client/config.cpp
index b8bb96c164..64f4502e08 100644
--- a/yt/yt/client/table_client/config.cpp
+++ b/yt/yt/client/table_client/config.cpp
@@ -153,6 +153,9 @@ void TChunkWriterConfig::Register(TRegistrar registrar)
.InRange(0.0, 0.001)
.Default(0.0001);
+ registrar.Parameter("use_original_data_weight_in_samples", &TThis::UseOriginalDataWeightInSamples)
+ .Default(false);
+
registrar.Parameter("chunk_indexes", &TThis::ChunkIndexes)
.DefaultNew();
diff --git a/yt/yt/client/table_client/config.h b/yt/yt/client/table_client/config.h
index fa096afa53..0b1c970012 100644
--- a/yt/yt/client/table_client/config.h
+++ b/yt/yt/client/table_client/config.h
@@ -148,6 +148,7 @@ struct TChunkWriterConfig
i64 MaxDataWeightBetweenBlocks;
double SampleRate;
+ bool UseOriginalDataWeightInSamples;
bool EnableLargeColumnarStatistics;
diff --git a/yt/yt/client/table_client/helpers.cpp b/yt/yt/client/table_client/helpers.cpp
index 857893c458..b2ef61558f 100644
--- a/yt/yt/client/table_client/helpers.cpp
+++ b/yt/yt/client/table_client/helpers.cpp
@@ -1607,13 +1607,16 @@ TUnversionedValueRangeTruncationResult TruncateUnversionedValues(
std::vector<TUnversionedValue> truncatedValues;
truncatedValues.reserve(values.size());
+ i64 inputSize = 0;
int truncatableValueCount = 0;
i64 remainingSize = options.MaxTotalSize;
for (const auto& value : values) {
+ auto valueSize = EstimateRowValueSize(value);
+ inputSize += valueSize;
if (IsStringLikeType(value.Type)) {
++truncatableValueCount;
} else {
- remainingSize -= EstimateRowValueSize(value);
+ remainingSize -= valueSize;
}
}
@@ -1656,7 +1659,9 @@ TUnversionedValueRangeTruncationResult TruncateUnversionedValues(
}
}
- return {MakeSharedRange(std::move(truncatedValues), rowBuffer), resultSize, clipped};
+ auto sampleSize = options.UseOriginalDataWeightInSamples ? inputSize : resultSize;
+
+ return {MakeSharedRange(std::move(truncatedValues), rowBuffer), sampleSize, clipped};
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/yt/yt/client/table_client/helpers.h b/yt/yt/client/table_client/helpers.h
index 36bbff3498..3b85e1edfb 100644
--- a/yt/yt/client/table_client/helpers.h
+++ b/yt/yt/client/table_client/helpers.h
@@ -377,6 +377,7 @@ struct TUnversionedValueRangeTruncationOptions
//! Otherwise, all values of primitive (not string-like) types are preserved and the remaining size
//! is uniformely distributed between truncated versions of the remaining string-like values.
bool ClipAfterOverflow = false;
+ bool UseOriginalDataWeightInSamples = false;
//! Limits the total size of the resulting value range.
//! See value-preservation rules described above.
i64 MaxTotalSize = NTableClient::MaxSampleSize;
diff --git a/yt/yt/core/concurrency/fair_throttler.cpp b/yt/yt/core/concurrency/fair_throttler.cpp
index 3899c949e7..9a5cf3c697 100644
--- a/yt/yt/core/concurrency/fair_throttler.cpp
+++ b/yt/yt/core/concurrency/fair_throttler.cpp
@@ -35,7 +35,7 @@ void TFairThrottlerConfig::Register(TRegistrar registrar)
registrar.Parameter("global_accumulation_ticks", &TThis::GlobalAccumulationTicks)
.Default(5);
- registrar.Parameter("ipc_path", &TThis::IPCPath)
+ registrar.Parameter("ipc_path", &TThis::IpcPath)
.Default();
}
@@ -95,27 +95,27 @@ static constexpr TStringBuf BucketsFileName = "buckets.v1";
////////////////////////////////////////////////////////////////////////////////
-class TFileIPCBucket
- : public IIPCBucket
+class TFileIpcBucket
+ : public IIpcBucket
{
public:
- TFileIPCBucket(const TString& path, bool create)
+ TFileIpcBucket(const TString& path, bool create)
: File_(path, OpenAlways | RdWr)
{
if (create) {
File_.Flock(LOCK_EX | LOCK_NB);
}
- File_.Resize(sizeof(TBucket));
+ File_.Resize(sizeof(TState));
Map_ = std::make_unique<TFileMap>(File_, TMemoryMapCommon::oRdWr);
Map_->Map(0, Map_->Length());
LockMemory(Map_->Ptr(), Map_->Length());
}
- TBucket* State() override
+ TState* GetState() override
{
- return reinterpret_cast<TBucket*>(Map_->Ptr());
+ return reinterpret_cast<TState*>(Map_->Ptr());
}
private:
@@ -123,15 +123,15 @@ private:
std::unique_ptr<TFileMap> Map_;
};
-DEFINE_REFCOUNTED_TYPE(TFileIPCBucket)
+DEFINE_REFCOUNTED_TYPE(TFileIpcBucket)
////////////////////////////////////////////////////////////////////////////////
-class TFileThrottlerIPC
- : public IThrottlerIPC
+class TFileThrottlerIpc
+ : public IThrottlerIpc
{
public:
- explicit TFileThrottlerIPC(const TString& path)
+ explicit TFileThrottlerIpc(const TString& path)
: Path_(path)
{
NFS::MakeDirRecursive(Path_);
@@ -166,7 +166,7 @@ public:
return reinterpret_cast<TSharedBucket*>(SharedBucketMap_->Ptr());
}
- std::vector<IIPCBucketPtr> ListBuckets() override
+ std::vector<IIpcBucketPtr> ListBuckets() override
{
Lock_->Acquire();
auto release = Finally([this] {
@@ -175,14 +175,14 @@ public:
Reload();
- std::vector<IIPCBucketPtr> buckets;
+ std::vector<IIpcBucketPtr> buckets;
for (const auto& bucket : OpenBuckets_) {
buckets.push_back(bucket.second);
}
return buckets;
}
- IIPCBucketPtr AddBucket() override
+ IIpcBucketPtr AddBucket() override
{
Lock_->Acquire();
auto release = Finally([this] {
@@ -191,7 +191,7 @@ public:
auto id = TGuid::Create();
OwnedBuckets_.insert(ToString(id));
- return New<TFileIPCBucket>(Path_ + "/" + BucketsFileName + "/" + ToString(id), true);
+ return New<TFileIpcBucket>(Path_ + "/" + BucketsFileName + "/" + ToString(id), true);
}
private:
@@ -202,8 +202,8 @@ private:
TFile SharedBucketFile_;
std::unique_ptr<TFileMap> SharedBucketMap_;
- THashMap<TString, IIPCBucketPtr> OpenBuckets_;
- THashSet<TString> OwnedBuckets_;
+ THashMap<std::string, IIpcBucketPtr> OpenBuckets_;
+ THashSet<std::string> OwnedBuckets_;
void Reload()
{
@@ -230,7 +230,7 @@ private:
continue;
}
- OpenBuckets_[fileName] = New<TFileIPCBucket>(bucketPath, false);
+ OpenBuckets_[fileName] = New<TFileIpcBucket>(bucketPath, false);
} catch (const TSystemError& ex) {
continue;
}
@@ -238,12 +238,12 @@ private:
}
};
-IThrottlerIPCPtr CreateFileThrottlerIPC(const TString& path)
+IThrottlerIpcPtr CreateFileThrottlerIpc(const TString& path)
{
- return New<TFileThrottlerIPC>(path);
+ return New<TFileThrottlerIpc>(path);
}
-DEFINE_REFCOUNTED_TYPE(TFileThrottlerIPC)
+DEFINE_REFCOUNTED_TYPE(TFileThrottlerIpc)
////////////////////////////////////////////////////////////////////////////////
@@ -623,12 +623,12 @@ TFairThrottler::TFairThrottler(
, SharedBucket_(New<TSharedBucket>(config->GlobalAccumulationTicks, Profiler_))
, Config_(std::move(config))
{
- if (Config_->IPCPath) {
- IPC_ = New<TFileThrottlerIPC>(*Config_->IPCPath);
+ if (Config_->IpcPath) {
+ Ipc_ = New<TFileThrottlerIpc>(*Config_->IpcPath);
SharedBucket_->Limit.Value = std::shared_ptr<std::atomic<i64>>(
- &IPC_->State()->Value,
- [ipc = IPC_] (auto /*ptr*/) { });
+ &Ipc_->State()->Value,
+ [state = Ipc_] (auto /*ptr*/) { });
Profiler_.AddFuncGauge("/leader", MakeStrong(this), [this] {
return IsLeader_.load();
@@ -646,7 +646,7 @@ TFairThrottler::TFairThrottler(
}
IThroughputThrottlerPtr TFairThrottler::CreateBucketThrottler(
- const TString& name,
+ const std::string& name,
TFairThrottlerBucketConfigPtr config)
{
if (!config) {
@@ -670,15 +670,15 @@ IThroughputThrottlerPtr TFairThrottler::CreateBucketThrottler(
throttler->SetLimited(config->Limit || config->RelativeLimit);
- IIPCBucketPtr ipc;
- if (IPC_) {
- ipc = IPC_->AddBucket();
+ IIpcBucketPtr state;
+ if (Ipc_) {
+ state = Ipc_->AddBucket();
}
Buckets_[name] = TBucket{
.Config = std::move(config),
.Throttler = throttler,
- .IPC = ipc,
+ .Ipc = state,
};
return throttler;
@@ -686,7 +686,7 @@ IThroughputThrottlerPtr TFairThrottler::CreateBucketThrottler(
void TFairThrottler::Reconfigure(
TFairThrottlerConfigPtr config,
- const THashMap<TString, TFairThrottlerBucketConfigPtr>& buckets)
+ const THashMap<std::string, TFairThrottlerBucketConfigPtr>& buckets)
{
for (const auto& [name, config] : buckets) {
CreateBucketThrottler(name, config);
@@ -712,7 +712,7 @@ void TFairThrottler::DoUpdateLeader()
std::vector<TBucketThrottler::TBucketState> states;
states.reserve(Buckets_.size());
- THashMap<TString, i64> bucketDemands;
+ THashMap<std::string, i64> bucketDemands;
for (const auto& [name, bucket] : Buckets_) {
auto state = bucket.Throttler->Peek();
@@ -736,12 +736,12 @@ void TFairThrottler::DoUpdateLeader()
states.push_back(state);
}
- std::vector<IIPCBucketPtr> remoteBuckets;
- if (IPC_) {
- remoteBuckets = IPC_->ListBuckets();
+ std::vector<IIpcBucketPtr> remoteBuckets;
+ if (Ipc_) {
+ remoteBuckets = Ipc_->ListBuckets();
for (const auto& remote : remoteBuckets) {
- auto state = remote->State();
+ auto state = remote->GetState();
weights.push_back(state->Weight.load());
@@ -771,9 +771,9 @@ void TFairThrottler::DoUpdateLeader()
}
auto freeIncome = ComputeFairDistribution(freeQuota, weights, demands, limits);
- THashMap<TString, i64> bucketUsage;
- THashMap<TString, i64> bucketIncome;
- THashMap<TString, i64> bucketQuota;
+ THashMap<std::string, i64> bucketUsage;
+ THashMap<std::string, i64> bucketIncome;
+ THashMap<std::string, i64> bucketQuota;
i64 leakedQuota = 0;
int i = 0;
@@ -792,7 +792,7 @@ void TFairThrottler::DoUpdateLeader()
}
for (const auto& remote : remoteBuckets) {
- auto state = remote->State();
+ auto state = remote->GetState();
state->InFlow += tickIncome[i] + freeIncome[i];
@@ -828,41 +828,41 @@ void TFairThrottler::DoUpdateFollower()
{
auto guard = Guard(Lock_);
- THashMap<TString, i64> bucketIncome;
- THashMap<TString, i64> bucketUsage;
- THashMap<TString, i64> bucketDemands;
- THashMap<TString, i64> bucketQuota;
+ THashMap<std::string, i64> bucketIncome;
+ THashMap<std::string, i64> bucketUsage;
+ THashMap<std::string, i64> bucketDemands;
+ THashMap<std::string, i64> bucketQuota;
i64 inFlow = 0;
i64 outFlow = 0;
for (const auto& [name, bucket] : Buckets_) {
- auto ipc = bucket.IPC->State();
+ auto* ipcState = bucket.Ipc->GetState();
- ipc->Weight = bucket.Config->Weight;
+ ipcState->Weight = bucket.Config->Weight;
if (auto limit = bucket.Config->GetLimit(Config_->TotalLimit)) {
- ipc->Limit = *limit;
+ ipcState->Limit = *limit;
} else {
- ipc->Limit = -1;
+ ipcState->Limit = -1;
}
- auto state = bucket.Throttler->Peek();
+ auto bucketState = bucket.Throttler->Peek();
auto guarantee = bucket.Config->GetGuarantee(Config_->TotalLimit);
- auto demand = state.Usage + state.Overdraft + state.QueueSize;
+ auto demand = bucketState.Usage + bucketState.Overdraft + bucketState.QueueSize;
if (guarantee && *guarantee > demand) {
demand = *guarantee;
}
- ipc->Demand = demand;
+ ipcState->Demand = demand;
bucketDemands[name] = demand;
- auto in = ipc->InFlow.exchange(0);
- auto out = bucket.Throttler->Refill(in, ipc->GuaranteedQuota);
- ipc->OutFlow += out;
+ auto in = ipcState->InFlow.exchange(0);
+ auto out = bucket.Throttler->Refill(in, ipcState->GuaranteedQuota);
+ ipcState->OutFlow += out;
bucketIncome[name] = in;
- bucketUsage[name] = state.Usage;
- bucketQuota[name] = state.Quota;
+ bucketUsage[name] = bucketState.Usage;
+ bucketQuota[name] = bucketState.Quota;
inFlow += in;
outFlow += out;
@@ -906,7 +906,7 @@ void TFairThrottler::RefillFromSharedBucket()
void TFairThrottler::UpdateLimits(TInstant at)
{
- if (!IsLeader_ && IPC_->TryLock()) {
+ if (!IsLeader_ && Ipc_->TryLock()) {
IsLeader_ = true;
YT_LOG_DEBUG("Throttler is leader");
diff --git a/yt/yt/core/concurrency/fair_throttler.h b/yt/yt/core/concurrency/fair_throttler.h
index ecf32ae14b..801ffaef6f 100644
--- a/yt/yt/core/concurrency/fair_throttler.h
+++ b/yt/yt/core/concurrency/fair_throttler.h
@@ -19,7 +19,7 @@ struct TFairThrottlerConfig
int GlobalAccumulationTicks;
- std::optional<TString> IPCPath;
+ std::optional<TString> IpcPath;
REGISTER_YSON_STRUCT(TFairThrottlerConfig);
@@ -52,11 +52,11 @@ DEFINE_REFCOUNTED_TYPE(TFairThrottlerBucketConfig)
////////////////////////////////////////////////////////////////////////////////
-struct IIPCBucket
+struct IIpcBucket
: public TRefCounted
{
// NB: This struct is shared between processes. All changes must be backward compatible.
- struct TBucket
+ struct TState
{
std::atomic<double> Weight;
std::atomic<i64> Limit;
@@ -66,14 +66,14 @@ struct IIPCBucket
std::atomic<i64> GuaranteedQuota;
};
- virtual TBucket* State() = 0;
+ virtual TState* GetState() = 0;
};
-DEFINE_REFCOUNTED_TYPE(IIPCBucket)
+DEFINE_REFCOUNTED_TYPE(IIpcBucket)
////////////////////////////////////////////////////////////////////////////////
-struct IThrottlerIPC
+struct IThrottlerIpc
: public TRefCounted
{
// NB: This struct is shared between processes. All changes must be backward compatible.
@@ -84,13 +84,13 @@ struct IThrottlerIPC
virtual bool TryLock() = 0;
virtual TSharedBucket* State() = 0;
- virtual std::vector<IIPCBucketPtr> ListBuckets() = 0;
- virtual IIPCBucketPtr AddBucket() = 0;
+ virtual std::vector<IIpcBucketPtr> ListBuckets() = 0;
+ virtual IIpcBucketPtr AddBucket() = 0;
};
-IThrottlerIPCPtr CreateFileThrottlerIPC(const TString& path);
+IThrottlerIpcPtr CreateFileThrottlerIpc(const TString& path);
-DEFINE_REFCOUNTED_TYPE(IThrottlerIPC)
+DEFINE_REFCOUNTED_TYPE(IThrottlerIpc)
////////////////////////////////////////////////////////////////////////////////
@@ -116,12 +116,12 @@ public:
NProfiling::TProfiler profiler);
IThroughputThrottlerPtr CreateBucketThrottler(
- const TString& name,
+ const std::string& name,
TFairThrottlerBucketConfigPtr config);
void Reconfigure(
TFairThrottlerConfigPtr config,
- const THashMap<TString, TFairThrottlerBucketConfigPtr>& bucketConfigs);
+ const THashMap<std::string, TFairThrottlerBucketConfigPtr>& bucketConfigs);
static std::vector<i64> ComputeFairDistribution(
i64 totalLimit,
@@ -140,15 +140,15 @@ private:
{
TFairThrottlerBucketConfigPtr Config;
TBucketThrottlerPtr Throttler;
- IIPCBucketPtr IPC;
+ IIpcBucketPtr Ipc;
};
// Protects all Config_ and Buckets_.
YT_DECLARE_SPIN_LOCK(NThreading::TSpinLock, Lock_);
TFairThrottlerConfigPtr Config_;
- THashMap<TString, TBucket> Buckets_;
+ THashMap<std::string, TBucket> Buckets_;
- IThrottlerIPCPtr IPC_;
+ IThrottlerIpcPtr Ipc_;
void DoUpdateLeader();
void DoUpdateFollower();
diff --git a/yt/yt/core/concurrency/public.h b/yt/yt/core/concurrency/public.h
index 10ffdda916..4b547a74fc 100644
--- a/yt/yt/core/concurrency/public.h
+++ b/yt/yt/core/concurrency/public.h
@@ -120,8 +120,8 @@ DECLARE_REFCOUNTED_STRUCT(TFiberManagerDynamicConfig)
DECLARE_REFCOUNTED_STRUCT(TFairThrottlerConfig)
DECLARE_REFCOUNTED_STRUCT(TFairThrottlerBucketConfig)
-DECLARE_REFCOUNTED_STRUCT(IThrottlerIPC)
-DECLARE_REFCOUNTED_STRUCT(IIPCBucket)
+DECLARE_REFCOUNTED_STRUCT(IThrottlerIpc)
+DECLARE_REFCOUNTED_STRUCT(IIpcBucket)
DECLARE_REFCOUNTED_CLASS(TFairThrottler)
DECLARE_REFCOUNTED_CLASS(TBucketThrottler)
diff --git a/yt/yt/core/concurrency/unittests/fair_throttler_ut.cpp b/yt/yt/core/concurrency/unittests/fair_throttler_ut.cpp
index 41ee845af7..2a6528bd31 100644
--- a/yt/yt/core/concurrency/unittests/fair_throttler_ut.cpp
+++ b/yt/yt/core/concurrency/unittests/fair_throttler_ut.cpp
@@ -274,7 +274,7 @@ TEST_F(TFairThrottlerTest, Release)
////////////////////////////////////////////////////////////////////////////////
-struct TFairThrottlerIPCTest
+struct TFairThrottlerIpcTest
: public ::testing::Test
{
TFairThrottlerConfigPtr Config = New<TFairThrottlerConfig>();
@@ -282,11 +282,11 @@ struct TFairThrottlerIPCTest
TFairThrottlerPtr DatNode, ExeNode;
- TFairThrottlerIPCTest()
+ TFairThrottlerIpcTest()
{
- TString testName = ::testing::UnitTest::GetInstance()->current_test_info()->name();
+ std::string testName = ::testing::UnitTest::GetInstance()->current_test_info()->name();
- Config->IPCPath = GetOutputPath() / (testName + ".throttler");
+ Config->IpcPath = GetOutputPath() / (testName + ".throttler");
Config->TotalLimit = 100;
auto logger = Logger().WithTag("Test: %v", testName);
@@ -296,7 +296,7 @@ struct TFairThrottlerIPCTest
}
};
-TEST_F(TFairThrottlerIPCTest, TwoBucket)
+TEST_F(TFairThrottlerIpcTest, TwoBucket)
{
auto first = DatNode->CreateBucketThrottler("first", BucketConfig);
auto second = ExeNode->CreateBucketThrottler("second", BucketConfig);
@@ -322,12 +322,12 @@ TEST_F(TFairThrottlerIPCTest, TwoBucket)
////////////////////////////////////////////////////////////////////////////////
#ifndef _win_
-TEST(TFileIPC, Test)
+TEST(TFileIpcTest, Test)
{
auto path = GetOutputPath() / "test_ipc";
- auto a = CreateFileThrottlerIPC(path);
- auto b = CreateFileThrottlerIPC(path);
+ auto a = CreateFileThrottlerIpc(path);
+ auto b = CreateFileThrottlerIpc(path);
ASSERT_TRUE(a->TryLock());
ASSERT_FALSE(b->TryLock());
diff --git a/yt/yt/core/http/server.cpp b/yt/yt/core/http/server.cpp
index d2fda153b5..43ca58c795 100644
--- a/yt/yt/core/http/server.cpp
+++ b/yt/yt/core/http/server.cpp
@@ -12,6 +12,7 @@
#include <yt/yt/core/concurrency/thread_pool_poller.h>
#include <yt/yt/core/misc/finally.h>
+#include <yt/yt/core/misc/memory_usage_tracker.h>
#include <yt/yt/core/misc/public.h>
#include <yt/yt/core/ytree/convert.h>
@@ -62,6 +63,7 @@ public:
IPollerPtr poller,
IPollerPtr acceptor,
IInvokerPtr invoker,
+ IMemoryUsageTrackerPtr memoryUsageTracker,
IRequestPathMatcherPtr requestPathMatcher,
bool ownPoller = false)
: Config_(std::move(config))
@@ -69,6 +71,7 @@ public:
, Poller_(std::move(poller))
, Acceptor_(std::move(acceptor))
, Invoker_(std::move(invoker))
+ , MemoryUsageTracker_(std::move(memoryUsageTracker))
, OwnPoller_(ownPoller)
, RequestPathMatcher_(std::move(requestPathMatcher))
{ }
@@ -123,6 +126,7 @@ private:
const IPollerPtr Poller_;
const IPollerPtr Acceptor_;
const IInvokerPtr Invoker_;
+ const IMemoryUsageTrackerPtr MemoryUsageTracker_;
const bool OwnPoller_ = false;
IRequestPathMatcherPtr RequestPathMatcher_;
@@ -291,7 +295,8 @@ private:
connection->GetRemoteAddress(),
GetCurrentInvoker(),
EMessageType::Request,
- Config_);
+ Config_,
+ MemoryUsageTracker_);
if (Config_->IsHttps) {
request->SetHttps();
@@ -302,7 +307,8 @@ private:
auto response = New<THttpOutput>(
connection,
EMessageType::Response,
- Config_);
+ Config_,
+ MemoryUsageTracker_);
while (true) {
auto requestId = TRequestId::Create();
@@ -381,6 +387,7 @@ IServerPtr CreateServer(
IPollerPtr poller,
IPollerPtr acceptor,
IInvokerPtr invoker,
+ IMemoryUsageTrackerPtr memoryUsageTracker,
bool ownPoller)
{
auto handlers = New<TRequestPathMatcher>();
@@ -390,6 +397,7 @@ IServerPtr CreateServer(
std::move(poller),
std::move(acceptor),
std::move(invoker),
+ std::move(memoryUsageTracker),
std::move(handlers),
ownPoller);
}
@@ -399,19 +407,15 @@ IServerPtr CreateServer(
IPollerPtr poller,
IPollerPtr acceptor,
IInvokerPtr invoker,
+ IMemoryUsageTrackerPtr memoryUsageTracker,
bool ownPoller)
{
auto address = TNetworkAddress::CreateIPv6Any(config->Port);
+ IListenerPtr listener;
for (int i = 0;; ++i) {
try {
- auto listener = CreateListener(address, poller, acceptor, config->MaxBacklogSize);
- return CreateServer(
- std::move(config),
- std::move(listener),
- std::move(poller),
- std::move(acceptor),
- std::move(invoker),
- ownPoller);
+ listener = CreateListener(address, poller, acceptor, config->MaxBacklogSize);
+ break;
} catch (const std::exception& ex) {
if (i + 1 == config->BindRetryCount) {
throw;
@@ -421,6 +425,14 @@ IServerPtr CreateServer(
}
}
}
+ return CreateServer(
+ std::move(config),
+ std::move(listener),
+ std::move(poller),
+ std::move(acceptor),
+ std::move(invoker),
+ std::move(memoryUsageTracker),
+ ownPoller);
}
} // namespace
@@ -440,6 +452,7 @@ IServerPtr CreateServer(
std::move(poller),
std::move(acceptor),
std::move(invoker),
+ /*memoryUsageTracker*/ GetNullMemoryUsageTracker(),
/*ownPoller*/ false);
}
@@ -447,7 +460,8 @@ IServerPtr CreateServer(
TServerConfigPtr config,
IListenerPtr listener,
IPollerPtr poller,
- IPollerPtr acceptor)
+ IPollerPtr acceptor,
+ IMemoryUsageTrackerPtr memoryUsageTracker)
{
auto invoker = poller->GetInvoker();
return CreateServer(
@@ -456,13 +470,15 @@ IServerPtr CreateServer(
std::move(poller),
std::move(acceptor),
std::move(invoker),
+ std::move(memoryUsageTracker),
/*ownPoller*/ false);
}
IServerPtr CreateServer(
TServerConfigPtr config,
IPollerPtr poller,
- IPollerPtr acceptor)
+ IPollerPtr acceptor,
+ IMemoryUsageTrackerPtr memoryUsageTracker)
{
auto invoker = poller->GetInvoker();
return CreateServer(
@@ -470,6 +486,7 @@ IServerPtr CreateServer(
std::move(poller),
std::move(acceptor),
std::move(invoker),
+ std::move(memoryUsageTracker),
/*ownPoller*/ false);
}
@@ -499,6 +516,7 @@ IServerPtr CreateServer(TServerConfigPtr config, int pollerThreadCount)
std::move(poller),
std::move(acceptor),
std::move(invoker),
+ /*memoryUsageTracker*/ GetNullMemoryUsageTracker(),
/*ownPoller*/ true);
}
@@ -513,6 +531,7 @@ IServerPtr CreateServer(
std::move(poller),
std::move(acceptor),
std::move(invoker),
+ /*memoryUsageTracker*/ GetNullMemoryUsageTracker(),
/*ownPoller*/ false);
}
diff --git a/yt/yt/core/http/server.h b/yt/yt/core/http/server.h
index e96720981b..171fb70399 100644
--- a/yt/yt/core/http/server.h
+++ b/yt/yt/core/http/server.h
@@ -89,14 +89,16 @@ IServerPtr CreateServer(
TServerConfigPtr config,
NNet::IListenerPtr listener,
NConcurrency::IPollerPtr poller,
- NConcurrency::IPollerPtr acceptor);
+ NConcurrency::IPollerPtr acceptor,
+ IMemoryUsageTrackerPtr memoryTracker = GetNullMemoryUsageTracker());
IServerPtr CreateServer(
TServerConfigPtr config,
NConcurrency::IPollerPtr poller);
IServerPtr CreateServer(
TServerConfigPtr config,
NConcurrency::IPollerPtr poller,
- NConcurrency::IPollerPtr acceptor);
+ NConcurrency::IPollerPtr acceptor,
+ IMemoryUsageTrackerPtr memoryTracker = GetNullMemoryUsageTracker());
IServerPtr CreateServer(
int port,
NConcurrency::IPollerPtr poller);
diff --git a/yt/yt/core/http/stream.cpp b/yt/yt/core/http/stream.cpp
index ec76d4e845..7f059df841 100644
--- a/yt/yt/core/http/stream.cpp
+++ b/yt/yt/core/http/stream.cpp
@@ -252,12 +252,14 @@ THttpInput::THttpInput(
const TNetworkAddress& remoteAddress,
IInvokerPtr readInvoker,
EMessageType messageType,
- THttpIOConfigPtr config)
+ THttpIOConfigPtr config,
+ IMemoryUsageTrackerPtr memoryUsageTracker)
: Connection_(std::move(connection))
, RemoteAddress_(remoteAddress)
, MessageType_(messageType)
, Config_(std::move(config))
, ReadInvoker_(std::move(readInvoker))
+ , MemoryUsageTracker_(std::move(memoryUsageTracker))
, InputBuffer_(TSharedMutableRef::Allocate<THttpParserTag>(Config_->ReadBufferSize))
, Parser_(messageType == EMessageType::Request ? HTTP_REQUEST : HTTP_RESPONSE)
, StartByteCount_(Connection_->GetReadByteCount())
@@ -514,7 +516,8 @@ TSharedRef THttpInput::DoRead()
auto chunk = Parser_.GetLastBodyChunk();
if (!chunk.Empty()) {
Connection_->SetReadDeadline(std::nullopt);
- return chunk;
+ auto trackedChunk = TrackMemory(MemoryUsageTracker_, chunk);
+ return trackedChunk;
}
bool eof = false;
@@ -576,11 +579,13 @@ THttpOutput::THttpOutput(
THeadersPtr headers,
IConnectionPtr connection,
EMessageType messageType,
- THttpIOConfigPtr config)
+ THttpIOConfigPtr config,
+ IMemoryUsageTrackerPtr memoryUsageTracker)
: Connection_(std::move(connection))
, MessageType_(messageType)
, Config_(std::move(config))
, OnWriteFinish_(BIND_NO_PROPAGATE(&THttpOutput::OnWriteFinish, MakeWeak(this)))
+ , MemoryUsageTracker_(std::move(memoryUsageTracker))
, StartByteCount_(Connection_->GetWriteByteCount())
, StartStatistics_(Connection_->GetWriteStatistics())
, LastProgressLogTime_(TInstant::Now())
@@ -590,12 +595,14 @@ THttpOutput::THttpOutput(
THttpOutput::THttpOutput(
IConnectionPtr connection,
EMessageType messageType,
- THttpIOConfigPtr config)
+ THttpIOConfigPtr config,
+ IMemoryUsageTrackerPtr memoryUsageTracker)
: THttpOutput(
New<THeaders>(),
std::move(connection),
messageType,
- std::move(config))
+ std::move(config),
+ std::move(memoryUsageTracker))
{ }
const THeadersPtr& THttpOutput::GetHeaders()
@@ -763,6 +770,8 @@ TFuture<void> THttpOutput::Write(const TSharedRef& data)
THROW_ERROR(AnnotateError(TError("Cannot write to finished HTTP message")));
}
+ auto trackedData = TrackMemory(MemoryUsageTracker_, data);
+
std::vector<TSharedRef> writeRefs;
if (!HeadersFlushed_) {
HeadersFlushed_ = true;
@@ -770,9 +779,9 @@ TFuture<void> THttpOutput::Write(const TSharedRef& data)
writeRefs.push_back(CrLfBuffer());
}
- if (!data.Empty()) {
- writeRefs.push_back(GetChunkHeader(data.Size()));
- writeRefs.push_back(data);
+ if (!trackedData.Empty()) {
+ writeRefs.push_back(GetChunkHeader(trackedData.Size()));
+ writeRefs.push_back(trackedData);
writeRefs.push_back(CrLfBuffer());
}
diff --git a/yt/yt/core/http/stream.h b/yt/yt/core/http/stream.h
index a45ab15f0f..4c11b32e11 100644
--- a/yt/yt/core/http/stream.h
+++ b/yt/yt/core/http/stream.h
@@ -91,7 +91,8 @@ public:
const NNet::TNetworkAddress& remoteAddress,
IInvokerPtr readInvoker,
EMessageType messageType,
- THttpIOConfigPtr config);
+ THttpIOConfigPtr config,
+ IMemoryUsageTrackerPtr memoryUsageTracker = GetNullMemoryUsageTracker());
EMethod GetMethod() override;
const TUrlRef& GetUrl() override;
@@ -136,6 +137,7 @@ private:
const EMessageType MessageType_;
const THttpIOConfigPtr Config_;
const IInvokerPtr ReadInvoker_;
+ const IMemoryUsageTrackerPtr MemoryUsageTracker_;
TSharedMutableRef InputBuffer_;
TSharedRef UnconsumedData_;
@@ -183,12 +185,14 @@ public:
THeadersPtr headers,
NNet::IConnectionPtr connection,
EMessageType messageType,
- THttpIOConfigPtr config);
+ THttpIOConfigPtr config,
+ IMemoryUsageTrackerPtr memoryUsageTracker = GetNullMemoryUsageTracker());
THttpOutput(
NNet::IConnectionPtr connection,
EMessageType messageType,
- THttpIOConfigPtr config);
+ THttpIOConfigPtr config,
+ IMemoryUsageTrackerPtr memoryUsageTracker = GetNullMemoryUsageTracker());
const THeadersPtr& GetHeaders() override;
void SetHeaders(const THeadersPtr& headers);
@@ -224,6 +228,7 @@ private:
const THttpIOConfigPtr Config_;
const TClosure OnWriteFinish_;
+ const IMemoryUsageTrackerPtr MemoryUsageTracker_;
// Debug
TRequestId RequestId_;
diff --git a/yt/yt/core/https/server.cpp b/yt/yt/core/https/server.cpp
index 92bdee379f..b97cb801e8 100644
--- a/yt/yt/core/https/server.cpp
+++ b/yt/yt/core/https/server.cpp
@@ -112,7 +112,8 @@ IServerPtr CreateServer(
const TServerConfigPtr& config,
const IPollerPtr& poller,
const IPollerPtr& acceptor,
- const IInvokerPtr& controlInvoker)
+ const IInvokerPtr& controlInvoker,
+ const IMemoryUsageTrackerPtr& memoryTracker)
{
auto sslContext = New<TSslContext>();
ApplySslConfig(sslContext, config->Credentials);
@@ -164,7 +165,8 @@ IServerPtr CreateServer(
configCopy,
tlsListener,
poller,
- acceptor);
+ acceptor,
+ memoryTracker);
return New<TServer>(std::move(httpServer), std::move(certificateUpdater));
}
diff --git a/yt/yt/core/https/server.h b/yt/yt/core/https/server.h
index c6c40eeec3..46994e8ea4 100644
--- a/yt/yt/core/https/server.h
+++ b/yt/yt/core/https/server.h
@@ -8,6 +8,8 @@
#include <yt/yt/core/http/public.h>
+#include <yt/yt/core/misc/memory_usage_tracker.h>
+
namespace NYT::NHttps {
////////////////////////////////////////////////////////////////////////////////
@@ -26,7 +28,8 @@ NHttp::IServerPtr CreateServer(
const TServerConfigPtr& config,
const NConcurrency::IPollerPtr& poller,
const NConcurrency::IPollerPtr& acceptor,
- const IInvokerPtr& controlInvoker);
+ const IInvokerPtr& controlInvoker,
+ const IMemoryUsageTrackerPtr& memoryTracker = GetNullMemoryUsageTracker());
////////////////////////////////////////////////////////////////////////////////
diff --git a/yt/yt/core/ytree/fluent.h b/yt/yt/core/ytree/fluent.h
index 366ca9794d..ea460e2bcd 100644
--- a/yt/yt/core/ytree/fluent.h
+++ b/yt/yt/core/ytree/fluent.h
@@ -78,8 +78,7 @@ namespace NYT::NYTree {
// `func` only if `condition` is true;
// * DoFor(TCollection collection, TFuncAny func) -> TAny, same as Do()
// but iterate over `collection` and pass each of its elements as a second
-// argument to `func`. Instead of passing a collection you may it is possible
-// to pass two iterators as an argument;
+// argument to `func`. You may pass two iterators as an argument instead;
//
// * DoMap(TFuncMap func) -> TAny, open a map, delegate invocation to a separate
// procedure and close map;
diff --git a/yt/yt/core/ytree/unittests/yson_struct_update_ut.cpp b/yt/yt/core/ytree/unittests/yson_struct_update_ut.cpp
index fd82265dd7..5d25807ada 100644
--- a/yt/yt/core/ytree/unittests/yson_struct_update_ut.cpp
+++ b/yt/yt/core/ytree/unittests/yson_struct_update_ut.cpp
@@ -132,8 +132,8 @@ TEST(TUpdateYsonStructTest, Inherited)
auto configurator = TConfigurator<TSpecBase>();
{
- TConfigurator<TSpecWithPool> parentRegistrar = configurator;
- parentRegistrar.Field("pool", &TSpecBase::Pool)
+ TConfigurator<TSpecWithPool> parentConfigurator = configurator;
+ parentConfigurator.Field("pool", &TSpecBase::Pool)
.Updater(BIND([&] (const std::string& newPool) {
updatedPool = newPool;
}));
@@ -154,8 +154,8 @@ TEST(TUpdateYsonStructTest, Nested)
auto configurator = TConfigurator<TSpecBase>();
{
- TConfigurator<TSpecWithPool> parentRegistrar = configurator;
- parentRegistrar.Field("pool", &TSpecBase::Pool)
+ TConfigurator<TSpecWithPool> parentConfigurator = configurator;
+ parentConfigurator.Field("pool", &TSpecBase::Pool)
.Updater(BIND([&] (const std::string& newPool) {
updatedPool = newPool;
}));
diff --git a/yt/yt/core/ytree/yson_struct_update-inl.h b/yt/yt/core/ytree/yson_struct_update-inl.h
index c6ae5f1ead..46ad7fe717 100644
--- a/yt/yt/core/ytree/yson_struct_update-inl.h
+++ b/yt/yt/core/ytree/yson_struct_update-inl.h
@@ -15,24 +15,24 @@ const IYsonStructMeta* GetYsonStructMeta() {
return New<TStruct>()->GetMeta();
}
-struct TRegisteredFieldDirectory
+struct TConfiguredFieldDirectory
: public TRefCounted
{
template <class TStruct>
- static TRegisteredFieldDirectoryPtr Create()
+ static TConfiguredFieldDirectoryPtr Create()
{
static auto* meta = GetYsonStructMeta<TStruct>();
- auto directory = New<TRegisteredFieldDirectory>();
+ auto directory = New<TConfiguredFieldDirectory>();
directory->Meta = meta;
return directory;
}
- THashMap<IYsonStructParameterPtr, IFieldRegistrarPtr> ParameterToFieldRegistrar;
+ THashMap<IYsonStructParameterPtr, IFieldConfiguratorPtr> ParameterToFieldConfigurator;
const IYsonStructMeta* Meta;
};
-DEFINE_REFCOUNTED_TYPE(TRegisteredFieldDirectory);
+DEFINE_REFCOUNTED_TYPE(TConfiguredFieldDirectory);
////////////////////////////////////////////////////////////////////////////////
@@ -49,7 +49,7 @@ struct TUnwrapYsonStructIntrusivePtr<TIntrusivePtr<T>>
////////////////////////////////////////////////////////////////////////////////
template <class TValue>
-TFieldRegistrar<TValue>& TFieldRegistrar<TValue>::Validator(TCallback<void(const TValue&, const TValue&)> validator)
+TFieldConfigurator<TValue>& TFieldConfigurator<TValue>::Validator(TCallback<void(const TValue&, const TValue&)> validator)
{
VerifyEmptyValidator();
Validator_ = validator;
@@ -57,7 +57,7 @@ TFieldRegistrar<TValue>& TFieldRegistrar<TValue>::Validator(TCallback<void(const
}
template <class TValue>
-TFieldRegistrar<TValue>& TFieldRegistrar<TValue>::Validator(TCallback<void(const TValue&)> validator)
+TFieldConfigurator<TValue>& TFieldConfigurator<TValue>::Validator(TCallback<void(const TValue&)> validator)
{
VerifyEmptyValidator();
Validator_ = BIND_NO_PROPAGATE([validator = std::move(validator)] (const TValue& /*oldValue*/, const TValue& newValue) {
@@ -67,7 +67,7 @@ TFieldRegistrar<TValue>& TFieldRegistrar<TValue>::Validator(TCallback<void(const
}
template <class TValue>
-TFieldRegistrar<TValue>& TFieldRegistrar<TValue>::Updater(TCallback<void(const TValue&, const TValue&)> updater)
+TFieldConfigurator<TValue>& TFieldConfigurator<TValue>::Updater(TCallback<void(const TValue&, const TValue&)> updater)
{
VerifyEmptyUpdater();
Updater_ = updater;
@@ -75,7 +75,7 @@ TFieldRegistrar<TValue>& TFieldRegistrar<TValue>::Updater(TCallback<void(const T
}
template <class TValue>
-TFieldRegistrar<TValue>& TFieldRegistrar<TValue>::Updater(TCallback<void(const TValue&)> updater)
+TFieldConfigurator<TValue>& TFieldConfigurator<TValue>::Updater(TCallback<void(const TValue&)> updater)
{
VerifyEmptyUpdater();
Updater_ = BIND_NO_PROPAGATE([updater = std::move(updater)] (const TValue& /*oldValue*/, const TValue& newValue) {
@@ -100,7 +100,7 @@ TFieldRegistrar<TValue>& TFieldRegistrar<TValue>::Updater(TCallback<void(const T
// written as TIntrusivePtr<TMyStruct>, so I need to unwrap that to TMyStruct.
template <class TValue>
template <CYsonStructDerived TUnwrappedValue>
-TFieldRegistrar<TValue>& TFieldRegistrar<TValue>::NestedUpdater(
+TFieldConfigurator<TValue>& TFieldConfigurator<TValue>::NestedUpdater(
TCallback<TSealedConfigurator<TUnwrappedValue>()> configureCallback)
{
static_assert(
@@ -117,7 +117,7 @@ TFieldRegistrar<TValue>& TFieldRegistrar<TValue>::NestedUpdater(
}
template <class TValue>
-void TFieldRegistrar<TValue>::DoValidate(
+void TFieldConfigurator<TValue>::DoValidate(
IYsonStructParameterPtr parameter,
TYsonStructBase* oldStruct,
TYsonStructBase* newStruct) const
@@ -134,7 +134,7 @@ void TFieldRegistrar<TValue>::DoValidate(
}
template <class TValue>
-void TFieldRegistrar<TValue>::DoUpdate(
+void TFieldConfigurator<TValue>::DoUpdate(
IYsonStructParameterPtr parameter,
TYsonStructBase* oldStruct,
TYsonStructBase* newStruct) const
@@ -151,13 +151,13 @@ void TFieldRegistrar<TValue>::DoUpdate(
}
template <class TValue>
-void TFieldRegistrar<TValue>::VerifyEmptyValidator() const
+void TFieldConfigurator<TValue>::VerifyEmptyValidator() const
{
YT_VERIFY(!Validator_);
}
template <class TValue>
-void TFieldRegistrar<TValue>::VerifyEmptyUpdater() const
+void TFieldConfigurator<TValue>::VerifyEmptyUpdater() const
{
YT_VERIFY(!Updater_);
}
@@ -169,32 +169,32 @@ void TFieldRegistrar<TValue>::VerifyEmptyUpdater() const
////////////////////////////////////////////////////////////////////////////////
template <CYsonStructDerived TStruct>
-TConfigurator<TStruct>::TConfigurator(NDetail::TRegisteredFieldDirectoryPtr registeredFields)
- : RegisteredFields_(registeredFields)
+TConfigurator<TStruct>::TConfigurator(NDetail::TConfiguredFieldDirectoryPtr configuredFields)
+ : ConfiguredFields_(configuredFields)
{
- // NB: Initialize TRegisteredFieldDirectory with
+ // NB: Initialize TConfiguredFieldDirectory with
// the youngest child in the hierarchy.
- if (!registeredFields) {
- RegisteredFields_ = NDetail::TRegisteredFieldDirectory::Create<TStruct>();
+ if (!configuredFields) {
+ ConfiguredFields_ = NDetail::TConfiguredFieldDirectory::Create<TStruct>();
}
}
template <CYsonStructDerived TStruct>
template <class TValue>
-NDetail::TFieldRegistrar<TValue>& TConfigurator<TStruct>::Field(const std::string& name, TYsonStructField<TStruct, TValue> field)
+NDetail::TFieldConfigurator<TValue>& TConfigurator<TStruct>::Field(const std::string& name, TYsonStructField<TStruct, TValue> field)
{
IYsonStructParameterPtr parameter;
try {
- parameter = RegisteredFields_->Meta->GetParameter(name);
+ parameter = ConfiguredFields_->Meta->GetParameter(name);
} catch (const std::exception& ex) {
YT_ABORT();
}
YT_VERIFY(parameter->HoldsField(CreateTypeErasedYsonStructField(field)));
- auto fieldRegistrar = New<NDetail::TFieldRegistrar<TValue>>();
- RegisteredFields_->ParameterToFieldRegistrar.emplace(parameter, fieldRegistrar);
- return *fieldRegistrar;
+ auto fieldConfigurator = New<NDetail::TFieldConfigurator<TValue>>();
+ ConfiguredFields_->ParameterToFieldConfigurator.emplace(parameter, fieldConfigurator);
+ return *fieldConfigurator;
}
template <CYsonStructDerived TStruct>
@@ -202,7 +202,7 @@ template <class TAncestor>
TConfigurator<TStruct>::operator TConfigurator<TAncestor>() const
{
static_assert(std::derived_from<TStruct, TAncestor> && std::derived_from<TAncestor, TYsonStructBase>);
- return TConfigurator<TAncestor>(RegisteredFields_);
+ return TConfigurator<TAncestor>(ConfiguredFields_);
}
template <CYsonStructDerived TStruct>
@@ -215,7 +215,7 @@ TSealedConfigurator<TStruct> TConfigurator<TStruct>::Seal() &&
template <CYsonStructDerived TStruct>
TSealedConfigurator<TStruct>::TSealedConfigurator(TConfigurator<TStruct> configurator)
- : RegisteredFields_(std::move(configurator.RegisteredFields_))
+ : ConfiguredFields_(std::move(configurator.ConfiguredFields_))
{ }
template <CYsonStructDerived TStruct>
@@ -223,7 +223,7 @@ void TSealedConfigurator<TStruct>::Validate(
TIntrusivePtr<TStruct> oldStruct,
TIntrusivePtr<TStruct> newStruct) const
{
- Do(oldStruct, newStruct, &NDetail::IFieldRegistrar::DoValidate);
+ Do(oldStruct, newStruct, &NDetail::IFieldConfigurator::DoValidate);
}
template <CYsonStructDerived TStruct>
@@ -231,26 +231,26 @@ void TSealedConfigurator<TStruct>::Update(
TIntrusivePtr<TStruct> oldStruct,
TIntrusivePtr<TStruct> newStruct) const
{
- Do(oldStruct, newStruct, &NDetail::IFieldRegistrar::DoUpdate);
+ Do(oldStruct, newStruct, &NDetail::IFieldConfigurator::DoUpdate);
}
template <CYsonStructDerived TStruct>
void TSealedConfigurator<TStruct>::Do(
TIntrusivePtr<TStruct> oldStruct,
TIntrusivePtr<TStruct> newStruct,
- TFieldRegistrarMethod fieldMethod) const
+ TFieldConfiguratorMethod fieldMethod) const
{
const auto* meta = oldStruct->GetMeta();
YT_VERIFY(meta == newStruct->GetMeta());
- const auto& parameterToFieldRegistrar = RegisteredFields_->ParameterToFieldRegistrar;
- YT_VERIFY(RegisteredFields_->Meta == meta);
+ const auto& parameterToFieldConfigurator = ConfiguredFields_->ParameterToFieldConfigurator;
+ YT_VERIFY(ConfiguredFields_->Meta == meta);
for (const auto& [name, parameter] : meta->GetParameterMap()) {
if (parameter->CompareParameter(oldStruct.Get(), newStruct.Get())) {
continue;
}
- auto fieldDescIter = parameterToFieldRegistrar.find(parameter);
- if (fieldDescIter == parameterToFieldRegistrar.end()) {
+ auto fieldDescIter = parameterToFieldConfigurator.find(parameter);
+ if (fieldDescIter == parameterToFieldConfigurator.end()) {
THROW_ERROR_EXCEPTION("Field %Qv is not marked as updatable, but was changed", name);
} else {
(*(fieldDescIter->second).*fieldMethod)(parameter, oldStruct.Get(), newStruct.Get());
diff --git a/yt/yt/core/ytree/yson_struct_update.h b/yt/yt/core/ytree/yson_struct_update.h
index 7a517d6f57..1b762b9cc4 100644
--- a/yt/yt/core/ytree/yson_struct_update.h
+++ b/yt/yt/core/ytree/yson_struct_update.h
@@ -19,11 +19,11 @@ namespace NDetail {
////////////////////////////////////////////////////////////////////////////////
-DECLARE_REFCOUNTED_STRUCT(TRegisteredFieldDirectory);
+DECLARE_REFCOUNTED_STRUCT(TConfiguredFieldDirectory);
////////////////////////////////////////////////////////////////////////////////
-struct IFieldRegistrar
+struct IFieldConfigurator
: public TRefCounted
{
virtual void DoValidate(
@@ -37,31 +37,31 @@ struct IFieldRegistrar
TYsonStructBase* newStruct) const = 0;
};
-DECLARE_REFCOUNTED_STRUCT(IFieldRegistrar);
-DEFINE_REFCOUNTED_TYPE(IFieldRegistrar);
+DECLARE_REFCOUNTED_STRUCT(IFieldConfigurator);
+DEFINE_REFCOUNTED_TYPE(IFieldConfigurator);
////////////////////////////////////////////////////////////////////////////////
template <class TValue>
-class TFieldRegistrar
- : public IFieldRegistrar
+class TFieldConfigurator
+ : public IFieldConfigurator
{
public:
// Registers validator that accepts old and new values as arguments.
- TFieldRegistrar& Validator(TCallback<void(const TValue&, const TValue&)> validator);
+ TFieldConfigurator& Validator(TCallback<void(const TValue&, const TValue&)> validator);
// Registers validator that accepts only new value as an argument.
- TFieldRegistrar& Validator(TCallback<void(const TValue&)> validator);
+ TFieldConfigurator& Validator(TCallback<void(const TValue&)> validator);
// Registers updater that accepts old and new values as arguments.
- TFieldRegistrar& Updater(TCallback<void(const TValue&, const TValue&)> updater);
+ TFieldConfigurator& Updater(TCallback<void(const TValue&, const TValue&)> updater);
// Registers updater that accepts only new value as an argument.
- TFieldRegistrar& Updater(TCallback<void(const TValue&)> updater);
+ TFieldConfigurator& Updater(TCallback<void(const TValue&)> updater);
// Registers nested YsonStruct to be updated recursively.
template <CYsonStructDerived TUnwrappedValue>
- TFieldRegistrar& NestedUpdater(
+ TFieldConfigurator& NestedUpdater(
TCallback<TSealedConfigurator<TUnwrappedValue>()> configureCallback);
void DoUpdate(
@@ -106,19 +106,19 @@ template <CYsonStructDerived TStruct>
class TConfigurator
{
public:
- explicit TConfigurator(NDetail::TRegisteredFieldDirectoryPtr state = {});
+ explicit TConfigurator(NDetail::TConfiguredFieldDirectoryPtr state = {});
template <class TValue>
- NDetail::TFieldRegistrar<TValue>& Field(const std::string& name, TYsonStructField<TStruct, TValue> field);
+ NDetail::TFieldConfigurator<TValue>& Field(const std::string& name, TYsonStructField<TStruct, TValue> field);
- // Converts to a registrar of a base class
+ // Converts to a configurator of a base class
template <class TAncestor>
operator TConfigurator<TAncestor>() const;
TSealedConfigurator<TStruct> Seal() &&;
private:
- NDetail::TRegisteredFieldDirectoryPtr RegisteredFields_;
+ NDetail::TConfiguredFieldDirectoryPtr ConfiguredFields_;
template <CYsonStructDerived TStructForSealed>
friend class TSealedConfigurator;
@@ -141,7 +141,7 @@ public:
TIntrusivePtr<TStruct> newStruct) const;
private:
- using TFieldRegistrarMethod = void(NDetail::IFieldRegistrar::*)(
+ using TFieldConfiguratorMethod = void(NDetail::IFieldConfigurator::*)(
IYsonStructParameterPtr parameter,
TYsonStructBase* oldStruct,
TYsonStructBase* newStruct) const;
@@ -149,9 +149,9 @@ private:
void Do(
TIntrusivePtr<TStruct> oldStruct,
TIntrusivePtr<TStruct> newStruct,
- TFieldRegistrarMethod fieldMethod) const;
+ TFieldConfiguratorMethod fieldMethod) const;
- NDetail::TRegisteredFieldDirectoryPtr RegisteredFields_;
+ NDetail::TConfiguredFieldDirectoryPtr ConfiguredFields_;
};
////////////////////////////////////////////////////////////////////////////////