I would say instead: for any good computer language, new versions need to retain compatibility with old versions. Every single system I run has python 2.7 (including my brand new Macbook running latest OS X). Luckily I don't need numpy, and I can probably do without python at all if I have to.
Compare to perl: I can run old perl scripts on basically any system without having to worry about it breaking. I do all of my server scripting in perl for this reason.
Everyone waxes lyrical about how Python 2.x was "good enough and why would you change it", but there were several things in Python 2.x that were objectively awful (unicode was broken, iterator variables can leak to the outer scope, division of integers producing integers, xrange, raw_input, mixed indentation "working", etc). And while no single issue alone would justify Python 3.x, the combination of all of these issues as well as some other semantic problems justified the need for Python 3.
Of course, that being said, Python 3 also had some issues that it took several versions to iron out.
{Describing the old python-2 behavior:}
-------- Quote: -------
The classic division operator makes it hard to write numerical expressions that are supposed to give correct results from arbitrary numerical inputs. For all other operators, one can write down a formula such as xy*2 + z, and the calculated result will be close to the mathematical result (within the limits of numerical accuracy, of course) for any numerical input type (int, long, float, or complex). But division poses a problem: if the expressions for both arguments happen to have an integral type, it implements floor division rather than true division.
-----------------------
To guarantee the correct mathematical behavior in python2, one would probably have to write:
def true_math_div(a,b) :
if type(a) is int or type(a) is long :
a = float(a)
if type(b) is int or type(b) is long :
b = float(b)
return a/b
as a and b could be int, float, complex, or some object defining the method __div__.The new case of / always being float division and // always being integer division just makes everything more explicit.
z = 3/y
you'll know that y is either always a float or always an int depending on its type and thus you'll 'know' what z is.I'm not a particular fan of that - they should have changed the name entirely, IMO, eg. to Rby - but Perl 5 is not getting discontinued.
It's really sad. In retrospect they certainly should have named it something different. The Perl 5 community could have progressed, maybe even made a Perl 6, while the NGPerl skunkworks project continued independently for 15 years.
I get that for people with no knowledge of programming whatsoever it can be confusing, but it's standard behavior in nearly every typed language.
In C/C++, you divide an Int and you get an Int. If you want floating point division, you divide by a float. Problem Solved.
Almost EVERYTHING else could have been done with slow migration, or simply documenting the odd or quirky behavior.
Iterator variable leaking is just a result of poor programming.
Raw_input vs input could have been solved by slowly deprecating input. Or just left as is.
xrange is the same story.
It all seems like someone just decided to throw their hands up in a fit, throw their toys on the ground, and make a new Python. I enthusiastically jumped at Python 3 in the begining, then ran into problems, and crawled back to my 2.7 and decided I could let others fight the stupid cult war that was coming over 2 vs 3. I'd rather use a tool that works than change all my code over someone's idea that newer is better.
And hence why it's a problem in Python. If you have a function like
def foo(a, b):
return a / b
What are the types of a and b? You don't know. Sure, you could check with isinstance, but now you've broken the illusion of duck typing. The argument is that Python should just do "the right thing". Just because 3/4==0 in most languages doesn't justify repeating that mistake. Not to mention that float(a)/float(b) -- aside from being incorrect in the general case -- is ugly as hell.> Iterator variable leaking is just a result of poor programming.
I think it's a language bug. Why? Imagine if you could do this in C:
for (int a = 1; i <= 3; a++)
foo(a);
printf("%d\n", a);
People would think this is clearly a language bug because it breaks the scoping semantics (not to mention common sense). Now, you could argue that Python supports this sort of nonsense so it's "fine": # a is not defined
if something:
a = 1
else:
a = 2
print(a)
But the reason that works is because otherwise Python would need to have JS-like "var" syntax to declare a variable. Personally I think that'd be better, but the for-loop situation is different.> raw_input vs input could have been solved by slowly deprecating input. Or just left as is. xrange is the same story.
And this is how PHP ended up having three different string escaping functions for SQL statements. The first one (escape_string) was broken, so they added real_escape_string, and then they needed to handle connection-specific quirks so they added mysqli_real_escape_string.
Some people still use escape_string even though it's broken -- and the language devs cannot fix it because "that would break users".
I don’t recall it ever surprising me or behaving poorly.
I know rather too much about how CPython and other VMs work under the hood and am in no mood to try and save the day any more. I still use python, but the latest stuff around MyPy and async io just make me despair frankly. I think rust+go will probably pick up a lot of people who used to care deeply about python. So it is.
Meh, more like a clutch for systems where you couldn't install List::UtilsBy. (One of my favorite Perl modules of all time.)
In retrospect it probably would have been better for the community if they'd given Perl 6 a new name.
The library ecosystem is the problem, and it's what's driving the language churn.
https://www.curiousefficiency.org/posts/2014/08/python-4000....
Back when I cared about Perl, doing "man perldelta" was a nice way to entertain myself.
As a non-Python pro, I cannot say why one version over another. However, arguing that the old one is bad just because it is inconvenient isn't valid.
As someone who struggles with versions of Python on my Mac and on production servers (and with code that runs on 2.7 and 3.6+), as far as I'm concerned (as a pragmatic solutions-first person goes), I cannot discern the difference between ancient Python and new Python.
There are really few languages with such impact as Python. So we cannot blame the Python community for this situation as they probably really labored over their decisions regarding compatibility and versions. But in retrospect, I would have preferred they killed off the old version long ago. It would definitely have made life better for the users in the long run.
In this case I'm included. Python is not my first, second, or third love. But it is the most available and the simplest tool available to glue things together. CSVs, json, web apis (private and commercial), etc., are all so easy to do with Python.
So my guess is that there are a lot of users who may not even realize the benefits that Python3.x gives vs 2. "We" don't know or care about features we don't need. But we do feel the pain of modules that only work for one version.
In hindsight, I would have voted for a hard break from 2->3 perhaps 2 years ago. I suspect the ultimate human time effort would have been less than we waste now straddling or stumbling with two versions.
In comparison PHP and Java always successfully transitioned to new versions, keeping it backward-compatible and do baby steps instead of a big incompatible cut. PHP canceled the ill fated PHP6 fork, and went from PHP 5.2 then up to 5.6 and then jumped to PHP7 (as several PHP6 books got published about an alpha version).
Language with a rocky transition (mostly due to incompatible syntax) were C#/dotNet 1->2, Perl 5 -> 6, Lua 5.1 -> 5.3, Ruby 1 -> 2, Swift 1 -> 2 -> 3, Rust 0.x -> 1, and more
You can run PHP3, PHP4 and PHP5 projects with little or no change at all, code dating back to 1990s with PHP7. If you cared a bit and adjusted your code over the years, most changes are announced many versions ago and got deprecated. E.g the original MySQL API had been deprecated for a decade or so years, and only got removed with v7, yet it's easy to update the code to the newer APIs, as it was possible since early 2000s, when the newer API got introduced and stayed unchanged since then. And you could use a shim too.
PHP and Java (and several other languages) have really kept an eye on backwards compatibility, you cannot deny that or paint it in another light.
It's an enormous amount of effort. It's been a decade and the end is nowhere in site. Python 3 is a tragedy.
The NumPy project has supported both Python 2 and Python 3 in parallel since 2010, and has found that supporting Python 2 is an increasing burden on our limited resources;
That's a real team saying that they just can't support 2 major versions of the language any longer.
This is a pure political decision based on ideology.
Official support will be dropped by 2020, by then you will be relying on the community (who ?) to provide bug and security fixes. I'm not aware of anybody stepping up and declaring they will take over maintenance.
At this point, insisting on python 2 is the ideological "side". There's no practical nor realisitic reasoning behind it. Major parts of the community are moving to python 3 and dropping python 2.
You can stay with python 2 and maintain the language / libraries, but don't begrudge those that move on.
I've plan to migrate away from py2 by 2020 too, just not to py3.
If you feel you have "plenty of resources" you can fork the python2 version of numpy and maintain it.
Aside from what others have said, NumFOCUS is woefully underfunded. If you're interested in seeing continued development of NumPy and other amazing scientific Python packages, you should think about contributing!
(Not a NumFOCUS person although I occasionally volunteer with them and definitely donate on a recurring basis.)
(I understand that in this particular case, I could have enforced ISO-8859-15 as well, but the crux of the matter is that with unicode built in python3, I don't have to think about it anymore)
And now my customer is copy/pasting additional information from documents coming from other countries as well...
The main difference is that unicode has a more efficient internal storage since Python 3.3+ (a neat technical detail), and that mixing bytestrings and unicode will fail with an explicit error since 3.0+ (a good idea IMO).
But that Python 2.7 didn't support unicode is simply FUD.
Not good enough means I had to prefix every single string with "u" to make sure it's unicode. It was especially painful with code like this :
logger.debug("Name of the person I'm debugging {}".format(name))
forgetting the "u" simply lead to various crashes if the name had characters that could not be encoded in whatever the debug was piped to. Always thinking about the "u" was nothing I had the time to.Just an example.
It's actually good practice to be explicit about the type, and write b"" and u"" always (easier on the person reading the code). The u'' literal prefix was re-introduced in 3.3 for this reason.
It doesn't because strings and text are a lot more common than bytes. Yours is a really weird line of argument - that the 3.x changes and what's in 2.7 are fundamentally equivalent and thus the changes are outright unnecessary and that the people who made them just got it wrong and did it for no apparent reason or benefit. I get that someone might not like what they did or how they did it but your take should give you pause just by its general improbability.
As I said, u'' literals were re-introduced by the Python developers themselves, in Python 3.3.
1. BOTH Python 2 and Python 3 come with built-in support for BOTH bytestring and unicode (contrary to OP's claims I responded to)
2. That mixing bytestrings and unicode will fail with an explicit error since 3.0+ (a good idea IMO)
3. Unicode has a more efficient internal storage since Python 3.3+ (a neat technical detail)
4. It's good practice to be explicit about the type of literals, and write b"" and u"" always
5. That Python 2.7 doesn't support unicode is simply FUD.
Can you articulate which point you're actually contesting? I'll be happy to clarify, but I'm honestly unsure what you're responding to.
The person you replied to didn't claim Python 2 doesn't support unicode. 'Bytestrings' has what is wrong with Python 2 neatly summarized in a single word (and this, incidentally, is a term the Python documentation avoids these days because it's bad). 3 is true but not really related to the topic at hand. 4 is, I think, outright wrong. As to 5, I'm not sure why you would even want to defend that. It's not what the poster said and even if they had said it, they'd be just wrong - it's not 'FUD'. That is just you being grumpy and rude.
that was my point, by moving to python 3, I removed all my "u", the thing other developers not wanted (see PEP-414 again); I loved the "purity".
but removing u was tedious (at best).
In my use case, strings are "string" and binary are "bytes". Which I think is much safer.
Lots of python 2 code out there fails because the default option was simple but bad. I know, because my name broke the CI pipelines in a few different projects.
For these folks encountering anything other than ASCII is pretty uncommon.
Personally, I've worked on a Python 2.x project deployed in heavy industry across the globe including Japan and the number of times we had Python 2 unicode nightmare issues was too many to mention.
Because the community is fragmented and that weakens language adoption, productivity, and enjoyment.
The 2-3 schism in Python has been a pain to deal with for years. I use Python casually here and there, but I'm so sick of trying to do something quickly in Python and finding out that I'm on a machine that only has 2 but the module I need is only for 3 or having the bulk of my app written in 3 but the only version of a module I need is for 2.
Same goes for examples you find on the Internet to do a particular thing. Ooops, it's 2.x syntax/modules so you have to fix it up for 3. Ooops, it's 3 syntax/modules so you have to fix it up for 2.
For the good of any computer language, old versions need to eventually die off.