Skip to content

fix: preserve string-hinted argument values without numeric coercion (#733) - #734

Open
Aryan9891 wants to merge 1 commit into
google:masterfrom
Aryan9891:fix/preserve-string-hinted-args-733
Open

Aryan9891 wants to merge 1 commit into
google:masterfrom
Aryan9891:fix/preserve-string-hinted-args-733

Conversation

@Aryan9891

Copy link
Copy Markdown

Problem

Fixes #733.

When a callable command function defines an argument with a string type hint (e.g., �rg: str or �rg: Optional[str]), passing a numerical or version-formatted string such as 1.10 or 123 causes DefaultParseValue to coerce the value via _LiteralEval into a float (1.1) or integer (123).

This is particularly problematic when handling software release versions, identifiers, zip codes, or semver strings where 1.1 has a fundamentally different meaning from 1.10.

Solution

  1. Annotation Inspection ( ire/inspectutils.py):

    • Added IsStringAnnotation(annotation) to determine whether a given annotation corresponds to a string type, supporting str, yping.Text, subclasses of str, yping.Optional[str], yping.Union[str, None], and Python 3.10+ union expressions (str | None).
    • Added AllowsNone(annotation) to check whether None is an accepted value for the annotated type.
  2. Targeted String Preservation ( ire/core.py):

    • Passed n_spec.annotations into _ParseArgs and _ParseValue.
    • When no custom parse function is attached via @SetParseFn/@SetParseFns and the argument is annotated as a string type:
      • If DefaultParseValue(value) returns a string (e.g. stripping explicit outer quotes), that parsed string is used.
      • If DefaultParseValue(value) returns None and the annotation allows None (e.g. Optional[str]), None is returned.
      • Otherwise, the original uncoerced string �alue is preserved instead of being coerced to a float or int.
    • For untyped or non-string arguments, standard literal evaluation remains 100% unchanged.
  3. Regression Tests:

    • Added unit tests in ire/inspectutils_test.py verifying IsStringAnnotation and AllowsNone behavior across string, union, and non-string types.
    • Added estFireStringHintedArgs in ire/fire_test.py verifying that version strings (1.10), numbers (123), and boolean-like strings (True) remain strings for both positional and flag syntax, while respecting None for optional strings.

…oogle#733)

When a function parameter is explicitly annotated with str or an
optional string type (Optional[str] / str | None), prevent
DefaultParseValue from coercing version strings, floats, and numeric
representations (e.g. 1.10) into loat(1.1) or int.

- Add IsStringAnnotation and AllowsNone helpers in inspectutils.py
  to identify string annotations across direct types, typing constructs,
  and union expressions.
- Pass argspec �nnotations into _ParseArgs and _ParseValue in core.py,
  preserving the original string when literal evaluation would otherwise
  coerce the value away from str.
- Preserve custom parse function decorator precedence and standard
  literal parsing for untyped or non-string arguments.
- Add regression test coverage in inspectutils_test.py and ire_test.py.

Signed-off-by: Aryan Sachin <aryansachinixd@gmail.com>
Aryan9891 added a commit to Aryan9891/Aryan9891 that referenced this pull request Nov 10, 2026

This branch has not been deployed

No deployments
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.

String hinted arguments passed numerical values should not be coerced

1 participant