Python has static typing unless you don't add any types. The vast majority of reputable Python codebases nowadays use static typing rigorously. If you don't, you should. To enforce it when coding with an agent you can either tell the agent to run the type checker after every edit (e.g. via a hook in Claude Code), or if you're using an agent that has access to the LSP diagnostics then tell it to look at them and demand that they are clean after every edit (easy with Cursor, and achieveable in Claude Code I believe via MCP).

Why isn't the agent smart enough to recognize typed Python code existing in a project or detect that an explicit py.typed file exists?

In the case of Claude Code the hook feature is ideal for this so I could imagine the designers deciding that it is more appropriate to put the user in control. That said I think I do agree with you that -- given Python's fairly unique position of having good static typing but not requiring it -- the agents should default to running the type checker if they see it configured in pyproject.toml.

> The vast majority of reputable Python codebases nowadays use static typing rigorously

As judged by who? And in what field?

I mean, if I look at the big Python libraries I use regularly none of them have types - Django, DRF, NumPy, SciPy, Scikit-learn. That’s not to say there aren’t externally provided stubs but the library authors themselves are often not the ones writing them

Yes fair enough my wording wasn't great. And we can add cpython to your list... But the provided type stubs for those libraries make the resulting user experience the same as if they had types. Does Django ORM have a good typing experience via stubs btw? I know that one's always been a challenge.

Overall though my point was that the article, and most comments here, were completely misrepresenting the situation regarding Python. It's a statically typed language for those that want it to be. There's no need to attempt to run any code that hasn't passed a type checker. And it's an expressive type system; much more so than Go which has been mentioned in comments.

However the fact that the standard library documentation doesn't have types is embarrassing IMO.

They do and they don't, there's often mismatches where the library gets updated and the stubs haven't been. It makes adopting difficult to recommend in some cases, especially if the library is under more flux.

Django's stubbing isn't great, there's a lot of polymorphism in the framework (and in DRF). You actually have to change your code rather than just sprinkling annotations in some of places to stop getting 'Any' types.

With the numeric stuff, it's even worse though, for with something like e.g.:

    np.sum(X)
the appropriate type of X can be a python list, a numpy array of any numeric type and dimension, etc.