Live data from Hacker News

The different uses of Python type hints

lukeplant.me.uk

1–10 of 70 posts

Re: The different uses of Python type hints

#2
A few other examples for the sections given:

Runtime behaviour determination: the stdlib [dataclasses](https://docs.python.org/3/library/dataclasses.html#module-da...)

Dataclasses is notable because it's the only example (I'm aware of) of type hints effecting runtime behavior as part of the stdlib.

Compiler instructions: mypyc was (one of?) the first to do this, but Cython actually supports this natively now, and is much more active than mypyc is last I checked.

Re: The different uses of Python type hints

#3
This sort of thing is why I gave up Python. I could see having strong typing. Or optional strong typing. But unchecked type hints are just silly.

The way everybody else seems to be going is strong typing at function interfaces, with automatic inference of as much else as can be done easily. C++ (since "auto"), Go, Rust, etc.

Re: The different uses of Python type hints

#4

A few other examples for the sections given: Runtime behaviour determination: the stdlib [dataclasses]( https://docs.python.org/3/library/dataclasses.html#module-da... ) Dataclasses is notable because it's the only example (I'm aware of) of type hints effecting runtime behavior as part of the stdlib. Compiler instructions: mypyc was (one of?) the first to do this, but Cython actually supports this natively now, and i…

The Annotated type is worth mentioning as well. Today in something like SQLModel you do (from the readme):

    class Hero(SQLModel, table=True):
        id: Optional[int] = Field(default=None, primary_key=True)
And that's fine. I wouldn't necessarily change anything here. Annotated gives you the option of approaching things in a different way, though.

    class Hero(SQLModel, table=True):
        id: PrimaryKey[Optional[int]] = None
I have some use cases where the alternative approach is useful, like quantification of class fields or function arguments.

Re: The different uses of Python type hints

#6
post #5

The only reason to consider type hints is for a performance increase and there wasn't any mention of that. What can you really expect from using type hints accurately?

Type hints are great when using FastAPI. Your inputs are automatically validated, and you get a /docs endpoint that tells people what to expect from your API.

I'd say performance is far from the only reason to consider type hints.

Re: The different uses of Python type hints

#7
The issue that I have with Python type hints is they they don't go nearly far enough in describing the data being manipulated. Specifically, I'm thinking of stuff like the dimensionality and cardinality of Numpy arrays or Pandas frames. Usually that's the stuff where I have most questions when I look at Python code and the type system as it's being used now offers no help there.

Re: The different uses of Python type hints

#8
post #3

This sort of thing is why I gave up Python. I could see having strong typing. Or optional strong typing. But unchecked type hints are just silly. The way everybody else seems to be going is strong typing at function interfaces, with automatic inference of as much else as can be done easily. C++ (since "auto"), Go, Rust, etc.

> The way everybody else seems to be going is strong typing at function interfaces, with automatic inference of as much else as can be done easily

Both mypy and pyright will do that. If your function return type is annotated, they will infer the type of the receiving variable. If you have two branches where a variable can receive two types, pyright will infer the union type. Similar for None.

Example:

    a = input()
    if a.isdigit():
        x = int(a)
    else:
        x = a
    reveal_type(a)
    reveal_type(x)
Pyright output, stripped of configuration noise:

    typetest.py:6:13 - information: Type of "a" is "str"
    typetest.py:6:13 - information: Type of "x" is "int | str"
Mypy doesn't allow this. It infers `a` as `int` and rejects the second assignment.

The only times I need to annotate local variables are (1) the function isn't typed, so it gets inferred as Any (2) I'm initialising an empty collection, so its type might get inferred as e.g. `list[Unknown]` (pyright; mypy can infer the element type).

Is there something inference-wise that you miss in Python compared to C++ or Go?

PS: The larger problem to me is the inconsistence between pyright and mypy, the leading type-checkers. Sometimes issues are raised between them and they work to achieve agreement, but I believe the two issues highlighted above (unions and collections) are design choices, unlikely to change.

Re: The different uses of Python type hints

#9
post #5

The only reason to consider type hints is for a performance increase and there wasn't any mention of that. What can you really expect from using type hints accurately?

Type hints are great when using FastAPI. Your inputs are automatically validated, and you get a /docs endpoint that tells people what to expect from your API. I'd say performance is far from the only reason to consider type hints.

Similarly for Typer, which is literally "the FastAPI of CLIs"[1]. Handy to type your `main` parameters and have CLI argument parsing. For more complicated cases, it's a wrapper around Click.

[1] https://typer.tiangolo.com/

Re: The different uses of Python type hints

#10
I'm a heavy user of type hints and enable pyright and mypy's strict modes whenever possible. However, you can't always be strict: if you use almost any package in the data science/ML ecosystem, you're unlikely to get good type inference and checking[1]. In those cases, it can still be useful to type some parameters and return values to benefit from _some_ checking, even if you don't have 100% coverage.

Type hints also bring improved completion, which is nice too.

[1] For example, huggingface's transformers library decided to drop support for full type checking because it was unsustainable but decided to keep the types for documentation[2]. There are stubs for pandas, but they're not enough because pandas has a tendency to change return types based on the input, and that breaks quickly.

[2] https://github.com/huggingface/transformers/pull/18485

Post reply on HN