It's not possible to determine the language. The extensions are the same and much of the syntax hasn't changed, and many of the backwards-incompatible differences are subtle.
Python2:
print(1/2 * 1000) # 0
print({b'a': 'bytes', u'a': 'text'}[b'a']) # text
print(b'A'[0]) # A
Python3's treatment of integer literals in that case is bad. The first is the behavior that someone used to programming will expect by default, since those are integers. If you want non-integer operations you should have to use a decimal point in the 1 or 2.
I disagree. A strong type system is good, but in this case pragmatism wins the battle. I personally have been bitten innumerous times by bugs where division was rounded down (usually to 0, which is especially destructive).
Most of the numbers I encounter start as integers and most of the calculations I need are floating-point. This language behavior saves me from sprinkling "* 1.0" everywhere on my code, or from introducing extremely subtle bugs.
And the integer division is always there, one character away:
Python3's '/' operator is different from Python2's '/' operator. This is clear when you try to overload them. Python2's is called '__div__', while Python3's is '__truediv__'.
The Python3's operator '/' (on numbers) is defined to return a float, and it'll convert any integer parameters as required. The same is true for other operators, like 'True + True' being 2.
Because of these definitions, you should consider the operators as explicit conversions. 'total / sum' is less explicit than 'total / float(sum)', but still clear enough.
And about guidelines, there are others that fit this case:
Simple is better than complex.
Flat is better than nested.
Readability counts.
[...] practicality beats purity.
PS: I think you made an important argument and I'm glad you did it, even though I disagree with it. I fail to see why you are getting downvotes.
I went to check out the operation and it seems a on two ints returns an int if the power is a nonnegative int, and a float if it's negative nonzero, in both 2.7 and 3. I didn't expect this kind of inconsistency from python, really.
I guess it does follow the last line of the guidelines there, though. Looking at this power example, the division returning float now is actually an increase in consistency.
I think it's better to think of it as division being an operation that returns the appropriate type for the operation, i.e., a float where necessary. The type of the operands remain unchanged so "upcasting" is not applicable if you ask me.
Even better is that // has been available in Python 2 for ages, so you can get used to using it everywhere. Evidently they were anticipating this change.
It could work, but can you imagine the extra complexity for the interpreter? It would require extensive type conversions every time an object passes the version barrier, and all the Python3 libraries' classes would have to be backported for compatibility.
And it's not just a matter of sacrificing core dev hours for the greater good, the result would be much slower and full of gotchas.
This is a very creative idea, ingenuously simple, but I don't think it would fly.
Unfortunately there's no way in knowing whether a Python 2 string (str, not unicode) originating from the module should be interpreted as a bytes string or text string. Python 2 doesn't have the clean separation between bytes and strings.
Solutions might include adding some sort of hinting to specify the conversion, or add a Python2-like string class to Python 3, which would pollute its purity.
Python2:
Python3: And the merits of doing a backwards-incompatible version have been discussed to death elsewhere.