Skip to main content

Strong type hints with Traits

Project description

Strong Type Hints with Traits

Build Status

This package supplies simple decorators to enforce Python type hints on function parameters and return types.

from typen import enforce_type_hints


@enforce_type_hints
def halve_integer(a: int) -> float:
    return a / 2

halve_integer(5)  # 2.5

halve_integer(5.0)  # ParameterTypeError
@enforce_type_hints
def give_int(a) -> int:
    return a

give_int(1)  # 1

give_int("a")  # ReturnTypeError

Trait Type Hints

Trait types can also be used to define complex patterns in type hints

from traits.api import Array, Either, Enum, Instance, Int, Str, Tuple


@enforce_type_hints
def complicated_function(
        a: Either(Str, Int),  # Either a string or an int
        b: Enum(2, 5, "foo"),  # One of a specific set of values
        c: Instance(MyClass),  # Class instances
        d: Array(size=(None, 2)),  # Numpy array validation
        ) -> Tuple(Str, Either(Str, Int)):  # Complicated return specification
    ...

Strict Enforcement

Type hints can also be required with the @strict_type_hints decorator. Both of the following examples will raise an exception when the function is first called. Without strict enforcement, parameters and return values without type hints can have any value.

from typen import strict_type_hints


@strict_type_hints
def add_numbers(a, b: float) -> float:
    return a + b

add_numbers(1, 2)  # UnspecifiedParameterTypeError
@strict_type_hints
def add_numbers(a: float, b: float):
    return a + b

add_numbers(1, 2)  # UnspecifiedReturnTypeError

Packed args and kwargs

Type hints on packed parameters apply to all values passed through that packing.

@enforce_type_hints
def foos_vs_bars(*foos: int, **bars: str) -> bool:
    return sum(foos) >= len(bars)


foos_vs_bars(1, 2, 3, a="a", b="b", c="c")  # True

foos_vs_bars(2, 3, 5, d=4)  # ParameterTypeError

foos_vs_bars(2, "three", 5, e="e")  # ParameterTypeError

Method Decoration

Methods can be decorated as well. self-references are exempt from strict type hint requirements, as is the return type of __init__. @enforce_type_hints and @strict_type_hints should decorate the product of the @classmethod or @staticmethod decorators.

class ExClass:
    @strict_type_hints
    def __init__(self, a: int, b: int):
        ...

    @strict_type_hints
    @classmethod
    def a_class_method(cls, a: int, c: int) -> int:
        ...

    @strict_type_hints
    @staticmethod
    def a_static_method(a: int, c: int) -> int:
        ...

Coercion

Values are enforced to types based on Trait type coercion. Casting behaviour is not added to the function:

@enforce_type_hints
def add_numbers(a: float, b: float) -> float:
    return a + b

type(add_numbers(1, 2))  # int

Recovering from ReturnTypeError

Because the function has to be executed to enforce the return value, the invalid value is stored on the exception. This makes it possible to recover from a ReturnTypeError programatically.

from typen.exceptions import ReturnTypeError


@enforce_type_hints
def give_int(a) -> int:
    return a

try:
    give_int("a")
except ReturnTypeError as err:
    print(err.return_value)  # a

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

typen-0.0.3-py3-none-any.whl (11.8 kB view hashes)

Uploaded Python 3

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