|
3 | 3 | This module provides a compatibility layer between Borg's argparse patterns |
4 | 4 | and jsonargparse's API. Key adaptations: |
5 | 5 |
|
6 | | -1. type+action combination: jsonargparse forbids combining type= and action= |
7 | | - in add_argument(). Our override strips type= from kwargs and ensures |
8 | | - type conversion happens within the action itself: |
9 | | - - Highlander action class: handles type via _type_fn (pops type in __init__) |
10 | | - - Standard actions (append, store, etc.): wrapped in TypeConvertingAction |
11 | | - - Custom action classes: type is popped and stored on the action after creation |
12 | | -
|
13 | | -2. Namespace flattening: jsonargparse creates nested namespaces for subcommands |
| 6 | +1. Namespace flattening: jsonargparse creates nested namespaces for subcommands |
14 | 7 | (args.create.name instead of args.name). flatten_namespace() merges these |
15 | 8 | into a flat namespace compatible with Borg's command handlers. |
16 | 9 | """ |
|
21 | 14 | from jsonargparse._core import ArgumentGroup as _JAPArgumentGroup |
22 | 15 |
|
23 | 16 |
|
24 | | -def _make_type_converting_action(base_action_name, type_fn): |
25 | | - """Create a custom action class that wraps a standard action and applies type conversion. |
26 | | -
|
27 | | - This is used for standard string actions (e.g. 'append', 'store') when combined with type=. |
28 | | - jsonargparse forbids type+action, so we strip type= and wrap the action to do conversion. |
29 | | - """ |
30 | | - # Map action name to argparse's built-in action class |
31 | | - _action_map = {"append": argparse._AppendAction, "store": argparse._StoreAction} |
32 | | - |
33 | | - base_cls = _action_map.get(base_action_name) |
34 | | - if base_cls is None: |
35 | | - # Unknown action string - can't wrap it |
36 | | - return None |
37 | | - |
38 | | - class TypeConvertingAction(base_cls): |
39 | | - def __call__(self, parser, namespace, values, option_string=None): |
40 | | - if type_fn is not None and isinstance(values, str): |
41 | | - try: |
42 | | - values = type_fn(values) |
43 | | - except argparse.ArgumentTypeError as e: |
44 | | - raise argparse.ArgumentError(self, str(e)) |
45 | | - super().__call__(parser, namespace, values, option_string) |
46 | | - |
47 | | - TypeConvertingAction.__name__ = f"TypeConverting{base_action_name.title()}Action" |
48 | | - return TypeConvertingAction |
49 | | - |
50 | | - |
51 | | -class BorgAddArgumentMixin: |
52 | | - """Mixin to provide Borg's add_argument logic to ArgumentParser and ArgumentGroup.""" |
53 | | - |
54 | | - def add_argument(self, *args, **kwargs): |
55 | | - """Handle type+action combination that jsonargparse forbids. |
56 | | -
|
57 | | - jsonargparse raises ValueError when both type= and action= are given. |
58 | | - We strip type= from kwargs and ensure the action handles type conversion: |
59 | | - - Standard string actions: wrapped in TypeConvertingAction |
60 | | - - Other custom actions: type stored as _type_fn on action instance |
61 | | - """ |
62 | | - action = kwargs.get("action") |
63 | | - if action is not None and "type" in kwargs: |
64 | | - type_fn = kwargs.pop("type") |
65 | | - |
66 | | - if isinstance(action, str): |
67 | | - # Standard action string like 'append', 'store' |
68 | | - wrapper = _make_type_converting_action(action, type_fn) |
69 | | - if wrapper is not None: |
70 | | - kwargs["action"] = wrapper |
71 | | - return super().add_argument(*args, **kwargs) |
72 | | - else: |
73 | | - # Unknown standard action, put type back and try anyway |
74 | | - kwargs["type"] = type_fn |
75 | | - |
76 | | - elif isinstance(action, type) and issubclass(action, argparse.Action): |
77 | | - # Custom action class - register without type, then patch the action |
78 | | - result = super().add_argument(*args, **kwargs) |
79 | | - # Store type_fn on the action for potential manual use |
80 | | - if hasattr(result, "_type_fn"): |
81 | | - pass # already handled |
82 | | - else: |
83 | | - result._type_fn = type_fn |
84 | | - return result |
85 | | - |
86 | | - return super().add_argument(*args, **kwargs) |
87 | | - |
88 | | - |
89 | | -class ArgumentGroup(BorgAddArgumentMixin, _JAPArgumentGroup): |
90 | | - """ArgumentGroup that supports Borg's add_argument patterns.""" |
| 17 | +class ArgumentGroup(_JAPArgumentGroup): |
| 18 | + """ArgumentGroup for Borg.""" |
91 | 19 |
|
92 | 20 | pass |
93 | 21 |
|
94 | 22 |
|
95 | | -class ArgumentParser(BorgAddArgumentMixin, _JAPArgumentParser): |
| 23 | +class ArgumentParser(_JAPArgumentParser): |
96 | 24 | """ArgumentParser bridging Borg's argparse patterns with jsonargparse.""" |
97 | 25 |
|
98 | 26 | def __init__(self, *args, **kwargs): |
|
0 commit comments