diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 01162500..1f78c697 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 4.34.1 +current_version = 4.35.0 commit = True tag = True tag_name = v{new_version} diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a14fc7a7..1fee07c8 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -12,9 +12,14 @@ The semantic versioning only considers the public API as described in paths are considered internals and can change in minor and patch releases. -v4.35.0 (2024-12-??) +v4.35.0 (2024-12-16) -------------------- +Added +^^^^^ +- Support for ``print config`` argument to reuse the name of the config argument + by using ``%s`` (`#630 `__). + Changed ^^^^^^^ - Argument groups created from dataclass-like that have zero configurable @@ -24,11 +29,19 @@ Changed the help of the base class is printed (`#628 `__). +Fixed +^^^^^ +- Account for change in ``ArgumentParser._parse_known_args`` since Python 3.12.8 + and 3.13.1 (`#644 `__). + Deprecated ^^^^^^^^^^ - ``add_dataclass_arguments`` is deprecated and will be removed in v5.0.0. Instead use ``add_class_arguments`` (`#634 `__). +- From v5.0.0 the print config argument will by default reuse the name of the + config argument as ``--print_%s`` instead of being always ``--print_config`` + (`#630 `__). v4.34.2 (2024-12-??) -------------------- diff --git a/jsonargparse/__init__.py b/jsonargparse/__init__.py index 06befba8..02227520 100644 --- a/jsonargparse/__init__.py +++ b/jsonargparse/__init__.py @@ -70,4 +70,4 @@ __all__ += _deprecated.__all__ -__version__ = "4.34.1" +__version__ = "4.35.0" diff --git a/jsonargparse/_actions.py b/jsonargparse/_actions.py index 42327c31..a3a55ed5 100644 --- a/jsonargparse/_actions.py +++ b/jsonargparse/_actions.py @@ -182,6 +182,9 @@ def _ensure_single_config_argument(container, action): @staticmethod def _add_print_config_argument(container, action): if isinstance(action, ActionConfigFile) and getattr(container, "_print_config", None) is not None: + if "%s" in container._print_config: + container._print_config = container._print_config % action.dest + assert container._print_config.startswith("--") container.add_argument(container._print_config, action=_ActionPrintConfig) @staticmethod diff --git a/jsonargparse/_core.py b/jsonargparse/_core.py index 8f35c566..d2ae6272 100644 --- a/jsonargparse/_core.py +++ b/jsonargparse/_core.py @@ -95,6 +95,9 @@ __all__ = ["ActionsContainer", "ArgumentParser"] +_parse_known_has_intermixed = "intermixed" in inspect.signature(argparse.ArgumentParser._parse_known_args).parameters + + class ActionsContainer(SignatureArguments, argparse._ActionsContainer): """Extension of argparse._ActionsContainer to support additional functionalities.""" @@ -246,7 +249,7 @@ def __init__( formatter_class: Class for printing help messages. logger: Configures the logger, see :class:`.LoggerProperty`. version: Program version which will be printed by the --version argument. - print_config: Add this as argument to print config, set None to disable. + print_config: Name for print config argument, ``%s`` is replaced by config dest, set None to disable. parser_mode: Mode for parsing config files: ``'yaml'``, ``'jsonnet'`` or ones added via :func:`.set_loader`. dump_header: Header to include as comment when dumping a config object. default_config_files: Default config file locations, e.g. ``['~/.config/myapp/*.yaml']``. @@ -288,7 +291,10 @@ def parse_known_args(self, args=None, namespace=None): with patch_namespace(), parser_context( parent_parser=self, lenient_check=True ), ActionTypeHint.subclass_arg_context(self): - namespace, args = self._parse_known_args(args, namespace) + kwargs = {} + if _parse_known_has_intermixed: + kwargs["intermixed"] = False + namespace, args = self._parse_known_args(args, namespace, **kwargs) except argparse.ArgumentError as ex: self.error(str(ex), ex) diff --git a/jsonargparse_tests/test_core.py b/jsonargparse_tests/test_core.py index 17906e5b..e82711d9 100644 --- a/jsonargparse_tests/test_core.py +++ b/jsonargparse_tests/test_core.py @@ -741,6 +741,14 @@ def test_print_config_empty_default_config_file(print_parser, tmp_cwd): assert yaml.safe_load(out) == {"g1": {"v2": "2"}, "g2": {"v3": None}, "v1": 1} +def test_print_config_reuse_name(): + parser = ArgumentParser(exit_on_error=False, print_config="--print_%s") + parser.add_argument("--conf", action="config") + parser.add_argument("--x", default=1) + out = get_parse_args_stdout(parser, ["--print_conf"]) + assert yaml.safe_load(out) == {"x": 1} + + def test_default_config_files(parser, subtests, tmp_cwd): default_config_file = tmp_cwd / "defaults.yaml" default_config_file.write_text("op1: from default config file\n")