The whole Python versioning fiasco is simply baffling to me as an outsider. Why not mark Python 3 modules with a tag, or different file extension, or anything, and require the Python 3 interpreter to be able to interpret Python 2 code as well as Python 3 code?
This is e.g. how the (roughly analogous) split between C and C++ is handled, and it works fine for the most part. No bizarre polyglot code games.
Are you expecting the same running interpreter to have both python 2 and 3 modules at the same time, with calls between the modules working? You can easily keep things separate - python 2 executable is named python while python 3 is python3. https://www.python.org/dev/peps/pep-0397/
Sadly concurrent running in the same interpreter won't work because Python 3 has different types for strings (unicode only) and a bytes type, while Python 2 has a str type (pretty much like bytes but can also be treated as a string) and a separate unicode type. Python 2 had code that tried to do the right thing automagically with str, such as automatic promotion to unicode where it looks like you really meant a string and that is what is needed. Automatic promotion can fail, be unexpected, is hard to test and numerous other issues. That is why Python 3 was needed and why it needed to be incompatible. To have Python 2 and 3 code interoperate in the same interpreter would require another layer of automatic promotion/demotion and heuristics when data goes between the two.
C++ was explicitly defined to be a superset of C so it doesn't have these kind of issues. The analogous situation would be if C didn't distinguish between long and pointer types, and C++ did. You'd need rules for how to convert between the two worlds, trying to combine or disambiguate the types depending on which way types are going. It would be a mess.
But imagine what would happen if they had created a compatibility layer. Yes, it would be very hacky, and require a lot of seemingly gratuitous work - tons of standard library functions would have to check the compatibility version of the caller and change behavior accordingly. And the goal of cleaning up the codebase by removing things like old-style classes wouldn't be achievable. But what if that work had been done, and the mess accepted?
Then Python 3 code could use every unmodified Python 2 library (albeit potentially requiring the former to do some messy conversions between str and bytes when making calls), including the long tail of legacy libraries that will never be upgraded. Meanwhile, once the issues in the first Python 3 release or two were straightened out, there would be very little reason to use the Python 2 interpreter, since the Python 3 one would be a drop-in replacement; so migration to the latter would be relatively swift, and it wouldn't be too much of a burden to ask someone to upgrade as a prerequisite to using your code. So there would be very little reason to write new Python code in the Python 2 dialect (unless you really really hate making print a function :), and existing code could be migrated one file at a time. Including popular libraries that wanted to maintain backwards compatibility with Python 2 programs - they would have to add compatibility checks similar to the standard library, but could otherwise go full Python 3, rather than having to use the awkward intersection of language semantics and compatibility libraries currently required.
With the transition so much smoother overall, native Python 3 code would probably take over relatively quickly. (Maybe it would have even been feasible to remove the Python 2 compatibility layer eventually, though probably not.) Whereas in reality, today, over 7 years later, Python 2 is still more popular than Python 3 [1].
C and C++ have a similar issue with strings. C code uses NUL-terminated char arrays, while C++ generally uses std::string. If you want to interface the two, you need glue code (written in C++).
Surely Python 3 can work the same way: to share strings between a Python 2 and Python 3 module, you need to convert them using glue code written in Python 3. Sure it's messy, but writing polyglot code is messier.
Except that you can easily go from std::string to cstring and back in the same program. And many of the standard library functions work fine on c strings (probably over half of <algorithm>), etc. IMO theres no compatibility issue between std::string and c strings.
I wonder if there's even a reasonable way to do this in Python. In C, strings are data that you're explicitly passing around, but in Python, you are constantly calling __getattribute__ under the hood just to execute your code.
I don't know that it would be impossible to make that all work, but I wouldn't assume that it is.
You don't need to actually convert anything: Python 2's str can be identified with Python 3's bytes, and unicode with str. You 'just' need to have their __getattribute__ methods, along with a ton of standard library functions, check the Python version of the caller and change behavior accordingly. Ugly, but I think it would mostly 'just work' for user code.
Since we are in pedant's corner, note that I very carefully used past tense. Yes it originally was a design goal.
Source: The Design and Evolution of C++, by Bjarne Stroustrup. (I don't know which printing I have.) Page 120, Section 4.5 "No gratuitous incompatibilities with C". It explains my original claim, and also why it couldn't be 100% compatible due to some other C++ desirables (eg better type safety). Partial quote:
"C++ doesn't aim at 100% compatibility with C because that would have compromised the aims of type safety and support for design. However, where these aims are not interfered with incompatibilities are avoided - even at the cost of inelegance. In most cases, C incompatibilities have been accepted only when a C rule left a gaping hole in the type system."
> python 2 executable is named python while python 3 is python3
Nope, not quite. Python 2 is named python2 and python 3 is named python3, on every system I am aware of. 'python' is ambiguous and can be linked to either [1]. I know at least on Arch Linux, python links to python3, and I have run into a handful of scripts that break by assuming python is always linked to python2.
Because you actually can write code that is compatible with both Python 2 and 3.
Also major issues people have with migration is unicode. In respect of unicode, majority of the code is simply broken and fails to work on Python 3 because Python 3 is more strict about it.
In Python 2 you store text and binary data as bytes (no distinction, there is unicode type but it's more hassle to use it and frankly almost no one does use it) while in Python 3 text and binary data are two distinct types.
So if you have code in Python 2 and you did not distinguish what is text and what is binary now you have to go through your entire code and identify all those parts, this is especially hard since Python is dynamically typed language and you don't have type checker to help you with that.
This is also why it is much easier to write Python 3 code and make it run on Python 2 as well than the other way around.
As for having interpreter compatibility layer. First python does not care about extension you use, and unlike some languages it actually allows you to install multiple versions at the same time without conflicts (checked 2.4 all the way to 3.5). You can easily control which version you want to use by shabang, for example:
You can also write code that is compatible with both C and Perl. Doesn't make it a good idea.
Shebang doesn't work on a per-module basis, which is what I am advocating. If there were a way to specify versions at that granularity, there would be no need for 2/3 polyglot tricks.
That's a strawman argument. Majority of python libraries are written that way.
I guess I'm incredibly lucky or you're incredibly unlucky, because I did not run into a library that would only run on Python 2. Ok, I did run into some, but those were no longer maintained and frankly I would not use them even on Python 2.
The problem with shebangs used to be (don't know if it still is) that quite a few OS's had python 2.X, but no actual binary called `python2`, just `python`.
Python installs itself as pythonX.Y (for example python2.7) then symlinks such as python2 (pointing to python2.7) and python (pointing to python2) are made.
It's mentioned in PEP0394 that some older distros did not have python2 even though python 2.X was installed. Since RedHat still supports a release with Python 2.4 as the default, I guess it might still crop up on some boxen, at least for another year until RHEL 5 reaches end-of-life.
Assuming python points to python2 will also break stuff, though, there are more bleeding-edge OS's where python points to python3 and has done so for years (e.g. ArchLinux).
I think this is fundamentally because of the Python philosophy around one-true-way to do things (something that's open to interpretation given the number of string functions that are around). IMHO, the Python 3 vs Python 2 split is a phlisophical rift rather than a technical one. There is no real technical reasons why print and print() cannot coexist.
In all reality, Python 2 and Python 3 are completely differently languages at this point. Communities/companies/projects that have adopted Python 2 do not care about anything that Python 3 gives them. Take for instance Flask - to maintain compatibility with the WSGI spec they have to maintain Python 2 compatibility indefinitely. Less than 30% of all software is compatible with Py3 and any new software releases are built on top of Python 2 - yes I'm looking at Tensorflow.
I'm very doubtful that Python Foundation is going to drop support by 2020. Quite simply - a highly funded Python company (like anaconda) can create a fork.
The only way this situation can be fixed is Python 4 with co-existence of Python 3 and Python 2 functions.
> the Python philosophy around one-true-way to do things
I've always thought to be a total joke. There's been like 5 different modules each for string interpolation, subprocess management, and argument parsing. Heck, I thought I was on top of which was in vogue and apparently just two weeks ago there's a new "one true way" to do string interpolation.
> Barry Warsaw, one of the core Python developers, once said that it frustrated him that "The Zen of Python" (PEP 20) is used as a style guide for Python code, since it was originally written as a poem about Python's internal design. [0]
I did a quick search for a little more background but didn't find anything. I'd be curious to hear more.
Almost all the lines on the Zen of Python are inversion of the Perl guidelines. Some with the exact same phrasing, just with the antonyms of the original.
I think this needs to be the responsibility of things like PEP rather than the actual language. Otherwise you break old code every time you find a better way.
What do you do when a value passes between major versions which have different implementations of its type? What do you do with the `int` type, which was actually two separate types in Python 2? What do you do when the binary representation of strings changes (as it did in the 3 series) and you want to pass that into Python 2 land? What do you do about extension modules written in C, which many popular Python libraries use to speed up hot code? Do you include copies of both standard libraries, meaning you now have duplicate modules and may get one or the other depending on the tag in your file? Which version of Python 2 do you target? What happens when there's a bug in one Python 2 implementation but not the other? How do you handle having two C APIs at the same time?
You mention C++ as though it worked out great, but C++ is still full of sharp edges and features that interact weirdly with its C legacy, and it has never completely replaced C (especially for libraries). And that's despite having a few advantages that made it possible in the first place, like having a completely different stdlib built on top of the C stdlib, and producing machine code rather than compiling for a VM on the fly.
I've always wondered this. Why not have .py and .py3 extensions, and require the python 3 interpreter to fall back to Python 2? That would also solve the problem of
"which version of Python is this script I found written in?"
> require the Python 3 interpreter to be able to interpret Python 2 code as well as Python 3 code
Because that would make the interpreter a whole lot more complicated. A lot of technical debt was cleared with the 2-3 transition, adding it back in defeats the point.
C/C++ is different, C++ is a superset of C. That makes things a lot easier.
Edit: Ok, C++ is not a superset, common misconception.
>C/C++ is different, C++ is a superset of C. That makes things a lot easier.
This is entirely incorrect, but I'll give you a break since it is a common misconception. C and C++ are truly two different languages. C is not 100% compatible with C++.
> and require the Python 3 interpreter to be able to interpret Python 2 code as well as Python 3 code?
The interpreter is too messy for that and the transition to Python 3 was not considered well enough. There is no hope on that front. Even if you solve everything else, the C ABI will still be broken.
No problem! I've already fixed it so that all my code is forward compatible with Python 7000, despite not knowing what any of the syntax or library changes are going to look like.
There is a difference between writing code that might break and code that is guaranteed to break. Badly written version checks are guaranteed to break.
Which is why GetVersionEx() on Windows will always tell you that you are running Windows 8, unless your application has a manifest entry indicating specifically that it is compatible with a higher version.
Microsoft thought there were too many broken version checks in the wild, so decided to hobble the version check function as a fix. I can understand why they did it.
That's just a silly rumor. The only examples I've seen of programs using strings to do version checks are Java ones. The function that returns "Windows 95" for Win4.0.xx could simply have been made to return "Windows Nine" or "Windows\xa09" for Win6.4.xx. "Problem" solved. The rest of the world, who's been using GetVersionEx(), wouldn't even notice it.
IMHO, the most probable reason was marketing (OS X).
No, it's not a silly rumor. It was Java programs (among others), but Microsoft takes backwards compatibility very seriously. Windows 9 builds were tested internally at Microsoft, and the bugs in third-party programs drove the decision to bump the version to 10.
Java would have returned "Windows NT (unknown)" as far as I know. How would programs get a string that said "Windows 9"? What API would be involved? What would they be reading that is text-based, wouldn't lie, [and existed on 9x]?
Silly you, time travel has existed for quite a while by the time python 7000 is released. No import statements are required as everything you need is, and always has been, included from the beginning of the ages.
Somehow all of those libraries are still smaller than my slack desktop app.
Six is called the "Python 2 and 3 Compatibility Library" for a reason. I'm certain that when Python 4 will be released six will be updated so that six.PY3 will include Python 4.
Of course, this opens the opportunity for two other compatibility libraries. "twelve" will be for supporting Python 3 and 4 and "twentyfour" will support Python 2, 3, and 4 at once (I hope nobody will seriously consider a library called "eight").
The only legitimate purpose of using six.PY3 is for managing a module that runs in both Python 2 or Python 3; for that purpose it's almost essential. When Python 4 eventually comes out you may find vestiges of code that still rely on it, even though it hasn't been required for ages. If PY3 is still True, your code will continue to run just fine without changes. If you find it necessary to manage the upgrade from 3 to 4 I'm sure there will be another package available with the required constants.
Someone recently made the argument to me that semantic version has nothing to say about increasing the major version even though there are no backwards compatible breaking changes. I am not sure what the point of increasing the major version would be in this case, and I think it's a bad idea, but I guess that person was correct in the literal sense of how semver is defined.
There could be other reasons for a version number bump other than the python code being written, like changing the limited ABI. In such a hypothetical version, the python code would be valid, but the stuff linking to the python interpreter wouldn't be.
Still wouldn't matter unless you allow for pure evil like 'import twelve as six'
EDIT: wouldn't matter because "six" shouldn't allow itself to be imported on PY4.
I am reminded of the horrible hacks that got encoded in various http user-agent strings so that new versions of browsers would be identified as various other older browsers so that badly written sites would send them the right version of the site for the features that they supported.
As someone that uses Python intermittently it seems like there's still a lot more tutorials, Q&A, and documentation for v2 on the internet than for v3. When searching for info about python it's often difficult to tell if I'm looking at something for v2 or v3, and when I can tell it's usually for v2.
Oh come on. That was a wart that was worth fixing at the same time as other more fundamental breaking changes. I doubt you really think that was all the 2>3 shift was about so why play dumb?
That is not the central and essential change. It's just a style cleanup that they did while they were breaking compatibility anyway.
The big change was string/byte-array typing, which was a mess in Python 2 and was cleaned up in Python 3. That's one of those things that, when changed, inherently breaks old code in ways that, like wizards, are subtle and quick to anger.
Also changing lots of sequence functions like range() to return iterators instead of lists, but those are mostly pure performance wins that don't break compatibility except for some very specific use cases.
The big change was string/byte-array typing, which was a mess in Python 2 and was cleaned up in Python 3.
And made worse in some cases (e.g. http://legacy.python.org/dev/peps/pep-0461/). Even aside from that, I would argue that the benefits of cleaning up Unicode didn't come close to the cost of breaking everyone's code and fragmenting the language for 7+ years.
Only central to the pedants who wanted to "clean it up", and not central to the user base which, as anybody can see, is now cleaved into two warring factions, a result which is far worse than any of the marginal "improvements" can compensate for.
much more likely: you'll finally find the motivation to upgrade your code, not to Python 3 which is 5% better than 2 and 50% more of a pain-in-the-butt, but because there are a multitude of new, faster, parallel-aware languages that are orders of magnitude better, and already make 3.x look like a dinosaur. Move from one dinosaur to a marginally better-but-fussier dinosaur? Doubt it.
There were faster languages (and probably more 'parallel-aware' languages - it's not an area I'm very knowledgeable about) before Python but that wasn't the reason it took off. It's fairly unlikely to be the reason it dies off either.
Python remains one of the most humane languages out there and that's a quality that is much more intangible and hard to replicate.
> We don't really know yet what Python 4 will look like, but we can be pretty sure that the transition from Python 3 to Python 4 will be a lot smoother
Doesn't compute.
You can't say you don't know anything about Python4 and immediately follow up with suggestions on how to program for it.
And if you really want to be consistent, at least:
if (python2):
// python 2
else if (python3):
// python 3
else:
raise "I have no idea what I'm doing"
At any rate, given the time lapse between Python releases and how catastrophic version migrations have been so far, it's safe to say that by the time Python 4 comes out (if ever), we will all have long retired from development.
My understanding is that the consensus is that Python 3 was the last time backwards incompatible changes would be made to the language. The author's point is that this makes Python 2 a special case, so you should make the default behaviour the Python 3 behaviour.
It's worse than that. If python 4 is not 100% backwards compatible with python 3, there's no reason to think the problems will be where python 3 is different from python 2. In fact, they will almost certainly be someplace else.
But long before we switch to python 4, we should stop trying to be backwards compatible with python 2.
Give a specific example of something that should have been done differently. It's hard to know which angle you're coming from with a throwaway comment like this.
Reminds me of when Linus tagged Linux 3.0 and it broke a bunch of peoples code due to their bad version checks. Linux 2.x had been going for about 15 years.
When FreeBSD 9 was released, and the development tree thus became FreeBSD 10, a lot of applications broke. GNU autotools considered a FreeBSD version number starting with 1 as FreeBSD 1.
Historical note: FreeBSD1 was rebased after the AT&T lawsuit on top of the unencumbered Berkeley release as FreeBSD2. To run FreeBSD1, you probably still need an AT&T UNIX license.
I was listening to a developer podcast and one of the hosts (Jeff Roberts?) had the right idea about version checks...
Never allow developers to read the version number. Instead have a function where they pass in the version number and get a boolean about whether or not it's supported.
It's really the only way to avoid code problems like this.
Version checks are also the reason why we have Windows 10 and not Windows 9 because people checked whether the OS version started with "Windows 9" (for Windows 95 and Windows 98).
The source to that information (as far as I can tell) is a Reddit post claiming to be from a Microsoft developer. I've worked with programmers dumb enough to write such a version check, so I totally believe this might be true, but I'd love an official source.
It's cute, because the dedication to backwards compatibility is so uniquely Microsoftian: "We're going to create this API that idiots will inevitably abuse or misuse. Then, in the next version, after all the idiots have abused or misused the API, we're going to deliberately return wrong results from it so that the idiots' applications don't all break." It's really baked into their DNA, all the way back to the early days of Windows where they replicated all those DOS bugs so buggy games that took advantage of them would still function on Windows.
Whether or not it's true, it's certainly not irrelevant. Application manifests only apply to applications. If an application aware of W10 loads a third-party plugin that isn't, the plugin will still get the real version.
This is a very real scenario when you consider the application is explorer.exe and the plugin is any software that installs custom context menu actions.
But the above isn't looking at (faked) version information / GetVersion, but the name of the operating system, which is not faked in any call that I know.
As someone who has had to pressure some of the most backwards companies to update their software, it is going to be the most horrible of pains, in the same way Linux 4.0 is right now, to have a pointless major version increment. Lawyers, suits, and investors shit themselves seeing that number go up when previous increments actually meant something, so when it now no longer does, it just makes my life a living hell for years.
I just wish software would take versions seriously. Please. For my sanity.
Semantic versioning is taking versions seriously. Far more seriously than arbitrary version numbering does, anyway.
Don't get me wrong, I do understand your frustration. But "previous increments actually meant something, so when it now no longer does" is just totally incorrect. Previous increments were an attempt at bundling together a series of unrelated changes into a 'thing'. What that 'thing' is varied wildly between organizations and products. Semantic version increments are breaking changes, pure and simple.
Neither Linux or Python (if 4.0 is non-breaking) are following semver.
For Linux, 2.0 was just SMP support. In defense of Linux, there has never been a backwards breaking major version increment, suits are just paranoid about the number going up randomly. They want it to have meaning, even when it does not.
For Python, 2.0 was not breaking, but 3.0 was. Now that major version has breaking significance in accordance with semver, business interests will treat it like that and make a big deal out of a 4.0, even if it is not breaking. I know this because I deal with clients paranoid about Linux 4.0 all the time, despite insistence Linux never breaks backwards compatibility.
Fundamentally neither project is adhering to semver and are using arbitrary version systems, but if you are going to do that, it would be so much nicer if they would use a two number version - major-patch - rather than having a dead major version that is meaningless. Honestly, in programming languages, Python 3 should have legitimately been a language fork like C++ is to C rather than a version increment (like Obj C is to C) - programming languages are making a bad habit of making breaking changes in a language, and while its understandable that the developers no longer want to maintain the old standard, its deceptive to call the version increment the same language since the semantics change when you make major breaking changes like that.
This is a surprisingly common anti-pattern. See also potential reason why there was no Windows 9 (programs checking for Windows 95/98) and various breakages for commercial programs on Linux when they check the kernel version.
I believe they said they were going to try very hard to not do major backwards compatible breaking changes again.
> My current expectation is that Python 4.0 will merely be "the release that comes after Python 3.9". That's it. No profound changes to the language, no major backwards compatibility breaks - going from Python 3.9 to 4.0 should be as uneventful as going from Python 3.3 to 3.4 (or from 2.6 to 2.7). I even expect the stable Application Binary Interface (as first defined in PEP 384) to be preserved across the boundary.
Semver isn't all that OLD; it came out in 2009, I think? (The SemVer site very helpfully doesn't have any dates on it.) Python, meanwhile, came out in 1991. Not having precognition made it difficult for Python to adopt SemVer, and now that they have versioning practices in place there needs to be more than "I like SemVer" as a compelling argument for them to change. Especially since there are reasonable people who have reasonable disagreements with how SemVer works.
I have nothing to back this up other than my increasingly unreliable memory, but the semantics of SemVer goes back further than 2009. Maybe it wasn't formally written out, but as far back as the 90s that XX.YY.zz could be translated as XX == major changes, breaking changes for APIs, reworked UI for end-user apps. YY == some new functionality, no breaking/major changes. zz == bug fixes.
It probably goes back further than that, and it was probably one of those "everybody knows..." kind of things, but it definitely didn't start to be a widely-known definition a measly seven years ago.
There were a lot of projects informally using what semver defined, but there were also a lot of other popular versioning schemes. Odd minor = unstable version, even minor = stable version used to be pretty popular and is still used by a few projects.
The main thing that helped make SemVer the default assumption was package managers that baked it into the dependency resolution, as until then a project's versioning scheme really didn't matter very much to the users of the project as long as it wasn't completely incomprehensible.
Well, baking it into dependency resolution is a response to the fact that figuring out if there were breaking changes in any given update becomes intractable as your dependency tree/graph gets large (and multi-levelled), when each dependency uses it's own versioning scheme, no matter how comprehensible they are individually.
The argument for semver is obviously "you should be able to tell if there are breaking changes between two versions from the version numbers", not "I like semver". You may or may not be persuaded by it, but that's the point of it.
There's code even in the stdlib which gets the major version by doing strversion[:3] , so it would see 3.10 as 3.1. That could be fixed, but who knows where else that assumption has been made.
There's also code that's going to break `if sys.version_info[0] is not in (2, 3)`, as the article points out -- so bugs are going to need to be fixed either way.
Please don't. From the site guidelines: When disagreeing, please reply to the argument instead of calling names. E.g. "That is idiotic; 1 + 1 is 2, not 3" can be shortened to "1 + 1 is 2, not 3."
He might have been just using that as a rough number for example purposes. Python does use semver loosely (effbot.org/pyfaq/how-does-the-python-version-numbering-schemae-work.htm).
I expect there probably will be at least some breaking changes in 4.0 or at least major new additions to warrant the major version bump, but I think they want to avoid anything that makes migrating code/libraries anything more than trivial for the majority of users. For 2->3 stuff like print as a function was straightforward, but other stuff like lazy range() or the Unicode strings would actually require people to make significant changes, which stagnated migration.
From Guido: he expects "Python 4.0 will merely be "the release that comes after Python 3.9". That's it. No profound changes to the language, no major backwards compatibility breaks"
Formally, no, but Guido expressed regret that Python 3 broke backwards compatibility, and made intentions of trying to minimize backwards incompatibility for Python 4.
I don't have any links but I know there have been statements by core devs that, when/if there is another major version of python being developed, there will be an upgrade path to make the 3->4 transition much better than the 2->3 transition.
Yeah, they pretty much botched the 2->3 transition. I would love to see a 4 that included a viable 2->4 transition with semantic versioning until then. But Guido&Co are going to do whatever the hell they feel like doing, community be damned. Py2.7 will be forked and going strong long after 2020. Actually 2020 will probably be a Python renaissance when the cruft, incompatibilities, gil, no jit, etc can finally be addressed without the Guido mafia. 2.8 will be what 3 should have been, using deprecation for dated syntax and gradual introduction of new features. Python is open source. There will be a 2.8 regardless of whether Guido is involved.
couldn't agree more. Yet all the evidence is that they're still using 3.x as their personal little hobby playground. Exhibit A: type annotations. Just because others are doing it. Nobody is asking for this. Even the PEP took ages to approve because even the yes-men had their doubts. Exhibit B: re-invent green threads. There are 15 solutions already.
Well Python doesn't use semantic versioning, but if it did, there would probably be no Python 4.0. It will just be Python 3.15, 3.16, ..., 3.99, 3.100, ...
> My current expectation is that Python 4.0 will merely be "the release that comes after Python 3.9". That's it.
What? If that's the idea, don't be stupid and just call it Python 3.10 then.
Otherwise, won't we risk a completely unnecessary major versioning problem as outlined in this very article??
Sometimes it feels like the Python team wants to change the major version number only to teach the development community a lesson about coding libraries right, not because they have to. This kind of masochistic idea of deciding version numbers, if it's there, needs to go since this lesson will never be learnt by each and everyone due to the immense size of the community. And if there is a support issue in some libraries, the ripple effect can and will affect other projects as well.
See previous HN discussion about YouTube's browser-version sniffing breaking video playback on Firefox because the sniffer was checking for version 43 and version 44 was released...
Is there a reason why any future syntax changes cannot be handled using transpilers in the same way it's worked for the JavaScript community? Such transpilers do exist for Python, but they never really saw much use, is it because 3to2 came along too late, and for a long time we only had the option of 2to3?
ie once future syntax develops, start using it immediately using a transpiler, and have builds that target as many versions as you care to support.
Python 4, really? I wonder how that will work out. Currently, we have to maintain at least 2 incompatible Python ecosystems on a box. With Python 4 it will be at least 3 to maintain if nothing changes. That's not something I'm looking forward to.
I don't get it. When Py4 comes in sight they'll fix it probably so `six.PY3` is only True when using a Python3 interpreter and I guess they'll introduce a viariable `six.PY4`.
That's the point...if the code says "If Py3, do (modern code) else do (old code)", then when/if py4 comes out, and six.PY3 is False, you end up running (old code).
Obviously you don't know if (modern code) is Py4 compatible, since we don't know what py4 is, but while the py3 code MIGHT be runnable under py4, the py2 code is ALMOST CERTAINLY not going to run under py4.
So instead, make the check for PY2 code:
If Py2 do (old code), else do (modern code).
That MIGHT break under Py4, if modern code isn't future code, but also MIGHT work, whereas the other version WOULD break under Py4.
Same story if you're using sys.version[] rather than six.
Guido has stated to not compare semver in the past.[0]
Will there be a 3.10 or go to 4.0 after 3.9, per one of his core developers?[1] It's hard to tell with Python's leadership (no intentional mockery of the term leadership).
My guess is that they'll indeed push onwards to Python4 as soon as possible. This being another attempt to make Python2 look as old and crufty as possible.
"You're still on Python2? Wow, I'm on 4!". That's the type of political and psychological game the Python core dev team has been playing since 2008 with 3's release. Right alongside the 2020 EOL, another political move. Even though Python 2.7.'10' was never supposed to exist but they went back on that.
This because Python3 is mere technical churn, it is not true technical innovation.
The issue here is really one with the Python core development team. They have also adopted every niche feature into Python3 by whoever came along to ask for it.[2] This was done for the same reasons as the relative rush to rebrand the failed 3.x branch as 4. An attempt to stir up any hype possible for 3.0+.
They got so much wrong with Python3. Feature soup, unicode, and performance losses over 2. Unicode-by-default is the big deal and they didn't even get that right. They simply remapped unicode to str. Which for such a big breaking change, should've been UTF8 alongside other new languages such as Go.[3] But it's worse than that, Python3's feature soup continues in 3.6 there will likely be a 4th string formatting option[4] among throwing everything they can against the wall to see what sticks (while bloating the supposedly simple, "beginners" language).
While Python2 has been riding high in popularity[5], it has absolutely nothing to do with Python3. It's in spite of it.
There's good reason the core dev team "extended support" for 2.7. It's because they really did create a new, much less successful language and would've lost complete control of Python had they not done it.
Python3 is a language that looks mostly like Python, but is Python in name-only. Worse of all, it doesn't stand on it's own two feet with technical merits. I would personally recommend sticking with 2 until 3 ever makes sense, or finding something else to use like Swift or Go.
Unlike a web browser or another piece of software, the "latest version" of a programming language is not always in the end-user's best interests.
> They have also adopted every niche feature into Python3 by whoever came along to ask for it.
You link to async/await as an example? You realize that's a huge deal and is an awesome feature right? It was something sorely missing, but replicated well with generators (thanks to Python being awesome) since Twisted and Python 2.4. Now is exactly the time to ratify it into the language. His complaints about concurrent programming are senseless as async/await are single threaded and avoid most of the concurrency issues you would typically run into when using threads. They also look a hell of a lot nicer and explicit than 'yield from x'.
That whole link[1] is garbage, I don't have enough space to comment on the many absurd statements it contains, but FYI the scientific community in Python is huge and they have been begging for a matrix operator.
You sound like you have a large Python 2 codebase that you don't have the time or resources to upgrade. That sucks. Don't channel that hate into Python 3 though. Start your new projects in it and have a play, you will like it.
Edit: That link is like reading the republican far-right news about how Obama is a Muslim sleeper agent. One of his complaints is that "The docs are broken on Windows and incomplete" when he's viewing them using an IE6 frame inside a Windows help file - it even tells him his browser is 'ancient', and he still complains some non-important JS is broken? Oh god. Or how getting rid of .pyo files is a terrible thing, or how type annotations will eventually destroy all that is holy about dynamic typing....
No, I don't have any significant Python2 codebase. I'm making my own judgement calls off the situation and facts as I see them. I wouldn't build any project in Python3 today, because the prod-ready PyPy option isn't there which adds CPU performance as a Python feature and removes the GIL.
Just because you agree with part of my post and arguments doesn't mean you have to downvote. I had the GVR quote about semver to directly responded to and added to the original post, which is more than most comments.
Anytime I post something critical of Python3 it seems to be a big tug-o-war between those who want to shame me and those who want to show approval. I do it because someone has to say this stuff because I believe the silent majority sees it this way and I frankly find the vocal Python3 promoters to be the loudest of the bunch. There's nothing wrong with other viewpoints unless you're wrong. :)
By the way, Mark Lutz is well respected. He has been teaching Python for decades.
> I wouldn't build any project in Python3 today, because the prod-ready PyPy option isn't there which adds CPU performance as a Python feature and removes the GIL.
But... that's a corner area of Python. Not everyone needs GIL-less STM, and arguably if you're using tonnes of threads maybe you're doing it wrong? Perhaps you should try asyncio :)
I mean that reason doesn't even make sense - I'm not using PyPy3 because of the GIL. Great, so uhh what about Django apps? What about small scripts and projects? What about using it for anything other than highly threaded applications that benefit from no GIL?
> Just because you agree with part of my post and arguments doesn't mean you have to downvote
I didn't (and I wouldn't have), I just upvoted after reading "This being another attempt to make Python2 look as old and crufty as possible" - thinking you viewed this in a positive light.
> frankly find the vocal Python3 promoters to be the loudest of the bunch
I see the opposite. I see lots of people angry about a statement being turned into a function, angry at not understanding encoding and angry at the Python developers. People demanding a JIT in cPython, people crying about type annotations, etc. Plus a shedload of FUD.
I'm sorry, your comments reek of someone angry for not very good reasons and I can't work out why. Python 3 is a much much nicer language to work with, it's more consistent and has less WTF's (along with far less UnicodeEncodeErrors). I took the plunge a year ago and won't ever look back, coding in 2.7-8 at work hurts.
I know Mark Lutz is well respected but that doesn't make some of his comments on Python 3 less silly. Anything that has been added to Python 3 has a comment explaining why it sucks, and most of those explanations are senseless. Even things like the statistics module - apparently that sucks because NumPy is better? He implies that should be bundled instead. :/
The matrix operator saves 3+ lines of Numpy code (and is a common operation). This of course sucks because "it's not used by the core language". Oh and it "expands Python's complexity and learning curve needlessly", despite not being used by the core language. Ok Mark.
I understand your frustration, because I've never been able to see eye to eye with Python3 folks either. I'm always searching for a convincing reason why I need to stop using 2 and start using 3 but I have yet to find a reason that makes sense considering what I lose moving from 2.
Example, I completely agree with all of Lutz's comments and can't see how someone could see it another way. I'm trying though because I'd love to be onboard (I'm sure Mark would too)- but I'd be lying to myself currently to turn a blind eye and move to Python3.
On the benefits of Python2 having production-ready PyPy. It's more than GIL free Python. You only discussed that, but the general performance is next-level plus some from CPython3.
>Not everyone needs GIL-less STM,
You don't need anything, until you do. :)
>What about using it for anything other than highly threaded applications that benefit from no GIL?
That's a "niche feature" like building async IO, but it actually matters because Python3 cannot and likely won't have it. When it does, it'll most likely remain 3.2. While Python2 has many ways to achieve async IO.
>Great, so uhh what about Django apps?
What about them? Django is dramatically superior on Python2/PyPy. I use Django on PyPy with gunicorn and nginx and I assure you I have no worries about any CPU bottleneck no matter what I do.
>people crying about type annotations, etc.
Most of the features in Python3 thus far have been gimmicks, and some are downright embarrassing like type annotations.
Python2 is the premier development platform for me. I can use PyPy and I still have the Python3 migration available. Why would I be in any rush when I only lose moving to 3 today. It just doesn't make sense.
I find it amazing folks have been banging down the gates wishing there was no GIL in Python- it's here but Python2 only. Therefore no longer a big deal. Not to mention the pure single threaded CPU performance improvements available to 2. :) That to me reeks of pure desperation.
Frankly, the only possibility of an "upgrade" available from CPython2/PyPy is not Python3. It's Go, Swift etc.
Ruby managed the transition to unicode much better as they delivered 2x performance increase at the same time AND labeled the new version 1.9 instead of two. Much the same problem.
Yes python 2 is OK but it's legacy mode and people will move on. I think one of the selling points of python vs ruby is that its so often OK to just use system python(2) versus ruby where you really need to use something like rbenv. Selling point for ruby is that the community is absolutely obsessed with making good tools to facilitate working with it.
I have already in my mind decided the future is in languages that are designed with parallelism in mind. Another breaking change for that?
No breaking change was required for that. :) The PyPy guys have removed the GIL with existing Python2 code.[0] The CPython core dev team doesn't want to work that hard though- they've just created a lot of needless work for others with their decisions.
You're right though, unless someone takes on the mantle of CPython2, we're looking at being forced to move to 3 or find something else. I personally think '16/'17 will be the year(s) of Swift. With the Perfect server-side Swift framework[1], and more sure to come, it's very intriguing.
I'm a pretty conservative user myself, and dislike churn and feature bloat so I'm also fairly attracted to Go. I'm not suggesting that's Swift by any means. Go promised no breaking changes for a long time so it's a good choice to write long-lived software in (and who knows what will and won't end up being long-lived so we should always assume the latter).
There isn't all that much code written for Python 3 to care about backwards compatibility. IMO Python 4 should be:
- backwards compatible with the latest release of Python 2
- contain all features of Python 3 in some form
I think this will result in a very speedy adoption.
In the future I propose the following numbering scheme: for any N > M, Python N contains all features of Python M and is backwards compatible with Python M if and only if M divides N.
Please elaborate. Which feature of Python 3 would be impossible to implement in Python 2? Note that Python 3 code is not guaranteed to work in Python 4, but you are guaranteed to (relatively) painlessly port it, since all Python 3 features are implemented in Python 4 in some way.
> Amazing! The magical, backwards-incompatible unicode strings backported to Python 2 with one single line.
Except it's not even slightly close to that is it. unicode_literals is something completely different.
How about removing old style classes? Is `class x:` old style or new style in Python 2, in this imaginary interpreter of yours? How about the default object comparison being sane in Python 3. How about the changes to builtins returning iterables over lists? How about the import system being more sane? How about removing backticks? How about actually handling the unicode differences?
I could go on and on, and I hope your answer is not 'well we just need more __future__ imports don't we'.
No, you are confusing "features" and "syntax". Both Python 2 and Python 3 are Turing complete. They have the same expressiveness. It's possible to backwards-compatibly extend Python 2 to achieve feature-parity with Python 3 while preserving Python 2 syntax. Python 4 proposed by me is possible, while Python 6 (which must be backwards-compatible with both 2 and 3) is probably not possible.
> It's possible to backwards-compatibly extend Python 2 to achieve feature-parity with Python 3 while preserving Python 2 syntax.
The syntax between 2 and 3 is essentially the same. A few minor tweaks here and there, but nothing major. Your point is a bit pointless because changes to the language that are not on the syntactical level (i.e unicode/bytes) cause the meaning of the code to change, despite the syntax being the same.
Read the article again. The people in charge of Python have said they will never make the same mistake as they did with 3 again; all future versions will be backwards-compatible.
So every program you write for Python3 will also be compatible with Python4, unless you use the deficient kinds of version-checking that the linked article extols against.
The problem with changing this one in particular is that it actually makes the author look more reasonable. I wonder if this would have nearly as many upvotes with the absurd headline it was actually written with.
The syntax changes introduced in python 3 are easy to fix, and most of them are backwards compatible with python 2.7.
The whole string/byte dichotomy, however, is a major change that I don't think any shim layer could handle correctly without major bugs, short of defining a whole new string-like class.
The shim layer would have to convert all strings from v2 representation every time to the v4 implementation. Slower, but at least v2 could run unchanged. As we all know certain code won't be touched for whatever reason. It could certainly prevent some from deciding to move off to other languages like Go, Elixir, Node.
The idea of using a runtime conditional to target different major versions of a programming language is hilarious. Really, given the Python 3 embarrassment, I'm not confident in the language as a long-term option.
Nice flame bait. Don't see how it matters whether it is decided at runtime or compile-time. Incompatible versions are a fact of life, and nothing particular of Python.
That's not an argument, you could say the exact same thing about braces in other languages. Truth is, it's something that works that really doesn't need to be debated to death like it is.
Well I think they're annoying, but there's not much point in complaining because it's not going to change overnight. Either way syntax is a very superficial aspect about programming languages, more interesting to consider semantics.
I would certainly hope code written today at least _could_ last until python 4. The idea that everything has to be rewritten just because of a language version bump is a flawed thought process IMO.
Python 2 going away in 2020? Yeah right. Python 3 is a dead end. If they rebooted Python 4 to run Python 2, maybe Python 4 would be relevant. As it stands, Python 3 is a total disaster and will never replace 2. Trying to improve unicode handling? Check. Replacing the print statement syntax just because? Ohmygodstupid.
Why even adapt for python 3? Nobody uses that stalinist version of python anyway. Its incredibly bad to have to use ifdefs in a scripting language like that. Code should be written so that it works regardless of version.
This is e.g. how the (roughly analogous) split between C and C++ is handled, and it works fine for the most part. No bizarre polyglot code games.
Edit: Just to be clear, C++ is not a superset of C: http://stackoverflow.com/a/1201840/270610