Live data from Hacker News

A Failed Experiment with Python Type Annotations

mortoray.com

1–10 of 82 posts

Re: A Failed Experiment with Python Type Annotations

#3
post #2

The first issue is fixed by just using a string. Yes, you can't do Sequence[Node], but you can do Sequence["Node"]. The docs talk about this here ("class name forward references"): https://mypy.readthedocs.io/en/stable/kinds_of_types.html#cl...

Great!

Re: A Failed Experiment with Python Type Annotations

#4
I would have to disagree with this post (first point is actually inaccurate and the second I could go either way on).

Type annotations/mypy, especially when coupled with dataclasses/pydantic has been very helpful in maintaining a rather substantial 3.7 codebase.

Re: A Failed Experiment with Python Type Annotations

#5
Why would you keep Python if you want static typing? I mean, there are several modern, performant (more than Python actually) statically typed languages. Rust, Go, Kotlin, Scala, Swift… All of them are mature and have a good library ecosystem. So, except if you need some math/AI/ML packages available only for Python, why bother? Choose the right tool for the job, no?

Re: A Failed Experiment with Python Type Annotations

#7
post #3
post #2

The first issue is fixed by just using a string. Yes, you can't do Sequence[Node], but you can do Sequence["Node"]. The docs talk about this here ("class name forward references"): https://mypy.readthedocs.io/en/stable/kinds_of_types.html#cl...

Great!

The second issue is a bit of a judgment call too, I think. If the types were inferred you could end up with errors that you're not able to see because inferred types end up compatible. Personally, I think I'd rather write them manually so that I'm validating whether the method actually matches what it was intended to return.

I can't find a more authoritative source right now, but I also remember seeing the same thing that this SO answer says - that it was a deliberate choice not to do this so that people could incrementally add type annotations: https://stackoverflow.com/a/38775381

There are also some separate tools that can infer and generate the annotations for you. I haven't tried them personally, but the mypy docs recommends MonkeyType: https://mypy.readthedocs.io/en/stable/existing_code.html#aut...

Re: A Failed Experiment with Python Type Annotations

#8

Why would you keep Python if you want static typing? I mean, there are several modern, performant (more than Python actually) statically typed languages. Rust, Go, Kotlin, Scala, Swift… All of them are mature and have a good library ecosystem. So, except if you need some math/AI/ML packages available only for Python, why bother? Choose the right tool for the job, no?

> Seems like all of this (adding static typing on top of Python, PHP, etc) started with the success of TypeScript

Mypy is a few years older than TypeScript, so, no.

Re: A Failed Experiment with Python Type Annotations

#9
> mypy has no trouble understanding this, but it’s unfortunately not valid Python code. You can’t refer to Node within the Node class.

No, the workaround is to stringify "Node".

    class Node(Object):
        def add_sub(self, sub: 'Node'):
            ...

        def get_subs(self) -> Sequence['Node']:  #Or maybe 'Sequence[Node]'
works just fine. As of python3.7, this stringification is done by automatically under a from future import, and will eventually become the default, so the original code will be valid.

> This complexity helped drive the introduction of the auto keyword to C++. There are many situations where writing the type information isn’t workable. This is especially true when dealing with parametric container classes,

This is absolutely wrong! You cannot annotate a function as returning `auto` in C++. `auto` and its variants in other languages are useful for eliding redundant type declarations. Especially long ones that use generics/templates. `auto foo = MyContainer>();` or whatever is nice than having to double write the type declaration. But, in C++ or java, if you write a function that returns a Mycontainer>, you have to write that in the function.

This is an intentional choice: function declarations are your apis, and explicit and clear APIs are useful for human readers of your code. That's why you should annotate the public apis[0] even when you can have them be type inferred. Speaking of which, if you want type inference, check out pytype[1], it's like MyPy, but does do type inference on unannotated code. But you should still annotate your public apis. It serves as a sanity check that you aren't accidentally returning something you don't expect.

And of course, being familiar with the differences between iterables, iterators, sequences, containers, etc. is not a bad idea.

[0]: https://google.github.io/styleguide/pyguide.html#3191-genera...

[1]: https://github.com/google/pytype

Re: A Failed Experiment with Python Type Annotations

#10
post #2

The first issue is fixed by just using a string. Yes, you can't do Sequence[Node], but you can do Sequence["Node"]. The docs talk about this here ("class name forward references"): https://mypy.readthedocs.io/en/stable/kinds_of_types.html#cl...

For Python 3.7, you can do:

    from __future__ import annotations
This will defer the parsing of annotations until after the file has been parsed, allowing you to use the actual symbol instead of a string.
Post reply on HN