The the introduction of Python 3 wasn't a mistake. The mistake was discontinuing Python 2.
Just look at how rust does it. Rust 1.0 code still works in the latest version of rustc, you just need to set the project to the Rust 2015 edition. You can even mix-and-match editions, as each crate can have a different edition. Newer versions of rustc will always support all previous editions, and breaking changes are only ever introduced when a new edition is released every 3 years. If the crate is stable, no real reason to upgrade, it will work forever. And if you do need to update a project, you can split it into multiple crates and do it incrementally.
Just imagine how much smoother the python 3 transition would have been if you could transition projects incrementally, module by module as needed.
I'd say Rust editions are more like going from Python 2.x to Python 2.y, than the 2->3 migration. The Rust standard library is still the same (and the string type is still "valid UTF-8") no matter the edition (this is why you can mix-and-match editions), the edition differences are mostly on the syntax.
> Just imagine how much smoother the python 3 transition would have been if you could transition projects incrementally, module by module as needed.
That would require manually converting strings to the correct type at each module boundary (you can't do it automatically, because on the Python 2.x side, you don't know whether or not a string has already been decoded/encoded into a specific character encoding; that is, you don't know whether a Python 2.x string should be represented by a "bytes" or a "str" on the Python 3.x side). That's made even harder by Python's dynamic typing (you can't statically look at the code and point all the places which might need manual review).
It seems you are both saying the same thing. Had Python not introduced a line in the sand and instead continued to support Python 2 amid future updates there would have been no reason for Python 3. The Python 2 line could have kept improving instead.
Just as you say, Python could have introduced what is found in Python 3 without breaking Python 2 support. Which is the direction Go has settled on; hence why Go 2 is off the table. Go 1.0 and Go 1.23 are very different languages, but backwards version support is retained, so no need for a new major version.