Skip to main content

Extend typing package functionalities

Project description

typingx

Tests codecov pypi versions license

How many times have you wanted to check the shape of your data either in application code or while testing? With this library, you can leverage typing types at runtime to do that!

# Check if `my_list` is a list of integers
isinstancex(my_list, [int])  # shortcut for typing.List[int]

# Check if `my_list` has only numbers (3.10 syntax)
isinstancex([3, 4, 3.14], list[int | float])

# Check if `my_list` starts with 2 integers and then has only strings
isinstancex(my_list, [int, int, str, ...])  # shortcut for Listx[int, int, str, ...] (see extra types)

# Check if `my_dict` is a mapping between integers and strings
isinstancex(my_dict, {int: str})  # shortcut for `typing.Dict[int, str]`

# Check deeper the shape of `my_dict`
isinstancex(my_dict, {'a': int, 'b': bool, ...: str})  # shortcut for `typing.TypedDict`

Since typing changed a lot since python 3.6, this library also makes sure the whole behaviour is consistent with 3.10 for all python versions.

It hence provides:

  • isinstancex: like isinstance but with typing types and extra types provided by this library
  • get_args and get_origin that have the exact same behaviour as the 3.10 python version ones, no matter which python version is used (the only exception being get_args with Generic on python 3.6)
  • is_literal, is_newtype, is_typeddict helpers
  • most typing types but with homogeneous behaviour (e.g. with 3.8, this libray will choose typing_extensions.TypedDict instead of typing.TypedDict since the latter doesn't store information to distinguish optional and required keys)
  • extanded types:
    • TypedDict with ... field to allow type checking on optional fields
  • extra types:
    • Listx and Tuplex: more sophisticated versions of List and Tuple to add ... anywhere in the parameters

Installation

    pip install typingx

Usage

from collections import ChainMap, Counter

from typingx import *

# Dict
assert isinstancex({"a": 1, "b": 2}, Dict[str, int]) is True
assert isinstancex({"a": 1, "b": 2}, Dict[str, str]) is False
assert isinstancex({"a": 1, "b": 2}, Dict[int, str]) is False
assert isinstancex({"a": 1, "b": 2}, Dict[str, Any]) is True

# Dict (shortcut)
assert isinstancex({"a": 1, "b": 2}, {str: int}) is True

# List
assert isinstancex([1, 2, 3], List[int]) is True
assert isinstancex([1, 2, "q"], List[int]) is False
assert isinstancex([1, 2, "q"], List[Union[str, int]]) is True

# Listx
assert isinstancex([1, 2, 3, 4], Listx[int]) is True
assert isinstancex([1, 2, "q"], Listx[int, ..., str]) is True
assert isinstancex([1, 2, "q", "w", "e"], Listx[int, ..., str]) is False
assert isinstancex([1, 2, "q", "w", "e"], Listx[int, ..., str, ...]) is True
assert isinstancex([1, 2, "q", "w", b"xyz", "e"], Listx[int, ..., str, ...]) is False
assert isinstancex([1, 2, "q", "w", b"xyz", "e"], Listx[int, ..., Union[str, bytes], ...]) is True

# Listx (shortcut)
assert isinstancex([1, 2, 3, 4, "q"], [int, ..., str]) is True

# Literal
assert isinstancex("a", Literal["a"]) is True
assert isinstancex(Literal["a"], Literal["a"]) is True
assert isinstancex("b", Literal["a"]) is False
assert isinstancex("b", Literal["a", Literal[Literal["b"]]]) is True
assert isinstancex(Literal["a", "b"], Literal["b", "a", "c"]) is True

# Mapping
assert isinstancex(Counter({"red": 4, "blue": 2}), Mapping[str, int]) is True
assert isinstancex(ChainMap({"art": "van gogh"}, {"music": "bach"}), Mapping[str, str]) is True

# NewType
UserId = NewType("UserId", int)
ProUserId = NewType("ProUserId", UserId)

assert isinstancex(1, UserId) is True
assert isinstancex(1, ProUserId) is True
assert isinstancex(UserId(1), UserId) is True
assert isinstancex("3", UserId) is False

# None
assert isinstancex([None, None], List[None]) is True
assert isinstancex([None, None], List[NoneType]) is True
assert isinstancex([None, None], List[type(None)]) is True
assert isinstancex([None, None], List[Literal[None]]) is True

# Sequence
assert isinstancex("abc", Sequence[Any]) is True
assert isinstancex("abc", Sequence[int]) is False
assert isinstancex((1, 3, 5), Sequence[int]) is True

# Set
assert isinstancex({"a", "b"}, Set[str]) is True
assert isinstancex({"a", "b"}, Set[int]) is False
# Can be written with the shortcut!
assert isinstancex({"a", "b"}, {str}) is True

# Tuple
assert isinstancex((1, 2), Tuple[int, ...]) is True
assert isinstancex((1, 2), Tuple[int, int]) is True
assert isinstancex((1, 2), Tuple[int, int, int]) is False

# Tuplex
assert isinstancex((3, "a", "b"), Tuplex[int, str, ...]) is True
assert isinstancex((3, "a", "b", "c"), Tuplex[int, str, ...]) is True
assert isinstancex((3, "a", "b", "c"), Tuplex[int, str, ..., bool]) is False
assert isinstancex((3, "a", "b", "c", True), Tuplex[int, str, ..., bool]) is True
assert isinstancex((3, "a", "b", "c", 3), Tuplex[int, str, ..., bool]) is False
assert isinstancex((3, "a", "b", "c", True, False), Tuplex[int, str, ..., bool, ...]) is True

# Type
class User: ...
class BaseUser(User): ...

assert isinstancex(BaseUser, Type[BaseUser]) is True
assert isinstancex(BaseUser, Type[User]) is True
assert isinstancex(User, Type[User]) is True
assert isinstancex(User, Type[BaseUser]) is False

# TypedDict
FullMovie = TypedDict("FullMovie", {"name": str, "year": int})

class PartialMovie(TypedDict, total=False):
    name: str
    year: int

class ExtraMovie(TypedDict):
    name: str
    year: int
    __extra__: str

assert isinstancex({"name": "The Matrix", "year": 1999}, FullMovie) is True
assert isinstancex({"name": "The Matrix", "year": "1999"}, FullMovie) is False
assert isinstancex({"name": "The Matrix"}, FullMovie) is False
assert isinstancex({"name": "The Matrix", "year": 1999, "extra": "qwe"}, FullMovie) is False

assert isinstancex({"name": "The Matrix", "year": 1999}, PartialMovie) is True
assert isinstancex({"name": "The Matrix"}, PartialMovie) is True
assert isinstancex({"name": "The Matrix", "year": 1999, "extra": "qwe"}, PartialMovie) is False

assert isinstancex({"name": "The Matrix", "year": 1999}, ExtraMovie) is True
assert isinstancex({"name": "The Matrix", "year": 1999, "q": "w", "e": "r"}, ExtraMovie) is True
assert isinstancex({"name": "The Matrix", "year": 1999, "q": "w", "e": 1}, ExtraMovie) is False

# TypedDict (shortcut)
assert isinstancex({"name": "The Matrix", "year": 1999, "q": "w", "e": "r"}, {"name": str, "year": int, ...: str}) is True

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

typingx-0.3.0.tar.gz (10.2 kB view details)

Uploaded Source

Built Distribution

typingx-0.3.0-py3-none-any.whl (8.8 kB view details)

Uploaded Python 3

File details

Details for the file typingx-0.3.0.tar.gz.

File metadata

  • Download URL: typingx-0.3.0.tar.gz
  • Upload date:
  • Size: 10.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.0.5 CPython/3.8.2 Darwin/18.7.0

File hashes

Hashes for typingx-0.3.0.tar.gz
Algorithm Hash digest
SHA256 707b3dd2bae4d07041b2ba9f0d9de98f3d1cb678cfee91a7e2391c7b9718f297
MD5 fefe3088318e5b0917d7c9eb78379219
BLAKE2b-256 61c465b4b8da990fbdb4e48c9b900cb48e7b790a1c1a24e42f8b6367dd9d4460

See more details on using hashes here.

File details

Details for the file typingx-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: typingx-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 8.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.0.5 CPython/3.8.2 Darwin/18.7.0

File hashes

Hashes for typingx-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 39b704de461c688b4c3582cbb01ca4ba334258dd7f21306d714bb98a7a2694bf
MD5 1b4887c783ff31f6909dc5a931b4aeb8
BLAKE2b-256 462d22af7702be9f2e5adcbc89380f89762dad458b1f504af6942e1325e2353e

See more details on using hashes here.

Supported by

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