From 92e69821e11a254073fd126a892793f27c764feb Mon Sep 17 00:00:00 2001 From: ckunki Date: Wed, 4 Feb 2026 12:21:14 +0100 Subject: [PATCH 01/11] #127: Refactored class `ParameterFormatters` and docstrings --- doc/changes/unreleased.md | 4 + .../cli/std_options.py | 113 ++++++++++++------ test/unit/cli/test_std_options.py | 17 +-- 3 files changed, 88 insertions(+), 46 deletions(-) diff --git a/doc/changes/unreleased.md b/doc/changes/unreleased.md index 79e701b..865006d 100644 --- a/doc/changes/unreleased.md +++ b/doc/changes/unreleased.md @@ -1 +1,5 @@ # Unreleased + +## Refactorings + +* #127: Refactored class `ParameterFormatters` and docstrings diff --git a/exasol/python_extension_common/cli/std_options.py b/exasol/python_extension_common/cli/std_options.py index 15421ca..1a2a5d9 100644 --- a/exasol/python_extension_common/cli/std_options.py +++ b/exasol/python_extension_common/cli/std_options.py @@ -1,10 +1,12 @@ import os import re +from dataclasses import dataclass from enum import ( Enum, Flag, auto, ) +from pathlib import Path from typing import ( Any, no_type_check, @@ -13,56 +15,91 @@ import click -class ParameterFormatters: - """ - Class facilitating customization of the cli. - - The idea is that some of the cli parameters can be programmatically customized based - on values of other parameters and externally supplied formatters. For example a specialized - version of the cli may want to provide its own url. Furthermore, this url will depend on - the user supplied parameter called "version". The solution is to set a formatter for the - url, for instance "http://my_stuff/{version}/my_data". If the user specifies non-empty version - parameter the url will be fully formed. +@dataclass(frozen=True) +class Param: + name: str | None + value: Any | None - A formatter may include more than one parameter. In the previous example the url could, - for instance, also include a username: "http://my_stuff/{version}/{user}/my_data". - Note that customized parameters can only be updated in a callback function. There is no - way to inject them directly into the cli. Also, the current implementation doesn't perform - the update if the value of the parameter dressed with the callback is None. +class ParamUpdater: """ + Dynamic update for customized CLI parameters. + + Example: A specialized variant of the CLI may want to provide a custom URL + "http://prefix/{version}/suffix" depending on CLI parameter "version". If + the user specifies version "1.2.3", then the default value for the URL + should be updated to "http://prefix/1.2.3/suffix". - def __init__(self): - self._formatters: dict[str, str] = {} + The URL parameter in this example is called a _destination_ CLI parameter + while the version is called _source_. - def __call__(self, ctx: click.Context, param: click.Parameter, value: Any | None) -> Any | None: + A destination parameter can depend on a single or multiple source + parameters. In the previous example the URL could, for instance, also + include a username: "http://prefix/{version}/{user}/suffix". - def update_parameter(parameter_name: str, formatter: str) -> None: - param_formatter = ctx.params.get(parameter_name, formatter) - if param_formatter: - # Enclose in double curly brackets all other parameters in the formatting string, - # to avoid the missing parameters' error. Below is an example of a formatter string - # before and after applying the regex, assuming the current parameter is 'version'. - # 'something-with-{version}/tailored-for-{user}' => 'something-with-{version}/tailored-for-{{user}}' - # We were looking for all occurrences of a pattern '{some_name}', where some_name is not version. - pattern = r"\{(?!" + (param.name or "") + r"\})\w+\}" - param_formatter = re.sub(pattern, lambda m: f"{{{m.group(0)}}}", param_formatter) - kwargs = {param.name: value} - ctx.params[parameter_name] = param_formatter.format(**kwargs) # type: ignore + The Click API allows updating customized parameters only in a callback + function. There is no way to inject them directly into the CLI, see + https://click.palletsprojects.com/en/stable/api/#click.Command.callback. - if value is not None: - for prm_name, prm_formatter in self._formatters.items(): - update_parameter(prm_name, prm_formatter) + The current implementation updates the destination parameter only if the + value of the source parameter is not ``None``. + """ - return value + def __init__(self) -> None: + # list of destination parameters to update + self._parameters: dict[str, str] = {} + + def __call__( + self, ctx: click.Context, source_param: click.Parameter, value: Any | None + ) -> Any | None: + def update(source: Param, dest: Param) -> None: + if not dest.value: + return None + # Enclose in double curly brackets all other parameters in + # dest.value to avoid error "missing parameters". + # + # Below is an example of a formatter string before and after + # applying the regex, assuming the source parameter is 'version'. + # + # "something-with-{version}/tailored-for-{user}" => + # "something-with-{version}/tailored-for-{{user}}" + # + # We were looking for all occurrences of a pattern "{xxx}", where + # xxx is not "version". + pattern = r"\{(?!" + (source.name or "") + r"\})\w+\}" + template = re.sub(pattern, lambda m: f"{{{m.group(0)}}}", dest.value) + kwargs = {source.name: source.value} + ctx.params[dest.name] = template.format(**kwargs) # type: ignore + + source = Param(source_param.name, value) + if source.value is not None: + for name, default in self._parameters.items(): + value = ctx.params.get(name, default) + update(source, dest=Param(name, value)) + + return source.value + + def update(self, param_name: str, default_value: str) -> None: + """Tags the specified destination parameter for update.""" + self._parameters[param_name] = default_value + + def clear(self): + """Deletes all destination parameters to be updated, mainly for testing purposes.""" + self._parameters.clear() + + +class ParameterFormatters(ParamUpdater): + """ + This class is deprecated. Please use ParamUpdater instead. + """ def set_formatter(self, custom_parameter_name: str, formatter: str) -> None: - """Sets a formatter for a customizable parameter.""" - self._formatters[custom_parameter_name] = formatter + """Deprecated. Please update() instead.""" + self.update(custom_parameter_name, formatter) def clear_formatters(self): - """Deletes all formatters, mainly for testing purposes.""" - self._formatters.clear() + """Deprecated. Please use clear() instead.""" + self.clear() # This text will be displayed instead of the actual value for a "secret" option. diff --git a/test/unit/cli/test_std_options.py b/test/unit/cli/test_std_options.py index 5eff577..ea59e8b 100644 --- a/test/unit/cli/test_std_options.py +++ b/test/unit/cli/test_std_options.py @@ -7,6 +7,7 @@ from exasol.python_extension_common.cli.std_options import ( SECRET_DISPLAY, ParameterFormatters, + ParamUpdater, StdParams, StdTags, check_params, @@ -24,8 +25,8 @@ def test_parameter_formatters_1param(): cmd = click.Command("a_command") ctx = click.Context(cmd) opt = click.Option(["--version"]) - formatters = ParameterFormatters() - formatters.set_formatter(container_url_param, "http://my_server/{version}/my_stuff") + formatters = ParamUpdater() + formatters.update(container_url_param, "http://my_server/{version}/my_stuff") formatters(ctx, opt, "1.3.2") assert ctx.params[container_url_param] == "http://my_server/1.3.2/my_stuff" @@ -37,9 +38,9 @@ def test_parameter_formatters_2params(): ctx = click.Context(cmd) opt1 = click.Option(["--version"]) opt2 = click.Option(["--user"]) - formatters = ParameterFormatters() - formatters.set_formatter(container_url_param, "http://my_server/{version}/{user}/my_stuff") - formatters.set_formatter(container_name_param, "downloaded-{version}") + formatters = ParamUpdater() + formatters.update(container_url_param, "http://my_server/{version}/{user}/my_stuff") + formatters.update(container_name_param, "downloaded-{version}") formatters(ctx, opt1, "1.3.2") formatters(ctx, opt2, "cezar") assert ctx.params[container_url_param] == "http://my_server/1.3.2/cezar/my_stuff" @@ -135,9 +136,9 @@ def func(**kwargs): assert kwargs[container_name_arg] == expected_name assert kwargs[container_url_arg] == expected_url - ver_formatter = ParameterFormatters() - ver_formatter.set_formatter(container_url_arg, url_format) - ver_formatter.set_formatter(container_name_arg, name_format) + ver_formatter = ParamUpdater() + ver_formatter.update(container_url_arg, url_format) + ver_formatter.update(container_name_arg, name_format) opts = select_std_options(StdTags.SLC, formatters={StdParams.version: ver_formatter}) cmd = click.Command("do_something", params=opts, callback=func) From b62ba7f753b568f077d98cf051fcdd71a33c1bb0 Mon Sep 17 00:00:00 2001 From: ckunki Date: Wed, 4 Feb 2026 12:26:55 +0100 Subject: [PATCH 02/11] Renamed variables in test --- test/unit/cli/test_std_options.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/test/unit/cli/test_std_options.py b/test/unit/cli/test_std_options.py index ea59e8b..d50bdf6 100644 --- a/test/unit/cli/test_std_options.py +++ b/test/unit/cli/test_std_options.py @@ -20,29 +20,29 @@ ) -def test_parameter_formatters_1param(): +def test_parameter_updater_1param(): container_url_param = "container_url" cmd = click.Command("a_command") ctx = click.Context(cmd) opt = click.Option(["--version"]) - formatters = ParamUpdater() - formatters.update(container_url_param, "http://my_server/{version}/my_stuff") - formatters(ctx, opt, "1.3.2") + updater = ParamUpdater() + updater.update(container_url_param, "http://my_server/{version}/my_stuff") + updater(ctx, opt, "1.3.2") assert ctx.params[container_url_param] == "http://my_server/1.3.2/my_stuff" -def test_parameter_formatters_2params(): +def test_parameter_updater_2params(): container_url_param = "container_url" container_name_param = "container_name" cmd = click.Command("a_command") ctx = click.Context(cmd) opt1 = click.Option(["--version"]) opt2 = click.Option(["--user"]) - formatters = ParamUpdater() - formatters.update(container_url_param, "http://my_server/{version}/{user}/my_stuff") - formatters.update(container_name_param, "downloaded-{version}") - formatters(ctx, opt1, "1.3.2") - formatters(ctx, opt2, "cezar") + updater = ParamUpdater() + updater.update(container_url_param, "http://my_server/{version}/{user}/my_stuff") + updater.update(container_name_param, "downloaded-{version}") + updater(ctx, opt1, "1.3.2") + updater(ctx, opt2, "cezar") assert ctx.params[container_url_param] == "http://my_server/1.3.2/cezar/my_stuff" assert ctx.params[container_name_param] == "downloaded-1.3.2" @@ -136,11 +136,11 @@ def func(**kwargs): assert kwargs[container_name_arg] == expected_name assert kwargs[container_url_arg] == expected_url - ver_formatter = ParamUpdater() - ver_formatter.update(container_url_arg, url_format) - ver_formatter.update(container_name_arg, name_format) + ver_updater = ParamUpdater() + ver_updater.update(container_url_arg, url_format) + ver_updater.update(container_name_arg, name_format) - opts = select_std_options(StdTags.SLC, formatters={StdParams.version: ver_formatter}) + opts = select_std_options(StdTags.SLC, formatters={StdParams.version: ver_updater}) cmd = click.Command("do_something", params=opts, callback=func) runner = CliRunner() runner.invoke(cmd, args=f"--version {version}", catch_exceptions=False, standalone_mode=False) From f3fcfc0a64414df534d6848f18205c3c1819b2a1 Mon Sep 17 00:00:00 2001 From: ckunki Date: Wed, 4 Feb 2026 12:29:09 +0100 Subject: [PATCH 03/11] Renamed method --- exasol/python_extension_common/cli/std_options.py | 8 ++++---- test/unit/cli/test_std_options.py | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/exasol/python_extension_common/cli/std_options.py b/exasol/python_extension_common/cli/std_options.py index 1a2a5d9..b45566c 100644 --- a/exasol/python_extension_common/cli/std_options.py +++ b/exasol/python_extension_common/cli/std_options.py @@ -79,8 +79,8 @@ def update(source: Param, dest: Param) -> None: return source.value - def update(self, param_name: str, default_value: str) -> None: - """Tags the specified destination parameter for update.""" + def set(self, param_name: str, default_value: str) -> None: + """Adds the specified destination parameter to be updated.""" self._parameters[param_name] = default_value def clear(self): @@ -94,8 +94,8 @@ class ParameterFormatters(ParamUpdater): """ def set_formatter(self, custom_parameter_name: str, formatter: str) -> None: - """Deprecated. Please update() instead.""" - self.update(custom_parameter_name, formatter) + """Deprecated. Please set() instead.""" + self.set(custom_parameter_name, formatter) def clear_formatters(self): """Deprecated. Please use clear() instead.""" diff --git a/test/unit/cli/test_std_options.py b/test/unit/cli/test_std_options.py index d50bdf6..6b51e9f 100644 --- a/test/unit/cli/test_std_options.py +++ b/test/unit/cli/test_std_options.py @@ -26,7 +26,7 @@ def test_parameter_updater_1param(): ctx = click.Context(cmd) opt = click.Option(["--version"]) updater = ParamUpdater() - updater.update(container_url_param, "http://my_server/{version}/my_stuff") + updater.set(container_url_param, "http://my_server/{version}/my_stuff") updater(ctx, opt, "1.3.2") assert ctx.params[container_url_param] == "http://my_server/1.3.2/my_stuff" @@ -39,8 +39,8 @@ def test_parameter_updater_2params(): opt1 = click.Option(["--version"]) opt2 = click.Option(["--user"]) updater = ParamUpdater() - updater.update(container_url_param, "http://my_server/{version}/{user}/my_stuff") - updater.update(container_name_param, "downloaded-{version}") + updater.set(container_url_param, "http://my_server/{version}/{user}/my_stuff") + updater.set(container_name_param, "downloaded-{version}") updater(ctx, opt1, "1.3.2") updater(ctx, opt2, "cezar") assert ctx.params[container_url_param] == "http://my_server/1.3.2/cezar/my_stuff" @@ -137,8 +137,8 @@ def func(**kwargs): assert kwargs[container_url_arg] == expected_url ver_updater = ParamUpdater() - ver_updater.update(container_url_arg, url_format) - ver_updater.update(container_name_arg, name_format) + ver_updater.set(container_url_arg, url_format) + ver_updater.set(container_name_arg, name_format) opts = select_std_options(StdTags.SLC, formatters={StdParams.version: ver_updater}) cmd = click.Command("do_something", params=opts, callback=func) From 22d311ba353801611e21676743d9c1d3d0beec7f Mon Sep 17 00:00:00 2001 From: ckunki Date: Wed, 4 Feb 2026 12:34:57 +0100 Subject: [PATCH 04/11] Added comment to deployment.language_container_deployer_cli --- .../deployment/language_container_deployer_cli.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/exasol/python_extension_common/deployment/language_container_deployer_cli.py b/exasol/python_extension_common/deployment/language_container_deployer_cli.py index 76a57d2..58f2425 100644 --- a/exasol/python_extension_common/deployment/language_container_deployer_cli.py +++ b/exasol/python_extension_common/deployment/language_container_deployer_cli.py @@ -28,6 +28,8 @@ class CustomizableParameters(Enum): class _ParameterFormatters: + # Is this class still needed? + # Or could it be replaced by std_options.ParamUpdater? """ Class facilitating customization of the cli. From e38ba91b1e629e4ef81d60d0abb9793355a41002 Mon Sep 17 00:00:00 2001 From: ckunki Date: Wed, 4 Feb 2026 13:19:34 +0100 Subject: [PATCH 05/11] Updated docstring of function select_std_options --- exasol/python_extension_common/cli/std_options.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/exasol/python_extension_common/cli/std_options.py b/exasol/python_extension_common/cli/std_options.py index b45566c..4e77703 100644 --- a/exasol/python_extension_common/cli/std_options.py +++ b/exasol/python_extension_common/cli/std_options.py @@ -290,6 +290,13 @@ def select_std_options( override: A dictionary of standard options with overridden properties formatters: + A dictionary, with each key being a source CLI parameter, + see docstring of class ParamUpdater. + + Each value is an instance of ParamUpdater representing a single or + multiple destination parameters to be updated based on the source + parameter's value. A destination parameter can be updated multiple + times, if it depends on multiple source parameters. """ if not isinstance(tags, list) and not isinstance(tags, str): tags = [tags] From e6e089de19d63128e7e996062fe020c65aabf93c Mon Sep 17 00:00:00 2001 From: ckunki Date: Wed, 4 Feb 2026 13:38:22 +0100 Subject: [PATCH 06/11] Updated docstring --- exasol/python_extension_common/cli/std_options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exasol/python_extension_common/cli/std_options.py b/exasol/python_extension_common/cli/std_options.py index 4e77703..7dfed91 100644 --- a/exasol/python_extension_common/cli/std_options.py +++ b/exasol/python_extension_common/cli/std_options.py @@ -94,7 +94,7 @@ class ParameterFormatters(ParamUpdater): """ def set_formatter(self, custom_parameter_name: str, formatter: str) -> None: - """Deprecated. Please set() instead.""" + """Deprecated. Please use set() instead.""" self.set(custom_parameter_name, formatter) def clear_formatters(self): From 9a08f85167dded1937b39cb0f63427a3f165daa5 Mon Sep 17 00:00:00 2001 From: ckunki Date: Wed, 4 Feb 2026 14:08:40 +0100 Subject: [PATCH 07/11] Reverted renaming --- .../cli/std_options.py | 22 +++----------- .../language_container_deployer_cli.py | 7 +++-- test/unit/cli/test_std_options.py | 29 +++++++++---------- 3 files changed, 23 insertions(+), 35 deletions(-) diff --git a/exasol/python_extension_common/cli/std_options.py b/exasol/python_extension_common/cli/std_options.py index 7dfed91..683f409 100644 --- a/exasol/python_extension_common/cli/std_options.py +++ b/exasol/python_extension_common/cli/std_options.py @@ -21,9 +21,9 @@ class Param: value: Any | None -class ParamUpdater: +class ParameterFormatters: """ - Dynamic update for customized CLI parameters. + Dynamic update for customized Click CLI parameters. Example: A specialized variant of the CLI may want to provide a custom URL "http://prefix/{version}/suffix" depending on CLI parameter "version". If @@ -79,29 +79,15 @@ def update(source: Param, dest: Param) -> None: return source.value - def set(self, param_name: str, default_value: str) -> None: + def set_formatter(self, param_name: str, default_value: str) -> None: """Adds the specified destination parameter to be updated.""" self._parameters[param_name] = default_value - def clear(self): + def clear_formatters(self): """Deletes all destination parameters to be updated, mainly for testing purposes.""" self._parameters.clear() -class ParameterFormatters(ParamUpdater): - """ - This class is deprecated. Please use ParamUpdater instead. - """ - - def set_formatter(self, custom_parameter_name: str, formatter: str) -> None: - """Deprecated. Please use set() instead.""" - self.set(custom_parameter_name, formatter) - - def clear_formatters(self): - """Deprecated. Please use clear() instead.""" - self.clear() - - # This text will be displayed instead of the actual value for a "secret" option. SECRET_DISPLAY = "***" diff --git a/exasol/python_extension_common/deployment/language_container_deployer_cli.py b/exasol/python_extension_common/deployment/language_container_deployer_cli.py index 58f2425..df6a75b 100644 --- a/exasol/python_extension_common/deployment/language_container_deployer_cli.py +++ b/exasol/python_extension_common/deployment/language_container_deployer_cli.py @@ -28,8 +28,11 @@ class CustomizableParameters(Enum): class _ParameterFormatters: - # Is this class still needed? - # Or could it be replaced by std_options.ParamUpdater? + # See language_container_deployer_main displaying a deprecation warning. + # + # Currently, there is only one other project still using this + # implementation, see + # https://github.com/exasol/advanced-analytics-framework/issues/333. """ Class facilitating customization of the cli. diff --git a/test/unit/cli/test_std_options.py b/test/unit/cli/test_std_options.py index 6b51e9f..c0908cd 100644 --- a/test/unit/cli/test_std_options.py +++ b/test/unit/cli/test_std_options.py @@ -7,7 +7,6 @@ from exasol.python_extension_common.cli.std_options import ( SECRET_DISPLAY, ParameterFormatters, - ParamUpdater, StdParams, StdTags, check_params, @@ -20,29 +19,29 @@ ) -def test_parameter_updater_1param(): +def test_parameter_formatters_1param(): container_url_param = "container_url" cmd = click.Command("a_command") ctx = click.Context(cmd) opt = click.Option(["--version"]) - updater = ParamUpdater() - updater.set(container_url_param, "http://my_server/{version}/my_stuff") - updater(ctx, opt, "1.3.2") + formatters = ParameterFormatters() + formatters.set_formatter(container_url_param, "http://my_server/{version}/my_stuff") + formatters(ctx, opt, "1.3.2") assert ctx.params[container_url_param] == "http://my_server/1.3.2/my_stuff" -def test_parameter_updater_2params(): +def test_parameter_formatters_2params(): container_url_param = "container_url" container_name_param = "container_name" cmd = click.Command("a_command") ctx = click.Context(cmd) opt1 = click.Option(["--version"]) opt2 = click.Option(["--user"]) - updater = ParamUpdater() - updater.set(container_url_param, "http://my_server/{version}/{user}/my_stuff") - updater.set(container_name_param, "downloaded-{version}") - updater(ctx, opt1, "1.3.2") - updater(ctx, opt2, "cezar") + formatters = ParameterFormatters() + formatters.set_formatter(container_url_param, "http://my_server/{version}/{user}/my_stuff") + formatters.set_formatter(container_name_param, "downloaded-{version}") + formatters(ctx, opt1, "1.3.2") + formatters(ctx, opt2, "cezar") assert ctx.params[container_url_param] == "http://my_server/1.3.2/cezar/my_stuff" assert ctx.params[container_name_param] == "downloaded-1.3.2" @@ -136,11 +135,11 @@ def func(**kwargs): assert kwargs[container_name_arg] == expected_name assert kwargs[container_url_arg] == expected_url - ver_updater = ParamUpdater() - ver_updater.set(container_url_arg, url_format) - ver_updater.set(container_name_arg, name_format) + ver_formatters = ParameterFormatters() + ver_formatters.set_formatter(container_url_arg, url_format) + ver_formatters.set_formatter(container_name_arg, name_format) - opts = select_std_options(StdTags.SLC, formatters={StdParams.version: ver_updater}) + opts = select_std_options(StdTags.SLC, formatters={StdParams.version: ver_formatters}) cmd = click.Command("do_something", params=opts, callback=func) runner = CliRunner() runner.invoke(cmd, args=f"--version {version}", catch_exceptions=False, standalone_mode=False) From ed9cc0169b3fa23610edb924d25ce579e6b4a2d2 Mon Sep 17 00:00:00 2001 From: ckunki Date: Wed, 4 Feb 2026 14:09:49 +0100 Subject: [PATCH 08/11] Updated docstring --- exasol/python_extension_common/cli/std_options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exasol/python_extension_common/cli/std_options.py b/exasol/python_extension_common/cli/std_options.py index 683f409..1575999 100644 --- a/exasol/python_extension_common/cli/std_options.py +++ b/exasol/python_extension_common/cli/std_options.py @@ -23,7 +23,7 @@ class Param: class ParameterFormatters: """ - Dynamic update for customized Click CLI parameters. + Dynamic formatting for customized Click CLI parameters. Example: A specialized variant of the CLI may want to provide a custom URL "http://prefix/{version}/suffix" depending on CLI parameter "version". If From 8b256d6a2c9464f981083df5303232fec37e2b3e Mon Sep 17 00:00:00 2001 From: ckunki Date: Wed, 4 Feb 2026 14:13:55 +0100 Subject: [PATCH 09/11] Moved internal class Param to separate file --- exasol/python_extension_common/cli/_param.py | 13 +++++++++++++ exasol/python_extension_common/cli/std_options.py | 7 +------ 2 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 exasol/python_extension_common/cli/_param.py diff --git a/exasol/python_extension_common/cli/_param.py b/exasol/python_extension_common/cli/_param.py new file mode 100644 index 0000000..d226646 --- /dev/null +++ b/exasol/python_extension_common/cli/_param.py @@ -0,0 +1,13 @@ +from dataclasses import dataclass +from typing import Any + + +@dataclass(frozen=True) +class Param: + """ + Only used internally to distinguish between source and destination + parameters. + """ + + name: str | None + value: Any | None diff --git a/exasol/python_extension_common/cli/std_options.py b/exasol/python_extension_common/cli/std_options.py index 1575999..2e5e213 100644 --- a/exasol/python_extension_common/cli/std_options.py +++ b/exasol/python_extension_common/cli/std_options.py @@ -12,15 +12,10 @@ no_type_check, ) +from exasol.python_extension_common.cli._param import Param import click -@dataclass(frozen=True) -class Param: - name: str | None - value: Any | None - - class ParameterFormatters: """ Dynamic formatting for customized Click CLI parameters. From ae311e375ccf19c3b4dbb52b61e785c3f8c09ccb Mon Sep 17 00:00:00 2001 From: ckunki Date: Wed, 4 Feb 2026 14:19:05 +0100 Subject: [PATCH 10/11] Updated comment --- exasol/python_extension_common/cli/std_options.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/exasol/python_extension_common/cli/std_options.py b/exasol/python_extension_common/cli/std_options.py index 2e5e213..35d8e55 100644 --- a/exasol/python_extension_common/cli/std_options.py +++ b/exasol/python_extension_common/cli/std_options.py @@ -41,7 +41,11 @@ class ParameterFormatters: """ def __init__(self) -> None: - # list of destination parameters to update + # Each key/value pair represents the name of a destination parameter + # to update, and its default value. + # + # The default value can contain placeholders to be replaced by the + # values of the other parameters, called "source parameters". self._parameters: dict[str, str] = {} def __call__( From 75ab20458d387e61b977a7a190216749cfd0086a Mon Sep 17 00:00:00 2001 From: ckunki Date: Wed, 4 Feb 2026 14:19:41 +0100 Subject: [PATCH 11/11] Updated docstring --- exasol/python_extension_common/cli/std_options.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exasol/python_extension_common/cli/std_options.py b/exasol/python_extension_common/cli/std_options.py index 35d8e55..3e82f5c 100644 --- a/exasol/python_extension_common/cli/std_options.py +++ b/exasol/python_extension_common/cli/std_options.py @@ -276,10 +276,10 @@ def select_std_options( A dictionary of standard options with overridden properties formatters: A dictionary, with each key being a source CLI parameter, - see docstring of class ParamUpdater. + see docstring of class ParameterFormatters. - Each value is an instance of ParamUpdater representing a single or - multiple destination parameters to be updated based on the source + Each value is an instance of ParameterFormatters representing a single + or multiple destination parameters to be updated based on the source parameter's value. A destination parameter can be updated multiple times, if it depends on multiple source parameters. """