Typish: Extended Type Functionality
Typish is a Python library that extends Python's native `typing` module, offering advanced functionality for thorough type checks, instance checks considering generics, and typesafe duck-typing. It provides utilities for introspection of type hints, such as retrieving origins and arguments of generic types, and determining optionality. Currently at version 1.9.3, it maintains a regular release cadence with a focus on bug fixes and compatibility improvements across Python versions.
Warnings
- gotcha Prior to v1.9.2, `get_origin` did not correctly handle parameterized collections (e.g., `dict[str, str]`) in Python 3.9+.
- gotcha In versions older than 1.8.0, `instance_of` could fail when used with `Literal` types containing multiple arguments.
- gotcha Before v1.8.0, `get_origin` might have failed when dealing with classes that had shadowing names, leading to incorrect type introspection.
- gotcha Python's native `typing` module has evolved significantly across versions (e.g., `Union[X, Y]` vs `X | Y` syntax). While `typish` aims to provide compatibility, mixing `typing` constructs from different Python versions or relying on `typish` to completely abstract away core `typing` changes might lead to subtle issues if not carefully managed.
Install
-
pip install typish
Imports
- instance_of
from typish import instance_of
- get_origin
from typish import get_origin
- is_optional_type
from typish import is_optional_type
- ClsDict
from typish import ClsDict
- hintable
from typish import hintable
- Literal
from typish import Literal
Quickstart
from typing import Iterable
from typish import instance_of
# Basic instance check with generics
result_iterable = instance_of([1, 2, 3], Iterable[int])
print(f"Is [1, 2, 3] an Iterable[int]? {result_iterable}")
from typish import get_origin
from typing import List, Dict
# Get the origin of a generic type
origin_list = get_origin(List[str])
origin_dict = get_origin(Dict[str, int])
print(f"Origin of List[str]: {origin_list}")
print(f"Origin of Dict[str, int]: {origin_dict}")
from typish import is_optional_type, Literal
from typing import Optional, Union
# Check for optional types
is_opt_str = is_optional_type(Optional[str])
is_union_none = is_optional_type(Union[int, None])
print(f"Is Optional[str] optional? {is_opt_str}")
print(f"Is Union[int, None] optional? {is_union_none}")
# Using typish.Literal for older Python compatibility (if needed)
from typish import Literal
def process_status(status: Literal['success', 'failure']):
return f"Processing status: {status}"
print(process_status('success'))