17 ms·
Python developers are embracing type hints
- totalhack 1y agoIt's optional, and that's great, because its necessity or benefit is situational.
- LoganDark 1y agoI think I've always used Python type hints, but that was partially because early versions of Discord.py relied on them (maybe it still does). But it was also because I like to be able to mentally verify my code's correctness before running it, and waiting for runtime errors is comparatively a huge waste of time (in my opinion).
- secondcoming 1y agoI recently had to debug someone else's Python code and trying to figure out what variables are was a massive headache, especially coming from C++.
- skydhash 1y agoI do not program that much in python, but I believe the general accepted wisdom in dynamic languages was explicit name and load of documentations (as comments and docstrings).
- imron 1y agoAbsolutely the general accepted wisdom in line with best practices - that are often ignored
- maleldil 1y ago> explicit name and load of documentations (as comments and docstrings). Which can be out of date are often missing. Might as well use type-hints that can be statically checked.
- skydhash 1y agoIf the name of a function and its docstring is out of date, then what you have is a bad culture for coding. It’s up there with god classes in OOP.
- Akronymus 1y agoEven c++ feels clunky in terms of types to me. Though that's probably down to me preferring a more complete type system like haskell has
- rcfox 1y agoIn Python, every variable is either defined or imported in the file in which it's used, so you always know where to find it. (Assuming you don't do `from foo import *`, which is frowned upon.) In C++, a variable might be defined in a header or in a parent class somewhere else, and there's no indication of where it came from.
- lacker 1y agoType hints are much easier to use nowadays than they were a few years ago, because the agentic tools like Claude Code are very good at converting an existing codebase to using type hints.
- OutOfHere 1y agoThe flip side of it is that Claude Code will have a very bad time in a code base with grossly unsatisfiable or conflicting types (where a type checker would fail the project). A human should always first ensure that the types are broadly correct, with or without the assistance of code tools.
- Waterluvian 1y agoI can empathize with the code tools. Sometimes I’ll read Python code and have no idea at first glance if these are type bugs or creative coding by the dev. Python is incredibly flexible. Though I think most of the time you really shouldn’t be using the flexibility.
- imron 1y agoI enforce strong types on all Python code I’m responsible for - and make sure others don’t play fast and loose with dict[str, Any] when they could use a well defined type. Doing otherwise is just asking for prod incidents.
- scuff3d 1y agoI worked on a project that did this. Drove me absolutely nuts. It's like having all the worst parts of a dynamic language and a static language with none of the benefits. I'd much rather just work in a statically typed language from the start.
- lrobinovitch 1y agoWhat exactly drove you nuts? The python ecosystem is very broad and useful, so it might be suitable for the application (if not, reasonable that you'd be frustrated). With strict mypy/pyright settings and an internal type-everything culture, Python feels statically typed IME.
- scuff3d 1y agoIt's not even close compared to working with Java or Go or any language built with static typing in mind. To be clear, I'm not opposed to type hints. I use them everywhere, especially in function signatures. But the primary advantage to Python is speed (or at least perceived speed but that's a separate conversation). It is so popular specifically because you don't have to worry about type checking and can just move. Which is one of the many reasons it's great for prototypes and fucking terrible in production. You turn on strict type checking in a linter and all that goes away. Worse, Python was not built with this workflow in mind. So with strict typing on, when types start to get complicated, you have to jump through all kinds of weird hoops to make the checker happy. When I'm writing code just to make a linter shut up something is seriously wrong. Trying to ad typing to a dynamic language in my opinion is almost always a bad idea. Either do what Typescript did and write a language that compiles down to the dynamic one, or just leave it dynamic. And if you want types just use a typed language. In a production setting, working with multiple developers, I would take literally almost any statically typed language over Python.
- Waterluvian 1y agoTypescript turned me into a believer but my gosh do python typings feel clumsy and quickly busy up files. I get why, and it’s not exactly realistic, but I wish a lot of it didn’t require an import. Whatever the solution is, it doesn’t include giving up on Python typings.
- mrln 1y agoWith the newest Python versions, most of the time I don't need typing imports!
- letmeinhere 1y agoYeah post 3.10 you don't need Union, Optional, List, Duct, Tuple. Any still necessary when you want to be permissive, and I'm still hoping for an Unknown someday...
- maleldil 1y ago> hoping for an Unknown someday Wouldn't that just be `object` in Python?
- Narushia 1y agoThat's what I use it for. If you type something as `object`, static type checkers can just narrow down the exact typing later.
- lexicality 1y agoNo, because the type checker should prevent you interacting with `Unknown` until you tie it down, but `object` is technically a valid type
- letmeinhere 1y agoExactly, I want it to complain if I try to manipulate the fields/methods of an unknown object.
- quotemstr 1y agoType hints in dynamic languages are great, but I wish they came with deeper integration into the language runtime for validation and for optimizer setup. If I have a function that takes an int, and I write down the requirement, why should a JIT have to learn independently of what I wrote down that the input is an int? I get that it's this way because of how these languages evolved, but it doesn't have to stay this way.
- dmurray 1y agoThat was the original intent of mypy, to allow a subset of Python to be interpreted by a JIT or transpiled to a compiled, statically typed language. The type hints proved to be useful on their own so the project moved past what was useful for that purpose, but a new JIT (such as the one the upcoming CPython 3.14 lays the groundwork for) could certainly use them.
- donatj 1y agoTypings have pretty cleanly been getting added to PHP over the last decade. I'm kind of surprised Python's are so bolted on by comparison
- morkalork 1y agoThey do remove an entire class of avoidable errors in code bases of course people will embrace it.
- bgwalter 1y agoBecause they follow any corporate initiative that gives them something to do, even if the type hints are the most unreadable and hackish form of typing in existence.
- LordDragonfang 1y agoThe biggest reason I use typehints is that VSCode's intellisense relies on them - and I know I've missed one when typing a dot doesn't give me the method I'm expecting.
- circadian 1y agoI really love Python for it's expedience, but type hints still feel like they don't belong in the language. They don't seem to come with the benefits of optimisation that you get with static typed languages. As someone who uses C and Julia (and wishes they had time for Rust), introducing solid typing yields better end results at a minimum, or is a requirement at the other end of the scale. The extra typing clarification in python makes the code harder to read. I liked python because it was easy to do something quickly and without that cognitive overhead. Type hints, and they feel like they're just hints, don't yield enough of a benefit for me to really embrace them yet. Perhaps that's just because I don't use advanced features of IDEs. But then I am getting old :P EDIT: also, this massively depends on what you're doing with the language! I don't have huge customer workloads to consider any longer..!
- imron 1y ago> I don't use advanced features of IDEs I use vanilla vim (no plugins) for my editor, and still consider type hints essential.
- zahlman 1y ago> They don't seem to come with the benefits of optimisation that you get with static typed languages They don't. And cannot, for compatibility reasons. Aside from setting some dunders on certain objects (which are entirely irrelevant unless you're doing some crazy metaprogramming thing), type annotations have no effect on the code at runtime. The Python runtime will happily bytecode-compile and execute code with incorrect type annotations, and a type-checking tool really can't do anything to prevent that.
- scuff3d 1y agoOr you could just use a statically typed language and get a much better experience.
- fnord77 1y agoA entire class of bugs, wiped out by a thing called a "compiler". Gigahours of downtime and bug fixing globally prevented by a modest extra step up front. Great stuff.
- scuff3d 1y agoI had someone say to me they preferred strict type checking in a Python linter over a statically typed language because they "don't like a build step"... Dudes it's literally just worse compilation with extra steps.
- __MatrixMan__ 1y agoI'm in favor of partitioning the set of reasons it can fail to compile into separate checks with separate tools. Taming the zoo of tooling is extra work, but smaller more focused tools are easier to work with once you understand their relationship to their neighbors. There's a world of difference between: > I've been using a different type checker and I like it, you should try it And > I'd like to switch our project to a different compiler The former makes for more nimble ecosystem.
- scuff3d 1y agoYes, if you are stuck with Python something is certainly better than nothing. But we shouldn't be writing large production apps in it in the first place.
- __MatrixMan__ 1y agoShould we be writing large apps at all?
- throwaway81523 1y agoOh datatype hints. I ignored the headline on first scan, thinking it was about font metrics.
- simonw 1y agoThe thing that finally got me on board with optional type hints in Python was realizing that they're mainly valuable as documentation. But it's really valuable documentation! Knowing what types are expected and returned just by looking at a function signature is super useful.
- lysace 1y agoDecent argument in principle. It still sucks for non-obvious types though: https://old.reddit.com/r/Python/comments/10zdidm/why_type_hinting_sucks/ https://old.reddit.com/r/Python/comments/10zdidm/why_type_hi... Edit: Yes, one can sometimes go with Any, depending on the linter setup, but that's missing the point, isn't it?
- mjr00 1y agoAs the top comment says, if you don't know or want to define the type just use Any. That's what it's there for. That entire Reddit post is a clueless expert beginner rant about something they don't really understand, unfortunate that it's survived as long as it has or that anyone is taking it as any sort of authoritative argument just because it's long.
- pdonis 1y ago> if you don't know or want to define the type That's not the issue the reddit post is raising. The reddit post is pointing out that what a "type" is is not as simple as it looks. Particularly in a language like Python where user-defined types proliferate, and can add dunder methods that affect statements that involve built-in operations. "Just use Any" doesn't solve any of those problems. > just use Any. All the above said: not putting a type in at all is even easier than using Any, and is semantically equivalent.
- mjr00 1y agoThe Reddit post falls under the case of "don't know" the type. If you want to allow users to pass in any objects, try to add and fail at runtime... that's exactly what Any is for. But the entire post is built upon the premise that accepting all types is good API design. Which it isn't, at all.
- tecoholic 1y agoI love typing in Python. I learnt programming with C++ and OOPs. It was freeing when I took up Python to note care about types, but I have come to enjoy types as I got older. But, boy have we gone overboard with this now? The modern libraries seem to be creating types for the sake of them. I am drowning in nested types that seem to never reach native types. The pain is code examples of the libraries don’t even show them. Like copy paste an OpenAI example and see if LSP is happy for example. Now I have gotten in this situation where I am mentally avoiding type errors of some libraries and edging into wishing Pydantic et al never happened.
- AlienRobot 1y agoMy love for python was critically hurt when I learned about typing.TYPE_CHECKING. For those unaware, due to the dynamic nature of Python, you declare a variable type like this foo: Type This might look like Typescript, but it isn't because "Type" is actually an object. In python classes and functions are first-class objects that you can pass around and assign to variables. The obvious problem of this is that you can only use as a type an object that in "normal python" would be available in the scope of that line, which means that you can't do this: def foo() -> Bar: return Bar() class Bar: pass Because "Bar" is defined AFTER foo() it isn't in the scope when foo() is declared. To get around this you use this weird string-like syntax: def foo() -> "Bar": return Bar() This already looks ugly enough that should make Pythonists ask "Python... what are you doing?" but it gets worse. If you have a cyclic reference between two files, something that works out of the box in statically typed languages like Java, and that works in Python when you aren't using type hints because every object is the same "type" until it quacks like a duck, that isn't going to work if you try to use type hints in python because you're going to end up with a cyclic import. More specifically, you don't need cyclic imports in Python normally because you don't need the types, but you HAVE to import the types to add type hints, which introduces cyclic imports JUST to add type hints. To get around this, the solution is to use this monstrosity: if typing.TYPE_CHECKING: import Foo from foo And that's code that only "runs" when the static type check is statically checking the types. Nobody wants Python 4 but this was such an incredibly convoluted way to add this feature, specially when you consider that it means every module now "over-imports" just to add type hints that they previously didn't have to. Every time I see it makes me think that if type checks are so important maybe we shouldn't be programming Python to begin with.
- biimugan 1y agoIn addition to what others have mentioned, it also just makes it easier to come back later to a code base and make changes, especially refactoring. In many cases you don't even really have to add many type hints to get benefits from it, since many popular libraries are more-or-less already well-typed. It can also substitute for many kinds of unit tests that you would end up writing even 5 years ago. If you're an infrastructure engineer or data scientist that's usually just writing a lot of glue code, then it greatly helps speed up your output (I've found)
- ashu1461 1y agoThis Without typing it is literally 100x harder to refactor your code, types are like a contract which if are maintained after the refactor gives you confidence. Over time it leads to faster development
- frou_dh 1y agoBecause you almost always have a specific type in mind for that function parameter, so you might as well just write it down.
- iandanforth 1y agoI hate typing in Python. I spend a good chunk of my day fighting the type checker and adding meaningless assertions, casts, and new types all to satisfy what feels like an obsessive compulsive nitpicker. "Type partially unknown" haunts my dreams. Duck typing is one of the best things about Python. It provides a developer experience second to none. Need to iterate over a collection of things? Great! Just do it! As long as it is an iterable (defined by methods, not by type) you can use it anywhere you want to. Want to create a data object that maps any hashable type to just about anything else? Dict has you covered! Put anything you want in there and don't worry about it. If we ended up with a largely bug free production system then it might be worth it, but, just like other truly strongly typed languages, that doesn't happen, so I've sacrificed my developer experience for an unfulfilled promise. If I wanted to use a strongly typed language I would, I don't, and the creeping infection of type enforcement into production codebases makes it hard to use the language I love professionally.
- maleldil 1y ago> Need to iterate over a collection of things? Iterable[T] > Want to create a data object that maps any hashable type to just about anything else? Mapping[T, U]
- dwattttt 1y agoBeyond the advantage that a type-checker/linter can tell if you're doing the right thing when writing those functions, it lets an IDE infer what type you're iterating over, in order to provide more support/completion/hinting/checks (without recursively analyzing arbitrary code, so: 'instantly' vs 'maybe not ever).
- jgb1984 1y agoCouldn't agree more! I've been using Python for almost 20 years, my whole career is built on it, and I never missed typing. Code with type hints is so verbose and unpythonic, making it much harder to read. Quite an annoying evolution.
- 1y ago
- jmward01 1y agoType hints in python are just that, hints. Use them to help with clarity but enforcing them and requiring them everywhere generally leads to the worst of all worlds. Lots of boilerplate, less readable code and throwing away many of the features that make python powerful. Use the best language for the job and use the right language features at the right time. I see too many black or white arguments in the developer community, there is a middle ground and the best code is almost always written there.
- IshKebab 1y ago> Use the best language for the job Sometimes you don't have a choice though, and other people have picked Python despite it rarely being the best language for any job. In that case it's nice to be able to use static type hints and benefit from improved readability, productivity and reliability.
- dragonwriter 1y ago> Lots of boilerplate, less readable code and throwing away many of the features that make python powerful. IMO, that complaint almost always goes with overuse of concrete types when abstract (Protocol/ABC) types are more accurate to the function of the code. There was a time that that was a limitation in Python typing, but that that hasn’t been true for almost as long as Python typing had been available at all before it stopped being true.
- zahlman 1y agoIt's the other way around, IMO: people who think the language should at least have type hints are now more willing to use it, now that there's better tooling for checking those hints.
- k3vinw 1y agoI really think that Rust has one of the best designed/inspired type systems. If I had to rewrite a Python project, I would consider Rust or another statically typed language before choosing to continue in a dynamic language with types bolted on. I hope the situation improves for dynamic languages with optional types, but it still feels weird and bolted onto the language because it is.
- hirvi74 1y ago> or another statically typed language I'm a professional .Net Core developer, but I'd throw my hat in the ring for Swift on this one. While obviously not exactly a 1:1 with Rust, there is definitely some common benefits between the two. Though, from what I understand of Rust (very little), its typing system is slightly more strict than Swift's which is slightly more strict than C#'s.
- yeasku 1y agoI am suspicius of every codder who does not appreciate types.
- a_t48 1y agoHas anyone had good luck with auto-annotation of types of existing codebases? Either via LLM or via various runtime hooks? I work in a codebase that started off in Python 2 and isn't annotated with types in the majority of places, and I feel the pain every time I have to wonder what exactly the arguments to a method is.
- EdwardDiego 1y agoYep, I've used this pretty successfully, the ideal is to run it under realistic prod traffic over time to capture as many types as can flow into a given function, but a good set of unit/integration tests can also provide good coverage. And if you re-use the same type store (SQLite DB) across multiple instrumented runs, you can further improve it. https://github.com/Instagram/MonkeyType https://github.com/Instagram/MonkeyType
- emeryberger 1y agoRightTyper is much better in addition to running orders of magnitude faster. https://github.com/RightTyper/RightTyper https://github.com/RightTyper/RightTyper (full disclosure, I am one of its authors).
- EdwardDiego 1y agoI'll look into it, cheers!
- EdwardDiego 1y agoJust looking at the README, I'm very excited as I have a Hackathon coming up and I am looking to bring more type love to a legacy Django codebase, and was going to utilise MonkeyType again, but this time I'll use this!
- dandanua 1y agoThis is why I think Julia will win in the long run. It has an amazing type system, simple yet powerful. In particular, abstract types are much easier to define and use than abstract classes in Python.
- jakobnissen 1y agoOoh, I completely disagree. Julia has a worse type system overall, IMO. The big downside of Julia is that Julia has no interfaces or protocols. So, you can't type assert that something is an iterable of integers, for example. Another issue is that abstract types are completely undocumented and have no tooling support. You say it's easier to use an abstract type. Can you tell me what I need to define to create a working subtype of AbstractDict? Or Number? Or IO? It's completely undefined, and the only way to do it is to just define the type and then try it out and patch when it breaks because a method was missing. Finally, there is no multiple inheritance. That means I can't define something which is both a subtype of AbstractArray and IO, for example.
- dandanua 1y agoThere are no traits in Julia by default, that's true. But since types are first class citizens in Julia, traits can be implemented within the language. There is a package SimpleTraits.jl that implements Holy's trait trick, see also this tutorial https://ahsmart.com/pub/holy-traits-design-patterns-and-best-practice-book/ https://ahsmart.com/pub/holy-traits-design-patterns-and-best... An ability to work with types within the language is already a win for me.
- ashu1461 1y agoA huge supporter of typing in python, but have observed that type sense which pycharm provides out of the box has its fair share of bugs as well. Also should check out ty by astral, it is pretty fast and does a good job at typechecking. https://docs.astral.sh/ty/editors/ https://docs.astral.sh/ty/editors/
- teiferer 1y agoMisleading title. I was expecting to read about why devs actually embrace type hints. What the article is about is why you should and how you can use type hints. That's valuable, but different from what the title suggests. Besides, the lack of static typic is what makes a lot of the appeal for beginners. It's much harder to convince a non-CS beginner why they should bother with the extra burden of type hits. They are optional anyway and just slow folks down (so they might think). Careful with generally demanding that everybody use them. But they probably help coding assistants to make fewer mistakes, so maybe that will soon be an argument if it isn't already. (That's an angle I expected in the article.)
- ambyra 1y agoWith duck typing, you don’t need type hints. You’re just supposed to use the variable however you “feel” it should be used when you’re using it, and it automagically just works!!! Try it! /s
- Havoc 1y agoIt’s ok. The mild ground of typing feels pretty clunky to me though Definitely not a best of both world type outcome
- lukaslalinsky 1y agoI was extremely skeptical when typing was introduced. What's the point if runtime ignores them. I forced myself to use them as documentation and now I'm on the other side of the spectrum, all code should have them. It already helped me a lot during refactors and I always wished more code had types. I think the same is true for AIs, they will benefit from having the types explicitly said. It's a shame they currently default to untyped Python.
- JodieBenitez 1y ago> What's the point if runtime ignores them. I've been using this sparingly: https://pypi.org/project/type-enforced/ https://pypi.org/project/type-enforced/
- dragonwriter 1y ago> What's the point if runtime ignores them. Ideally, with static checking, the runtime shouldnn’t need to care about types because cide that typechecks shouldn’t be capable of not behaving according to the types declared. Python, even with the most restrictive settings in nost typecheckers, may not quite achieve that, but it certainly reeuces the chance of surprises lf that kind compared to typing information in docstrings, or just locked away in the unststed assumptions of some developer.
- lukaslalinsky 1y agoThe thing is, when typing was being discussed, I was hoping it would lead to JavaScript-like evolution, where the dynamic nature of Python could be restricted if I use the right types, and a JIT compiler could optimize parts of the code, expecting u32 ints instead of PyObjects.
- mixmastamyk 1y agoCython is still around.
- fithisux 1y agoI started using Python at work with type hints. I am very satisfied.
- zoom6628 1y agoBoring old me would be reaching for mojo in order to have types that actually are "real" rather than just an editing overlay of decorators/DSL/tooling.
- Too 1y agoToo bad Mojo gave up on Python compatibility on code level. Now it’s just one of a dozen “Python inspired” languages, with the only benefit that they aim for easily calling into other Python code.
- defraudbah 1y agoPython developers are embracing RuntimeError.. It's amazing language that had it place, now it's time to sunset it and forget it. Leave it to prototyping only
- seanparsons 1y agoAs a static typing advocate I do find it funny how all the popular dynamic languages have slowly become statically typed. After decades of people saying it's not at all necessary and being so critical of statically typed languages. When I was working on a fairly large TypeScript project it became the norm for dependencies to have type definitions in a relatively short space of time.
- adalacelove 1y agoPeople adapt to the circumstances. A lot of Python uses are no longer about fast iteration on the REPL. Instead of that we are shipping Python to execute in clusters on very long running jobs or inside servers. It's not only about having to start all over after hours, it's simply that concurrent and distributed execution environments are hostile to interactive programming. Now you can't afford to wait for an exception and launch the debugger in postmortem. Or even if you do it's not very useful. And now my personal opinion: If we are going the static typing way I would prefer simply to use Scala or similar instead of Python with types. Unfortunately in the same way that high performance languages like C attracts premature optimizers static types attract premature "abstracters" (C++ both). I also think that dynamic languages have the largest libraries for technical merit reasons. Being more "fluid" make them easier to mix. In the long term the ecosystem converges organically on certain interfaces between libraries. And so here we are with the half baked approach of gradual typing and #type: ignore everywhere.
- yurishimo 1y agoPHP is a great example of the convergence of interfaces. Now they have different “PSR” standards for all sorts of things. There is one for HTTP clients, formatting, cache interfaces, etc. As long as your library implements the spec, it will work with everything else and then library authors are free to experiment on the implementation and contribute huge changes to the entire ecosystem when they find a performance breakthrough. Types seem like a “feature” of mature software. You don’t need to use them all the time, but for the people stuck on legacy systems, having the type system as a tool in their belt can help to reduce business complexity and risk as the platform continues to age because tooling can be built to assert and test code with fewer external dependencies.
- alex_suzuki 1y agoI recently discovered that the folks building uv and ruff are also building a type checker, and it already works really well (and fast!), despite beta status: https://github.com/astral-sh/ty https://github.com/astral-sh/ty
- Marazan 1y agoMy view on typing in Python (a language I have used for decades) is that if I wanted types I would use a language designed from the ground up with strong and consistent typing built-in. Not bolt on a sort of type system which actively fights against the way I use the language on a day to day basis. I use plenty of statically typed languages, Python's type hinting does not bring me joy.
- Hackbraten 1y ago> Not bolt on a sort of type system which actively fights against the way I use the language on a day to day basis. Can you help me out with an example of a Python usage pattern against which the type system seems to be fighting?
- Marazan 1y agoOk, so this is just one of many examples but the most immediate one is where I don't care about the immutable sanctity of the variable I have just declared. I often use Python for data munging and I'll frequently write code that goes foo = initial_value ... foo = paritally_cleaned_up_value ... if check: foo = fianllylikethis else: foo = orlikethis Where the type of the value being assigned to foo is different each time. Now, obviously (in this simplistic example that misses subtleties) I could declare a new variable for each transformation step or do some composite type building type thing or refactor this into separate functions for each step that requires a different type but all of those options are unnecessary busy work for what should be a few simple lines of code.
- Hackbraten 1y agoThanks, now I get why you feel like the type system is fighting your style of programming. > all of those options are unnecessary busy work for what should be a few simple lines of code If you re-type your variable often, then how do you make sure you’re really keeping track of all those types? If you re-type it only a few times, then I’m not entirely convinced that declaring a few additional variables really constitutes busywork. Small example with additional variables instead of re-typing the same variable: # pylint: disable=disallowed-name, missing-function-docstring, missing-module-docstring, redefined-outer-name from typing import NewType NEEDS_CHECKING = True NotCleaned = NewType("NotCleaned", str) Checked = NewType("Checked", str) Cleaned = NewType("Cleaned", str) original_foo = ["SOME ", "dirty ", " Data"] annotated_foo = [NotCleaned(item) for item in original_foo] cleaned_foo = [ Cleaned(item.lower().strip().replace("dirty", "tidy")) for item in annotated_foo ] foo: list[Checked | Cleaned] if NEEDS_CHECKING: for idx, item in enumerate(cleaned_foo): if item and (item[0] == " " or item[-1] == " "): raise RuntimeError(f"Whitespace found in item #{idx}: {item=}") if "dirt" in item: raise RuntimeError(f"Item #{idx} is dirty: {item=}") foo = [Checked(item) for item in cleaned_foo] else: foo = list(cleaned_foo) print(foo) # => ['some', 'tidy', 'data'] This survives strict type checking (`mypy --strict`). I don’t feel that renaming the variables introduces much noise or busywork here? One might argue that renaming even adds clarity?
- deleted 1y ago[deleted]
- JackSlateur 1y agoOne can hope that cpython will use them, one day "if a parameter is typed as an int, then only run the specialized 'int' code to process it" This would increase performance and make typing more useful
- aunderscored 1y agoWithout significant language changes, this is not possible. While your code may be typed as an int, I can simply redefine what int means. I can also modify the code in your method.
- JackSlateur 1y agoYes I guess it would work with the ongoing jit work, which (as far as I understood..) run the code "as usual", then notice that a specific variable is always a dict (or whatever). Then it patches the code to run the dict-optimized code by default (and fallback to the generic code if, somehow, the variable is no longer a dict). With typing, the generic code could be avoided altogether. The algorithm would be: - notice that some variable can be processed by a dict-optimized code (because its typing is a dict, or something that looks like a dict etc) - when processing, check that the variable is indeed a "dict", raise an exception if not - run the optimized code - if the typing information changes (because the class has been redefined and the variable is no longer a "dict"), then go to step 1 and either stick with the current optimized code, use another one, or use the generic one This would: - enforce types (you said that variable is a Thing but a Thing was not given: exception) - improve the jit by removing the bootstrap phase (where the jit watches and then try to guess what could be improved) (or perhaps this is a stupid idea that cannot work :) )
- aunderscored 1y agoThere are already some bits of this with specific bytecode and the upcoming jit, it's not using annotations at all though
- ciupicri 1y agoI think you're forgetting that int is actually what other people call a BigInt, an integer with unlimited precision, not int32 or int64.
- picafrost 1y agoMy experience adding types to un-typed Python code has convinced me that static typing should be required for anything more complicated than a single purpose script. Even in old and battle tested code bases so many tiny bugs and false assumptions are revealed and then wiped out. It's not perfect in Python, and I see some developers introduce unnecessary patterns trying to make type-"perfect" `class Foo(Generic[T, V])` (or whatever) abstractions where they are not really necessary. But if the industry is really going all-in on Python for more than scripting, so should we for typed Python.
- entropyneur 1y agoI know I am going to be in the minority, but I don't understand why we can't let Python be Python. Static typing is great, and there are already other statically typed languages for all your needs. Why not use them? Well, at least it doesn't create two incompatible Pythons like async and (I assume) free threading.
- Galanwe 1y agoI used to be of the same opinion, but after giving type hints a real try, I changed my mind. You should not see type hints as real, hard types, but more as a kind of documentation that helps your linter and type checker catch mistakes.
- Matthyze 1y ago> Why not use them? Because you can now use typing WITH the entire Python ecosystem.
- Ekaros 1y agoI sometimes felt that Python was rather strong in many parts of typing. As such being able to track what type of something is would often have been useful. Instead of waiting it to crash to some error. Like back in 2.7 difference between byte-array and string... Offloading such cases is mentally useful.
- chpatrick 1y agoBecause Python has a lot of things it's great at (numeric stuff, ML, computer vision, scripting), and with types you can actually rely on it to work. It's the best of both worlds.
- gooodvibes 1y agoIsn't this a very 2018-2019 topic? I don't get the motivation to write about it in 2025, it's like telling people to use version control.
- Hackbraten 1y agohttps://xkcd.com/1053/ https://xkcd.com/1053/
- yoshi389111 1y agoBeyond the usual advantages of Python’s type hints, it seems they can also improve code suggestions and completions when working with AI coding tools.
- ciupicri 1y agoIs there a type checker that works with numbers.Number?
- spooky_deep 1y agoPython with type hints still lacks the performance benefits of static typing in a compiled language setting?
- maxfurman 1y agoIt's the developer performance benefit of catching type bugs early, not the application performance benefit from a compiler, that Python developers find compelling
- pansa2 1y agoYes. It also lacks the ease-of-deployment of a compiled language.
- chpatrick 1y agoYou generally don't write Python if you want it to be really fast anyway (non-Python parts like numpy notwithstanding).
- tmarice 1y agoType hints in Python add a great amount of visual noise to the code, and I actively avoid them wherever possible. If static typing is a must, use a language where static typing is not an afterthought, and let Python be Python.
- ctxc 1y agoI guess one man's noise is another man's treasure :P
- cindyllm 1y ago[dead]
- corwinxpro 1y agoIndeed, I almost can't read untyped python code these days. It just feels like "what the hell is going on here?" and "what is this object?" ever so often. Sorry to say that but most people who write python just aren't good API designers, or software engineers in general, and type hints can at least help others get a vague idea of what the intent was.
- chrysoprace 1y agoWould you rather deal with a little visual noise or a runtime exception that you could've caught before code got to production? For me it's about tradeoffs, and so far the tradeoff has been well worth it.
- mixmastamyk 1y agoWe have a reliable codebase with tests, pyflakes, sentry, etc. Very few issues make it to prod, though a few might make it to staging. That said, I’m looking into the stubs.
- mgaunard 1y agoin general I see two types of Python in the wild: - simple self-contained scripts, everything is a free function, no type hints - over-engineered hierarchies of classes spread over dozens of files and modules, type hints everywhere I personally largely prefer the first kind, but it seems even the standard formatting rules are against it (two empty lines between free functions etc.)
- Matthyze 1y agoI'm always surprised when people suggest using a different language if you want typing in Python. Python's (second?) largest appeal is probably its extensive ecosystem. Whenever people suggest just changing languages, I wonder if they work in isolation, without the need for certain packages or co-worker proficiency in that language.
- sigmoid10 1y agoTyping has only been around since python 3.5. As someone who has formally learned 2.7 in university when 3.0 had already been around for a few years, I suppose there are many who still lag years behind what the language can do due to old codebases and fears of incompatibility.
- f311a 1y agoI think people usually say it for a different reason. Types are not enforced. You can annotate your code that looks correct to the type checker, but the actual data flow at runtime can be with different types. And it happens quite often in large codebases. Sometimes external dependencies report wrong types, e.g., a tuple instead of a list. It's easy to make such a mistake when a library is written in a compiled language and just provides stubs for types. Tuples and lists share the same methods, so it will work fine for a lot of use cases. And since your type checker will force you to use a tuple instead of a list, you will never know that it's actually a list that can be modified unless you disable type checking and inspect the data.
- chpatrick 1y agoTo be pedantic compiled languages only check types at compile time as well. If you have a C library that takes void* then it can easily go wrong at runtime.
- ctxc 1y agoFor some reason, I find typing in Python to be more ergonomic and "get out of your way" compared to Typescript. But they both seem to handle typing similarly. I can't put my finger on why. Anybody else?
- chrysoprace 1y agoTypeScript is kind of all or nothing. It's not quite all or nothing, but it's annoying to work with it if you only use it for some things and not for others. I find that if you have a mixture of TS and JS in various files I would rather just go all in on TypeScript so I don't have to manually annotate. With Python you're still just working with Python files.
- xurukefi 1y agoFor me, type hints are mainly useful because they're the only reliable way to get decent IDE auto-completion. Beyond that, they feel like a bolted-on compromise that goes against the spirit of Python. If you really need strict typing, you're probably better off using a statically typed language.
- kitd 1y agoJSDoc plays a similar role with Javascript. Moreover it is supported out of the box by VSCode, so add a few JSDoc comments to your types and functions, and intellisense instantly kicks in.
- Dr_Birdbrain 1y agoI actually don’t like python type hints! At my work we have a jit compiler that requires type hints under some conditions. Aside from that, I avoid them as much as possible. The reason is that they are not really a part of the language, they violate the spirit of the language, and in high-usage parts of code they quickly become a complete mess. For example a common failure mode in my work’s codebase is that some function will take something that is indexable by ints. The type could be anything, it could be List, Tuple, Dict[int, Any], torch.Size, torch.Tensor, nn.Sequential, np.ndarray, or a huge host of custom types! And you better believe that every single admissible type will eventually be fed to this function. Sometimes people will try to keep up, annotating it with a Union of the (growing) list of admissible types, but eventually the list will become silly and the function will earn a # pyre-ignore annotation. This defeats the whole point of the pointless exercise. So, if the jit compiler needs the annotation I am happy to provide it, but otherwise I will proactively not provide any, and I will sometimes even delete existing annotations when they are devolving into silliness.
- burnerRhodov2 1y agoYou explained some hyper niche instance where type hints should be ignored. 99% of the time, they are extremely helpful.
- chlorion 1y agoIt's not even a niche instance, protocols solve their problem lol.
- thr0w4w4y1337 1y agofrom typing import Protocol, TypeVar T_co = TypeVar("T_co", covariant=True) class Indexable(Protocol[T_co]): def __getitem__(self, i: int) -> T_co: ... def f(x: Indexable[str]) -> None: print(x[0]) I am failing to format it proprely here, but you get the idea.
- matusp 1y agoThere is also bunch of prepackaged types, such as collections.abc.Sequence that could be used in this case.
- jlnthws 1y agoUse them for what they are (hints, documentation). Use it for gradual typing when implementation makes it hard to understand return or parameters types. But don't enforce it across your code base, use another language or another mindset instead.
- ktosobcy 1y agoI liked python in my early days because it felt simple and easy and when I tried other languages having to deal with types felt so annoying... but then I grew and had to work with bigger codebases and guess what - having types (and static type checking during compilatin) helps A LOT... :)
- physicsguy 1y agoI like it but in my experience a lot of teams use them loosely without a type checker, more for understanding than for correctness. Reason for that is largely that it can be difficult to make the checkers happy…
- procaryote 1y agoI like the type hints. The're not perfect and they've changed a lot between versions, but they really help catch issues early that you'd usually need to write unit tests for. Adding type hints is easier than writing those unit tests. Then you can focus your tests on more interesting things You just need to set your build up to actually do the checking as type hints by default are just documentation
- setopt 1y agoMy main complaint about them is no first-party support for type checking, you need external packages like beartype decorators.
- procaryote 1y agoYeah, it would have been much better to have them be default enforces if present. Keeping them optional is fine, but I don't get the use-case for "you can add them but not check them"... that just leads to actively misleading hints
- zelphirkalt 1y agoPython's dynamic nature can make it quite difficult to express some things correctly. That, or the type checkers have issues when it comes to understanding what would be considered safe in other languages. Years ago when I knew far less about types and programming, I never had such problems in for example Java. It was sometimes stupid, but I always found a way to express things. Although it could also be, that I merely want more out of inference and and safety. For example recently I wanted a pipeline of steps, but the steps could have any input and output type, as long as that type aligns with the previous step's types and the type checker should also know what the final output type is, and I additionally wanted it to work so that I don't have to add all the steps at once, so that I can construct the pipeline step by step. Tried for hours, but didn't find a working solution that type checks. Also tried with the help of LLMs, which gave superficially looking great code for this, but then there was always some type error somewhere, and they struggled to fix that. Ultimately, I gave up on the type checking between steps and output type of the pipeline, as I realized, that I invested hours into something that might be impossible or way waaay too much work for what I get from it. I would not have spent any time on this without type annotating and would have simply gone with a dynamic solution.
- whilenot-dev 1y agoThat doesn't sound like it'd have something to do with the dynamic nature of python. Type checking is a static analysis of the source code, so if you'd want something to be inferred dynamically, then you'll have to make use of generics: from typing import Callable class Pipeline[T]: def __init__(self, value: T) -> None: self._value = value def step[U](self, cb: Callable[[T], U]) -> 'Pipeline[U]': return Pipeline(cb(self._value)) def terminate(self) -> T: return self._value def _float_to_int(value: float) -> int: return int(value) def _int_to_str(value: int) -> str: return str(value) def main() -> None: result = Pipeline(3.14)\ .step(_float_to_int)\ .step(_int_to_str)\ .terminate() print(result) if __name__ == '__main__': main() You could further constrain the generic type through type variables: https://docs.python.org/3/library/typing.html#typing.TypeVar https://docs.python.org/3/library/typing.html#typing.TypeVar
- ksynwa 1y agoHow do type hints work if for example you import a library that has not implemented type hints into your project in which you hope to have type hints? Do you just manually assign types to the outputs of this library?
- geenat 1y agoCompany selling a product based on what's being glazed in the article. It's always a small vocal fraction or they'd be using a different language.
- davidatbu 1y agoI doubt that Meta (the company that sponsors the work on pyrefly) is looking forward to selling a product based on Python typing (assuming that's what's "what's being glazed in the article").
- storus 1y agoThey are optional until Pydantic is forced on you by some required library.
- dvcoolarun 1y agoI believe types are a great way to encourage good practices with relatively little investment. They provide type-safety, act as living documentation, and add an extra layer of protection in production. However, in a large codebase, consistency can become a challenge. Different developers often approach the same problem in different ways, leading to a mix of type patterns and styles, especially when there’s no clear standard or when the problem itself is complex. With the rise of LLM-generated code, this issue becomes even more pronounced — code quality and craftsmanship can easily degrade if not guided by proper conventions.
- sota_pop 1y agoPython types - all the onus of static types, with none of the performance! I enjoy packages like pydantic and SOME simple static typing, but if I’m implementing anything truly OOP, I wouldn’t first reach for Python anyway; the language doesn’t even do multiple constructors or public/private props. Edit: as a side note, I was interested to learn that for more verbose type specification, it’s possible to define a type in variable-like syntax at the top: mytype = int|str|list|etc.
- the__alchemist 1y agoThere is an important (I would say primary) benefits of types that isn't performance: it's making a program structure [you | your IDE | LLMs] can reason about.
- sota_pop 1y agoAgreed, it definitely improves my experience when the compiler “knows” the variable types.
- coldtea 1y agoOne shouldn't be implementing anything "trully OOP" to begin with...
- sota_pop 1y agoQuotes speak louder than words… However it’s hard to say “what one should or shouldn’t” be implementing in general terms.
- __MatrixMan__ 1y agoWhat does "multiple constructors" buy you that you can't get from multiple static methods that return an object of the enclosing class's type. Maybe I'm missing out on something cool...
- sota_pop 1y ago
- coldtea 1y agoMore likely "Python developers phone-in AI code that uses type hints".
- lupusreal 1y agoTypes are invaluable in modern code bases because they end up saving a ton of tokens when agentic coding tools are trying to comprehend let alone modify the code. Python isn't intrinsically a great language for LLMs to work with, except in practice it is because they've had a great deal of training data for python. Type hints help a lot with this.
- revanwjy 1y ago[dead]
- pif 1y agoOnly lazy and lame developers can prefer dynamic type.
- DarkNova6 1y agoShocker. Static typing wins once again.
- david422 1y agoI used python on a large code base for quite a while. Many team members did not like type hints, and a codebase that doesn't maintain type hints makes it harder to use them. However, if I had a choice, rather than use typehints in python, I would much rather just use a statically typed language. Short, tiny scripts in python? Sure. Anything that grows or lives a long time? Use something where the compiler helps you out.
- olokobayusuf 1y agoI'm founding a company that is building an AOT compiler for Python (Python -> C++ -> object code) and it works by propagating type information through a Python function. That type propagation process is seeded by type hints on the function that gets compiled: https://blog.codingconfessions.com/i/174257095/lowering-to-c-via-type-propagation https://blog.codingconfessions.com/i/174257095/lowering-to-c...
- franktankbank 1y agoHave you talked to anyone about where this flat out will not work? Obviously it will work in simple cases but someone with good language understanding will probably be able to point out cases where it just won't. I didn't read your blog so apologies if this is covered. How does this compiler fit into your company business plan?
- olokobayusuf 1y agoOur primary use case is cross-platform AI inference (unsurprising), and for that use case we're already in production by startups to larger co's. It's kind of funny: our compiler currently doesn't support classes, but we support many kinds of AI models (vision, text generation, TTS). This is mainly because math, tensor, and AI libraries are almost always written with a functional paradigm. Business plan is simple: we charge per endpoint that downloads and executes the compiled binary. In the AI world, this removes a large multiplier in cost structure (paying per token). Beyond that, we help co's find, eval, deploy, and optimize models (more enterprise-y).
- franktankbank 1y agoI understood some of it. Sounds reasonable if your market already is running a limited subset of the language, but I guess there is a lot of custom bullshit you actually wind up maintaining.
- olokobayusuf 1y ago
- throwaway106382 1y agoRuby has had static typing via RBS for a while now, and I don't know if it's because I'm primarily a Rails developer and DHH doesn't like static typing so using these with Rails feels third-class or maybe just that I'm really just all the way in "the ruby way" but it feels antithetical to a dynamically typed language to start shoehorning in static types. Even as a type definition in a separate file it just feels wrong. Ruby particularly is already strongly typed so there isn't too many suprises with automatic conversions or anything like that. RBS also just makes metaprogramming more annoying - and Ruby's ability to do metaprogramming easily is one of its biggest strengths in my opinion. If I wanted a statically typed language I would just use a statically typed language.
- tedivm 1y agoI've been working with Python for years (since 2014) and typing makes the code less buggy and easier to maintain. I also would hardly call it "shoehorning", as years of design went into it. Honestly the only people I see who really push back against it are the people who haven't bothered learning it. Once people use it for a bit, in my experience at least, they don't want to go back.
- throwaway106382 1y agoMaybe it's just because Python is just kindof a lousy language to use in the first place. I started with Java and C++, did Python for a bit and switched to Ruby and never looked back. Being forced to use Python for anything feels like a punishment. Years of design also went into Ruby's type system, and for the people that enjoy it - be my guest - but I would never use it for my own code.
- vintagedave 1y agoMy permanent instructions to Claude are: * Always strongly type, for local variables, method parameters, and return types * Avoid Any unless absolutely required * hasattr() and get() are often code smells; if the type can be known, use that type * Use beartype for all methods. I _love_ beartype and want to plug it to everyone on HN: https://github.com/beartype/beartype https://github.com/beartype/beartype I'm building my own coding agent, like Claude, and it is built with opinionated style. Strongly typing Python and using beartype are what it will try to do unless the user specifies otherwise.
- lend000 1y agoNot willingly, but it's a lost cause getting AI generated code to avoid it.
- beebmam 1y agoI just don't see why people use Python in the AI era. Statically typed languages help AI reason about code enormously during compilation.
- pedrellimath 1y agoPython is amazing for that reason. You choose whether you want to do it or not.
- notatoad 1y agoan underrated benefit of type hints is how much better my copilot autocompletions are on type hinted code.
- rao-v 1y agoI’d love to see an analysis of how much typing hurts LLMs that need to read / edit your code (due to increased context) vs helps (due to more clear type context). I want to believe that corrected typed python code is easier for smaller models to generate / interact with, but who knows how the trade-offs actually work out.
- _alternator_ 1y agoThe reason to use type hints is simple: it vastly improves scalability, making LLM agents much less error prone. Try it: tell Claude to type hint every function (e.g., in your Claude.md file) and see how much easier it is to scale your agents. This also works for humans, but many python programmers who learned python before type hints can't be bothered. :sad_panda:
- dajonker 1y agoA dynamic language with type hints has all of the disadvantages of a dynamic language with all the disadvantages of a static language on top of it.
- amne 1y agoIs it me or is everything slowly moving to strong types but don't want to commit? For PHP it slowly got introduced in php5.4 and now it's expected to type hint everything and mark the file strict with linters complaining left and right that "you're doing a bad job by having mixed-type variables" In Ruby you get Sorbet or RBS. What is JavaScript? Oh, you mean TypeScript. and so on .. My take is that if you need strong types switch to a language with strong types so you can enjoy some "private static final Map<String, ImmutableList<AttemptType>> getAttemptsBatches(...)"