Skip to content

TypeParser.get_parser does not dispatch PEP 604 unions (X | None) — "Unsupported type", order-dependent via lru_cache #558

Description

@mgrbyte

Summary

TypeParser.get_parser (nemo_run/cli/cli_parser.py, v0.9.0) dispatches union annotations with:

elif origin is Union:
    return self.parse_union

but for PEP 604 unions (X | None, X | Y) get_origin(...) returns types.UnionType, not typing.Union, so the annotation falls through to "Unsupported type". Any CLI entrypoint annotated with modern union syntax (extraction: Extraction | None = None) fails to parse.

Reproduction

from nemo_run.cli.cli_parser import parse_value
parse_value("200", int | None)   # Unsupported type: int | None

Subtlety: order-dependent behaviour

get_parser is wrapped in @lru_cache(maxsize=128), and typing.Optional[X] == X | None (equal, equal hashes). So if Optional[int] is parsed first, its cached parser is returned for a later int | None — and the failure caches the same way. Symptom: the same annotation works or fails depending on which spelling any earlier code path parsed first, which makes this confusing to diagnose.

Workaround (public API)

import types
from nemo_run.cli.cli_parser import type_parser
type_parser.register_parser(types.UnionType)(type_parser.parse_union)

Suggested fix

elif origin is Union or origin is types.UnionType:
    return self.parse_union

Related minor finding

Enum-valued list annotations (list[SomeEnum]) are unsupported entirely; list[str] with in-factory conversion is the workaround. Happy to split that into a separate issue if preferred.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions