Skip to main content

Compatibility helpers for typing.get_origin() and typing.get_args() on Python < 3.8.

Project description

get_args_and_origin

get_args_and_origin provides get_origin() and get_args() on Python < 3.8.

  • On Python >= 3.8, it simply re-exports the stdlib implementations.
  • On Python < 3.8, it backports equivalent behavior for the older typing constructs, plus typing_extensions.Annotated, typing_extensions.Final, and typing_extensions.Literal.

Installation

pip install get-args-and-origin

Usage

from get_args_and_origin import get_origin, get_args

Supported on Python < 3.8

Core typing constructs:

  • List[T]
  • Dict[K, V]
  • Set[T]
  • FrozenSet[T]
  • Tuple[...]
  • Callable[..., T]
  • Callable[[A, B], R]
  • Union[...]
  • Optional[T]
  • Type[T]
  • nested generic aliases
  • unsubscripted Generic

typing_extensions constructs:

  • typing_extensions.Final[T]
  • typing_extensions.Literal[...]
  • typing_extensions.Annotated[T, ...]

Notes

  • On Python < 3.8, Final, Literal, and Annotated should be used from typing_extensions, and get_origin() normalizes them to those typing_extensions objects.
  • On Python >= 3.8, behavior is exactly whatever typing.get_origin() and typing.get_args() do in the standard library.
  • Union argument ordering can vary slightly across old typing backports.

Quick assert-style smoke tests

These assert-style checks are meant to double as a compact, high-coverage compatibility suite for Python 2.7, 3.4, 3.5, 3.6, and 3.7.

from typing import (
    Callable,
    Dict,
    FrozenSet,
    Generic,
    List,
    Optional,
    Set,
    Tuple,
    Type,
    TypeVar,
    Union,
)
import typing_extensions
from get_args_and_origin import get_origin, get_args

T = TypeVar('T')
S = TypeVar('S')

assert get_origin(int) is None
assert get_origin(str) is None
assert get_args(int) == ()
assert get_args(str) == ()

assert get_origin(T) is None
assert get_args(T) == ()

assert get_origin(List[int]) is list
assert get_args(List[int]) == (int,)

assert get_origin(Dict[int, str]) is dict
assert get_args(Dict[int, str]) == (int, str)

assert get_origin(Set[int]) is set
assert get_args(Set[int]) == (int,)

assert get_origin(FrozenSet[int]) is frozenset
assert get_args(FrozenSet[int]) == (int,)

assert get_origin(Tuple[int, str]) is tuple
assert get_args(Tuple[int, str]) == (int, str)

assert get_origin(Tuple[int, ...]) is tuple
assert get_args(Tuple[int, ...]) == (int, Ellipsis)

assert get_origin(Union[int, str]) is Union
assert get_args(Union[int, str]) == (int, str)

assert get_origin(Optional[int]) is Union
assert get_args(Optional[int]) == (int, type(None))

assert get_origin(Callable[[int, str], bool]).__name__ == 'Callable'
assert get_args(Callable[[int, str], bool]) == ([int, str], bool)

assert get_origin(Callable[..., bool]).__name__ == 'Callable'
assert get_args(Callable[..., bool]) == (Ellipsis, bool)

assert get_origin(Type[int]) is type
assert get_args(Type[int]) == (int,)

assert get_origin(Generic) is Generic
assert get_args(Generic) == ()

assert get_origin(List) is list
assert get_origin(Dict) is dict
assert get_origin(Set) is set
assert get_origin(FrozenSet) is frozenset
assert get_origin(Tuple) is tuple
assert get_args(List) == ()
assert get_args(Dict) == ()
assert get_args(Set) == ()
assert get_args(FrozenSet) == ()

assert get_origin(Dict[str, List[Tuple[int, str]]]) is dict
assert get_args(Dict[str, List[Tuple[int, str]]]) == (str, List[Tuple[int, str]])

assert get_origin(List[Union[int, str]]) is list
assert get_args(List[Union[int, str]]) == (Union[int, str],)

assert get_origin(Dict[str, Optional[int]]) is dict
assert get_args(Dict[str, Optional[int]]) == (str, Optional[int])

assert get_origin(Tuple[List[int], Dict[str, bool]]) is tuple
assert get_args(Tuple[List[int], Dict[str, bool]]) == (List[int], Dict[str, bool])

assert get_origin(Tuple[List[T], Dict[str, S]]) is tuple
assert get_args(Tuple[List[T], Dict[str, S]]) == (List[T], Dict[str, S])

assert get_origin(Tuple[Union[int, str], Optional[bool]]) is tuple
assert get_args(Tuple[Union[int, str], Optional[bool]]) == (Union[int, str], Optional[bool])

Literal = typing_extensions.Literal
Final = typing_extensions.Final
Annotated = typing_extensions.Annotated

assert get_origin(Literal[1, 'x', True]) is Literal
assert get_args(Literal[1, 'x', True]) == (1, 'x', True)
assert get_origin(Literal[1]) is Literal
assert get_origin(Literal) is None
assert get_args(Literal) == ()

assert get_origin(Final[int]) is Final
assert get_args(Final[int]) == (int,)
assert get_origin(Final) is None
assert get_args(Final) == ()

assert get_origin(Annotated[int, 'm1', 'm2']) is Annotated
assert get_args(Annotated[int, 'm1', 'm2']) == (int, 'm1', 'm2')
assert get_origin(Annotated[int, 'm']) is Annotated
assert get_origin(Annotated[List[int], 'tag']) is Annotated
assert get_args(Annotated[List[int], 'tag']) == (List[int], 'tag')
assert get_origin(Annotated[Union[int, str], 'u']) is Annotated
assert get_args(Annotated[Union[int, str], 'u']) == (Union[int, str], 'u')

nested = Dict[
    str,
    Tuple[
        List[Optional[int]],
        Annotated[Literal[1, 2], 'meta'],
    ],
]
assert get_origin(nested) is dict
assert get_args(nested) == (
    str,
    Tuple[
        List[Optional[int]],
        Annotated[Literal[1, 2], 'meta'],
    ],
)

Contributing

Contributions are welcome! Please submit pull requests or open issues on the GitHub repository.

License

This project is licensed under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

get_args_and_origin-0.1.0a0.tar.gz (6.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

get_args_and_origin-0.1.0a0-py2.py3-none-any.whl (6.5 kB view details)

Uploaded Python 2Python 3

File details

Details for the file get_args_and_origin-0.1.0a0.tar.gz.

File metadata

  • Download URL: get_args_and_origin-0.1.0a0.tar.gz
  • Upload date:
  • Size: 6.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for get_args_and_origin-0.1.0a0.tar.gz
Algorithm Hash digest
SHA256 d586f52c0fc07f6806439107152eedc2490d8ce832d089ce13e4301aeb80f360
MD5 0fc6f4f5f96ddd41d573d46c5e5cc5bc
BLAKE2b-256 967968b1bc0963b389f7d4b3d4006b6bd97aa2e62d7321691df01f1ec5134f68

See more details on using hashes here.

File details

Details for the file get_args_and_origin-0.1.0a0-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for get_args_and_origin-0.1.0a0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 1f678c954ea985d6ac697667db911ef51bcb79491a704b608ae6885cd5b4e723
MD5 bce34b2da74124a88016adb44af8e2cb
BLAKE2b-256 3c1098621f6e06f10dee7cc5d3404f37fc4a439a1a97e5d72663a1b1e063e75b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page