Skip to content

use jsonargparse#9413

Open
ThomasWaldmann wants to merge 26 commits intoborgbackup:masterfrom
ThomasWaldmann:jsonargparse2
Open

use jsonargparse#9413
ThomasWaldmann wants to merge 26 commits intoborgbackup:masterfrom
ThomasWaldmann:jsonargparse2

Conversation

@ThomasWaldmann
Copy link
Member

@ThomasWaldmann ThomasWaldmann commented Feb 25, 2026

Description

Adopt jsonargparse, fixes #6551.

Checklist

  • PR is against master (or maintenance branch if only applicable there)
  • New code has tests and docs where appropriate
  • Tests pass (run tox or the relevant test subset)
  • Commit messages are clean and reference related issues

@ThomasWaldmann ThomasWaldmann force-pushed the jsonargparse2 branch 2 times, most recently from 89f6898 to 5aa0956 Compare February 25, 2026 14:08
@ThomasWaldmann ThomasWaldmann mentioned this pull request Feb 25, 2026
@codecov
Copy link

codecov bot commented Feb 25, 2026

Codecov Report

❌ Patch coverage is 86.80739% with 50 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.48%. Comparing base (ec9e32a) to head (41f7d9e).
⚠️ Report is 9 commits behind head on master.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/borg/helpers/parseformat.py 67.76% 29 Missing and 10 partials ⚠️
src/borg/patterns.py 66.66% 3 Missing ⚠️
src/borg/archiver/__init__.py 93.75% 1 Missing and 1 partial ⚠️
src/borg/archiver/completion_cmd.py 86.66% 1 Missing and 1 partial ⚠️
src/borg/archiver/diff_cmd.py 66.66% 2 Missing ⚠️
src/borg/archiver/transfer_cmd.py 66.66% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #9413      +/-   ##
==========================================
- Coverage   76.52%   76.48%   -0.04%     
==========================================
  Files          85       86       +1     
  Lines       14819    14907      +88     
  Branches     2214     2248      +34     
==========================================
+ Hits        11340    11402      +62     
- Misses       2802     2819      +17     
- Partials      677      686       +9     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@ThomasWaldmann ThomasWaldmann changed the title use jsonargparse, try 2 use jsonargparse Feb 26, 2026
@ThomasWaldmann ThomasWaldmann force-pushed the jsonargparse2 branch 2 times, most recently from 14adfd2 to c6452f7 Compare February 26, 2026 10:44
@ThomasWaldmann
Copy link
Member Author

@mauvilsa can you have a look, please?

maybe look at the individual commits.

is that flatten_namespace code in borg.helpers.argparsing interesting for other jsonargparse users?

had to import some internal stuff to implement borg completion command, guess there is currently no better way?

guess this can soon be merged - it does not use most features of jsonargparse, but that should be in future PRs.

Copy link

@mauvilsa mauvilsa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't tried to run the code yet. But might do that in case I see weird behaviors.

@ThomasWaldmann
Copy link
Member Author

(rebased on current master, added auto env var support)

@ThomasWaldmann
Copy link
Member Author

ThomasWaldmann commented Feb 27, 2026

Hmm, I can't get "store_true" stuff working correctly:

subparser.add_argument("-s", "--stats", dest="stats", action="store_true", help="print stats")

With that and without the value being set in the default config, overriding via BORG_CREATE__STATS=true crashes the code, because it puts a str into args.stat instead of the expected bool.

If I set the value in the default config, it works, but I can not overwrite it with the env var.

A hack with ActionYesNo also didn't work, because it does not like short options like -s. omni-us/jsonargparse#355 (comment)

Another weird hack: omni-us/jsonargparse#497 - is that the intended way?

@ThomasWaldmann ThomasWaldmann added this to the 2.0.0b21 milestone Feb 28, 2026
@mauvilsa
Copy link

mauvilsa commented Feb 28, 2026

Hmm, I can't get "store_true" stuff working correctly:

This I would consider this a bug. I will fix it.

Previously, ArgparsePatternAction and ArgparsePatternFileAction
appended recursion roots directly to args.paths. This mixed
CLI positional paths with paths derived from patterns
(e.g., using the `R` root path command in a pattern file),
complicating downstream argument parsing and future jsonargparse
integration.

This commit introduces `args.pattern_roots` as a dedicated list
for these accumulated root paths:
- All argparse definition sites now initialize `pattern_roots=[]` alongside `paths=[]`
- ArgparsePatternAction and ArgparsePatternFileAction write directly to `args.pattern_roots`
- The build_matcher utility accepts both `include_paths` and `pattern_roots` and concatenates them internally
- `create_cmd` iterations explicitly concatenate both lists before processing

This ensures `args.paths` strictly reflects exactly what the
user provided positionally, paving the way for a clean
jsonargparse implementation without regressions in pattern behavior.
Guess it was triggered due to naming the variable "token",
maybe "sort_key" is less problematic.
other validators / specs are also there and it is easier to maintain
as Python code. the compress module is Cython code.
…approach

The old code worked around argparse's flat namespace by appending
_maincommand / _midcommand / _subcommand suffixes to every common
option's dest (e.g. log_level_subcommand), then resolving them with
CommonOptions.resolve() after parsing.  This polluted config key names
and env var names (BORG_LOG_LEVEL_SUBCOMMAND instead of BORG_LOG_LEVEL).

jsonargparse nests subcommand arguments automatically, so the workaround
is no longer needed.  Each parser level now registers common options with
their clean dest name.  flatten_namespace() is updated to a two-pass
depth-first walk so the most-specific (innermost) value wins naturally:

  borg --info create --debug  →  log_level = "debug"  (subcommand wins)
  borg --info create          →  log_level = "info"   (top-level fills gap)

For append-action options (--debug-topic) values from all levels are
merged (outer + inner) to preserve the accumulation behaviour.
Borg's ArgumentParser (in borg.helpers.argparsing) now subclasses
jsonargparse's ArgumentParser and pre-sets two defaults that every
borg parser uses:

  formatter_class = RawDescriptionHelpFormatter
  add_help        = False
@ThomasWaldmann
Copy link
Member Author

ThomasWaldmann commented Mar 4, 2026

TODO before merging this:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

argparse++

2 participants