From 36132fcca2dfaf18d2cc905b6f1b3716ad3337a9 Mon Sep 17 00:00:00 2001 From: wb <20113294+wowtor@users.noreply.github.com> Date: Fri, 18 Sep 2026 10:03:32 +0200 Subject: [PATCH 1/3] config: functions annotated with `@config_parser` are still callable --- lir/config/base.py | 12 +++++++++++- tests/config/test_base.py | 4 +++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lir/config/base.py b/lir/config/base.py index 0fa873dc..4c0ae6ae 100644 --- a/lir/config/base.py +++ b/lir/config/base.py @@ -1,4 +1,5 @@ import inspect +import warnings from abc import ABC, abstractmethod from collections.abc import Callable, Iterator, Mapping, Sequence from dataclasses import dataclass @@ -627,6 +628,15 @@ def parse( ) -> Any: return func(config, output_dir) # type: ignore + def __call__(self, config: ConfigValue | None = None, output_dir: Path | None = None) -> Any: + if config and output_dir: + return self.parse(config, output_dir) + else: + warnings.warn( + DeprecationWarning('legacy invocation of annotated function (remove parentheses)'), stacklevel=2 + ) + return self + def reference(self) -> str: # return the reference argument, if any if reference is not None: @@ -643,7 +653,7 @@ def reference(self) -> str: # last resort: fallback to wrapped function name return get_full_name(func) - return ConfigParserFunction + return ConfigParserFunction() def pop_field( diff --git a/tests/config/test_base.py b/tests/config/test_base.py index a22fbe9e..3c898fe7 100644 --- a/tests/config/test_base.py +++ b/tests/config/test_base.py @@ -129,9 +129,11 @@ def my_config_parser(config: ConfigValue, output_path: Path) -> int: return pop_field(config, 'key', validate_type=int) +@pytest.mark.filterwarnings('ignore:legacy') def test_config_parser(): config = ConfigValue.wrap([], {'key': 42}) - assert my_config_parser().parse(config, Path('/')) == 42 + assert my_config_parser(config.clone(), Path('/')) == 42 + assert my_config_parser().parse(config.clone(), Path('/')) == 42 def test_generic_config_parser(): From fb27b6dac574784fd7c9694da0423a65c61eca61 Mon Sep 17 00:00:00 2001 From: wb <20113294+wowtor@users.noreply.github.com> Date: Fri, 18 Sep 2026 10:19:13 +0200 Subject: [PATCH 2/3] config: resolve warnings (legacy invocation of annotated functions) --- lir/config/substitution.py | 8 ++++---- tests/algorithms/test_bootstraps.py | 2 +- tests/datasets/test_csv_parser.py | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lir/config/substitution.py b/lir/config/substitution.py index 8b918f4b..4ecf6193 100644 --- a/lir/config/substitution.py +++ b/lir/config/substitution.py @@ -564,13 +564,13 @@ def parse_parameter( parser = registry.get(parameter_type, search_path=['hyperparameter_types']) elif 'value' in spec: - parser = parse_constant() # type: ignore + parser = parse_constant # type: ignore elif 'options' in spec and 'path' in spec: - parser = parse_categorical() # type: ignore + parser = parse_categorical # type: ignore elif 'options' in spec and 'name' in spec: - parser = parse_clustered() # type: ignore + parser = parse_clustered # type: ignore elif 'high' in spec: - parser = parse_float() # type: ignore + parser = parse_float # type: ignore else: raise YamlParseError( spec.context, diff --git a/tests/algorithms/test_bootstraps.py b/tests/algorithms/test_bootstraps.py index 291fa1fa..8270e4d9 100644 --- a/tests/algorithms/test_bootstraps.py +++ b/tests/algorithms/test_bootstraps.py @@ -125,4 +125,4 @@ def test_interval_extrapolation(sample_steps_and_data): ) def test_bootstrap_config(config): config = ConfigValue.wrap([], config) - bootstrap().parse(config, Path('/')) + bootstrap(config, Path('/')) diff --git a/tests/datasets/test_csv_parser.py b/tests/datasets/test_csv_parser.py index edef8f1b..de07c236 100644 --- a/tests/datasets/test_csv_parser.py +++ b/tests/datasets/test_csv_parser.py @@ -156,7 +156,7 @@ def test_csv_parser( parser_args['file'] = str(csv_file) parser_args = ConfigValue.wrap([], parser_args) try: - parser = feature_data_csv_file_parser().parse(parser_args, tmp_path) + parser = feature_data_csv_file_parser(parser_args, tmp_path) actual_result = parser.get_instances() if expected_result is not None: assert actual_result == expected_result @@ -173,7 +173,7 @@ def test_csv_parser_label_column_alias_warns(tmp_path: Path): parser_args = ConfigValue.wrap([], {'label_column': 'label', 'file': str(csv_file)}) with pytest.warns(UserWarning, match='label_column'): - parser = feature_data_csv_file_parser().parse(parser_args, tmp_path) + parser = feature_data_csv_file_parser(parser_args, tmp_path) actual_result = parser.get_instances() assert actual_result == FeatureData(hypothesis=np.array([1]), features=np.ones((1, 2))) From 3978e1323c11b853d14a23e0c614388c20758e60 Mon Sep 17 00:00:00 2001 From: wb <20113294+wowtor@users.noreply.github.com> Date: Fri, 18 Sep 2026 11:54:53 +0200 Subject: [PATCH 3/3] docs: fix links to hyperparameter types --- docs/test_docs.py | 12 ++++++++++++ lir/config/substitution.py | 16 ++++++++-------- pyproject.toml | 13 ++++--------- 3 files changed, 24 insertions(+), 17 deletions(-) create mode 100644 docs/test_docs.py diff --git a/docs/test_docs.py b/docs/test_docs.py new file mode 100644 index 00000000..fc16ad19 --- /dev/null +++ b/docs/test_docs.py @@ -0,0 +1,12 @@ +from docs import GetRegistryLink + + +def test_registry_link(): + assert ( + GetRegistryLink()('lir.config.substitution.parse_categorical') + == ':class:`lir.config.substitution.parse_categorical `' + ) + assert ( + GetRegistryLink()('hyperparameter_types.categorical') + == ':class:`hyperparameter_types.categorical `' + ) diff --git a/lir/config/substitution.py b/lir/config/substitution.py index 4ecf6193..2277de42 100644 --- a/lir/config/substitution.py +++ b/lir/config/substitution.py @@ -225,8 +225,8 @@ def _parse_categorical_option(spec: Any, path: str, option_index: int | None) -> return HyperparameterOption(name, {path: value}) -@config_parser(reference='lir.config.substitution.parse_categorical') -def parse_categorical(spec: ConfigValue, output_path: Path) -> 'CategoricalHyperparameter': +@config_parser +def parse_categorical(spec: ConfigValue, output_path: Path) -> CategoricalHyperparameter: """ Parse a categorical hyperparameter from configuration. @@ -282,7 +282,7 @@ def _parse_clustered_option(spec: ConfigValue) -> HyperparameterOption: return HyperparameterOption(option_name, substitutions) -@config_parser(reference='lir.config.substitution.parse_clustered') +@config_parser def parse_clustered(spec: ConfigValue, output_path: Path) -> CategoricalHyperparameter: """ Parse the configuration section of a clustered hyperparameter. @@ -316,7 +316,7 @@ def parse_clustered(spec: ConfigValue, output_path: Path) -> CategoricalHyperpar return CategoricalHyperparameter(parameter_name, options) -@config_parser(reference='lir.config.substitution.parse_constant') +@config_parser def parse_constant(spec: ConfigValue, output_path: Path) -> CategoricalHyperparameter: """ Parse the configuration section of a constant. @@ -400,8 +400,8 @@ def options(self) -> list[HyperparameterOption]: return [HyperparameterOption(str(value), {self.path: value}) for value in values] -@config_parser(reference='lir.config.substitution.parse_float') -def parse_float(spec: ConfigValue, output_path: Path) -> 'FloatHyperparameter': +@config_parser +def parse_float(spec: ConfigValue, output_path: Path) -> FloatHyperparameter: """ Parse a floating-point hyperparameter from configuration. @@ -514,8 +514,8 @@ def options(self) -> list[HyperparameterOption]: return options -@config_parser(reference='lir.config.substitution.parse_folder') -def parse_folder(spec: ConfigValue, output_path: Path) -> 'FolderHyperparameter': +@config_parser +def parse_folder(spec: ConfigValue, output_path: Path) -> FolderHyperparameter: """ Parse a folder hyperparameter from configuration. diff --git a/pyproject.toml b/pyproject.toml index 34e8e5ad..67c1e2ac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -119,15 +119,10 @@ lint.select = [ "S", # bandit "PIE", # flake8-pie ] -lint.per-file-ignores = {"tests/*" = [ - "D", # Ignore missing docstrings in tests. - "S101", # Allow use of assert in tests. - ], "*_test.py" = [ - "D", # Ignore missing docstrings in tests. - "S101", # Allow use of assert in tests. - ], "docs/snippets/*.py" = [ - "D", # Ignore missing docstrings in snippets. - ]} +lint.per-file-ignores = {"!lir/*" = [ + "D", # Ignore missing docstrings in tests. + "S101", # Allow use of assert in tests. +]} lint.pydocstyle.convention = "numpy" [tool.mypy]