diff --git a/CHANGES.md b/CHANGES.md index 651d5469b..757f5d711 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,10 +12,12 @@ * filter: Improved the speed and memory usage of subsampling with `--group-by` and `--subsample-max-sequences` by caching each record's group during the first pass instead of reading the metadata a second time. [#2018][] @trvrb * filter: Improved the speed of computing groups for `--group-by` subsampling by replacing a row-wise pandas apply with a vectorized operation. [#2018][] @trvrb * filter: Improved the speed of writing `--output-metadata` by streaming rows instead of building a dictionary per row. [#2018][] @trvrb +* Improved the error message for unrecognized arguments. [#2028][] @victorlin [#2014]: https://github.com/nextstrain/augur/issues/2014 [#2018]: https://github.com/nextstrain/augur/pull/2018 [#2025]: https://github.com/nextstrain/augur/pull/2025 +[#2028]: https://github.com/nextstrain/augur/issues/2028 ## 34.0.0 (7 July 2026) diff --git a/augur/__init__.py b/augur/__init__.py index eadbdbd27..2c2e929d1 100644 --- a/augur/__init__.py +++ b/augur/__init__.py @@ -14,7 +14,7 @@ from .debug import DEBUGGING from .errors import AugurError from .io.print import print_err -from .argparse_ import HelpFormatter, add_command_subparsers, add_default_command +from .argparse_ import HelpFormatter, add_command_subparsers, add_default_command, SUBPARSER_ATTRIBUTE DEFAULT_AUGUR_RECURSION_LIMIT = 10000 sys.setrecursionlimit(int(os.environ.get("AUGUR_RECURSION_LIMIT") or DEFAULT_AUGUR_RECURSION_LIMIT)) @@ -68,7 +68,18 @@ def make_parser(): def run(argv): - args = make_parser().parse_args(argv) + parser = make_parser() + args, extras = parser.parse_known_args(argv) + + # Workaround for + if extras: + # Message format copied from ArgumentParser.parse_args() + msg = "unrecognized arguments: %s" % " ".join(extras) + if subparser := getattr(args, SUBPARSER_ATTRIBUTE, None): + subparser.error(msg) + else: + parser.error(msg) + try: return args.__command__.run(args) except AugurError as e: diff --git a/augur/argparse_.py b/augur/argparse_.py index 2a2d132a1..c4029033e 100644 --- a/augur/argparse_.py +++ b/augur/argparse_.py @@ -85,6 +85,8 @@ def add_subparser(parent_subparsers: _SubParsersAction, *args, **kwargs) -> Argu return parent_subparsers.add_parser(*args, **kwargs) +SUBPARSER_ATTRIBUTE = '__subparser__' + def add_command_subparsers(subparsers, commands, command_attribute='__command__'): """ Add subparsers for each command module. @@ -109,8 +111,10 @@ def add_command_subparsers(subparsers, commands, command_attribute='__command__' subparser = command.register_parser(subparsers) # Add default attribute for command module - if command_attribute: - subparser.set_defaults(**{command_attribute: command}) + subparser.set_defaults(**{command_attribute: command}) + + # Add a reference to the subparser + subparser.set_defaults(**{SUBPARSER_ATTRIBUTE: subparser}) # Use the same formatting class for every command for consistency. # Set here to avoid repeating it in every command's register_parser().