No project description provided
Project description
isinstance2
isinstance2
is a module that provides a powerful runtime type checker for Python's built-in generic classes and
generic type hints. It allows you to perform runtime instance type checks on objects that are instances of a generic
class, as well as subclass checks on generic classes, even if you don't know the exact type of the generic parameters.
tl;dr
from isinstance2 import isinstance2, issubclass2
from typing import Iterable
assert isinstance2((1, 2.0, 'three'), tuple[int, float, str])
assert issubclass2(dict[str, int], dict[str, int | float])
assert issubclass2(list[int] | set[int] | tuple[int, ...], Iterable[int])
Features
- Perform runtime instance and subclass checks on generic classes
- Supports built-in generic classes such as
list
,tuple
,dict
,set
, andfrozenset
, as well asOptional
andLiteral
. - Check if an object is an instance of a
tuple
with variadic arguments. - Register custom class or function with
isinstance2
's instance checker registry.
Installation
pip install isinstance2
Basic Usage
Instance Checks
from typing import Iterable, Literal
from isinstance2 import isinstance2
# Basic instance checks
assert isinstance2([1, 2, 3], list[int])
assert isinstance2((1, 2.0, 'three'), tuple[int, float, str])
assert isinstance2({1, 2, 3}, set[int])
assert isinstance2({"foo": 1, "bar": 2}, dict[str, int])
assert isinstance2(frozenset([1, 2, 'Hi! 😊', 'literally amazing']), frozenset[int | Literal['Hi! 😊', 'literally amazing']])
# Ellipses in tuples work
assert isinstance2((1, 'two', 3.0, 'four'), tuple[int | float | str, ...])
# You can also check against abstract generic classes
assert isinstance2(range(10), Iterable[int])
assert not isinstance2(range(10), Iterable[float])
Subclass Checks
from typing import Collection, Iterable
from isinstance2 import issubclass2
# Basic subclass checks
assert issubclass2(list[int], list[int | float])
assert issubclass2(tuple[int, float], tuple[int | float, ...])
# Classes without generic parameters are presumed to match
assert issubclass2(list, list[int])
assert issubclass2(list[int], list)
# Abstract generic classes
assert issubclass2(list[int], Iterable[int])
assert issubclass2(Collection[bool], Iterable[int]) # Yes, bool is a subclass of int
Advanced Usage
To check if an object is an instance of a custom generic class, register it with isinstance2
's instance checker
from typing import Generic, TypeVar, Any
from isinstance2 import isinstance2, register_instance_checker
T = TypeVar('T')
class MyClass(Generic[T]):
...
@register_instance_checker
def is_instance_of_my_class(obj: Any) -> bool:
return isinstance(obj, MyClass)
assert isinstance2(MyClass(), MyClass)
If you'd prefer not to add your checkers globally, you can use isinstance2
's register
instead and pass a custom registry (which is just a dict
).
from typing import Generic, TypeVar
from isinstance2 import register, instance_checker_registry
from functools import partial
# Copy the default registry
my_registry = instance_checker_registry.copy()
# Make a custom registration function
my_register = partial(register, registry=my_registry)
Now you can use my_register
in place of register_instance_checker
.
Limitations
- Does not yet support
TypeVar
Container
- And likely quite a few other generic classes that I've missed. Please open an issue if you find one.
- Subclass checks for custom classes (instance checks are supported)
- Subclass checks are, in general, unreliable.
- I haven't yet figured out how to deal with things like structural subtyping. For instance,
issubclass2(str, Iterator[int])
currently returnsTrue
when it clearly shouldn't - Instance checks are somewhat simpler and shouldn't suffer as much from this problem.
- I haven't yet figured out how to deal with things like structural subtyping. For instance,
- Requires Python 3.11 or later
License
isinstance2
is released under the MIT License.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for isinstance2-0.1.7-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 891420ca06beafe53b6adff79080831401cf685d6474f5f32e60dfe17bf8e6fe |
|
MD5 | 89bc6c07069ba477439bc29fc1087e1f |
|
BLAKE2b-256 | 2b3e8870b5b812ea831360b43450352b27674e3e12a59148bd39161c01d6c3b7 |