4 ms·
It was source-level incompatible with older code so it couldn't be used as a smooth transition like... almost any other language upgrade I've ever seen. Breaki
by problems 9y ago
It was source-level incompatible with older code so it couldn't be used as a smooth transition like... almost any other language upgrade I've ever seen.
Breaking code like this was a big mistake in my opinion - it resulted in many people sticking on the old version for code and library compatibility. There are still libraries which don't work on Python 3, though now fairly few of them.
In addition to that, the unicode changes were in my opinion another mistake - they made it far more complicated to deal with strings and byte arrays as now even for the simplest of applications you have to put thought into character encodings. Another annoyance for me personally is that I often use python to do things like hex and base64 encoding, the removal of .encode("hex") really wrecked this one for me. Now I have to remember weird import libraries like "binascii" with weird function names like "hexlify".
Ultimately Python 2 works. And it works well, there just aren't that many compelling reasons to move to 3 given that it often is more complicated and breaks existing code. They have a few cool things now, so I sometimes use it for new code but there's still nothing that's making me want to delve into a port of my older codebases.
- maxerickson 9y ago`hex` and `fromhex` were added to the bytes type in Python 3.5. And while it isn't trivial, it is easy enough to just deal with bytes in 3.x.
- problems 9y agoNice, do they have similar for base64 too?
- dbcurtis 9y agoI strongly disagree with respect to unicode changes. From my perspective, where 95% of my Python is Python3+Twisted implementing obscure and obtuse protocols, the strong firewall between byte strings and character strings plays a key role in my keeping my sanity. Unicode + byte strings alone are worth moving to Python3. I also make heavy use of other new features, I can't imagine going back to Python2.
- sheepz 9y agoMost Python 2 codebases probably have a lot of unknown bugs in them related to Unicode. The code will work fine for cases where the inputs are ASCII, but will subtly break if unicode inputs are provided. In term's of code reliability, Python 3's approach is much more sane.
- chc 9y agoI work at a company that uses Python 2 in older projects and Python 3 in newer projects, and this 100% matches my experience. Python 2's string implementation is simply busted, and the benefit you get in exchange for that brokenness is that some cases are slightly shorter to write.
- netheril96 9y agoAnd if Python simply used utf-8 everywhere, those ASCII expecting code would continue to work fine when unicode inputs are provided.
- pjmlp 9y agoWell, even languages that bend themselves for backwards compatibility do introduce breaking changes, every now and then.
- chc 9y ago> It was source-level incompatible with older code so it couldn't be used as a smooth transition like... almost any other language upgrade I've ever seen. Ruby released the source-incompatible Ruby 1.9 just months before Python 3. IIRC most versions of Swift have been source-incompatible with each other. Even a language as buttoned-down as C++ has made source-incompatible changes[1]. I have no idea where people got the notion that Python invented the idea of breaking changes, but it just isn't so. [1]: https://stackoverflow.com/questions/6399615/what-breaking-changes-are-introduced-in-c11 https://stackoverflow.com/questions/6399615/what-breaking-ch...
- problems 9y agoGo ahead and look at those breaking changes, then compare with Python 2 to 3's breaking changes. It's a difference of a few minor things versus a whole swath of changes to the handling of strings in the language, heck, a python 2 print statement isn't compatible with python 3. These are much more significant breaking changes which make porting code much harder than any of the other examples you've given. For the most part, developers don't have to touch or only have to make minor changes for specific cases to port to Ruby 1.9 or C++11 - look at those C++11 changes for example, so few people were doing those things and they're such bad practices that it simply didn't matter. They successfully preserved compatibility in the nominal case. But even following all the best practices in your Python 2 code will not make it run under Python 3.
- chc 9y agoI don't use Swift or C++ much, but I have several years of experience in both Ruby and Python. The changes in Python might be a bit bigger, but the changes in Python 3 and Ruby 1.9 seem of roughly the same magnitude to me. Text encoding is now a problem you need to think about, some methods were removed, other methods were added, the output of some methods changed (e.g. the output of Array.to_s, the result of indexing a string), a few syntactic constructs changed (e.g. character literals used to return numbers, now return strings), and all C-based libraries broke in Ruby 1.9. In both cases, more than 99% of your code will probably be the same (unless your program is mostly print statements, I guess). What's more, Python took more pains than Ruby to ease the upgrade process, with stuff like __future__ imports, 2to3, and the six library. IIRC the Ruby team just changed stuff and said, "OK, update your code accordingly and we promise not to do this to you again for a long time." It seems to me like the primary difference that made the Python upgrade worse is that the authors of the big libraries in Ruby were enthusiastic about moving to Ruby 1.9, so that it was possible to start porting most Ruby apps very soon after 1.9 released, while a few big Python library authors dragged their feet on even getting started. This was a very real problem, but it was essentially a cultural problem of the library landscape being very different, not a matter of the language itself being drastically different.
- jwilk 9y ago"hex" and "base64" are still available via the codecs module: >>> import codecs >>> codecs.encode(b'eggs', 'hex') b'65676773' >>> codecs.encode(b'eggs', 'base64') b'ZWdncw==\n'
- dom0 9y agoThough I agree that it was an annoying change. hex/fromhex have helped there, though a 3.4 codebase retains stupid helpers like bin_to_hex.