235 comments

[ 3.3 ms ] story [ 246 ms ] thread
don't be silly - my code will long be replaced when python 4 comes out! it's just a temporary hack/short term solution anyway.
This is what people said to themselves when Python 3 was at the horizon...
That joke went way over your head.
(comment deleted)
(comment deleted)
Has there actually been a statement that python 4 will be backwards compatible to python 3?
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.
> community be damned

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.

Where is GPU? Where is multicore? Where is speed?

Where is the leadership?

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.

http://www.curiousefficiency.org/posts/2014/08/python-4000.h... (which was linked by Guido from his Twitter).

... thats stupid. Semver isn't that complicated, and everyone understands what 3.10 means.
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.
This. Why would you gratuitously change the major version of a language, if there are no back-incompatible changes?

Everyone understands what 3.100 means, too.

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.

> thats stupid

Please don't do this here. 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."

https://news.ycombinator.com/newsguidelines.html

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"

http://www.curiousefficiency.org/posts/2014/08/python-4000.h...

Would be nice if it was simply 3.10 not 4.0, as there's much discussion on that too.

2020! I wonder if I'll have more luck finding the time to upgrade my python 2 scripts in the next four years than I've had in the last four?
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.
> new, faster, parallel-aware languages

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.

What do you think about Julia?
I don't do much (any) numerical stuff so I don't have a terribly informed opinion.

Glancing at the code samples, I don't hate it. It looks rather pleasant.

I can't fathom

Its also for general programming.
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.

Hell, the reason Windows 10 is Windows 10 is because of all the bad version checks looking for "9X"
Ha! Is that true in a documented fashion or just widely suspected? I had never heard that, but it makes perfect sense.
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]?
All my code uses

    from __future__ import __all__
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.

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.
Maybe Python 4 will be properly compatible with Python 2?? Kidding.

But more seriously, probably good advice. Isn't "explicit" one of the Pythonic mantras?

But I'm wondering if any code written today really will survive until "Python 4"?

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.
> Maybe Python 4 will be properly compatible with Python 2??

That'd be wild. What do you call something that is even MORE backward compatible? Going retro.

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").

Unless Python 4 is 100% compatible with Python 3, I hope they wouldn't overload that constant!
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.
Yes, they should make the constant True for both Python 3 and Python 4. If you need to make a finer distinction, use a different package.
Then what was the point of using the PY3 constant?
Maybe readability? "if six.PY3" is easier on the eyes than "if not six.PY2". At least to me. ;)
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.
If it was 100% compatible it wouldn't be Python 4, it'd be Python 3.x.x.
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.
Python does not follow Semantic Versioning as far as I know.
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, ...
just take the emacs approach and drop the leading digit. i'm hoping to live to see an emacs 2.0 release someday...
I feel like I'm taking crazy pills
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.

Because Python's philosophy is that the language designers known the one best way to do everything.
Because it's not just syntax changes.
Same with Babel in JavaScript-land, there's a runtime module for changes that can't be achieved with a syntax transform alone.
> In this case, no code will get executed on Python 4 at all!

Maybe `import six` should trigger ImportError when imported on python 4. Only "eight" or "twelve" should support Python4. :)

(comment deleted)
Surely it's `import twentyfour`?

2 x 3 = 6 => 2 x 3 x 4 = 24

;)

LCM(2,3,4) = 12
LCM would imply that anything supporting python4 would also support python2, which is clearly not the case!
I only imagined a need for spanning pairs of subsequent releases, but sure, why not?
(comment deleted)
(comment deleted)
Often I discover projects that are still in v2, and no words about v3 on their roadmap.

Maybe v4 should learn from JavaScript5 and Visual Basic 3-6.

Support v2 syntax out of the box using a (slow) shim layer if there is no

  "use strict"
in the first line. If that statement is present, don't load the shim layer and support only v4 syntax (faster).

That way old v2 code would still work without any changes.

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.
Your shim layer would have to make assumptions on the encoding of your strings, which can lead to nasty bugs.

And also handle reading from files correctly, or list file names from the os, or anything that communicates outside of the python interpreter.

The main reason why python 3 was created was to manage these complexities, and even then some people[1] say it wasn't done properly.

[1] http://lucumr.pocoo.org/2014/5/12/everything-about-unicode/

Holy shit - people actually write code like this?
(comment deleted)
Yes. Lots of people. You basically have to if you want to support both Python2 and Python3. (And in some spaces, you really do want to support both.)
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.

Those two statements are mutually incompatible. Python3 is a different language with different semantics.

It is possible to work in a subset of python2 and python3 that is syntactically valid under both interpreters but this is not what you are suggesting.

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.

> IMO Python 4 should be:

> - backwards compatible with the latest release of Python 2

> - contain all features of Python 3 in some form

I'm lost for words.

Python 4 should be magic.
Maybe by that time the Python community will have figured out how to make computers (or their owners) fly when you import antigravity!
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.
Pick a Python 3 feature and let us know how you would implement it in Python 2.
Easy.

Feature: print function.

Implementation: from __future__ import print_function

Yes, that magical, backwards-incompatible, print function has been in Python 2 all along!

Feature: unicode strings

Implementation: from __future__ import unicode_literals

Amazing! The magical, backwards-incompatible unicode strings backported to Python 2 with one single line.

I could go on and on.

> 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'.

Python is Turing Complete, so everything you can do in Py3 you can do in Py2, but so you can also implement in Brainfuck.

The question is whether programming in one version vs the other is more enjoyable.

This is just getting tiring. Please just switch to some other language so you and everyone else will be happy.
Or just update to Python 3. It's honestly not that hard.
(comment deleted)
I have a feeling Python 2.7x will be around forever, so I'm not too worried.
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 is exactly the problem. Code that assumes `not six.PY3` means Python 2 will start breaking.
You misread the article (six.PY3 is already like that).
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.

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.
Usually when it's hard to tell that's because it applies to both. The differences between the two are really not that large.
...which begs the question: why are there any differences at all!
Because the differences were important and central to the language.
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.
> Only central to the pedants who wanted to "clean it up"

You're talking about the Python development team, by the way.

Of course they're pedants who want to clean things up. That's why we have Python.

print "HI" # oh my god, the horror!

print("HI") # yaaaah, order out of chaos

Unconvincing.

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.

More like:

  print >>sys.stderr, "Hi",             # horror

  print("Hi", file=sys.stderr, end="")  # order
But the important change was Unicode.
They could always take the Microsoft route: Python 4 will be internally versioned as Python 3.1 to avoid this sort of problem.
"Version: Python 3.1 (Python 4.2)"
"Version: Python 3.1 (Python 4.2) ruby 2.1.6p336 (2015-04-13 revision 50298) [x64-mingw32], like 2.7.8 [GCC 4.8.3] on cygwin"
That's right, LIE to fix the deficiencies of developers!
How about the Sun route? Solaris 2.7 vs. SunOS 5.7
Even more fun..

  SunOS 4.1.4 was retroactively renamed Solaris 1.1.2.
  
  SunOS 5.6 was Solaris 2.6, but
  SunOS 5.7 was Solaris 7.
  
To Sun's eternal credit, they were smart about keeping the internal versioning and the marketing versioning separate.

Even to this day, so far, Oracle hasn't messed with "SunOS".

This should be normal routine -- it is called "defensive programming".
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.
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.
Yep, that change broke CrashPlan's JNI module that handles inotify on Linux because they were checking only the minor version number.

I had to write a shared library to override the call and inject that into the CrashPlan process so it'd be happy. Fun times.

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.

This is apparently also one reason Windows jumped from 8 to 10 -- "Windows 9" would have been read as "Windows 98" (or 95) by some software. :-(
Why don't they just stop changing the syntax? They already ruined print statements. Don't engineers have better things to do?
This has nothing to do with changing the syntax, it's a problem even if Python 4 has the exact same syntax and APIs as Python 3.
This is a joke, right? Obviously we can't write code that will work on python 4.
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.

You can't write code that is guaranteed to work on Python 4, but you definitively can write code that is guaranteed that will not work on Python 4.

That's what this article is about, anyway. Based on the issues with Py3 I'm quite confident that switch from 3 to 4 will be similar as from 1 to 2.