rive_n <rivenfornotificati...@gmail.com> added the comment:
Hi again. previous solution with: ```python3 try: namespace, args = self._parse_known_args(args, namespace) if hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR): args.extend(getattr(namespace, _UNRECOGNIZED_ARGS_ATTR)) delattr(namespace, _UNRECOGNIZED_ARGS_ATTR) return namespace, args except ArgumentError: err = _sys.exc_info()[1] self.error(str(err)) ``` Is not working at all. So i spent some time (a lot of time) to make changes in source code. I figured out exactly how the algorithm works, I read about 3,000 lines of code. And here's what I came up with: argparse.py: line 1774: parse_known_args basically this function calling protected one on line 1800: amespace, args = self._parse_known_args(args, namespace) This one is making magic. But we need to check line 1856: def take_action(action, argument_strings, option_string=None): This function creating objects of necessary classes. For example: _SubParsersAction (problem in it). Before fix: ```python3 def __call__(self, parser, namespace, values, option_string=None): parser_name = values[0] arg_strings = values[1:] # set the parser name if requested if self.dest is not SUPPRESS: setattr(namespace, self.dest, parser_name) # select the parser try: parser = self._name_parser_map[parser_name] except KeyError: args = {'parser_name': parser_name, 'choices': ', '.join(self._name_parser_map)} msg = _('unknown parser %(parser_name)r (choices: %(choices)s)') % args raise ArgumentError(self, msg) # parse all the remaining options into the namespace # store any unrecognized options on the object, so that the top # level parser can decide what to do with them # In case this subparser defines new defaults, we parse them # in a new namespace object and then update the original # namespace for the relevant parts. subnamespace, arg_strings = parser.parse_known_args(arg_strings, None) for key, value in vars(subnamespace).items(): setattr(namespace, key, value) if arg_strings: vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, []) getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings) ``` After fix: ```python3 def __call__(self, parser, namespace, values, option_string=None, arg_strings_pattern:list =None): o_amount = arg_strings_pattern.count("O") if not o_amount: raise ValueError("No Os found") o_start, o_stop, indexes = arg_strings_pattern.index('O'), len(arg_strings_pattern), [] print(parser) try: while arg_strings_pattern.index('O', o_start, o_stop): indexes.append(arg_strings_pattern.index('O', o_start, o_stop)) o_start = arg_strings_pattern.index('O', o_start + 1, o_stop) except ValueError: pass for parser in range(o_amount): parser_name = values[indexes[parser] - 1] # indexes[parser] could give int (real index) arg_strings = values[indexes[parser]: indexes[(parser + 1)] - 1] if parser < len(indexes) - 1 else \ values[indexes[parser]:] # could give all data # set the parser name if requested if self.dest is not SUPPRESS: setattr(namespace, self.dest, parser_name) # select the parser try: parser = self._name_parser_map[parser_name] except KeyError: args = {'parser_name': parser_name, 'choices': ', '.join(self._name_parser_map)} msg = _('unknown parser %(parser_name)r (choices: %(choices)s)') % args raise ArgumentError(self, msg) # parse all the remaining options into the namespace # store any unrecognized options on the object, so that the top # level parser can decide what to do with them # In case this subparser defines new defaults, we parse them # in a new namespace object and then update the original # namespace for the relevant parts. subnamespace, arg_strings = parser.parse_known_args(arg_strings, None) for key, value in vars(subnamespace).items(): setattr(namespace, key, value) if arg_strings: vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, []) getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings) ``` That's not the best solution but this solution works. ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue47043> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com