From 6c1ee978a72376d2957df53b19f387e565f2697f Mon Sep 17 00:00:00 2001 From: Grigory Statsenko Date: Thu, 9 Nov 2023 15:54:51 +0100 Subject: [PATCH] Implemented function extensions for formula ref and connectorized some note blocks --- .../target_update_po/Dockerfile | 2 + .../formula_ref/plugin.py | 58 +++++++++++++++++- .../en/LC_MESSAGES/dl_connector_clickhouse.po | 2 +- .../dl_formula_ref_dl_connector_clickhouse.po | 24 +++++++- .../ru/LC_MESSAGES/dl_connector_clickhouse.po | 2 +- .../dl_formula_ref_dl_connector_clickhouse.mo | Bin 405 -> 2285 bytes .../dl_formula_ref_dl_connector_clickhouse.po | 37 ++++++++++- .../db/api/base.py | 3 +- .../dl_connector_metrica/formula_ref/i18n.py | 23 +++++++ .../formula_ref/plugin.py | 21 +++++++ .../dl_formula_ref_dl_connector_metrica.mo | Bin 0 -> 241 bytes .../dl_formula_ref_dl_connector_metrica.po | 13 ++++ .../dl_formula_ref_dl_connector_metrica.mo | Bin 0 -> 417 bytes .../dl_formula_ref_dl_connector_metrica.po | 13 ++++ lib/dl_connector_metrica/pyproject.toml | 3 + .../formula_ref/plugin.py | 16 +++++ .../dl_formula_ref_dl_connector_postgresql.po | 6 ++ .../dl_formula_ref_dl_connector_postgresql.mo | Bin 679 -> 1149 bytes .../dl_formula_ref_dl_connector_postgresql.po | 9 +++ lib/dl_formula/dl_formula/core/dialect.py | 16 +++++ .../dl_formula_ref/function_extension.py | 43 +++++++++++++ .../dl_formula_ref/functions/array.py | 16 ++--- .../dl_formula_ref/functions/date.py | 17 +---- .../dl_formula_ref/functions/operator.py | 15 +---- .../dl_formula_ref/functions/string.py | 4 +- .../dl_formula_ref/functions/time_series.py | 7 ++- .../functions/type_conversion.py | 29 +++------ .../dl_formula_ref/functions/window.py | 3 +- .../dl_formula_ref_dl_formula_ref.po | 36 +---------- .../dl_formula_ref_dl_formula_ref.mo | Bin 122800 -> 120274 bytes .../dl_formula_ref_dl_formula_ref.po | 52 +--------------- .../dl_formula_ref/plugins/base/plugin.py | 4 ++ .../dl_formula_ref/plugins/registration.py | 4 ++ .../dl_formula_ref/registry/base.py | 9 +++ .../dl_formula_ref/registry/note.py | 20 +++--- .../dl_formula_ref/registry/note_extractor.py | 11 +++- 36 files changed, 348 insertions(+), 170 deletions(-) create mode 100644 lib/dl_connector_metrica/dl_connector_metrica/formula_ref/i18n.py create mode 100644 lib/dl_connector_metrica/dl_connector_metrica/locales/en/LC_MESSAGES/dl_formula_ref_dl_connector_metrica.mo create mode 100644 lib/dl_connector_metrica/dl_connector_metrica/locales/en/LC_MESSAGES/dl_formula_ref_dl_connector_metrica.po create mode 100644 lib/dl_connector_metrica/dl_connector_metrica/locales/ru/LC_MESSAGES/dl_formula_ref_dl_connector_metrica.mo create mode 100644 lib/dl_connector_metrica/dl_connector_metrica/locales/ru/LC_MESSAGES/dl_formula_ref_dl_connector_metrica.po create mode 100644 lib/dl_formula_ref/dl_formula_ref/function_extension.py diff --git a/docker_build/target_translations/target_update_po/Dockerfile b/docker_build/target_translations/target_update_po/Dockerfile index 11dda437a..fa2ce697c 100644 --- a/docker_build/target_translations/target_update_po/Dockerfile +++ b/docker_build/target_translations/target_update_po/Dockerfile @@ -28,6 +28,8 @@ RUN for domain_pair in $(dl-package --package-path=. list-i18n-domains) ; do \ for locale in $(ls $PACKAGE_NAME/locales/) ; do \ mkdir -p $LOCALES_DIR/$locale/LC_MESSAGES ; \ msgmerge $PACKAGE_NAME/locales/$locale/LC_MESSAGES/$DOMAIN_NAME.po $DOMAIN_NAME.po > $LOCALES_DIR/$locale/LC_MESSAGES/$DOMAIN_NAME.po; \ + # Now replace the date with a fixed one so that it doesn't get updated every time + sed -i -r "s/POT-Creation-Date: [0-9]+-[0-9]+-[0-9]+ [0-9]+:[0-9]+\\+[0-9]+/POT-Creation-Date: 2023-09-22 08:16+0000/g" $LOCALES_DIR/$locale/LC_MESSAGES/$DOMAIN_NAME.po; \ done; \ done diff --git a/lib/dl_connector_clickhouse/dl_connector_clickhouse/formula_ref/plugin.py b/lib/dl_connector_clickhouse/dl_connector_clickhouse/formula_ref/plugin.py index ee2ebe928..34908a965 100644 --- a/lib/dl_connector_clickhouse/dl_connector_clickhouse/formula_ref/plugin.py +++ b/lib/dl_connector_clickhouse/dl_connector_clickhouse/formula_ref/plugin.py @@ -1,10 +1,22 @@ -from dl_formula_ref.functions.type_conversion import DbCastExtension +from dl_formula_ref.functions.date import FUNCTION_DATETRUNC +from dl_formula_ref.functions.operator import FUNCTION_OP_COMPARISON +from dl_formula_ref.functions.type_conversion import ( + FUNCTION_DATE, + DbCastExtension, +) from dl_formula_ref.plugins.base.plugin import FormulaRefPlugin +from dl_formula_ref.registry.note import ( + Note, + NoteLevel, +) from dl_connector_clickhouse.formula.constants import ClickHouseDialect from dl_connector_clickhouse.formula.definitions.functions_type import FuncDbCastClickHouseBase from dl_connector_clickhouse.formula_ref.human_dialects import HUMAN_DIALECTS -from dl_connector_clickhouse.formula_ref.i18n import CONFIGS +from dl_connector_clickhouse.formula_ref.i18n import ( + CONFIGS, + Translatable, +) class ClickHouseFormulaRefPlugin(FormulaRefPlugin): @@ -15,3 +27,45 @@ class ClickHouseFormulaRefPlugin(FormulaRefPlugin): db_cast_extension = DbCastExtension( type_whitelists=FuncDbCastClickHouseBase.WHITELISTS, ) + function_extensions = [ + FUNCTION_DATETRUNC.extend( + dialect=ClickHouseDialect.CLICKHOUSE, + notes=( + Note( + Translatable( + "The function with three arguments is only available for the sources " + "{dialects:CLICKHOUSE_21_8} or higher." + ), + ), + ), + ), + FUNCTION_DATE.extend( + dialect=ClickHouseDialect.CLICKHOUSE, + notes=( + Note( + Translatable( + "For {dialects:CLICKHOUSE} data sources, numeric {arg:0} values less than or " + "equal to `65535` are interpreted as the number of days (not seconds, like in " + "all other cases) since January 1st 1970. This is the result of the behavior " + "of available {dialects:CLICKHOUSE} functions.\n" + "\n" + "One way to surpass this is to use the following formula: " + "`DATE(DATETIME([value]))`. The result is more consistent, but is likely to " + "be much slower." + ), + level=NoteLevel.warning, + ), + ), + ), + FUNCTION_OP_COMPARISON.extend( + dialect=ClickHouseDialect.CLICKHOUSE, + notes=( + Note( + Translatable( + "Due to implementation details of the {type:FLOAT} type in {dialects:CLICKHOUSE} sources " + "it is recommended to use the {ref:COMPARE} function instead of comparison operators for this type." + ), + ), + ), + ), + ] diff --git a/lib/dl_connector_clickhouse/dl_connector_clickhouse/locales/en/LC_MESSAGES/dl_connector_clickhouse.po b/lib/dl_connector_clickhouse/dl_connector_clickhouse/locales/en/LC_MESSAGES/dl_connector_clickhouse.po index 71fd2817b..d1b431729 100644 --- a/lib/dl_connector_clickhouse/dl_connector_clickhouse/locales/en/LC_MESSAGES/dl_connector_clickhouse.po +++ b/lib/dl_connector_clickhouse/dl_connector_clickhouse/locales/en/LC_MESSAGES/dl_connector_clickhouse.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: datalens-opensource@yandex-team.ru\n" -"POT-Creation-Date: 2023-09-22 08:15+0000\n" +"POT-Creation-Date: 2023-09-22 08:16+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/lib/dl_connector_clickhouse/dl_connector_clickhouse/locales/en/LC_MESSAGES/dl_formula_ref_dl_connector_clickhouse.po b/lib/dl_connector_clickhouse/dl_connector_clickhouse/locales/en/LC_MESSAGES/dl_formula_ref_dl_connector_clickhouse.po index 666272369..3765ef03c 100644 --- a/lib/dl_connector_clickhouse/dl_connector_clickhouse/locales/en/LC_MESSAGES/dl_formula_ref_dl_connector_clickhouse.po +++ b/lib/dl_connector_clickhouse/dl_connector_clickhouse/locales/en/LC_MESSAGES/dl_formula_ref_dl_connector_clickhouse.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: datalens-opensource@yandex-team.ru\n" -"POT-Creation-Date: 2023-09-22 08:15+0000\n" +"POT-Creation-Date: 2023-09-22 08:16+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -14,3 +14,25 @@ msgstr "" msgid "`ClickHouse` version `22.10`" msgstr "" + +msgid "" +"The function with three arguments is only available for the sources " +"{dialects:CLICKHOUSE_21_8} or higher." +msgstr "" + +msgid "" +"For {dialects:CLICKHOUSE} data sources, numeric {arg:0} values less than or " +"equal to `65535` are interpreted as the number of days (not seconds, like in " +"all other cases) since January 1st 1970. This is the result of the behavior " +"of available {dialects:CLICKHOUSE} functions.\n" +"\n" +"One way to surpass this is to use the following formula: " +"`DATE(DATETIME([value]))`. The result is more consistent, but is likely to " +"be much slower." +msgstr "" + +msgid "" +"Due to implementation details of the {type:FLOAT} type in {dialects:" +"CLICKHOUSE} sources it is recommended to use the {ref:COMPARE} function " +"instead of comparison operators for this type." +msgstr "" diff --git a/lib/dl_connector_clickhouse/dl_connector_clickhouse/locales/ru/LC_MESSAGES/dl_connector_clickhouse.po b/lib/dl_connector_clickhouse/dl_connector_clickhouse/locales/ru/LC_MESSAGES/dl_connector_clickhouse.po index bc1f80a46..4a2939dd6 100644 --- a/lib/dl_connector_clickhouse/dl_connector_clickhouse/locales/ru/LC_MESSAGES/dl_connector_clickhouse.po +++ b/lib/dl_connector_clickhouse/dl_connector_clickhouse/locales/ru/LC_MESSAGES/dl_connector_clickhouse.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: datalens-opensource@yandex-team.ru\n" -"POT-Creation-Date: 2023-09-22 08:15+0000\n" +"POT-Creation-Date: 2023-09-22 08:16+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/lib/dl_connector_clickhouse/dl_connector_clickhouse/locales/ru/LC_MESSAGES/dl_formula_ref_dl_connector_clickhouse.mo b/lib/dl_connector_clickhouse/dl_connector_clickhouse/locales/ru/LC_MESSAGES/dl_formula_ref_dl_connector_clickhouse.mo index 708bea238787e9ccf39886250a85c4e3b82eba22..93f3b79f5de636c0e80593e94647b3877877e962 100644 GIT binary patch literal 2285 zcmaJ>-EJF26kebpWVk}y0n*_vkzx}E1%eS0Ax&v$L!#8}4MO$U9@|UTyJluKZB!yP zDWOO$jf8~615_#?A(Awq8z*repf|HGz_ak3Svx6_%Ua{JJ9B=%^PO|%pEu6@;^BD( z>us!ySg&DyhsDotSY52&u^ztQd37uw@2|h)d2c~3L$ck^kdGn%f_w)$%`={N|3%N+ zc-iwfz?-jn9zp&A`7Y#BNT?k@P;(e~1EwBKj~}@7ytA<+6OrHU1hOqdBa9z~RF_8h zfu^WIrX}g7S?S2qxr+?-LfRyC=~H{@$l zvKF=Bwl3=&CDsVW{*-K#W)|ibrWA7$QRk>I>j>p*V2L_X2@@$zjYz>9 zZW%(sJBQEVAnL-10g^Ea<`b9jlITDfWY$@ZX4nAiC~{O{TOR2ckrkv(x3-5&kRB&CiZ}rxs9TAqs=mp2_E-BjZy(z&vb}W8_UyLZvq$*hD_zI?KBc!H zw(NmTSTFqnG9jEL_6f}XGud{BY~l=i=^Z#pY!?x>?7Md3CIBuxd(-N0MxTP2(g~tqx5??II>+vnBG5iML-KtGH6H@4)%~2 z43X$9c0xGA2K0^`nk3yUfSpsxB+p3&W=!7`xJX>yhwyzrT_@1Mcn>&4de`m|ARpoE z&LGI~rIN9b-b;UEt%Uhzh8!YiIk;GuQ`;p7Z~*Uc_gWI+v!~{-!|4hHb9YU5hT~I z0F%Ovfgr5F)NpIKG9O}-E3yB-x0QYHj56jTag{-5k_&r)e2^a42NgUTU4+5B49VH< z0T+%49(wj~fI&lWNdX^5S=$~rM8a^hGGr#q9Y^DFL`<~f16Rtd!!aFem?0_+X=3+yOSmJRAsqvYlZ+x{Fqkv$QQk+*v!UgI7*?46jmdt|&fKb}?o2K@cv%B$ N$b;@5QSk-Qn{o~u|-M-Nar|;1Xu=H$O$42{l+_(MP}C89ZPVKoF%v6EDTNf zrEjXIxeOkEds1IKiD&U3hT>K%{=}=eZT?$(cfg7vH?Tz?tfNG&XX$FT%+xm9eC3}X z(FR-R8H!L_1M{v9P`X4J&ALGf;99w^^A%3dnhc(RQ6ERXi;BF+?r&d4lPGn>NDSq< q#Y8clc-%JH(wnOG+6UzK?{We0edjfW9eT*9a>i1fsQAZn)Vl(gx +# This file is distributed under the same license as the DataLens package. +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: datalens-opensource@yandex-team.ru\n" +"POT-Creation-Date: 2023-11-06 10:45+0000\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "{dialects: METRIKAAPI} does not support string concatenation." +msgstr "" diff --git a/lib/dl_connector_metrica/dl_connector_metrica/locales/ru/LC_MESSAGES/dl_formula_ref_dl_connector_metrica.mo b/lib/dl_connector_metrica/dl_connector_metrica/locales/ru/LC_MESSAGES/dl_formula_ref_dl_connector_metrica.mo new file mode 100644 index 0000000000000000000000000000000000000000..7406edd087de4c4813ce79dab68a74d8ecf2ae07 GIT binary patch literal 417 zcmZ{fy-ve05XS?8B_lJ#Jpc}{Re?%`DpXMw2qjcvG_ff`#g1%8YK4%X10zhlM};U< zm0DiGc>$h{7r#@efcT17UIEo2?pM;1zuI&zA9A}`1V(p+&I+<#is z|LTtAw8t}}eTc)f9kqfWiSB_(u0coxx-1H*@H8qHUC5-!sNsT|Tnf)gl)S-W5;4-@ zN@L82BxtmPW(b|IeHNV@yKTN`Kw{m^896MwnxxVPMh(stn#cmJELFx222?QKCx+8o zPnB*Q#o@B;uD9bhq`=vRq=SO{V0hnb7d@JbJ;<)9(%jU~(<4$_<|!)l6;~t_nPm8W zA8MDmah-pDZD)22_RG%gJFao{U_b1{zS$A_L$Fi4n4uk2Lpw%qR6W^A^$gWxHN@Px HoqEm>;#iPX literal 0 HcmV?d00001 diff --git a/lib/dl_connector_metrica/dl_connector_metrica/locales/ru/LC_MESSAGES/dl_formula_ref_dl_connector_metrica.po b/lib/dl_connector_metrica/dl_connector_metrica/locales/ru/LC_MESSAGES/dl_formula_ref_dl_connector_metrica.po new file mode 100644 index 000000000..a47485d8a --- /dev/null +++ b/lib/dl_connector_metrica/dl_connector_metrica/locales/ru/LC_MESSAGES/dl_formula_ref_dl_connector_metrica.po @@ -0,0 +1,13 @@ +# Copyright (c) 2023 YANDEX LLC +# This file is distributed under the same license as the DataLens package. +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: datalens-opensource@yandex-team.ru\n" +"POT-Creation-Date: 2023-11-06 10:45+0000\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "{dialects: METRIKAAPI} does not support string concatenation." +msgstr "{dialects: METRIKAAPI} не поддерживает конкатенацию строк." diff --git a/lib/dl_connector_metrica/pyproject.toml b/lib/dl_connector_metrica/pyproject.toml index a6d528fe1..dad244fbf 100644 --- a/lib/dl_connector_metrica/pyproject.toml +++ b/lib/dl_connector_metrica/pyproject.toml @@ -76,3 +76,6 @@ dl_connector_metrica = [ {path = "dl_connector_metrica/api"}, {path = "dl_connector_metrica/core"}, ] +dl_formula_ref_dl_connector_metrica = [ + {path = "dl_connector_metrica/formula_ref"}, +] diff --git a/lib/dl_connector_postgresql/dl_connector_postgresql/formula_ref/plugin.py b/lib/dl_connector_postgresql/dl_connector_postgresql/formula_ref/plugin.py index 0a9c91256..83359b1b5 100644 --- a/lib/dl_connector_postgresql/dl_connector_postgresql/formula_ref/plugin.py +++ b/lib/dl_connector_postgresql/dl_connector_postgresql/formula_ref/plugin.py @@ -1,5 +1,7 @@ +from dl_formula_ref.functions.array import FUNCTION_UNNEST from dl_formula_ref.functions.type_conversion import DbCastExtension from dl_formula_ref.plugins.base.plugin import FormulaRefPlugin +from dl_formula_ref.registry.note import Note from dl_connector_postgresql.formula.constants import PostgreSQLDialect from dl_connector_postgresql.formula.definitions.functions_type import FuncDbCastPostgreSQLBase @@ -28,3 +30,17 @@ class PostgresSQLFormulaRefPlugin(FormulaRefPlugin): (PostgreSQLDialect.NON_COMPENG_POSTGRESQL, "varchar"): Translatable("Alias for `character varying`"), }, ) + function_extensions = [ + FUNCTION_UNNEST.extend( + dialect=PostgreSQLDialect.NON_COMPENG_POSTGRESQL, + notes=( + Note( + Translatable( + "{dialects: POSTGRESQL} doesn't allow filtering fields containing the UNNEST " + "function. If the data source is {dialects: POSTGRESQL}, do not use such " + "fields in selectors." + ) + ), + ), + ), + ] diff --git a/lib/dl_connector_postgresql/dl_connector_postgresql/locales/en/LC_MESSAGES/dl_formula_ref_dl_connector_postgresql.po b/lib/dl_connector_postgresql/dl_connector_postgresql/locales/en/LC_MESSAGES/dl_formula_ref_dl_connector_postgresql.po index 82d9b822b..df2e51720 100644 --- a/lib/dl_connector_postgresql/dl_connector_postgresql/locales/en/LC_MESSAGES/dl_formula_ref_dl_connector_postgresql.po +++ b/lib/dl_connector_postgresql/dl_connector_postgresql/locales/en/LC_MESSAGES/dl_formula_ref_dl_connector_postgresql.po @@ -26,3 +26,9 @@ msgstr "" msgid "Alias for `character varying`" msgstr "" + +msgid "" +"{dialects: POSTGRESQL} doesn't allow filtering fields containing the UNNEST " +"function. If the data source is {dialects: POSTGRESQL}, do not use such " +"fields in selectors." +msgstr "" diff --git a/lib/dl_connector_postgresql/dl_connector_postgresql/locales/ru/LC_MESSAGES/dl_formula_ref_dl_connector_postgresql.mo b/lib/dl_connector_postgresql/dl_connector_postgresql/locales/ru/LC_MESSAGES/dl_formula_ref_dl_connector_postgresql.mo index 861511b84ec801d7cf7b2502ecf3f9fc9edaa19f..4e5949e74fad717146e5781f2d5f34c4865fed73 100644 GIT binary patch delta 637 zcmZ`#Jxc>Y6ukHWK@mi-5yjW22qCRtrGw3RiiD9{hA0G+@Ypw=@m z0K5Rbzz5I;d;{G;XGGKb!2L}g17G5t09V0Z;34pJOX%|o?!oyJ48LKmqgB%eAyAVi zz{)HI1_dj6QohP>q%GYx4Nr{I!hCXRIx&@8oZY0fYYJz?Bi**$b;?+_XJ##D6+6>T z3o=~C(=A6S-kM3vb8}P4CCcO+!?Ro`PBWQ6PwSpe!p&t3lPp1hWQ`&$hBR_qk8;8! zku%nQQ!IyssfKg2B7Qv?$wdAem#bXiCs|-$?qlc663K0@@x45hCCC-I%QbmK{KSpm zgPUW1h>!wJ{7LR z02SfwF~J%^VM-N;3T$hk;PXBE$S83`4HzQ~QG`|t`~!JURdZdrsK!TmFerEEy>R;1 JOX4Bp+7HC%{;>c6 delta 163 zcmey%v7EL3o)F7a1|VPuVi_O~0b*_-?g3&D*a5_{K)e%(MS=J_5c2}@TObwy;@?0l z1;jjz5Lz8bZwK<7fV3)*{sp8#`W2WM7=(bd9gqf@69}Z`85qPE(jg3nb|4K@3jq_C LuHF2bF_jSj;Eoak diff --git a/lib/dl_connector_postgresql/dl_connector_postgresql/locales/ru/LC_MESSAGES/dl_formula_ref_dl_connector_postgresql.po b/lib/dl_connector_postgresql/dl_connector_postgresql/locales/ru/LC_MESSAGES/dl_formula_ref_dl_connector_postgresql.po index a79856aa2..2c31887a8 100644 --- a/lib/dl_connector_postgresql/dl_connector_postgresql/locales/ru/LC_MESSAGES/dl_formula_ref_dl_connector_postgresql.po +++ b/lib/dl_connector_postgresql/dl_connector_postgresql/locales/ru/LC_MESSAGES/dl_formula_ref_dl_connector_postgresql.po @@ -26,3 +26,12 @@ msgstr "Алиас для `character`" msgid "Alias for `character varying`" msgstr "Алиас для `character varying`" + +msgid "" +"{dialects: POSTGRESQL} doesn't allow filtering fields containing the UNNEST " +"function. If the data source is {dialects: POSTGRESQL}, do not use such " +"fields in selectors." +msgstr "" +"{dialects: POSTGRESQL} запрещает фильтрацию по полям, содержащим функцию " +"`UNNEST`. Не используйте такие поля для создания селектора, если источник " +"данных — {dialects: POSTGRESQL}." diff --git a/lib/dl_formula/dl_formula/core/dialect.py b/lib/dl_formula/dl_formula/core/dialect.py index b5c225f61..5777cc84b 100644 --- a/lib/dl_formula/dl_formula/core/dialect.py +++ b/lib/dl_formula/dl_formula/core/dialect.py @@ -2,12 +2,15 @@ from __future__ import annotations +from functools import reduce import inspect from itertools import chain import logging +from operator import ior import re from typing import ( Any, + Collection, Generator, NamedTuple, Optional, @@ -283,6 +286,19 @@ def register_dialect_namespace(dialect_ns: Type[DialectNamespace]) -> None: _NAMED_DIALECT_COMBOS[name] = combo +def dialect_combo_is_supported(supported: DialectCombo | Collection[DialectCombo], current: DialectCombo) -> bool: + supported_dcombo: DialectCombo + if not isinstance(supported, DialectCombo): + supported_dcombo = reduce(ior, supported) # bitwise "or" (|) of the collection's elements + else: + supported_dcombo = supported + + if supported_dcombo & StandardDialect.ANY: + return True + + return supported_dcombo & current == current + + def get_dialect_combos() -> list[DialectCombo]: return list(_NAMED_DIALECT_COMBOS.values()) diff --git a/lib/dl_formula_ref/dl_formula_ref/function_extension.py b/lib/dl_formula_ref/dl_formula_ref/function_extension.py new file mode 100644 index 000000000..83125e97d --- /dev/null +++ b/lib/dl_formula_ref/dl_formula_ref/function_extension.py @@ -0,0 +1,43 @@ +import attr + +from dl_formula.core.dialect import ( + DialectCombo, + dialect_combo_is_supported, +) +from dl_formula_ref.registry.env import GenerationEnvironment +from dl_formula_ref.registry.note import Note + + +@attr.s +class FunctionExtension: + category_name: str = attr.ib(kw_only=True) + function_name: str = attr.ib(kw_only=True) + notes: tuple[Note, ...] = attr.ib(kw_only=True) + dialect_combo: DialectCombo = attr.ib(kw_only=True) + + +_FUNCTION_EXTENSION_REGISTRY: dict[tuple[str, str], list[FunctionExtension]] = {} + + +def register_function_extension(func_ext: FunctionExtension) -> None: + key = (func_ext.category_name, func_ext.function_name) + found_exts = _FUNCTION_EXTENSION_REGISTRY.get(key, []) + if func_ext not in found_exts: + _FUNCTION_EXTENSION_REGISTRY[key] = found_exts + [func_ext] + + +def get_function_extensions(category: str, name: str, env: GenerationEnvironment) -> list[FunctionExtension]: + key = (category, name) + extensions = _FUNCTION_EXTENSION_REGISTRY.get(key, []) + extensions = [ + ext + for ext in extensions + if dialect_combo_is_supported(supported=env.supported_dialects, current=ext.dialect_combo) + ] + return extensions + + +def get_function_extension_notes(category: str, name: str, env: GenerationEnvironment) -> list[Note]: + return [ + note for func_ext in get_function_extensions(category=category, name=name, env=env) for note in func_ext.notes + ] diff --git a/lib/dl_formula_ref/dl_formula_ref/functions/array.py b/lib/dl_formula_ref/dl_formula_ref/functions/array.py index 83c51826e..9988ea2fc 100644 --- a/lib/dl_formula_ref/dl_formula_ref/functions/array.py +++ b/lib/dl_formula_ref/dl_formula_ref/functions/array.py @@ -4,6 +4,7 @@ ExampleConfig, ExampleSource, ) +from dl_formula_ref.i18n.registry import FormulaRefTranslatable as Translatable from dl_formula_ref.localization import get_gettext from dl_formula_ref.registry.base import FunctionDocRegistryItem from dl_formula_ref.registry.example import ( @@ -114,7 +115,9 @@ category=CATEGORY_ARRAY, description=_("Returns an array containing the passed values."), notes=[ - Note(_("All passed values must be of the same type or `NULL`. At least one value must be non-`NULL`.")), + Note( + Translatable("All passed values must be of the same type or `NULL`. At least one value must be non-`NULL`.") + ), ], examples=[ SimpleExample("ARRAY(1, 2, NULL, 3)"), @@ -127,15 +130,6 @@ name="unnest", category=CATEGORY_ARRAY, description=_("Expands the {arg:0} array expression to a set of rows."), - notes=[ - Note( - _( - "{dialects: POSTGRESQL} doesn't allow filtering fields containing the UNNEST " - "function. If the data source is {dialects: POSTGRESQL}, do not use such " - "fields in selectors." - ) - ), - ], examples=[ DataExample( example_config=ExampleConfig( @@ -404,7 +398,7 @@ ) ARRAY_AGGREGATION_FUNCTIONS_NOTE = Note( - _( + Translatable( "This function cannot work with arrays with `Nullable` items. To remove `NULL` items from the array," " use {ref:ARR_REMOVE} or {ref:array/REPLACE}." ) diff --git a/lib/dl_formula_ref/dl_formula_ref/functions/date.py b/lib/dl_formula_ref/dl_formula_ref/functions/date.py index de6190d31..0996c2c1c 100644 --- a/lib/dl_formula_ref/dl_formula_ref/functions/date.py +++ b/lib/dl_formula_ref/dl_formula_ref/functions/date.py @@ -6,6 +6,7 @@ ExampleConfig, ExampleSource, ) +from dl_formula_ref.i18n.registry import FormulaRefTranslatable as Translatable from dl_formula_ref.localization import get_gettext from dl_formula_ref.registry.base import FunctionDocRegistryItem from dl_formula_ref.registry.example import ( @@ -52,7 +53,8 @@ ), notes=[ Note( - _("For all sources except {dialects:CLICKHOUSE}, {arg:2} takes " "only constant values."), + # FIXME: Connectorize dialect mentions (https://github.com/datalens-tech/datalens-backend/issues/81) + Translatable("For all sources except {dialects:CLICKHOUSE}, {arg:2} takes " "only constant values."), ), ], examples=[ @@ -162,14 +164,6 @@ '- `"quarter"`;\n' '- `"year"`.' ), - notes=[ - Note( - _( - "The function with three arguments is only available for the sources " - "{dialects:CLICKHOUSE_21_8} or higher." - ), - ), - ], examples=[ SimpleExample(example_str) for example_str in ( @@ -297,11 +291,6 @@ name="now", category=CATEGORY_DATE, description=_("Returns the current date and time, depending on the data source and " "connection type."), - notes=[ - Note( - _("On {dialects:YQL}, the function always returns the UTC date and time."), - ), - ], examples=[ SimpleExample("NOW() = #2019-01-23 12:53:07#"), ], diff --git a/lib/dl_formula_ref/dl_formula_ref/functions/operator.py b/lib/dl_formula_ref/dl_formula_ref/functions/operator.py index 0c438b5f7..fe332fb88 100644 --- a/lib/dl_formula_ref/dl_formula_ref/functions/operator.py +++ b/lib/dl_formula_ref/dl_formula_ref/functions/operator.py @@ -1,4 +1,5 @@ from dl_formula_ref.categories.operator import CATEGORY_OPERATOR +from dl_formula_ref.i18n.registry import FormulaRefTranslatable as Translatable from dl_formula_ref.localization import get_gettext from dl_formula_ref.registry.aliased_res import ( AliasedTableResource, @@ -248,12 +249,6 @@ "#2019-01-06 03# + 2.5 = #2019-01-08 15:00:00#", ) ], - notes=[ - Note( - level=NoteLevel.warning, - text=_("{dialects: METRIKAAPI} does not support string concatenation."), - ) - ], ) FUNCTION_OP_MINUS = FunctionDocRegistryItem( @@ -366,14 +361,6 @@ internal_name="op_comparison", ), description=_("Compares the value {arg:0} with the value {arg:1}."), - notes=[ - Note( - _( - "Due to implementation details of the {type:FLOAT} type in {dialects:CLICKHOUSE} sources " - "it is recommended to use the {ref:COMPARE} function instead of comparison operators for this type." - ), - ) - ], signature_gen=TemplatedSignatureGenerator( signature_templates=( SignatureTemplate(title=_("Equality"), body="{1} = {2}"), diff --git a/lib/dl_formula_ref/dl_formula_ref/functions/string.py b/lib/dl_formula_ref/dl_formula_ref/functions/string.py index 5b1bf712a..bfeb584c7 100644 --- a/lib/dl_formula_ref/dl_formula_ref/functions/string.py +++ b/lib/dl_formula_ref/dl_formula_ref/functions/string.py @@ -1,5 +1,6 @@ from dl_formula.core.datatype import DataType from dl_formula_ref.categories.string import CATEGORY_STRING +from dl_formula_ref.i18n.registry import FormulaRefTranslatable as Translatable from dl_formula_ref.localization import get_gettext from dl_formula_ref.registry.base import FunctionDocRegistryItem from dl_formula_ref.registry.example import SimpleExample @@ -258,7 +259,7 @@ ) _REGEXP_NOTES = [ - Note(_("See the documentation of the data source to clarify the regular expression syntax.")), + Note(Translatable("See the documentation of the data source to clarify the regular expression syntax.")), ] FUNCTION_REGEXP_EXTRACT = FunctionDocRegistryItem( @@ -343,6 +344,7 @@ FUNCTION_SPLIT = FunctionDocRegistryItem( name="split", category=CATEGORY_STRING, + # FIXME: Connectorize dialect mentions (https://github.com/datalens-tech/datalens-backend/issues/81) description=_( "Returns a substring from {arg:0} using the {arg:1} delimiter character to " "divide the string into a sequence of {arg:2} parts. Delimiter is a comma by " diff --git a/lib/dl_formula_ref/dl_formula_ref/functions/time_series.py b/lib/dl_formula_ref/dl_formula_ref/functions/time_series.py index 5de49d411..34d180d36 100644 --- a/lib/dl_formula_ref/dl_formula_ref/functions/time_series.py +++ b/lib/dl_formula_ref/dl_formula_ref/functions/time_series.py @@ -1,4 +1,5 @@ from dl_formula_ref.categories.time_series import CATEGORY_TIME_SERIES +from dl_formula_ref.i18n.registry import FormulaRefTranslatable as Translatable from dl_formula_ref.localization import get_gettext from dl_formula_ref.registry.base import FunctionDocRegistryItem from dl_formula_ref.registry.example import SimpleExample @@ -9,7 +10,11 @@ _NOTES_TIME_SERIES = [ - Note(_("The first argument must be a measure (aggregated expression), otherwise an " "error will be raised.")), + Note( + Translatable( + "The first argument must be a measure (aggregated expression), otherwise an " "error will be raised." + ) + ), ] FUNCTION_AGO = FunctionDocRegistryItem( diff --git a/lib/dl_formula_ref/dl_formula_ref/functions/type_conversion.py b/lib/dl_formula_ref/dl_formula_ref/functions/type_conversion.py index 79e676ffd..87cfeff24 100644 --- a/lib/dl_formula_ref/dl_formula_ref/functions/type_conversion.py +++ b/lib/dl_formula_ref/dl_formula_ref/functions/type_conversion.py @@ -9,6 +9,7 @@ WhitelistTypeSpec, ) from dl_formula_ref.categories.type_conversion import CATEGORY_TYPE_CONVERSION +from dl_formula_ref.i18n.registry import FormulaRefTranslatable as Translatable from dl_formula_ref.localization import get_gettext from dl_formula_ref.registry.aliased_res import ( AliasedResource, @@ -22,7 +23,7 @@ Note, NoteLevel, ) -from dl_i18n.localizer_base import Translatable +from dl_i18n.localizer_base import Translatable as BaseTranslatable _ = get_gettext() @@ -41,20 +42,8 @@ ), notes=[ Note( - _("Argument {arg:1} is available only for {dialects:CLICKHOUSE} " "sources."), - ), - Note( - _( - "For {dialects:CLICKHOUSE} data sources, numeric {arg:0} values less than or " - "equal to `65535` are interpreted as the number of days (not seconds, like in " - "all other cases) since January 1st 1970. This is the result of the behavior " - "of available {dialects:CLICKHOUSE} functions.\n" - "\n" - "One way to surpass this is to use the following formula: " - "`DATE(DATETIME([value]))`. The result is more consistent, but is likely to " - "be much slower." - ), - level=NoteLevel.warning, + # FIXME: Connectorize dialect mentions (https://github.com/datalens-tech/datalens-backend/issues/81) + Translatable("Argument {arg:1} is available only for {dialects:CLICKHOUSE} " "sources."), ), ], examples=[ @@ -76,7 +65,7 @@ ), notes=[ Note( - _("Argument {arg:1} is available only for {dialects:CLICKHOUSE} " "sources."), + Translatable("Argument {arg:1} is available only for {dialects:CLICKHOUSE} " "sources."), ), ], examples=[ @@ -202,7 +191,7 @@ ], notes=[ Note( - _( + Translatable( "If an array is passed (only for {dialects:CLICKHOUSE|POSTGRESQL} sources), the conversion is " "performed by a function in the source database and results may vary for different data sources. " "For consistent results use {ref:ARR_STR}." @@ -296,17 +285,17 @@ def _make_type_macro_from_dtype_spec(data_type_spec: DataTypeSpec) -> str: raise TypeError(type(data_type_spec)) -def _get_comment_for_type(dialect: DialectCombo, native_type_name: str) -> str | Translatable: +def _get_comment_for_type(dialect: DialectCombo, native_type_name: str) -> str | BaseTranslatable: return _DB_CAST_TYPE_COMMENTS.get((dialect, native_type_name), "") @attr.s class DbCastExtension: type_whitelists: dict[DialectCombo, dict[DataType, list[WhitelistTypeSpec]]] = attr.ib(kw_only=True, factory=dict) - type_comments: dict[tuple[DialectCombo, str], str | Translatable] = attr.ib(kw_only=True, factory=dict) + type_comments: dict[tuple[DialectCombo, str], str | BaseTranslatable] = attr.ib(kw_only=True, factory=dict) -_DB_CAST_TYPE_COMMENTS: dict[tuple[DialectCombo, str], str | Translatable] = {} +_DB_CAST_TYPE_COMMENTS: dict[tuple[DialectCombo, str], str | BaseTranslatable] = {} _DB_CAST_WHITELIST: dict[DialectCombo, dict[DataType, list[WhitelistTypeSpec]]] = {} diff --git a/lib/dl_formula_ref/dl_formula_ref/functions/window.py b/lib/dl_formula_ref/dl_formula_ref/functions/window.py index 34ecce3a4..ebdeecfbf 100644 --- a/lib/dl_formula_ref/dl_formula_ref/functions/window.py +++ b/lib/dl_formula_ref/dl_formula_ref/functions/window.py @@ -6,6 +6,7 @@ ExampleConfig, ExampleSource, ) +from dl_formula_ref.i18n.registry import FormulaRefTranslatable as Translatable from dl_formula_ref.localization import get_gettext from dl_formula_ref.registry.aliased_res import ( AliasedTableResource, @@ -387,7 +388,7 @@ def _make_simple_order_by_examples(func: str) -> List[DataExample]: _ORDERED_WFUNC_NOTES = [ Note( level=NoteLevel.warning, - text=_( + text=Translatable( "The sorting order is based on the fields listed in the sorting section of " "the chart and in the `ORDER BY` clause. First, `ORDER BY` fields are used, " "and then they are complemented by the fields from the chart." diff --git a/lib/dl_formula_ref/dl_formula_ref/locales/en/LC_MESSAGES/dl_formula_ref_dl_formula_ref.po b/lib/dl_formula_ref/dl_formula_ref/locales/en/LC_MESSAGES/dl_formula_ref_dl_formula_ref.po index cbda939e0..2a2159fa2 100644 --- a/lib/dl_formula_ref/dl_formula_ref/locales/en/LC_MESSAGES/dl_formula_ref_dl_formula_ref.po +++ b/lib/dl_formula_ref/dl_formula_ref/locales/en/LC_MESSAGES/dl_formula_ref_dl_formula_ref.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: datalens-opensource@yandex-team.ru\n" -"POT-Creation-Date: 2023-11-01 14:19+0000\n" +"POT-Creation-Date: 2023-09-22 08:16+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -777,12 +777,6 @@ msgstr "" msgid "Expands the {arg:0} array expression to a set of rows." msgstr "" -msgid "" -"{dialects: POSTGRESQL} doesn't allow filtering fields containing the UNNEST " -"function. If the data source is {dialects: POSTGRESQL}, do not use such " -"fields in selectors." -msgstr "" - msgid "" "Returns the element with the index {arg:1} from the array {arg:0}. Index " "must be any integer. Indexes in an array begin with one." @@ -930,11 +924,6 @@ msgid "" "- `\"year\"`." msgstr "" -msgid "" -"The function with three arguments is only available for the sources " -"{dialects:CLICKHOUSE_21_8} or higher." -msgstr "" - msgid "" "Returns the number of the second in the minute of the specified date " "{arg:0}. When the date is specified without time, it returns `0`." @@ -992,9 +981,6 @@ msgid "" "connection type." msgstr "" -msgid "On {dialects:YQL}, the function always returns the UTC date and time." -msgstr "" - msgid "" "Returns the current date, depending on the data source and connection type." msgstr "" @@ -1276,9 +1262,6 @@ msgstr "" msgid "The merging (concatenation) of arrays {arg:0} and {arg:1}." msgstr "" -msgid "{dialects: METRIKAAPI} does not support string concatenation." -msgstr "" - msgid "Subtraction (-)" msgstr "" @@ -1327,12 +1310,6 @@ msgstr "" msgid "Compares the value {arg:0} with the value {arg:1}." msgstr "" -msgid "" -"Due to implementation details of the {type:FLOAT} type in {dialects:" -"CLICKHOUSE} sources it is recommended to use the {ref:COMPARE} function " -"instead of comparison operators for this type." -msgstr "" - msgid "Equality" msgstr "" @@ -1549,17 +1526,6 @@ msgstr "" msgid "Argument {arg:1} is available only for {dialects:CLICKHOUSE} sources." msgstr "" -msgid "" -"For {dialects:CLICKHOUSE} data sources, numeric {arg:0} values less than or " -"equal to `65535` are interpreted as the number of days (not seconds, like in " -"all other cases) since January 1st 1970. This is the result of the behavior " -"of available {dialects:CLICKHOUSE} functions.\n" -"\n" -"One way to surpass this is to use the following formula: " -"`DATE(DATETIME([value]))`. The result is more consistent, but is likely to " -"be much slower." -msgstr "" - msgid "" "Converts the {arg:0} expression to date and time format. When converting " "`Date` to `DateTime`, the time is set to '00:00:00'.\n" diff --git a/lib/dl_formula_ref/dl_formula_ref/locales/ru/LC_MESSAGES/dl_formula_ref_dl_formula_ref.mo b/lib/dl_formula_ref/dl_formula_ref/locales/ru/LC_MESSAGES/dl_formula_ref_dl_formula_ref.mo index 78ab1efcc1df5f8ac549c2f20463d0e1cfd63649..a5f0064eabc45bc561ccf396e641bd2c48c5e163 100644 GIT binary patch delta 7302 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 TI&ZE8tx7plsW|0|8EpOs4ImY< delta 9333 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 M#4S3?HRI9$1w3u%4*&oF diff --git a/lib/dl_formula_ref/dl_formula_ref/locales/ru/LC_MESSAGES/dl_formula_ref_dl_formula_ref.po b/lib/dl_formula_ref/dl_formula_ref/locales/ru/LC_MESSAGES/dl_formula_ref_dl_formula_ref.po index cc81cfe9e..62ec84256 100644 --- a/lib/dl_formula_ref/dl_formula_ref/locales/ru/LC_MESSAGES/dl_formula_ref_dl_formula_ref.po +++ b/lib/dl_formula_ref/dl_formula_ref/locales/ru/LC_MESSAGES/dl_formula_ref_dl_formula_ref.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: datalens-opensource@yandex-team.ru\n" -"POT-Creation-Date: 2023-09-15 14:28+0000\n" +"POT-Creation-Date: 2023-09-22 08:16+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -1202,15 +1202,6 @@ msgstr "" msgid "Expands the {arg:0} array expression to a set of rows." msgstr "Дублирует исходную строку для каждого элемента массива {arg:0}." -msgid "" -"{dialects: POSTGRESQL} doesn't allow filtering fields containing the UNNEST " -"function. If the data source is {dialects: POSTGRESQL}, do not use such " -"fields in selectors." -msgstr "" -"{dialects: POSTGRESQL} запрещает фильтрацию по полям, содержащим функцию " -"`UNNEST`. Не используйте такие поля для создания селектора, если источник " -"данных — {dialects: POSTGRESQL}." - msgid "" "Returns the element with the index {arg:1} from the array {arg:0}. Index " "must be any integer. Indexes in an array begin with one." @@ -1431,13 +1422,6 @@ msgstr "" "- `\"quarter\"`;\n" "- `\"year\"`." -msgid "" -"The function with three arguments is only available for the sources " -"{dialects:CLICKHOUSE_21_8} or higher." -msgstr "" -"Функция с тремя аргументами доступна только для источников {dialects:" -"CLICKHOUSE_21_8} и выше." - msgid "" "Returns the number of the second in the minute of the specified date " "{arg:0}. When the date is specified without time, it returns `0`." @@ -1519,9 +1503,6 @@ msgstr "" "Возвращает текущую дату и время в зависимости от источника данных и типа " "соединения." -msgid "On {dialects:YQL}, the function always returns the UTC date and time." -msgstr "В {dialects:YQL} функция всегда возвращает дату и время в зоне UTC." - msgid "" "Returns the current date, depending on the data source and connection type." msgstr "" @@ -1889,9 +1870,6 @@ msgstr "Объединение (конкатенация) строк {arg:0} и msgid "The merging (concatenation) of arrays {arg:0} and {arg:1}." msgstr "Объединение (конкатенация) массивов {arg:0} и {arg:1}." -msgid "{dialects: METRIKAAPI} does not support string concatenation." -msgstr "{dialects: METRIKAAPI} не поддерживает конкатенацию строк." - msgid "Subtraction (-)" msgstr "Вычитание (-)" @@ -1957,15 +1935,6 @@ msgstr "Сравнение" msgid "Compares the value {arg:0} with the value {arg:1}." msgstr "Сравнивают значение {arg:0} со значением {arg:1}." -msgid "" -"Due to implementation details of the {type:FLOAT} type in {dialects:" -"CLICKHOUSE} sources it is recommended to use the {ref:COMPARE} function " -"instead of comparison operators for this type." -msgstr "" -"Из-за особенностей реализации типа {type:FLOAT} в источниках {dialects:" -"CLICKHOUSE} рекомендуется для этого типа использовать функцию {ref:COMPARE} " -"вместо операторов сравнения." - msgid "Equality" msgstr "Равенство" @@ -2266,25 +2235,6 @@ msgstr "" msgid "Argument {arg:1} is available only for {dialects:CLICKHOUSE} sources." msgstr "Параметр {arg:1} доступен только для источников {dialects:CLICKHOUSE}." -msgid "" -"For {dialects:CLICKHOUSE} data sources, numeric {arg:0} values less than or " -"equal to `65535` are interpreted as the number of days (not seconds, like in " -"all other cases) since January 1st 1970. This is the result of the behavior " -"of available {dialects:CLICKHOUSE} functions.\n" -"\n" -"One way to surpass this is to use the following formula: " -"`DATE(DATETIME([value]))`. The result is more consistent, but is likely to " -"be much slower." -msgstr "" -"Источники {dialects:CLICKHOUSE} воспринимают числовые значения {arg:0} " -"меньше или равные `65535` как количество дней (не секунд, как во всех " -"остальных случаях) с 1 января 1970 г. Это следствие поведения доступных в " -"{dialects:CLICKHOUSE} функций.\n" -"\n" -"Чтобы обойти это, воспользуйтесь формулой: `DATE(DATETIME([value]))`. " -"Формула имеет более корректное поведение, но может работать значительно " -"медленнее." - msgid "" "Converts the {arg:0} expression to date and time format. When converting " "`Date` to `DateTime`, the time is set to '00:00:00'.\n" diff --git a/lib/dl_formula_ref/dl_formula_ref/plugins/base/plugin.py b/lib/dl_formula_ref/dl_formula_ref/plugins/base/plugin.py index 090bff164..790c65d07 100644 --- a/lib/dl_formula_ref/dl_formula_ref/plugins/base/plugin.py +++ b/lib/dl_formula_ref/dl_formula_ref/plugins/base/plugin.py @@ -5,6 +5,7 @@ ConfigVersion, RefDocGeneratorConfig, ) +from dl_formula_ref.function_extension import FunctionExtension from dl_formula_ref.functions.type_conversion import DbCastExtension from dl_formula_ref.texts import StyledDialect from dl_i18n.localizer_base import TranslationConfig @@ -25,3 +26,6 @@ class FormulaRefPlugin: # Connector-specific types and comments for the DB_CAST function db_cast_extension: ClassVar[DbCastExtension] = DbCastExtension() + + # Dialect-specific extensions for functions + function_extensions: list[FunctionExtension] = [] diff --git a/lib/dl_formula_ref/dl_formula_ref/plugins/registration.py b/lib/dl_formula_ref/dl_formula_ref/plugins/registration.py index 9da469e0c..e65724945 100644 --- a/lib/dl_formula_ref/dl_formula_ref/plugins/registration.py +++ b/lib/dl_formula_ref/dl_formula_ref/plugins/registration.py @@ -1,6 +1,7 @@ from typing import Type from dl_formula_ref.config import register_config_version +from dl_formula_ref.function_extension import register_function_extension from dl_formula_ref.functions.type_conversion import register_db_cast_extension from dl_formula_ref.i18n.registry import register_translation_configs from dl_formula_ref.plugins.base.plugin import FormulaRefPlugin @@ -22,5 +23,8 @@ def register_plugin(self, plugin_cls: Type[FormulaRefPlugin]) -> None: register_compeng_support_dialects(plugin_cls.compeng_support_dialects) register_db_cast_extension(plugin_cls.db_cast_extension) + for func_ext in plugin_cls.function_extensions: + register_function_extension(func_ext) + FORMULA_REF_PLUGIN_REG = FormulaRefPluginRegistrator() diff --git a/lib/dl_formula_ref/dl_formula_ref/registry/base.py b/lib/dl_formula_ref/dl_formula_ref/registry/base.py index a1ca02d16..d0ea8d685 100644 --- a/lib/dl_formula_ref/dl_formula_ref/registry/base.py +++ b/lib/dl_formula_ref/dl_formula_ref/registry/base.py @@ -11,6 +11,7 @@ import attr from dl_formula.core.dialect import DialectCombo +from dl_formula_ref.function_extension import FunctionExtension from dl_formula_ref.registry.aliased_res import ( AliasedResourceRegistryBase, SimpleAliasedResourceRegistry, @@ -166,3 +167,11 @@ def is_supported(self, env: GenerationEnvironment) -> bool: def get_args(self, env: GenerationEnvironment) -> List[_arg_base.FuncArg]: return self._arg_extractor.get_args(self, env=env) + + def extend(self, dialect: DialectCombo, notes: tuple[Note, ...]) -> FunctionExtension: + return FunctionExtension( + function_name=self.name, + category_name=self.category_name, + dialect_combo=dialect, + notes=notes, + ) diff --git a/lib/dl_formula_ref/dl_formula_ref/registry/note.py b/lib/dl_formula_ref/dl_formula_ref/registry/note.py index be3a34bb5..b9fa9855e 100644 --- a/lib/dl_formula_ref/dl_formula_ref/registry/note.py +++ b/lib/dl_formula_ref/dl_formula_ref/registry/note.py @@ -1,15 +1,13 @@ from __future__ import annotations from enum import Enum -from typing import ( - Any, - NamedTuple, -) +from typing import NamedTuple import attr from dl_formula_ref.registry.scopes import SCOPES_DEFAULT from dl_formula_ref.registry.text import ParameterizedText +from dl_i18n.localizer_base import Translatable class NoteLevel(Enum): @@ -18,14 +16,12 @@ class NoteLevel(Enum): alert = "alert" -class Note(NamedTuple): - text: str - level: NoteLevel = NoteLevel.info - formatting: bool = True - scopes: int = SCOPES_DEFAULT - - def format(self, *args: Any, **kwargs: Any) -> Note: - return self._replace(text=self.text.format(*args, **kwargs)) +@attr.s(frozen=True) +class Note: + text: Translatable = attr.ib() + level: NoteLevel = attr.ib(kw_only=True, default=NoteLevel.info) + formatting: bool = attr.ib(kw_only=True, default=True) + scopes: int = attr.ib(kw_only=True, default=SCOPES_DEFAULT) class NoteType(Enum): diff --git a/lib/dl_formula_ref/dl_formula_ref/registry/note_extractor.py b/lib/dl_formula_ref/dl_formula_ref/registry/note_extractor.py index f7a6913bf..c5bfde00e 100644 --- a/lib/dl_formula_ref/dl_formula_ref/registry/note_extractor.py +++ b/lib/dl_formula_ref/dl_formula_ref/registry/note_extractor.py @@ -2,6 +2,7 @@ from typing import TYPE_CHECKING +from dl_formula_ref.function_extension import get_function_extension_notes from dl_formula_ref.registry.arg_common import TypeStrategyInspector from dl_formula_ref.registry.note import ( NoteType, @@ -24,14 +25,20 @@ def get_notes( env: GenerationEnvironment, ) -> list[ParameterizedNote]: # explicitly defined notes + # - from function definition + # - from extensions + raw_notes = [ + *item.get_explicit_notes(env=env), + *get_function_extension_notes(category=item.category_name, name=item.name, env=env), + ] notes = [ ParameterizedNote( - param_text=ParameterizedText.from_str(text=note.text), + param_text=ParameterizedText(text=note.text), level=note.level, formatting=note.formatting, type=NoteType.REGULAR, ) - for note in item.get_explicit_notes(env=env) + for note in raw_notes ] args = item.get_args(env=env)