I like to think of engineering as "solving problems within a system of constraints". In the physical world, engineering constraints are things like the amount of load a beam will bear. One of the primary easily-overlooked constraints in the software world is backwards compatibility or migration paths.
There are many examples of systems where many look at them today and say: "This is terrible, I could design a better/less-complicated system with the same functionality in a day". Some examples of this dear to my heart are HTML, OpenID, and SPDY. It's important to recognize the reason these systems succeeded is they sacrificed features, good ideas, and sometimes even making sense to provide the most critical piece: compatibility with the existing world or a migration plan that works piecemeal. Because without such a story, even the most perfect jewel is difficult to adopt.
The OP, about Python 3, is right on except for when it claims making Python 3 parallel installable with 2 was a mistake; doing that would make it even more impossible to migrate to 3 (unless the single binary was able to execute Python 2 code). (Also related: how Arch screwed up Python 3 even more: https://groups.google.com/d/topic/arch-linux/qWr1HHkv83U/dis... )