Convenience is API design. In a fully dynamically-typed language, there's no real downside for heavily polymorphic APIs and a lot of upside in terms of brevity and flexibility.
I believe pretty strongly that you can design great dynamically-typed APIs for dynamically-typed languages or great statically-typed APIs for statically-typed ones, but I don't think you can easily layer static types on a great dynamic API. The affordances are just too different.
One obvious challenge is that statically typed languages almost always support overloading. This makes it dramatically easier to have these kinds of polymorphic APIs while having sane types. Most dynamically typed language support overloading at all, which is where these giant union types come from when you try to cram a single static type onto what is effectively a number of different method overloads.
Wow, I'd say that's a major pain point for me—reasoning about polymorphic code with only vague guidelines:
"give me something that looks like a string".
"Well, which types are those?"
"Hell if I know! But it needs these methods, but it can also change its behavior if it doesn't have them"
"stabs self in neck because this was solved in the 60s"
Seeing a hard-to-skim polymorphic API for anything but a quick script is a massive problem for me—the time sink in just parsing its behavior isn't worth the inevitable problems that come with the edge cases at runtime.
That said, requests is great and I use it to do all my web scraping because it's super idiomatic. I had no idea the interface was that complicated, though, and it reduces my confidence in the library.
This PEP reminds me of typed racket: pretty awesome, but a completely separate language to write with separate considerations.