But it was still full of unnecessary breaking changes.
- The `print()` function is nice, but they could have left in the `print` statement for a transitional (deprecation) period. Or left the `print` statement in, and advise against its use.
- A lot of the incompatibilities are just stdlib modules being moved around unnecessarily. They could have made both import paths work for a transitional (deprecation) period. Or let the old paths continue to work forever, and just document usage of the new paths.
- All the new features in Python 3 (async, nice helper functions, etc.) are compatible with Python 2. They could have added them to Python 2.
The only true breaking change was unicode literal strings. But again, that could be handled with a slow transitional (deprecation) period. The Python 2 stdlib could have been made compatible with both types of strings (as nearly all third-party libraries have). And users could have been told to `from __future__ import unicode_literals` for a transitional (deprecation) period, to ensure their code is compatible before it becomes the default.
Basically Python 3 could have been a single hard breaking change (unicode literal strings), with a smooth transition. Instead they decided to make Python 2 and 3 diverge from each other, making it harder to do the transition.