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.

Files for typen, version 0.0.3
Filename, size File type Python version Upload date Hashes
Filename, size typen-0.0.3-py3-none-any.whl (11.8 kB) File type Wheel Python version py3 Upload date Hashes View hashes

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN SignalFx SignalFx Supporter DigiCert DigiCert EV certificate StatusPage StatusPage Status page