Runtime type checks in Python
<!-- PLACE KOOL INTRO HERE -->
I always loved the concept of type hints in Python. It is such a great concept to help you and other people, who work on the same project to have a direct help on what this function takes. No docstrings, no alt-tabing to documentation and code editor. That's very handy! And the best part? They're optional.
And recently I had started working on a minimal, handrolled framework for AWS Lambda API. And I felt like I should keep it as minimal as possible, only using the Python's builtin lib, and I can say, while it is an easy task, if you are determined, it is easy to make it your worst nightmare. So back to the framework, I was building a validation engine, and in front of that I had a small sanitation pipeline for each type, so at the moment of validation we would work only with pure Python-inferred objects.
And as a good, or as a bad developer (you are free to choose for yourself), I was worried and still did type checks inside the validation method. And I hated that, you just repeat there:
def validator(args: Type) -> bool:
if not isinstance(args, Type):
return False
# validation logic
return True
Why I have to check everytime if I passed the right type to my function, if I already typed it in the definition?
The research begins
Actually, like almost every problem in Python, it was already solved:
- beartype - cool, performant, modern runtime type checker, I personally recommend it!
- typeguard - another solid choice; maybe a little less performant, because it doesn't cache things, but still recommend checking this out!
But what if I don't want a dependency?
Right.... Well, I'll ask you to love and favor: exact!
exact is a:
- Teeny-tiny runtime type checker
- Extendible and easy to understand (less than 200 LoC)
- I like the name I came up with
And it works beautifully, imho
@exact
def greet(name: str, age: int) -> str:
return f"Hello {name}, you’re {age}!"
greet("Alice", "twenty")
# TypeError: [EXACT] In function "greet": argument "age" must be "int", got str('twenty')
While my solution is defintely less 100% and precise as others, it gets the job done, and is easy to extend/modify if I ever will have such a necessity.
After finishing writing exact I went on a walk and thought a lot
about typization in languages, especially the case of JavaScript and its nerdy
sibling TypeScript. Though, I can't stand JS at all, I find it interesting,
how everyone loves and hates TS for its forced typing, which leads to
shitposting any so bad, that it often misses the whole point of
being type checked. And I thought that maybe, TS had to be able optionally
enforce types, just like my and other libs do? We definetely will not get a
final question on that, because, obviously, it depends, but I think
this is something, many developers would find as safe and convinient in their
everyday life
<!-- PLACE ENGAGING OUTRO HERE -->
If you are interested, take a look, fork it, play with it, discuss on issues, or just completely ignore what I wrote here and come back to doomscrolling you news.
$$$$$$$$$$$$$$$$$$$$$$$$$
$$$$$$$$$$$$$$$$$$$$$$$$$
$$$$$'`$$$$$$$$$$$$$'`$$$
$$$$$$ $$$$$$$$$$$ $$$$
$$$$$$$ '$/ `/ `$' .$$$$
$$$$$$$$. i i /! .$$$$$
$$$$$$$$$.--'--' $$$$$$
$$^^$$$$$' J$$$$$$
$$$ ~"" `. .$$$$$$$
$$$$$e, ; .$$$$$$$$
$$$$$$$$$$$.' $$$$$$$$$
$$$$$$$$$$$$. $$$$$$$$
$$$$$$$$$$$$$ $by&TL$