The problem is that other people might use those features and you also might have to read the code created by those people.
I have the same problem with classes in JavaScript. You can't ignore them and stick to prototypes nor ignore prototypes and stick to classes. What should have been a simplification has turned out to make things more complex.
You can only read the code and guess the type yourself.
There are massive differences between languages, though. I think I might use close to 70% of Objective-C's or Java's features regularly, while I can't even hope to use 50% of C++'s.
I'm personally not a fan of it (I'm still a gevent proponent; Go seems to be doing fine with a green thread model), but a lot of libraries I use are written with it, so it's pretty annoying for me. That and the dependency/package story are the two things that've made me seriously consider switching to a different language. (The article's complaints about things like pre-commit and isort are pretty silly and irrelevant, IMO, though it would be nice if there was something official like "go fmt".)
So far the benefits still outweigh the costs for me, compared to other languages, but I predict a better, cleaner, and more performant successor to Python may come this decade. If it does, I think I might become an early adopter.
Yes, this is true. I don't think there's a lot of existing code using it at this point since it's still a fairly new feature. But of course that will change as time goes on.
> I'm personally not a fan of it
I haven't tried it yet in an actual project, but my initial reactions just looking at the specifications and examples were mixed. I like the idea of the await keyword to label call sites where your code might be suspended, but I don't like having "async" cluttering up function definitions, for loops, and with statements. The way generators were handled when they were first introduced in Python 2 was much cleaner IMO: one new keyword, yield, and any function that had that keyword in it automatically became a generator. I don't see why a similar rule couldn't have been implemented for the await keyword: any block with await in it automatically becomes an async block.
If black does non-PEP 8 formatting, as the article says, then I would not expect it to be in the standard library, since PEP 8 formatting is the Python standard.
> the language itself is increasingly baroque and complicated
I don't find current Python 3 any more baroque or complicated than Python 2.7. In fact I have plenty of Python code that runs just fine, unmodified, under both interpreters. And I have plenty of other Python code that only needs from __future__ import print_function to run unmodified under both interpreters.
That's not to say I think there are no issues with current Python 3; just that I wouldn't describe those issues as "the language is increasingly baroque and complicated". See further comments below.
> Type-annotated, asyncio-enabled Python hardly resembles the language I fell in love with back in 2006.
You don't have to use these features if you don't want or need them. Nobody uses 100% of any language's features, and the subset that is used can be very different from person to person. I don't see that as a problem.
I did see the way the Python 3 transition was handled as a big problem, but that's water under the bridge now and the issues that gave many people headaches during the transition were pretty much resolved by Python 3.3.
The two big problems I see with current Python 3 are memory usage and the GIL. Python 3 objects take more memory than Python 2 objects did; for programs that create a lot of objects that can be an issue. (To be fair, many such programs are numerical simulations that can take advantage of the many optimizations in the NumPy and SciPy libraries.) There seems to be work in progress on supporting multiple interpreters running in the same Python process, which would fix the GIL issue, but it's too soon to see if that will really address the issues surrounding the GIL.