Skip to content

Commit f327492

Browse files
authored
Rename yaml_comments parameter of ArgumentParser.dump to with_comments (#811)
1 parent 76fabbe commit f327492

File tree

8 files changed

+73
-13
lines changed

8 files changed

+73
-13
lines changed

CHANGELOG.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,19 @@ Changed
2121
parser/subcommand the option was given to. Also suggests running ``--help``
2222
for the corresponding parser/subcommand (`#809
2323
<https://github.com/omni-us/jsonargparse/pull/809>`__).
24+
- The ``yaml_comments`` parameter of ``ArgumentParser.dump`` has been renamed to
25+
``with_comments`` to allow future comments support of other formats (`#811
26+
<https://github.com/omni-us/jsonargparse/pull/811>`__).
2427

2528
Deprecated
2629
^^^^^^^^^^
2730
- ``ArgumentParser.default_meta`` property and ``with_meta`` parameter of
2831
``ArgumentParser.parse_*`` are deprecated and will be removed in v5.0.0.
2932
Instead use ``.clone(with_meta=...)`` (`#810
3033
<https://github.com/omni-us/jsonargparse/pull/810>`__).
34+
- The ``yaml_comments`` parameter of ``ArgumentParser.dump`` is deprecated and
35+
will be removed in v5.0.0. Use ``with_comments`` instead (`#811
36+
<https://github.com/omni-us/jsonargparse/pull/811>`__).
3137

3238

3339
v4.43.0 (2025-11-11)

DOCUMENTATION.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ Depending on the parse method used (see :class:`.ArgumentParser`) and how the
284284
parser was built, some of the options above might not apply. Parsing of
285285
environment variables must be explicitly enabled, except if using
286286
:py:meth:`.ArgumentParser.parse_env`. If the parser does not have an
287-
`action="config"` argument, then there is no parsing of a full config
287+
``action="config"`` argument, then there is no parsing of a full config
288288
environment variable or a way to provide a config file from command line.
289289

290290

@@ -755,9 +755,9 @@ If you import ``from jsonargparse import set_parsing_settings`` and then run
755755
``set_parsing_settings(config_read_mode_fsspec_enabled=True)``, the following
756756
functions and classes will also support loading from URLs:
757757
:py:meth:`.ArgumentParser.parse_path`, :py:meth:`.ArgumentParser.get_defaults`
758-
(``default_config_files`` argument), `action="config"`,
758+
(``default_config_files`` argument), ``action="config"``,
759759
:class:`.ActionJsonSchema`, :class:`.ActionJsonnet` and :class:`.ActionParser`.
760-
This means that a tool that can receive a config file via `action="config"` is
760+
This means that a tool that can receive a config file via ``action="config"`` is
761761
able to get the content from a URL, thus something like the following would
762762
work:
763763

@@ -1338,7 +1338,7 @@ string respectively.
13381338
Serialization
13391339
-------------
13401340

1341-
Parsers that have an `action="config"` argument also include a
1341+
Parsers that have an ``action="config"`` argument also include a
13421342
``--print_config`` option. This is useful particularly for command line tools
13431343
with a large set of options to create an initial config file including all
13441344
default values. If the `ruamel.yaml <https://pypi.org/project/ruamel.yaml>`__
@@ -2550,7 +2550,7 @@ There is also the :py:meth:`.ArgumentParser.parse_env` function to only parse
25502550
environment variables, which might be useful for some use cases in which there
25512551
is no command line call involved.
25522552

2553-
If a parser includes an `action="config"` argument, then the environment
2553+
If a parser includes an ``action="config"`` argument, then the environment
25542554
variable for this config file will be parsed before all the other environment
25552555
variables.
25562556

@@ -2758,7 +2758,7 @@ following:
27582758
When using the :class:`.ActionParser` class, the value of the node in a config
27592759
file can be either the complex node itself, or the path to a file which will be
27602760
loaded and parsed with the corresponding inner parser. Naturally using
2761-
`action="config"` to parse a complete config file will parse the inner
2761+
``action="config"`` to parse a complete config file will parse the inner
27622762
nodes correctly.
27632763

27642764
Note that when adding ``inner_parser`` a title was given. In the help, the added

jsonargparse/_actions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ def __call__(self, parser, namespace, value, option_string=None):
260260
kwargs = {"subparser": parser, "key": None, "skip_none": False, "skip_validation": False}
261261
valid_flags = {"": None, "skip_default": "skip_default", "skip_null": "skip_none"}
262262
if ruamel_support:
263-
valid_flags["comments"] = "yaml_comments"
263+
valid_flags["comments"] = "with_comments"
264264
if value is not None:
265265
flags = value[0].split(",")
266266
invalid_flags = [f for f in flags if f not in valid_flags]

jsonargparse/_core.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
argcomplete_namespace,
4949
handle_completions,
5050
)
51-
from ._deprecated import ParserDeprecations, deprecated_skip_check
51+
from ._deprecated import ParserDeprecations, deprecated_skip_check, deprecated_yaml_comments
5252
from ._formatters import DefaultHelpFormatter, empty_help, get_env_var
5353
from ._jsonnet import ActionJsonnet
5454
from ._jsonschema import ActionJsonSchema
@@ -739,7 +739,7 @@ def dump(
739739
skip_none: bool = True,
740740
skip_default: bool = False,
741741
skip_validation: bool = False,
742-
yaml_comments: bool = False,
742+
with_comments: bool = False,
743743
skip_link_targets: bool = True,
744744
**kwargs,
745745
) -> str:
@@ -753,7 +753,7 @@ def dump(
753753
skip_none: Whether to exclude entries whose value is None.
754754
skip_default: Whether to exclude entries whose value is the same as the default.
755755
skip_validation: Whether to skip parser checking.
756-
yaml_comments: Whether to add help content as comments. ``yaml_comments=True`` implies ``format='yaml'``.
756+
with_comments: Whether to add help content as comments. Currently only supported for ``format='yaml'``.
757757
skip_link_targets: Whether to exclude link targets.
758758
759759
Returns:
@@ -762,7 +762,9 @@ def dump(
762762
Raises:
763763
TypeError: If any of the values of cfg is invalid according to the parser.
764764
"""
765+
with_comments = deprecated_yaml_comments(kwargs, with_comments)
765766
skip_validation = deprecated_skip_check(ArgumentParser.dump, kwargs, skip_validation)
767+
766768
check_valid_dump_format(format)
767769

768770
cfg = cfg.clone(with_meta=False)
@@ -786,7 +788,7 @@ def dump(
786788
self._dump_delete_default_entries(cfg_dict, defaults.as_dict())
787789

788790
with parser_context(parent_parser=self):
789-
return dump_using_format(self, cfg_dict, "yaml_comments" if yaml_comments else format)
791+
return dump_using_format(self, cfg_dict, dump_format=format, with_comments=with_comments)
790792

791793
def _dump_cleanup_actions(self, cfg, actions, dump_kwargs, prefix=""):
792794
skip_none = dump_kwargs["skip_none"]

jsonargparse/_deprecated.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,21 @@ def deprecated_skip_check(component, kwargs: dict, skip_validation: bool) -> boo
668668
return skip_validation
669669

670670

671+
def deprecated_yaml_comments(kwargs: dict, with_comments: bool) -> bool:
672+
yaml_comments = kwargs.pop("yaml_comments", None)
673+
if yaml_comments is not None:
674+
deprecation_warning(
675+
deprecated_yaml_comments,
676+
(
677+
"yaml_comments parameter was deprecated in v4.44.0 and will be removed in "
678+
"v5.0.0. Instead use with_comments."
679+
),
680+
stacklevel=3,
681+
)
682+
return yaml_comments
683+
return with_comments
684+
685+
671686
ParserError = ArgumentError
672687

673688

jsonargparse/_loaders_dumpers.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,10 +281,16 @@ def check_valid_dump_format(dump_format: str):
281281
raise ValueError(f'Unknown output format "{dump_format}".')
282282

283283

284-
def dump_using_format(parser: ArgumentParser, data: dict, dump_format: str) -> str:
284+
def dump_using_format(parser: ArgumentParser, data: dict, dump_format: str, with_comments: bool = False) -> str:
285285
if dump_format == "parser_mode":
286286
dump_format = parser.parser_mode if parser.parser_mode in dumpers else "yaml"
287-
args = (data, parser) if dump_format == "yaml_comments" else (data,)
287+
if with_comments:
288+
if f"{dump_format}_comments" not in dumpers:
289+
if dump_format == "yaml":
290+
raise ValueError("ruamel.yaml is required for dumping YAML with comments.")
291+
raise ValueError(f"Dumping with comments is not supported for format '{dump_format}'.")
292+
dump_format = f"{dump_format}_comments"
293+
args = (data, parser) if dump_format.endswith("_comments") else (data,)
288294
dump = dumpers[dump_format](*args)
289295
if parser.dump_header and comment_prefix.get(dump_format):
290296
prefix = comment_prefix[dump_format]

jsonargparse_tests/test_core.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,24 @@ def test_dump_order(parser, subtests):
566566
assert dump == "\n".join(v + ": " + str(n) for n, v in args.items()) + "\n"
567567

568568

569+
def test_dump_comments_not_supported(parser):
570+
parser.parser_mode = "json"
571+
parser.add_argument("--op", type=int, default=1)
572+
cfg = parser.get_defaults()
573+
with pytest.raises(ValueError, match="Dumping with comments is not supported for format 'json'"):
574+
parser.dump(cfg, with_comments=True)
575+
576+
577+
@skip_if_no_pyyaml
578+
def test_dump_comments_missing_ruamel(parser):
579+
parser.add_argument("--op", type=int, default=1)
580+
cfg = parser.get_defaults()
581+
with patch.dict("jsonargparse._loaders_dumpers.dumpers") as dumpers:
582+
dumpers.pop("yaml_comments", None)
583+
with pytest.raises(ValueError, match="ruamel.yaml is required for dumping YAML with comments"):
584+
parser.dump(cfg, with_comments=True)
585+
586+
569587
@pytest.fixture
570588
def parser_schema_jsonnet(parser, example_parser):
571589
parser.add_argument("--cfg", action="config")

jsonargparse_tests/test_deprecated.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,19 @@ def test_DefaultHelpFormatter_yaml_comments(parser):
853853
assert "formatter.set_yaml_argument_comment(" in source[w[-1].lineno - 1]
854854

855855

856+
@pytest.mark.skipif(not ruamel_support, reason="ruamel.yaml package is required")
857+
def test_deprecated_dump_yaml_comments_parameter(parser):
858+
parser.add_argument("--arg", type=int, default=1, help="Description")
859+
cfg = parser.get_defaults()
860+
with catch_warnings(record=True) as w:
861+
parser.dump(cfg, yaml_comments=True)
862+
assert_deprecation_warn(
863+
w,
864+
message="yaml_comments parameter was deprecated in v4.44.0 and will be removed in v5.0.0",
865+
code="parser.dump(cfg, yaml_comments=True)",
866+
)
867+
868+
856869
@dataclasses.dataclass
857870
class ComposeA:
858871
a: int = 1

0 commit comments

Comments
 (0)