<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Tue, 3 Apr 2018 at 07:39 Paul G <<a href="mailto:paul@ganssle.io">paul@ganssle.io</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">> When programs use calendar-based versioning, I'm left with no<br>
> information as to whether it's breaking changes or not. In fact, it<br>
> might as well have no version numbers whatsoever. If I care about<br>
> backward compatibility, I just have to stick with the exact same<br>
> unpatched version that I had before. Not a good thing for a language<br>
> that releases periodic bugfix updates to older versions.<br>
<br>
Well, this is not true. As a general rule, you don't know if anything *you care about* breaks at a given version change anyway, and I've seen plenty of handwringing about what should and should not be considered a breaking change. A major change is basically the "nuclear option", and everything I've seen from core developers is "there will never be another major change on the scale of 2->3". Given that from an optics perspective there's no interest in creating a Python 4 and it's been repeatedly emphasized in this thread that Python doesn't use semantic versioning, I don't see how you can really say that the version number gives you much information at all about what will and will not break.<br></blockquote><div><br></div><div>Paul's point is that he knows e.g. code working in 3.6.0 will work when he upgrades to 3.6.5, and if his code is warning-free  and works with all __future__ statements in 3.6 that it will work fine in 3.7. With CalVer you could make a similar promise if you keep the major version the year of release and then keep our feature/bugfix number promise like we already have, but at that point who cares about the year?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
This thread started in response to a proposal to just have a rolling backwards compatibility window (e.g. no discontinuous major version changes), which is basically ideal for calendar versioning - any time you make a backwards incompatible change, you give X notice period. You can encode X directly into the deprecation warnings (e.g. "This feature will be removed in Python >= 2025"), that way users will know on a *per feature basis* where to pin, even before specific version numbers are announced.<br></blockquote><div><br></div><div>While we have an 18 month schedule for releases, we also can't guarantee we will hit our release window in a specific year, e.g. 3.6 was first released in December but we could have slipped into January. That makes promises for a specific version tied to a year number problematic.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Presumably if major breaking changes ever *do* occur, the mechanism for upgrading Python would be either to create a new program called something else (e.g. the core Python simply *does not break backwards compat*), or a slow rollout with individual feature flags that start out defaulting on (opt in to the new behavior), eventually default to off (opt out of the new behavior), and then are removed after a very long deprecation period.<br></blockquote><div><br></div><div>We already have this with __future__ statements. The transition from 2 to 3 was such a big deal because we changed so much without using __future__ statements. We've already said that going forward we are not skipping that step for any other releases.<br><br></div><div>If we chose to switch to semantic versioning, we would probably make it so that any version that makes a __future__ statement the new default is a major version bump. But then the issue becomes the stdlib. Do we drop everything that was previously deprecated in the stdlib for every major version bump? That might be a bit drastic when e.g. all you did was make old code that used `await` as a variable name raise a SyntaxError. And saying "deprecated for two versions" then becomes messy because you have no idea what that second version will be. And what if you **really** want to get rid of something in the next release? Can a single module dropping a function force a version bump for Python itself?<br><br></div><div>I have not read the other thread, but knowing it's from Lukasz makes me guess he wants to move up the minor number to become the major one in terms of our current semantics so we have a rolling window of support. That would mean that as long as you are warnings-free and run fine with all __future__ statements turned on for version N then N+1 should work for you without modification (sans relying on buggy semantics). That approach would deal with the above issues cleanly while dropping what our current major number semantics which some people view as a fallacy and are getting upset over (I'm personally +0 on this last idea as it's easy to explain to folks and I have been doing Python version explanations a lot over the last several months).<br></div></div></div>