Skip to content

Conversation

cnaples79
Copy link

Summary

Treat '-' tokens as values during argument splitting so that positional arguments of numeric types (Int/Double) can accept negative literals, e.g. or .

Motivation

Currently, inputs like are interpreted as options, causing errors for commands that legitimately expect a negative number as a positional argument (see #31). This change aligns with common CLI expectations where negative numeric literals are valid values.

Implementation

  • Update to classify '-' and '-.' as values rather than options.
  • Preserve existing short/long option behavior (e.g. , , , and ).
  • Add unit tests covering negative and positional arguments.

Considerations

  • This change gives precedence to numeric literals over short options that would be single-digit flags (which are relatively uncommon). Options with letters or grouped short options are unaffected.

Fixes #31

…guments (Fixes apple#31)

- Update SplitArguments to classify '-5' and '-3.14' as values, not options
- Add unit tests for negative Int and Double positional arguments
@rgoldberg
Copy link
Contributor

@cnaples79 I don't have the chance to look at the code right now, but quick question about "This change gives precedence to numeric literals over short options that would be single-digit flags":

Does this completely preclude the ability to use digits as short or old-style-long flags?

Or is this only if a signed number could otherwise be accepted in that position?

If the latter, could this output a build warning about such clashes when they can occur?

@cnaples79
Copy link
Author

cnaples79 commented Sep 20, 2025

Thanks for the questions / feedback @rgoldberg !

  • Does this preclude digit flags? Yes in this PR: standalone "-" or "-." are always classified as values, so numeric short/old-style-long flags like "-1"/"-10" would be taken as values. Grouped flags (e.g. "-1v") and non-numeric options are unaffected.
  • Is it context-only? No — this change isn’t context-aware; it doesn’t check whether a numeric positional is expected at that position.
  • Build warnings? The library can’t emit compile-time warnings, and this PR doesn’t add runtime warnings.

If you prefer, I can revise to a context-aware approach: only reinterpret "-" as a value when the parser is about to consume a numeric positional and there’s no defined option matching it, which preserves digit flags elsewhere.

Workaround users can use today: pass negative numbers with the standard terminator or quoting, e.g. -- -5 or "-5".

@rgoldberg
Copy link
Contributor

rgoldberg commented Sep 20, 2025

@cnaples79 Thanks for the reply.

IIUC, quoting a dash followed solely by digits (dash/digits) won't be handled any differently by the shell or by SAP than if it were unquoted.

IIRC, there's some setting to make SAP consider dash-prefixed tokens where an option value should have been supplied to be considered an option value or a different flag/option. So that should take care of option values. Maybe there could be a new setting that considers such dash-prefixed tokens to be option values only if the option value type can accept such a token (e.g., a UInt64 couldn't).

Barring the presence of a prior flag/option terminator, and outside of an option value, I think that dash/digits should by default first match any applicable flags/options, then match any enumerated arguments (like if an enum case had a -1 raw value; maybe flags/options & enumerated values should be transposed in the priority list), then match any applicable signed-number arguments. Dash/digits shouldn't, e.g., match any unsigned-number arguments. Maybe there already is a setting to allow dash-prefixed tokens to be taken as arguments if they don't match any applicable flags/options; if it doesn't exist, maybe it could be added. Maybe there are other circumstances that I've missed. Maybe these priorities could later be configurable, but I assume that's not needed for an MVP.

@cnaples79
Copy link
Author

@rgoldberg do you want me to update the PR with this new criteria?

@rgoldberg
Copy link
Contributor

@cnaples79 I'm not a member of the project.

If you agree with my suggestions, by all means make any updates you want.

If some updates will take a lot of time, or if you disagree with my suggestions, however, you might want to wait for feedback from @natecook1000 and/or @rauhul, as they know the project better & are the project owners.

Thanks for discussing, and for submitting the PR.

@cnaples79
Copy link
Author

@rgoldberg Ah got it! Yeah of course, I'll wait for feedback from one of the POs. Thanks a bunch for your suggestions! I'm not entirely sure which approach is best yet, will have to do a bit more research.

@natecook1000
Copy link
Member

@cnaples79 Thanks for working on this! I would have sworn that there was more discussion on #31, but it looks like the notes are fairly brief.

Unconditionally treating inputs like -1 as values instead of flags isn't a viable solution, since it's potentially source breaking and closes off using ArgumentParser for implementing some common CLI patterns. What I meant to add to the thread (all those years ago) is the idea of allowing an ExpressibleByParsing type to opt into negative number representations, which would then change the parsing behavior when looking for those values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support passing a negative number as an argument
3 participants