One example comes from the new-style / old-style classes distinction and the method resolution order when considering multiple inheritance.
Python 2.3 introduced "new-style" classes which inherit from `object` and use the C3 resolution algorithm [1]. For backwards compatibility reasons, "old-style" classes without an explicit `object` base class still used the old method resolution semantics.
Python 3 does away with "old-style" classes entirely and all classes must use the "new-style" semantics.
There's presumably a ton of code that doesn't specify `object` as an explicit base class, and thus may have subtle broken behaviour under "new-style". Given Python 3's inability / unwillingness to simulate the old behaviour, I'm unaware of any tool that's able to rewrite Python 2 to 3 in a bullet proof fashion [2].
This is not the same kind of breakage that other people mention, like `print` being a function or `reduce` being moved to `functools`. Those are simply backwards incompatible "movements", not outright removals, and thus can be rewritten by automated tools.
[1] https://www.python.org/download/releases/2.3/mro/ [2] https://portingguide.readthedocs.io/en/latest/classes.html#n...
https://docs.python.org/3.0/whatsnew/3.0.html#removed-syntax
The removals were actually an easier pill to swallow than the numerous subtle changes in behavior introduced by the big, deep switch to Unicode. I'm over it now, but that was painful!
python 2:
print "foo" # foo
3 / 5 # 0
apply # <built-in function apply>
python 3: print "foo" # SyntaxError: Missing parentheses in call to 'print'
3 / 5 # 0.6
apply # NameError: name 'apply' is not definedWhen working with a wire protocol like ssh, you need to work with sequences of bytes, not Unicode strings, and porting code that assembled them using % formatting was a huge pain; I tried and failed to port paramiko to python 3.
Actually, even those people aren't what hobbled the Python migration. What made it such a mess was that the core team didn't tell that crowd to fuck right off and get with the program or get left behind.
And even now with 2.7 nearing end of life, those same grumpy curmudgeons hang around web forums and reddit and blogs here and there, giving new people bad advice, complaining about how much better the old days were before unicode and async and types. I even saw someone griping about those new-fangled decorators and how monkeypatching was better.
The thing that made a mess out of the transition was the core team trying too hard to coax people who didn't want to move into coming along with them with a small bucket of carrots and no sticks. They tried to pull the bandaid off slowly and it took too long and still hurt like hell.
Yes, you have to write correct code now. Yes, this requires changing some stuff. But yes, this is better for everyone in the (not so) long run.