Most of the common 2.x programs don't depend on the change in Unicode semantics or whatever, but they really don't work simply because really unnecessary changes in the way print and formatting must be written in 3.x. It was technically possible to make much more programs still work while still introducing the more convenient syntax and it was in my opinion bad judgement not to do so.
In my view, those that made the decision took to seriously "there's only one way to do it." Zen of Python actually says: "There should be one-- and preferably only one --obvious way to do it." Even if the obvious way for 3.x can be different from 2.x, I can't imagine any real-life effects from allowing the alternative syntax for formatting and printing except for a few special-case branches somewhere in the source. Yes, then the people would continue to write it with the "wrong syntax" in the new programs too, so what?
In Python3 print is now a function, and no longer a keyword. The syntax got strictly simpler that way, and semantics, too.
You could try to make the interpreter guess when you want to use print as a function and when as a keyword. But that would be horribly complicated, and is bound to go wrong.
No it wouldn't. There would be some corner cases, but mostly it would just work for the existing code whereas, from the perspective of the 2.x users, now it just doesn't. I know, I write compilers for living. The maintenance cost from the point of view of the compiler maintainer would almost invisibly increase (there are much less trivial things to worry about) the benefit for the current users would be significant. The reason it wasn't done is much more "political" ("just one way to do it") than technical.
Specifically: once it's declared that print is a function, you don't need to treat the string print as keyword. Then you can notice comparing print expression and print( expression ) that if you know that print is a function the braces aren't giving you any new information. So the difference is do you want to encode the knowledge "print is a function" in the compiler or not. That encoding is trivial, and even if it can be called "a special case" isn't anything that anybody would spend any significant energy maintaining. It obviously appears to be "less elegant" to describe your compiler having "a special knowledge that print is a function" but there are even ways out of that: you can generalize such constructs (function calls without using the return value). But then "there would be more than one way to do it."
But orders of magnitude more 2.x Python programs would "just work" when started under a such 3.x. Of course, once you accept that the transition should be less painful, you'd need provide the way for libraries to also have the "newer" and the "older" ways to do it. "More than one way" is potentially contagious. But, sometimes "worse is better."
OK, as a litmut test, how would your proposed compromise Python variant deal with the following program
print
As Python 3, this program does nothing. As Python 2 it prints a newline.
I do agree that Python could have adopted the ML/Haskell syntax for calling functions that does away with most parens. But I don't think anyone in Python land would have swallowed that.
It's clear, in Python 3 that would have to behave as in Python 2 if our goal were to have most of existing Python 2 programs "still working" when people give them to Python 3.
In my view, those that made the decision took to seriously "there's only one way to do it." Zen of Python actually says: "There should be one-- and preferably only one --obvious way to do it." Even if the obvious way for 3.x can be different from 2.x, I can't imagine any real-life effects from allowing the alternative syntax for formatting and printing except for a few special-case branches somewhere in the source. Yes, then the people would continue to write it with the "wrong syntax" in the new programs too, so what?