Hacker News new | ask | show | jobs
by Boxxed 110 days ago
My favorite part about the type annotations in python is that it steers you into a sane subset of the language. I feel like it's kind of telling that python is this super dynamic language but the type annotations aren't powerful enough to denote all that craziness.
2 comments

That's nice if you're starting from scratch, but if you have existing code to deal with, you don't have the privilege of ignoring the insane subset.
The type hints are not even enforced at runtime. They are mostly documentation.
They can be used at runtime though. I wrote typedload, to load external data (json/bson/yaml) into python typed objects. In this way you know that if the data doesn't match the expectations you will have an exception at a specific point in the code, and after that it's safe to use the objects, rather than having to manually check at every access.

Now there are several other libraries that do this thing, but at the time (python3.5 and 3.6) it was the only option.

That seems to handle deserialization? But would it protect you from assigning a value of the wrong type to the object later on?
That depends on what you're using. If you're using Pydantic, which lets you define a struct-like data type with validation, you can tell it to validate assignments as well [1]. Or you can set the class as frozen and forbid assignment entirely [2].

However, if you mean annotating a local variable with a type, then no, nothing will stop it at runtime. If you use a type checker, though, it will tell you that statically.

The ecosystem also offers other runtime validation options, such as beartype [3]. For example, you can annotate a function such that it always checks the data types of input parameters when called. You can even apply this to a whole module if you want, but I don't think that's commonly done.

[1] https://docs.pydantic.dev/latest/api/config/#pydantic.config...

[2] https://docs.pydantic.dev/latest/api/config/#pydantic.config...

[3] https://beartype.readthedocs.io/en/latest/eli5/

Checking types on all function calls adds a considerable amount of extra work that I personally am not willing to pay, especially since static type checkers exist.
Me neither! I was just mentioning it as a possibility. My main use of beartype is `is_bearable` for runtime checking of specific data structures, in cases where `isinstance` isn't quite enough. I would still explore turning full checks during tests, though [1].

[1] https://github.com/beartype/pytest-beartype

It must be used in combination with a static checker to be useful.

So you can do like a = typedload.load(json_data, int) and then "a" is considered to be an int and at runtime will be an int.

Of course your static checker should prevent you from doing a + "string" later on because that would fail.