A config loader that loads aliases and flags with argparse, as well as arbitrary --Class.trait value
| 987 | |
| 988 | |
| 989 | class KVArgParseConfigLoader(ArgParseConfigLoader): |
| 990 | """A config loader that loads aliases and flags with argparse, |
| 991 | |
| 992 | as well as arbitrary --Class.trait value |
| 993 | """ |
| 994 | |
| 995 | parser_class = _KVArgParser # type:ignore[assignment] |
| 996 | |
| 997 | def _add_arguments(self, aliases: t.Any, flags: t.Any, classes: t.Any) -> None: |
| 998 | alias_flags: dict[str, t.Any] = {} |
| 999 | argparse_kwds: dict[str, t.Any] |
| 1000 | argparse_traits: dict[str, t.Any] |
| 1001 | paa = self.parser.add_argument |
| 1002 | self.parser.set_defaults(_flags=[]) |
| 1003 | paa("extra_args", nargs="*") |
| 1004 | |
| 1005 | # An index of all container traits collected:: |
| 1006 | # |
| 1007 | # { <traitname>: (<trait>, <argparse-kwds>) } |
| 1008 | # |
| 1009 | # Used to add the correct type into the `config` tree. |
| 1010 | # Used also for aliases, not to re-collect them. |
| 1011 | self.argparse_traits = argparse_traits = {} |
| 1012 | for cls in classes: |
| 1013 | for traitname, trait in cls.class_traits(config=True).items(): |
| 1014 | argname = f"{cls.__name__}.{traitname}" |
| 1015 | argparse_kwds = {"type": str} |
| 1016 | if isinstance(trait, (Container, Dict)): |
| 1017 | multiplicity = trait.metadata.get("multiplicity", "append") |
| 1018 | if multiplicity == "append": |
| 1019 | argparse_kwds["action"] = multiplicity |
| 1020 | else: |
| 1021 | argparse_kwds["nargs"] = multiplicity |
| 1022 | argparse_traits[argname] = (trait, argparse_kwds) |
| 1023 | |
| 1024 | for keys, (value, fhelp) in flags.items(): |
| 1025 | if not isinstance(keys, tuple): |
| 1026 | keys = (keys,) |
| 1027 | for key in keys: |
| 1028 | if key in aliases: |
| 1029 | alias_flags[aliases[key]] = value |
| 1030 | continue |
| 1031 | keys = ("-" + key, "--" + key) if len(key) == 1 else ("--" + key,) |
| 1032 | paa(*keys, action=_FlagAction, flag=value, help=fhelp) |
| 1033 | |
| 1034 | for keys, traitname in aliases.items(): |
| 1035 | if not isinstance(keys, tuple): |
| 1036 | keys = (keys,) |
| 1037 | |
| 1038 | for key in keys: |
| 1039 | argparse_kwds = { |
| 1040 | "type": str, |
| 1041 | "dest": traitname.replace(".", _DOT_REPLACEMENT), |
| 1042 | "metavar": traitname, |
| 1043 | } |
| 1044 | argcompleter = None |
| 1045 | if traitname in argparse_traits: |
| 1046 | trait, kwds = argparse_traits[traitname] |
no outgoing calls
searching dependent graphs…