Live data from Hacker News

A Failed Experiment with Python Type Annotations

mortoray.com

51–60 of 82 posts

Re: A Failed Experiment with Python Type Annotations

#51
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...

OK, that works, but it does seem dumb, or even deliberately obtuse.

The language could just as well recognize Node as it recognizes 'Node', but instead it given as a burden for the human programmer to handle.

Is it maybe because mypy is not really part of the Python language, and can't really make changes to it?

Re: A Failed Experiment with Python Type Annotations

#52
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...

OK, that works, but it does seem dumb, or even deliberately obtuse. The language could just as well recognize Node as it recognizes 'Node', but instead it given as a burden for the human programmer to handle. Is it maybe because mypy is not really part of the Python language , and can't really make changes to it?

The language will recognise it in a future version by default, or a from future import can be used now.

mypy isn't behind (here), it's ahead.

Re: A Failed Experiment with Python Type Annotations

#53
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...

OK, that works, but it does seem dumb, or even deliberately obtuse. The language could just as well recognize Node as it recognizes 'Node', but instead it given as a burden for the human programmer to handle. Is it maybe because mypy is not really part of the Python language , and can't really make changes to it?

This is not mypy, it's "python-the-language": the annotations are values, and, in this case, the method annotations are evaluated when encountered - which is before the end of the class. So you are trying to use a value still not defined. It's like doing something like

    def foo() -> Bar:
       ...

    class Bar:
       ...
obviously the python interpreter cannot find a "Bar" definition during the parsing of the foo function

Re: A Failed Experiment with Python Type Annotations

#54
While the first complaint is just a reflect of the lack of good tutorials on mypy, the second one is very valid: I too wish for automatic type detection for obvious cases.

What's more, while I found mypy useful myself in several instances, it's still cumbersome to use:

- you must know to use the magic command line arguments to avoid mypy complaining about other libs and imports all the time

- you need to use List[], Dict[], Set[], Iteratble[], Tuple[], etc. instead of list[], dict[], set[], iter[], tuple[], etc., which means an import in almost every file and a very unnatural workflow.

- you need to use Union and instead of |. This is ridiculous. I have to do:

    from typing import Union, List

    def mask(...) -> List[Union[bool, int]]
Instead of:

    def mask(...) -> list[bool|int]
And Guido explicitly rejected the proposal for those on github despite the fact most imports are due to those.

Now, mypy has improved a lot. It's way faster, shows many more things that before, way less false positive, and has support for duck typing and dunder methods (named "protocol").

But it's sad to thing TypeScript is actually easier to use. Having a JS tech easier to use than a Python tech is a good sign we can improve things.

Re: A Failed Experiment with Python Type Annotations

#55

> 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 ev…

There's a great 5m lightning talk from Pycon 2019 explaining the difference between pytype and mypy[0]. It's great that there's different libraries approaching the problem from different angles. Speaking of which, I'm also curious to see how Facebook's Pyre[1] differs from the former two. I'm surprise there's isn't a comprehensive comparison of the 3 libraries yet. [0] https://www.youtube.com/watch?v=yFcCuinRVnU&t=38…

Pyre is similar to mypy, in that it:

1. Is gradually typed,

2. Doesn't infer types, and

3. Is strict, in that it doesn't allow operations that change types.

It was originally developed as a replacement for mypy that was faster and scaled better to very large codebases.

Re: A Failed Experiment with Python Type Annotations

#56

I really like using and writing type annotated Python, but every time I do, I wonder if I should just use a language where all the annotation time I put in gets me actual runtime improvements.

And accurate compile time checks.

I recommend checking F# if you want mostly inferred, strong static types and terse pythonesque Syntax (few braces, significant whitespace). Also much faster.

Considering you can use all of .NET from F# you can benefit from the work on C# as well.

Re: A Failed Experiment with Python Type Annotations

#57
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...

OK, that works, but it does seem dumb, or even deliberately obtuse. The language could just as well recognize Node as it recognizes 'Node', but instead it given as a burden for the human programmer to handle. Is it maybe because mypy is not really part of the Python language , and can't really make changes to it?

PEP 563 is intended to resolve it: https://www.python.org/dev/peps/pep-0563/

As rcfox said, you can already enable this behavior, and it will be included in Python 4.0.

Re: A Failed Experiment with Python Type Annotations

#58
post #17

Earlier quoted context omitted.

"[...]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 funct…

Yuck, apparently I missed this happening. Its still (I think) true in java, where you can't have a function return `var`.

You're correct about Java. It was an explicit decision that the only local variable's type declarations and lambda parameters may be inferred with `var`.

This excludes, as you mentioned, the return types of a function, its parameter's types, as well as the types of fields in a class.

Re: A Failed Experiment with Python Type Annotations

#59
This is a really poor article with a click-bait headline. I was expecting this to be a case study where Python type annotations just couldn't work due to some interesting specifics of the projects. Instead, it's some petty gripes about the syntax of annotations not being just to the author's liking.

Re: A Failed Experiment with Python Type Annotations

#60
I feel baking type annotations on top of dynamic, late binding languages is fundamentally misunderstanding what they are about. Python might not go as far as say, smalltalk, but if you're picking a dynamic language just accept the runtime dynamism and don't program against it.
Post reply on HN