Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

How? How it's not close to typescript? I mean what are features that python's type annotation (and mypy) lacks in comparison to typescript?


Was battling it today. Latest stable release of python mind you 3.7.3. We have to move structured data around from a legacy system and integrate it with our new website. Perfect opertunity for types. This also includes trying to use mypy.

  * it doesn't track the state of the variable. If I get a value thats Optional[int] there is no way to say 'if a is not None:' it will still complain that the variable could be none
 * even with the mypy experimental TypedDict they're basically unusable IMO
 * there is no 'keyof' 
* there is no way to constrain to specific strings (or other primitives). I don't understand what literals are supposed to be but they aren't useful for us

Coming from typescript it's been very lackluster.


I agree that mypy can be a bit lacking, but to address a couple of your mypy woes:

- TypedDict is an option but if you can, dataclasses work much better

- mypy does refine Optional[T] to T with an if check. Maybe you need to futz with the compiler options?

- Does Literal["foo"] not work? I've been using it with pydantic for de-serializing a tagged union of dicts and also for function args.

e.g.,

    def call_to_service(api_type: Literal["users", "teams", "orgs") -> None: ...


The problem I had with Literal["foo"] is that at least according to mypy "foo" is a string and it was expecting Literal["foo"].

I think you're right, something must be mixed up. But then again this is the latest version of python and mypy, on intellij, so I'm not sure what I did wrong, it's using otherwise default options.


That is false.

On point 1: def use_int(n: int): return n * 2

  def foo(n: Optional[int]):
      use_int(n) # MYPY complaints here because n could be None
      if n is not None:
          use_int(n) #MYPY allows this because it understood it cannot be None
2) TypeDict work fine, do you have an example of waht does not work 3) Of course, JS is different from Python, "keyof" doesn't make any sense in Python because Python uses class where JS uses dicts 4) Of course there is:

  Accepted = Literal["foo", "bar", 3]
  
  def accept_values(v: Accepted):
      print(v)
  
  accept_values("foo")
  accept_values("bar")
  accept_values(3)
  accept_values("wrong")  # MYPY complains
  accept_values(5)  # MYPY complains


> "I'm familiar with tool A. Today I tried tool B and I couldn't figure out how to use it correctly, so it must be lacking. Everyone should know!"

From the points you make it seem like you haven't really figured out how to use mypy...

TS and Python/Mypy are my daily drivers. I don't find the experience working with mypy any worse than working with TS. In fact I prefer composing and consuming types via dataclasses and NamedTuples over interfaces and TS classes.


One of the very useful things Typescript has for a dynamic-language-turned-static is smart casts, union types and dependent types union types. Things like these are possible:

    type Animal =
      {
         type: "Dog"
         dogtag: string
         name: string
      } | {
         type: "Cat"
         name: string
         allowedOutside: boolean
      }


      function f(a: Animal) {
          console.log(a.name) // always allowed
          console.log(a.dogtag) // compile error
          if(a.type === "Dog") {
              console.log(a.dogtag) // Allowed
          }
      }

I believe Typescript is fairly unique in this capability.


You can do that in Python as well though.

  from typing import Union
   
  class Dog:
      dogtag: str
      name: str
  
  class Cat:
      name: str
      allowedOutside: bool
  
  Animal = Union[Cat, Dog]
  
  def do(a: Animal):
      print(a.name)  # Always allowed
      print(a.dogtag)  # MYPY error
      if isinstance(a, Dog):
          print(a.dogtag) # MYPY allows


And you can even do that with dict in the most recent version of mypy.

But the fact you have to import Union instead of using a pipe bothers me. It's useless boilerplate and verbose. So not o Python. I reported it, but Guido told me it will not happen.


Explicit is good in Python world.

And I have to agree with him. Just look at the mess sclalaz did/does with its use of clever pictogram-like symbol names.

Python is very much a language where newcomers are the norm. Make the source code at least a bit self-teaching seems like a good feature.


You are right. Let's remove the "+" operator in favor of operator.add. It's totally worth the readability.

I'm sorry but "|" is not only a very commonly known operator in the entire programming world, it is already an officially supported operator by python, vastly used by the community for doing unions: sets use it, sqlalchemy use it, pandas use it.

Let's not confuse explicite and paperwork.


It is not unique, union type and path aware type system will do this, for example in Crystal: https://crystal-lang.org/reference/syntax_and_semantics/unio...


Fairly unique as in the only mainstream programming language that can do this


Not to nitpick too much, but wouldn't the function expecting an interface be a much better fit for a case like this?


You can name the things I left anonymous, wouldn't change the principles.

The Typescript docs have more details and advantages for this specific scenario: https://www.typescriptlang.org/docs/handbook/advanced-types....


The absence of two PEPs that haven't shipped yet cause me great annoyance on a daily basis: 0544 [1] and 0589 [2].

On the implementation side, I've found TypeScript's type inference to be far more capable. I've encountered several mypy bugs around type narrowing. The issues I've filed have greeted by a "yeah, this is a problem, but low priority since you can restructure your code to make it more explicit." I understand staffing is an issue for community projects, and the PSF is trying to do a lot with very little, but that doesn't change the fact that it's a deficiency when compared to other systems.

1: https://www.python.org/dev/peps/pep-0544/

2: https://www.python.org/dev/peps/pep-0589/


Typescript feels like it's own language. Whereas python types are just optional extra information you can add (more like Flow does), and they are rather verbose and clunky compared to Typescript


You can try and take some old JS lib and annotate it in TS. It'll work. It'll be very clunky, and full of any/unknown.

There's a reason why strong static typeable code looks the way it looks (basically functional programming). You can type a monad chain, because it's a container type for arbitrary types interacting, but you can't easily type a switch nested in a for loop that uses a queue to walk a tree.

Of course the flip side is that to walk a tree functionally you need recursion schemas, and they are ugly/complex.


For one, they're not actually enforced


http://mypy-lang.org/

Disclaimer: I have not used MyPy. I'm just interested.


Both TS and mypy has strict mode and "implicit Any" mode.

In the latter they don't enforce much, you just get a JS or regular Python file. (mypy is not a transpiler like TS, mostly because it explicitly wants to be able to target legacy JS runtimes - eg IE8 ES5 - whereas mypy needs a recent Python that supports type annotations)


Typescript is way more ahead and mature than Python static type annotations or other community libraries for static type check

Ref Link :- https://www.typescriptlang.org/docs/handbook/advanced-types....


Conditional types and the `infer` directive, I’d imagine. Which end up being very powerful.


Python doesn't properly do static typing. Strong typing alone gives you none of the benefits of dynamic typing and none of the benefits of static typing.


mypy is a static type checker for Python


It's an unnecessary extra hurdle. Unless it's the default, it's basically not existent.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: