Skip to main content

A type-checking utility for Python functions

Project description

Typeca

Typeca is a Python decorator for enforcing type checks on both positional and keyword arguments on functions with annotated types.

It ensures that arguments passed to functions and the function's return value match their specified types, raising a TypeError if any type mismatch is found.

P.S. Anyway, this decorator would negatively affect a function`s performance, so the best approach would be to use it during development and testing phases.

%timeit -n 10 -r 7 gen_array(1_000_000)
48 ms ± 1.36 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit -n 10 -r 7 gen_array_type_enforced(1_000_000)
424 ms ± 34.2 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

Supported Python Versions

  • Python 3.10 and later.

Features

  • Flexible Enforcement: Skips type checking for arguments without annotations.
  • Nested Annotation Check: The decorator supports recursive type checking for nested data structures.
  • Configurable Cache Size: Uses a cache to store function signatures, with a configurable maxsize parameter (default is 64).
  • Enable/Disable Type Checking: Users can enable or disable type enforcement on a function by using the enable parameter, defaults to True.
  • Error Handling: Raises a TypeError if a type mismatch is detected for either function args or the return value.

Supported Types

  • Standard Types: Such as int, str, float, bool, and other built-in types.
  • Annotated Data Structures:
    1. list[T]: Checks that the value is a list and that every element conforms to type T.
    2. dict[K, V]: Checks that the value is a dictionary, and that each key has type K and each value has type V.
    3. tuple[T1, T2, ...]: Checks that the value is a tuple, and that each element has specified type (e.g., tuple[int, str] for (41, 'Saturday')).
    4. set[T]: Checks that the value is a set and that every element conforms to type T.
    5. frozenset[T]: Checks that the value is a frozenset and that every element conforms to type T.
  • Type Combinations:
    1. Union[T1, T2, ...]: Checks if the value matches one of the types in the Union, e.g., Union[int, str] would accept both int and str. (Supports both traditional Union from typing and the new | syntax introduced in Python 3.10)
    2. Optional[T]: Equivalent to Union[T, None], checks that the value is either None or matches type T.

Installation

pip install typeca

Usage

Use @type_enforcer to enforce type checks on your functions:

from typeca import type_enforcer


@type_enforcer()
def two_num_product(a: int, b: int) -> int:
    return a * b


two_num_product(2, 3)  # Output: 6

two_num_product(2, '3')  # Raises TypeError

Examples

Example 1: Simple Type Enforcement

@type_enforcer()
def add(a: int, b: int) -> int:
    return a + b


add(3, 4)  # Works fine

add(3, '4')  # Raises TypeError

Example 2: Complex Data Structures

Supports lists, dictionaries, and tuples with type annotations:

@type_enforcer()
def process_items(items: list[int]) -> list[int]:
    return [item * 2 for item in items]


process_items([1, 2, 3])  # Works fine

process_items(['a', 'b', 'c'])  # Raises TypeError

Example 3: Disable Type Enforcement

At any moment you can disable check to improve performance of the function:

@type_enforcer(enable=False)
def process_array(*args) -> list[int]:
    return list(args) * 2


process_array(1, 2, 3)  # Works without type enforcement

Example 4: Custom Cache Size

The type_enforcer decorator will cache up to 128 unique signatures for process_data:

@type_enforcer(maxsize=128)
def process_data(x: int, y: int) -> int:
    return x + y


process_data(5, 10)  # Type enforcement applies, returns 15

process_data("5", "10")  # Raises TypeError

Example 5: Using frozenset

@type_enforcer()
def unique_numbers(data: frozenset[int]) -> frozenset[int]:
    return frozenset([n * 2 for n in data])


unique_numbers(frozenset({1, 2, 3}))  # Returns: frozenset({2, 4, 6})

unique_numbers(frozenset({1, 2, "3"}))  # Raises TypeError

Example 6: Using Union with | syntax

@type_enforcer()
def process_value(value: int | str) -> str:
    return f"Processed: {value}"


process_value(42)  # Returns: "Processed: 42"
process_value("hello")  # Returns: "Processed: hello"

process_value([1, 2, 3])  # Raises TypeError

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

typeca-0.2.0.tar.gz (7.4 kB view details)

Uploaded Source

Built Distribution

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

typeca-0.2.0-py3-none-any.whl (5.9 kB view details)

Uploaded Python 3

File details

Details for the file typeca-0.2.0.tar.gz.

File metadata

  • Download URL: typeca-0.2.0.tar.gz
  • Upload date:
  • Size: 7.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.10.15

File hashes

Hashes for typeca-0.2.0.tar.gz
Algorithm Hash digest
SHA256 f363338eef48d4a7931dd103616c59eb996b89e893f92578b1511d636274e4e8
MD5 376581c5c5a6c2137307d6db4e8d62b0
BLAKE2b-256 d84bf8c5ac7b6297f05ae4e45ab8818a3d4a0b4eeb4a4e3d5c6d365d467ce2ca

See more details on using hashes here.

File details

Details for the file typeca-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: typeca-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 5.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.10.15

File hashes

Hashes for typeca-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4b9e062ec4c96d5f84a5e5a41125b0b841afa1e07bc5ac8945ee1d7090a97036
MD5 0226a179c0f9c975e380d6d62f628097
BLAKE2b-256 3dca2f74b78960e9935bf041fa29096b4cc25f90e5bb9a2e33fb11d5441e2b9b

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