Skip to main content

No project description provided

Project description

isinstance2

isinstance2 is an experimental 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, and frozenset, as well as Optional and Literal.
  • 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 returns True when it clearly shouldn't
    • Instance checks are somewhat simpler and shouldn't suffer as much from this problem.
  • Requires Python 3.11 or later

License

isinstance2 is released 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

isinstance2-0.1.8.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.

isinstance2-0.1.8-py3-none-any.whl (6.1 kB view details)

Uploaded Python 3

File details

Details for the file isinstance2-0.1.8.tar.gz.

File metadata

  • Download URL: isinstance2-0.1.8.tar.gz
  • Upload date:
  • Size: 6.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.3.1 CPython/3.11.0 Darwin/22.2.0

File hashes

Hashes for isinstance2-0.1.8.tar.gz
Algorithm Hash digest
SHA256 8058f15e8368e76c0acb59fc59ab5d90569d7ddb06ae1f4457fe7f6fca149083
MD5 1457e6ab0568d2d2e742faeecadf6fa1
BLAKE2b-256 f88fb09f56f8aeafa9736c4c67428405fa02e5ef2a0968c9d5e5346d3d39aa85

See more details on using hashes here.

File details

Details for the file isinstance2-0.1.8-py3-none-any.whl.

File metadata

  • Download URL: isinstance2-0.1.8-py3-none-any.whl
  • Upload date:
  • Size: 6.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.3.1 CPython/3.11.0 Darwin/22.2.0

File hashes

Hashes for isinstance2-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 871c47197f84772878344969dad13e19f36c0f7ee19645148d34063b2135a575
MD5 b4194bd56f5b3eb7b0bdb41ef49614d6
BLAKE2b-256 e28fadda28eda22a80792f2d092ab643d7f312492288dca9e4d4876378cf2467

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