I like these ideas, and practice many of them regularly. Unfortunately one gets the feeling that they're swimming upstream a bit of the time.
For instance: data classes instead of tuples or dicts. Great, love it.
Now add immutability (frozen=true isn't enough so you're probably going to need pyrsistent) and serialization (dataclasses_json works reasonably well for this), and precommit hooks with pyright or mypy... And you've got yourself a reasonable system for leaning on the type checker.
Except you've been at it all day and you still haven't gotten any "work" done, and you've got all of these weird constructions that aren't complex themselves but they'll make a newcomer to your project go "huh?"
Sometimes it's a necessary evil. My users write python, so I need to write python to ensure that their experience is nice and ergonomic. But if I try to write python like it's rust (which I usually do) I end up with quite a pile of things that add toolchain complexity without addressing any business problems.
Don't get me wrong, I still do it, but I've never managed to make it look like a good enough idea to get other people to join me, which is maybe the universe trying to tell me I should stop.
I agree that it's not easy to explain this to other people, and Python tooling in general is pretty terrible. OTOH, having types in the code and giving newcomers to the codebase the ability to actually see what types "flow" through functions, and having the ability to "Go to definition" is a big benefit for introducing old Python code to newcomers.
One thing I liked about the post was I can sell some of the suggestions to the non-engineer Python users I work with. Types in signatures and data classes are big wins overall.
While I miss working with OCaml, Python's pay-as-you-go style of typing meets many users where they're at.
For instance: data classes instead of tuples or dicts. Great, love it.
Now add immutability (frozen=true isn't enough so you're probably going to need pyrsistent) and serialization (dataclasses_json works reasonably well for this), and precommit hooks with pyright or mypy... And you've got yourself a reasonable system for leaning on the type checker.
Except you've been at it all day and you still haven't gotten any "work" done, and you've got all of these weird constructions that aren't complex themselves but they'll make a newcomer to your project go "huh?"
Sometimes it's a necessary evil. My users write python, so I need to write python to ensure that their experience is nice and ergonomic. But if I try to write python like it's rust (which I usually do) I end up with quite a pile of things that add toolchain complexity without addressing any business problems.
Don't get me wrong, I still do it, but I've never managed to make it look like a good enough idea to get other people to join me, which is maybe the universe trying to tell me I should stop.