whitequark,
@whitequark@mastodon.social avatar

i really dislike mypy

its main utility seems to be producing busywork and making your code worse with annotations

i don't expect i'll be ever using mypy in any of my projects

ratkins,
@ratkins@mastodon.social avatar

@whitequark My background up until recently has been exclusively in statically typed languages and I’m completely and utterly lost in Python. Having mypy in our pre-commit hook gets me more than what just PyCharm does.

KatS,
@KatS@chaosfem.tw avatar

@whitequark I used it a lot at work, once I discovered it, and convinced the rest of my team to start using it.
It does help catch a bunch of things at compile-time, and our automation would have been worse without it.

However, that was in a team of network engineers who were learning how to code so they could automate the network.

In my own stuff, without having to slow down for them? Holy cow, it's pretty much as you describe: lots of busywork to set expectations, which still somehow lets a bunch of type-related runtime errors though.

My life is too short for playing whack-a-mole with python.

whitequark,
@whitequark@mastodon.social avatar

@KatS yeah, it's not completely without applicability, but I'm on a team where I'm paid specifically to navigate a hostile bureaucracy I don't see why I should be using it

timonsku,
@timonsku@mastodon.social avatar

@whitequark similar experience, did not feel like it was doing/enforcing anything useful

whitequark,
@whitequark@mastodon.social avatar

that's not to say that python type annotations aren't useful; they are! it's well worth the small hassle of adding a few around the codebase to get the Python language server to have near-complete contextual information

i just don't think they're useful for type checking

you know what's useful for type checking? assert isinstance(x, ty)

whitequark,
@whitequark@mastodon.social avatar

you know what's really good about assert isinstance(x, ty)?

not only that adds a runtime type check, preventing frustration for your users (rather than adding it by requiring them to use mypy)

but also, good tools are perfectly capable of inferring that after that line, x has the type of ty or a subtype

unlambda,
@unlambda@hachyderm.io avatar

@whitequark I find mypy useful for ensuring the consistency of my type annotations. There's a little bit of busywork if you're first introducing it in a codebase that has existed for a while without it, but it isn't a huge amount.

And yes, it works with assert isinstance(x, ty), the vast majority of my type annotations are on function signatures or just assert x (in a lot of cases where x: ty | None but you know it can't be None), assert isinstance(x, ty), or if isinstance(x, ty)`

unlambda,
@unlambda@hachyderm.io avatar

@whitequark But I do consider mypy to be optional in codebases that I work on, and make liberal use of # type: ignore when there would be too much effort to make mypy happy. I just like having something double check my work to make sure I wasn't completely missing that I said this function could accept something of type x | y but then I passed it into something that just takes type x.

whitequark,
@whitequark@mastodon.social avatar

@unlambda I think that if you have to liberally sprinkle # type: ignore it creates enough cognitive burden that mypy becomes actively harmful rather than just useless; I also disagree that the amount of busywork isn't excessive, and I think subjecting contributors to it is outright rude

whitequark,
@whitequark@mastodon.social avatar

@unlambda as for isinstance(), pyright is perfectly capable of inferring the return type from the body, and in principle so is mypy, but it whines about it anyway

unlambda,
@unlambda@hachyderm.io avatar

@whitequark I guess I kind of like the Rust style "you have to declare types in interfaces, and can use inference in bodies"

It also heavily depends on the code base. When I say "liberal use", I really just mean that I'm not afraid to use it; I don't bend over backwards to make the types fully consistent if it's way more work than necessary (usually because I'm using some library that declares overly-restrictive types when it actually happily accepts something more general).

unlambda,
@unlambda@hachyderm.io avatar

@whitequark It was a little hard for me to get over the "but that means that the types are wrong" mentality.

Like the saying goes about models, mypy types are wrong, but still can be useful

whitequark,
@whitequark@mastodon.social avatar

@unlambda (I take it to "type hints are wrong but can still be useful, despite mypy's best efforts")

whitequark,
@whitequark@mastodon.social avatar

@unlambda the problem here is that type annotations serve completely different purposes in Rust and Python

in Rust, they can be used to enforce invariants. in Python, they're essentially spicy documentation (and often worse at this job than actual English-language documentation too)

so trying to use them in the same way results in suffering

whitequark,
@whitequark@mastodon.social avatar

@unlambda because in Rust, you actually have to know every single type precisely, you [language designer] need to think very hard about making their use tractable; this means no global type inference, which means enforcing written annotations at every function, usually (OCaml does it at every module)

in Python you don't and you can't, you rely on global type inference anyway, so you may (and, in my view, should) rely on it a lot more

archiloque,
@archiloque@felin.social avatar

@whitequark @unlambda I wonder if Python type annotations will be used for runtime check one day, on one hand it feels inevitable, on the other hand people can block it

whitequark,
@whitequark@mastodon.social avatar

@archiloque @unlambda all the PEPs are extremely explicit that they will never be used for runtime type checks

unlambda,
@unlambda@hachyderm.io avatar

@whitequark I use them as documentation with a bit of automation to help make sure I'm not missing anything.

Yeah, they can't be used to enforce invariants; you need isinstance or the like for that.

But I've just found that the "documentation checked for consistency" is helpful enough to a be benefit.

whitequark,
@whitequark@mastodon.social avatar

@unlambda I find that they are bad enough as documentation that I'm actually planning to turn them off in Sphinx when we start using them more widely in Amaranth

unlambda,
@unlambda@hachyderm.io avatar

@whitequark Yeah, I do find them difficult to read in docs; Python doc tools are not well set up for dealing with type annotations. When I mention use for docs, I generally mean when reading the code or using tooling that understands types for autocomplete, etc.

whitequark,
@whitequark@mastodon.social avatar

@unlambda right, that makes sense. I agree that checking annotations for consistency is helpful, I just disagree that requiring fully annotated signatures everywhere is a useful part of that

SnoopJ,
@SnoopJ@hachyderm.io avatar

@whitequark they're also super useful for "narrowing, but for humans", e.g.

UsernameT = str  
StonksT = int

MarketT = dict[UsernameT, StonksT]  

You could spell that dict[str, int] but it's super useful to be able to define an alias, even if adds literally nothing for a checker or editor.

whitequark,
@whitequark@mastodon.social avatar

@SnoopJ those should morally be newtypes, but yes

  • All
  • Subscribed
  • Moderated
  • Favorites
  • random
  • ngwrru68w68
  • rosin
  • GTA5RPClips
  • osvaldo12
  • love
  • Youngstown
  • slotface
  • khanakhh
  • everett
  • kavyap
  • mdbf
  • DreamBathrooms
  • thenastyranch
  • magazineikmin
  • megavids
  • InstantRegret
  • normalnudes
  • tacticalgear
  • cubers
  • ethstaker
  • modclub
  • cisconetworking
  • Durango
  • anitta
  • Leos
  • tester
  • provamag3
  • JUstTest
  • All magazines