brbzull0 opened a new issue, #13597: URL: https://github.com/apache/trafficserver/issues/13597
`ArgParser` decides whether a token following an option is that option's value by looking the token up in the current command's option table (`ArgParser::Command::is_registered_option()`). Two consequences follow. ### 1. A parent command's option swallows a subcommand's option Because the lookup is scoped to a single command, an option of a parent command does not recognise an option belonging to a subcommand, and takes it as its own value: ``` $ traffic_ctl config reload -f -m # --format is set to "-m"; --monitor is silently dropped $ traffic_ctl config reload -f -D ip_allow.id=foo Error: Unknown command, option or args: 'ip_allow.id=foo' ``` `--format`/`-f` and `--run-root` are declared on the top level command, while `-m` and `-D` belong to `config reload`. The reverse direction is safe only because each level strips its own options before recursing into its subcommands, so this is a one-directional accident rather than a property of the design. ### 2. Making the lookup recursive trades one problem for another Walking the subcommand tree inside `is_registered_option()` fixes the above, but couples parent value parsing to the entire command tree: adding an option to any subcommand retroactively narrows the values that unrelated parent options accept. A new `--json` on `config get` would turn `traffic_ctl --format --json` from a value into a usage error. ### What argparse does `ArgParser`'s arities are documented to mirror the `nargs` values of Python's `argparse`, which resolves this syntactically and never consults the option table. A token following an option is refused as that option's value when it starts with a prefix character, is longer than one character, contains no space, and does not look like a negative number (`-\.?\d`): ``` -t -5 -> value '-5' -t -x -> error: expected one argument -t -5.5 -> value '-5.5' -t -zzz -> error (not a registered option either) -t - -> value '-' -t -- -> error ``` The negative-number exception is itself withdrawn if any registered option looks numeric. The documented escape for a dash-prefixed value is `--opt=value`. `argparse` also scopes subcommands: an option of the parent parser may not appear after the subcommand name at all (`reload -f json` gives `unrecognized arguments: -f json`). That is the structural reason it rarely meets this case. `ArgParser` scans the whole argv at every level, which is more permissive and is what creates the ambiguity. ### Proposal Adopt the syntactic rule, keep `ArgParser`'s existing `--` escape, and decide explicitly how numeric values are treated, since several ATS options take them. This subsumes every case above with no tree walk. Found while reviewing #13570, which fixed the same class of problem within a single command. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
