RussBaz / enforce

Python 3.5+ runtime type checking for integration testing and data validation
542 stars 21 forks source link

Usage with `typing.NamedTuple` #29

Closed Tarrasch closed 7 years ago

Tarrasch commented 7 years ago

First, thanks for this awesome project!

Can this project be used with typing.NamedTuple? I tried this but I couldn't get it to work.

import enforce
import typing
MyNamedTuple = typing.NamedTuple('MyNamedTuple', [('my_int', int)])
MyNamedTuple = enforce.runtime_validation(MyNamedTuple)
# I assumed enforce.runtime_validation would work on any callable
MyNamedTuple(5)  # For me it crashes here already on a "missing a required argument: 'my_int'"
MyNamedTuple(my_int=5) # Now it gives a "missing a required argument: '_cls'", I give up
MyNamedTuple(my_int='hello')  # I never got here

I use version typing=0.3.1 and python=3.5.2.

RussBaz commented 7 years ago

Thanks for trying it out!

It is an interesting problem. As it turns out, this is a problem with blindly attempting to enforce runtime type safety on every attribute of a given class (especially if it inherits from an inbuilt class).

It will be possible to use named tuples as a type hint in the functions. However, it will be slightly harder to make named tuples truly typed.

I have some ideas how it can be done. I will look at it over the coming weekend and will keep you updated.

RussBaz commented 7 years ago

OK, I just pushed a patch into 'dev' branch enabling your specific use case of NamedTuples. Full support for named tuples (i.e. named tuple as a type hint) will be coming a bit later.

Tarrasch commented 7 years ago

As I don't consider myself a power user yet, I'll wait for some sort of pypi release. But thanks for implementing this!

RussBaz commented 7 years ago

I am sorry for the long delay but the pypi version of Enforce.py was just updated to 0.3.2. This version includes all the fixes for the NamedTuples and adds a support for Python 3.5.3 and 3.6.0.

Please have a look if you are still interested.