PEP 605: A rolling feature release stream for CPython (#1184)

* proposes the regular publication of production-ready beta releases rather than making full X.Y.0 feature releases more common
* PEP 598 is being withdrawn in favour of this proposal
* originally drafted in collaboration with @zooba, @aeros167, and @h-vetinari
This commit is contained in:
Nick Coghlan 2019-10-01 23:03:33 +10:00 committed by GitHub
parent 26d325dbcc
commit 4c797d6e9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 900 additions and 7 deletions

View File

@ -4,7 +4,7 @@ Version: $Revision$
Last-Modified: $Date$
Author: Nick Coghlan <ncoghlan@gmail.com>
Discussions-To: https://discuss.python.org/t/pep-596-python-3-9-release-schedule-doubling-the-release-cadence/1828
Status: Draft
Status: Withdrawn
Type: Informational
Content-Type: text/x-rst
Created: 15-Jun-2019
@ -14,7 +14,7 @@ Python-Version: 3.9
Abstract
========
PEP 596 has proposed reducing the feature delivery latency for the Python
PEP 602 proposes reducing the feature delivery latency for the Python
standard library and CPython reference interpreter by increasing the frequency
of CPython feature releases from every 18-24 months to instead occur every 9-12
months.
@ -26,11 +26,18 @@ changes, and C ABI compatibility breaks) to occur only every other year (2020,
allows the introduction of backwards compatible features in the initial set of
point releases within a given release series.
In the event that this more complex proposal is *not* accepted (and either a
faster release cycle is adopted, or the status quo continues), the PEP aims to
provide useful design input for any other "Long Term Support branch"
proposals that may be put forward in the future (such as the EL Python draft at
[3_]).
PEP Withdrawal
==============
This PEP has been withdrawn in favour of the rolling beta release stream
proposal in PEP 605.
However, the concerns raised in this PEP are likely to apply to any other
"Long Term Support branch" proposals that allow feature backports to improve
the developer experience of supporting such releases (such as the EL Python
draft at [3_]), so the ideas presented here may provide useful design
suggestions for such proposals.
Summary

886
pep-0605.rst Normal file
View File

@ -0,0 +1,886 @@
PEP: 605
Title: A rolling feature release stream for CPython
Version: $Revision$
Last-Modified: $Date$
Author: Steve Dower <steve.dower@python.org>, Nick Coghlan <ncoghlan@gmail.com>
Discussions-To: Link TBD
Status: Draft
Type: Informational
Content-Type: text/x-rst
Created: 20-Sep-2019
Python-Version: 3.9
Post-History: 30-Sep-2019
Abstract
========
Rather than proposing more frequent full CPython releases (as PEP 602 does),
or a policy change to allow backwards compatible feature additions later in a
release series (as PEP 598 does), this PEP instead proposes that we create a
rolling stream of production-ready beta releases by amending CPython's
pre-release management process as follows:
* Feature freeze, ABI freeze, pyc file format freeze, and maintenance branch
creation all correspond with the first release candidate for an X.Y.0 release
* The X.Y.0 release candidate period is extended from 3 weeks to 2 months
* Beta releases from the master git branch would occur every 2 months
whenever there is no X.Y.0 release in the release candidate phase
* Routine alpha releases are removed from the process
* Release managers may still choose to mark particular releases as alpha
releases if they feel such releases are appropriate. If any such alpha
releases are made, it is expected that they would be in place of one of the
scheduled beta releases
* The deprecation policy for interfaces that have been included in an X.Y.0
release or release candidate without being explicitly declared provisional
remains unchanged (refer to PEP 387 for details)
* Each new alpha or beta release may introduce new deprecation warnings for
interfaces that appeared in the previous X.Y release series
* Each new alpha or beta release may change or remove interfaces that either did
not appear in the previous X.Y release series, or emitted a relevant
deprecation warning in that series
* Additions to the `abi3` stable C ABI are permanent once they have been
declared to be part of that ABI in at least one beta release
* All other newly added interfaces that have appeared only in alpha or beta
releases are considered provisional, and may be changed in incompatible ways
without requiring a preceding deprecation warning
As part of this change, the current "not for production use" guidance given for
beta releases would be amended to state "suitable for production use only in
environments with sufficiently robust compatibility testing and operational
monitoring capabilities".
This PEP also proposes that the frequency of X.Y.0 releases be adjusted to
begin each new release series in August every two years (starting in 2021,
around two years after the release of Python 3.8.0).
Motivation
==========
The current CPython pre-release and release management processes were developed
in an era where automated continuous integration and operational monitoring
systems were still relatively immature. Since that time, many organisations
have adopted deployment models that allow them to incorporate new CPython
feature releases without adding substantially more risk than they incur for any
other code change. Newer deployment models, such as lightweight task specific
application containers, also make it easier to combine an application with a
language runtime in a CI pipeline, and then keep them together until the entire
container image is later replaced by an updated one.
In light of those changes in the wider environment, PEP 602 has proposed
reducing the feature delivery latency for the Python standard library and
CPython reference interpreter by increasing the frequency of CPython feature
releases from every 18-24 months to instead occur every 12 months.
Unfortunately, for many organisations, the cost of adopting a new Python release
doesn't automatically scale down with a reduced number of changes in the release,
as the primary costs aren't associated with resolving any discovered issues;
the primary costs are associated with the *search* for issues. This search may
involve manual testing of software systems, human review of written materials,
and other activities where the time required scales with the size of the
existing system, rather than with the number of changes between the versions of
Python.
For third party library developers, costs are primarily associated with the
*number* of distinct Python versions in widespread usage. This currently tends
to be influenced by a combination of which releases are still actively
maintained by python-dev, and which releases are the latest versions offered
by particular redistributors (with the Debian, Ubuntu LTS, and RHEL/CentOS
system Python versions being particularly popular development targets). In
addition to the basic CI cost of testing against more Python versions, having
more variants in widespread use can make it more difficult to determine when a
fault report is an actual error in the project, or an issue in the reporting
user's environment.
PEP 602 proposes that affected organisations and projects simply switch to
adopting every second or third CPython release, rather than attempting to adopt
every release, but that creates its own set of new problems to be resolved, both
practical (e.g. deprecations would need to cover more than one release if we're
expecting users to routinely skip releases) and cultural (e.g. with a larger
number of versions in active use, there is a much higher chance that open source
library maintainers will receive bug reports that only occur on Python versions
that they're not using themselves).
PEP 598 was an initial attempt by one of the authors of this PEP to propose
an alternative scheme to reduce feature delivery latency by adopting a
semantic versioning style policy that allowed for the incremental delivery of
backwards compatible features within a release series, until that series
reached feature complete status. That variant still had the undesirable
consequence of imposing visible changes on end users that are happy enough
with the current release management model.
This PEP takes the view that both PEP 598 and PEP 602 share a common flaw: they
are attempting to satisfy the needs of two quite distinct audiences within the
constraints of a single release model, which results in conflicting design
requirements, and the need for awkward trade-offs between those conflicting
requirements. The proposal in this PEP aims to avoid that flaw by proposing the
creation of two *distinct* production-ready release streams, with the existing
release stream being largely left alone, while the new release stream is
tailored towards the audience that would most benefit from a reduction in
feature delivery latency.
Aims of this Proposal
=====================
The core of the proposal in this PEP is changing the beta phase of the CPython
pre-release process to produce a rolling stream of releases at a regular
cadence, and to ensure those builds offer a sufficient level of stability as
to be suitable for use in appropriately managed production systems.
By adopting this approach, the proposal aims to provide an improved outcome
for almost all Python users and contributors:
* for users of the new release stream, targeting the beta phase allows for even
lower feature delivery latency than the annual cadence proposed in PEP 602;
* for core developers working on new features, increased frequency and adoption
of the beta releases should improve pre-release feedback cycles;
* for users of the established release stream, the increased adoption and
improved feedback cycles during the pre-release period should result in
increased feature maturity at the time of its first X.Y.0 release, as well
as higher levels of ecosystem readiness;
* for Python library maintainers, the rolling stream of beta releases will
hopefully provide more opportunities to identify and resolve design issues
before they make it into a full stable release than is offered by the current
pre-release management process; and
* for developers of alternative Python implementations, the proposed rolling
beta releases provide an additional incentive for extension module authors
to migrate from the full CPython ABI to the Python stable ABI, which may
over time make more of the ecosystem compatible with implementations that
don't fully emulate the CPython C API.
That said, it is acknowledged that not all the outcomes of this proposal will be
beneficial for all members of the wider Python ecosystem:
* for Python library maintainers, both this PEP and PEP 602 would likely
result in user pressure to support the faster release cadence. While this PEP
attempts to mitigate that by marking the faster releases with the "beta" label
and removing the expectation to publish pre-built wheel archives, and PEP 602
attempts to mitigate it by keeping the minimum time between full releases at
12 months, it isn't possible to eliminate this downside completely;
* for third party extension module maintainers, both this PEP and PEP 602 would
likely result in user pressure to start supporting the stable ABI in order to
provide wheel archives that work on the new version as soon as it is
available. Whether that's a net negative or not will depend on how the request
is presented to them (it could be a positive if the request comes in the form
of a courteous contribution to their project from a developer interested in
supporting the rolling beta releases);
* for some users of the established release stream that rely on the
availability of pre-built wheel archives, switching to adopting a new release
every 12 months may be an acceptable rate increase, while moving consistently
to the 24 month end of the historical 18-24 month cadence would be an
undesirable rate reduction relative to the 18 month cycle used for recent
releases. Whether this proposal would be a net negative for these users in the
long run would depend on how many projects migrated over to targeting the
Python stable ABI and hence produced wheel archives that would still be usable
on the rolling beta releases.
Proposal
========
The majority of the proposed changes in this PEP only affect the handling of
pre-release versions. The one change affecting full release versions is a
suggested change to their cadence.
Changes to beta release policy, phase duration, and cadence
-----------------------------------------------------------
This PEP proposes that the policy for beta releases be adjusted to be a
combination of the policies for alpha and beta releases:
* as with current beta releases, the stable BuildBot fleet is expected to be
green prior to preparation and publication of the beta release
* as with current beta releases, the release manager is expected to review
open release blocker issues prior to preparation and publication of the beta
release
* as with current beta releases, any additions to the `abi3` stable C ABI would
be expected to become a permanent part of that ABI unless and until that
stable ABI version is retired completely (Note: there are no current plans
to increment the stable ABI version)
* as with current alpha releases, beta releases would *not* be considered
feature complete for the next X.Y.0 release
* as with current alpha releases, all APIs added since the last CPython feature
release (other than additions to the stable C ABI) would be considered
provisional
* as with current alpha releases, beta releases would be prepared and published
from the master development branch
Rather than being released monthly for a period of a few months while preparing
a new X.Y.0 release, beta releases would instead be consistently published every
two months.
The only time this would not be the case is during the two month release
candidate period for an upcoming X.Y.0 release, as described in the following
section.
Changes to release candidate policy, phase duration, and cadence
----------------------------------------------------------------
Given the proposed changes to the beta release phase, the release candidate
phase would see the following related adjustments:
* Feature freeze, ABI freeze, pyc file format freeze, and maintenance branch
creation would all correspond with the creation of X.Y.0rc1 (currently these
occur across a mixture of X.Y.0b1, the last beta release, and X.Y.0rc1)
* The X.Y.0 release candidate period would be extended from 3 weeks to 2 months
* There would normally be two release candidates issued a month apart, but
additional candidates may be published at the release manager's discretion
* The final X.Y.0 release would occur between 1 and 4 weeks after the final
release candidate (depending if additional release candidates were needed
after the second)
* If the final X.Y.0 release is delayed beyond the August target date, the
subsequent release series is not affected, and will still be scheduled for
August (now slightly less than two years later).
In addition to allowing more time for end user feedback on the release
candidate, this adjusted policy also provides additional time for maintainers
of Python projects to build and publish pre-built wheel archives for the new
stable release series, significantly improving the initial user experience of
the X.Y.0 release.
Removal of routine alpha releases
---------------------------------
Due to the proposed policy changes for beta releases and release candidates,
the traditional CPython alpha release period would no longer serve a clear
purpose, and as such would be skipped, with the first pre-release in a new
series being X.Y.0b1.
However, when it seems appropriate to do so, release managers may choose to
declare that a scheduled beta release will be marked as an alpha release
instead. For example, a release manager may choose to do this when major changes
have been made to the release management tooling, when a particularly
large feature has landed that the release manager views as having a high chance
of introducing unintended side effects, or when a new interface has been added
to the stable C ABI that is only useful when it appears as part of that ABI
(e.g. it may be enabling a new capability in the stable ABI that the full ABI
already supports in a different way), and requires further testing and design
feedback before being locked down in a beta release.
In such cases, the beta serial number would be retained, but the release would
be marked as an alpha release instead, and hence the "not for production use"
caveat would apply.
(The serial number would still be reset to 1 when entering the release
candidate phase - only alpha and beta release would share a serial number
sequence)
Changes to management of the CPython stable C ABI
-------------------------------------------------
The CPython stable ABI [5_] makes the commitment that binary extension modules
built against any particular CPython release will continue to work on future
CPython releases that support the same stable ABI version (this version is
currently ``abi3``).
Under the proposed rolling beta release model, this commitment would be extended
to also apply to the beta releases: once an intentional addition to the ``abi3``
stable ABI for the upcoming Python version has been shipped in a beta release,
then it will not be removed from future releases for as long as the ``abi3``
stable ABI remains supported.
Two main mechanisms will be available for obtaining community feedback on
additions to the stable ABI:
* the preferred mechanism will be to add new APIs to the full CPython API first,
and only promote them to the stable ABI after they have been included in at
least one published beta release and received relevant user feedback
* for APIs where that approach is unavailable for some reason (e.g. some API
additions may serve no useful purpose when the full CPython API is available),
then developers may request that the release manager mark the next release
as an alpha release, and attempt to obtain further feedback that way
As a slight readability and usability improvement, this PEP also proposes the
introduction of aliases for each major stable ABI version::
#define Py_LIMITED_API_3_3 0x03030000
#define Py_LIMITED_API_3_4 0x03040000
#define Py_LIMITED_API_3_5 0x03050000
#define Py_LIMITED_API_3_6 0x03060000
#define Py_LIMITED_API_3_7 0x03070000
#define Py_LIMITED_API_3_8 0x03080000
#define Py_LIMITED_API_3_9 0x03090000
// etc...
These would be used both in extension module code to set the target ABI
version::
#define Py_LIMITED_API Py_LIMITED_API_3_8
And also in the CPython interpreter implementation to check which symbols should
be made available::
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= Py_LIMITED_API_3_9
// A Python 3.9+ addition to the stable ABI would appear here
#endif
The documentation for the rolling beta releases and the stable C ABI would make
it clear that extension modules built against the stable ABI in a later beta
release may not load correctly on earlier alpha or beta releases.
The documentation for alpha releases and the stable C ABI would make it clear
that even extension modules built against the stable ABI in an alpha release
release may not load correctly on any other release.
Changes to management of the CPython version-specific ABI
---------------------------------------------------------
The CPython version-specific ABI has long operated under a policy where binary
compatibility only applies within a release series after the ABI has been
declared frozen, and only source compatibility applies between different
release series.
This policy means that extension modules built against CPython pre-releases
prior to the ABI freeze for that release series may not actually load correctly
on the final release.
This is due to the fact that the extension module may be relying on provisional
or previously deprecated interfaces that were changed or removed in a later
alpha or beta release, or it may be due to public structures used by the
extension module changing size due to the addition of new fields.
Historically, adoption of alpha and beta releases has been low enough that this
hasn't really been a problem in practice. However, this PEP proposes to actively
encourage widespread operational use of beta releases, which makes it desirable
to ensure that users of those releases won't inadvertently publish binary
extension modules that cause segfaults for users running the release candidates
and final releases.
To that end, this PEP proposes amending the extension module ``SOABI`` marker
on non-Windows systems to include a new "p" flag for CPython pre-releases, and
only switch back to omitting that flag once the ABI for that particular X.Y.0
version has been frozen on entry to the release candidate stage.
With this change, alpha and beta releases of 3.9.0 would get an SOABI tag of
``cpython-39p``, while all release candidates and final builds (for both 3.9.0
and later 3.9.x releases) would get an unqualified SOABI tag of ``cpython-39``
Debug builds would still add the "d" to the end of the tag, giving
``cpython-39pd`` for debug builds of pre-releases.
On Windows systems, the suffix for tagged ``pyd`` files in pre-release builds
would include "p" as a pre-release marker immediately after the version number,
giving markers like "cp39p-win_amd64".
A proposed reference implementation for this change is available at [4_] (Note:
at time of writing, that implementation had not yet been tested on Windows).
Example Future Release Schedules
================================
Under this proposal, Python 3.9.0b1 would be released in December 2019, two
months after the Python 3.8.0 baseline feature release in October 2019.
The 3.9.0b2 release would then follow 2 months later in February 2020,
continuing through to 3.9.0b9 in April 2021.
3.9.0rc1 would be published in June 2021, 3.9.0rc2 in July 2021, and then
the full release published as 3.9.0 in August 2021.
The cycle would start over again in October 2021, with the publication
of 3.10.0b1.
Assuming maintenance releases of 3.9.x were also to occur every other month
(offset from the 3.10.0 beta releases), the overall release timeline
would look like:
* 2019-12: 3.9.0b1
* ... beta releases every other month
* 2021-04: 3.9.0b9
* 2021-06: 3.9.0rc1 (feature freeze, ABI freeze, pyc format freeze)
* 2021-07: 3.9.0rc2
* 2021-08: 3.9.0
* 2021-09: 3.9.1, 3.8.x (final 3.8.x binary maintenance release)
* 2021-10: 3.10.0b1
* 2021-11: 3.9.2
* 2021-12: 3.10.0b2
* ... beta and maintenance releases every other month
* 2023-04: 3.10.0b10
* 2023-05: 3.9.11
* 2023-06: 3.10.0rc1 (feature freeze, ABI freeze, pyc format freeze)
* 2023-07: 3.10.0rc2, 3.9.12
* 2023-08: 3.10.0
* 2023-09: 3.10.1, 3.9.13 (final 3.9.x binary maintenance release)
* 2023-10: 3.11.0b1
* ... etc
(The exact schedule of maintenance releases would be up to the release team -
alternating months with the rolling beta releases is the proposed target)
There are always two or three active maintenance branches in this model,
which preserves the status quo in that respect.
Caveats and Limitations
=======================
Actual release dates may be scheduled up to a month earlier or later at
the discretion of the release manager, based on release team availability, and
the timing of other events (e.g. PyCon US, or the annual core developer
sprints). However, as one goal of the proposal is to provide a consistent
release cadence, adjustments should ideally be rare.
Within a release series, the exact frequency of maintenance releases would
still be up to the release manager and the binary release team; this PEP
only proposes an expected cadence for pre-releases and X.Y.0 releases.
However, for the sake of the example timelines, the PEP assumes maintenance
releases every other month, allowing them to alternate months with the rolling
beta releases.
Design Discussion
=================
Why rolling beta releases over simply doing more frequent X.Y.0 releases?
-------------------------------------------------------------------------
For large parts of Python's user base, *availability* of new CPython feature
releases isn't the limiting factor on their adoption of those new releases
(this effect is visible in such metrics as PyPI download metadata).
As such, any proposal based on speeding up full feature releases needs to strike
a balance between meeting the needs of users who would be adopting each release
as it became available, and those that would now be in a position of adopting
every 2nd, 3rd, or 4th release, rather than being able to migrate to almost
every release at some point within its lifecycle.
This proposal aims to approach the problem from a different angle by defining a
*new* production-ready release stream that is more specifically tailored to the
interests of operating environments that are able to consume new releases as
fast as the CPython core team is prepared to produce them.
Why rolling beta releases rather than rolling alpha releases?
----------------------------------------------------------------
The code quality standards upheld by the CPython code review process and
BuildBot fleet make the "beta" label more suitable than the "alpha" label.
The "production ready for some environments, but subject to change with limited
notice" caveat also aligns well with at least some uses of the "beta" term,
whereas "alpha" almost universally indicates "not yet ready for production".
Why rolling beta releases rather than something like "brisk release cadence"?
-----------------------------------------------------------------------------
Using the "b" initial for the proposed rolling releases is a design constraint
imposed by some of the pragmatic aspects of the way CPython version numbers are
published (specifically, alpha releases, beta releases, and release candidates
are reported in some places using the strings "a", "b", and "c" respectively,
while in others they're reported using the hex digits ``0xA``, ``0xB``, and
``0xC``, and we want to preserve that, while also ensuring that the rolling
releases are all sorted after any alpha releases, and before the first release
candidate).
However, there isn't anything forcing us to say that the "b" stands for "beta".
That means that if we wanted to increase adoption amongst folks that were
only being put off by the "beta" label, then it could make sense to rebrand the
rolling beta releases as "brisk" releases, emphasising the rate of release over
the fact that the release includes APIs and ABIs that aren't necessarily stable
yet.
In the near term, limiting adoption to folks that are comfortable with the
"beta" label would be a good thing, as initial adopters are likely to
encounter unexpected consequences at the level of the wider Python ecosystem,
and would need to take an active part in getting those issues resolved.
Moving away from the "beta" naming would then become an option to keep in mind
for the future (with "brisk releases" as a potential alternative name).
Why rolling beta releases rather than alternating between stable and unstable release series?
---------------------------------------------------------------------------------------------
Rather than using the beta period for rolling releases, another option would be
to alternate between traditional stable releases (for 3.8.x, 3.10.x, etc), and
release series that used the new rolling release cadence (for 3.9.x, 3.11.x,
etc).
This idea suffers from the same core problem as PEP 598 and PEP 602: it imposes
changes on end users that are happy with the status quo without offering them
any clear compensating benefit.
It's also affected by one of the main concerns raised against PEP 598: at least
some core developers and end users strongly prefer that no particular semantics
be assigned to the *value* of any of the numbers in a release version. These
community members instead prefer that all the semantic significance be
associated with the *position* within the release number that is changing.
By contrast, the rolling beta release proposal aims to address that concern by
ensuring that the proposed changes in policy all revolve around whether a
particular release is an alpha release, beta release, release candidate, or
final release.
Why not use Calendar Versioning for the rolling release stream?
---------------------------------------------------------------
Steve Dower's initial write-up of this proposal [1_] suggested the use of
calendar versioning for the rolling release stream (so the first rolling
pre-release after Python 3.8.0 would have been Python 2019.12 rather than
3.9.0b1).
Paul Moore pointed out [2_] two major practical problems with that proposal:
* it isn't going to be clear to users of the calendar-based versions where they
stand in relation to the traditionally numbered versions
* it breaks ``Python-Requires`` metadata processing in packaging tools with
no clear way of fixing it reliably (since all calendar versions would appear
as newer than any standard version)
This PEP aims to address both of those problems by using the established beta
version numbers for the rolling releases.
As an example, consider the following question: "Does Python 2021.12 include
all the new features released in Python 3.9.0?". With calendar versioning on
the rolling releases, that's impossible to answer without consulting a release
calendar to see when 3.9.0rc1 was branched off from the rolling release series.
By contrast, the equivalent question for rolling beta releases is
straightforward to answer: "Does Python 3.10.0b2 include all the new features
released in Python 3.9.0?". Just from formulating the question, the answer is
clearly "Yes, unless they were provisional features that got removed".
The beta numbering approach also avoids other questions raised by the calendar
versioning concept, such as how ``sys.version_info``, ``PY_VERSION_HEX``,
``site-packages`` directory naming, and installed Python binary and extension
module naming would work.
How would users of the rolling beta releases detect API changes?
----------------------------------------------------------------
When adding new features, core developers would be strongly encouraged to
support feature detection and graceful fallback to alternative approaches via
mechanisms that don't rely on either ``sys.version_info`` or runtime code object
introspection.
In most cases, a simple ``hasattr`` check on the affected module will serve this
purpose, but when it doesn't, alternative approaches would be considered as part
of the feature addition. Prior art in this area includes the
``pickle.HIGHEST_PROTOCOL`` attribute, the ``hashlib.algorithms_available`` set,
and the various ``os.supports_*`` sets that the ``os`` module already offers for
platform dependent capability detection.
It would also be possible to add features that need to be explicitly enabled
via a ``__future__`` import when first included in the rolling beta releases,
even if that feature flag was subsequently enabled by default before its first
appearance in an X.Y.0 release candidate.
The rationale behind these approaches is that explicit detection/enabling like
this would make it straightforward for users of the rolling beta release stream
to notice when we remove or change provisional features
(e.g. ``from __future__`` imports break on compile if the feature flag no
longer exists), or to safely fall back on previous functionality.
The interpreter's rich attribute lookup machinery means we can also choose to
add warnings for provisional or deprecated imports and attributes that we don't
have any practical way to add for checks against the value of
``sys.version_info``.
Implications for CPython core development
-----------------------------------------
The major change for CPython core development is the need to keep the master
branch more consistently release ready.
While the main requirement for that would be to keep the stable BuildBot fleet
green, there would also be encouragement to keep the development version of
the documentation up to date for the benefit of users of the rolling beta
releases. This will include providing draft What's New entries for changes as
they are implemented, although the initial versions may be relatively sparse,
and then expanded based on feedback from beta release users.
On the specific topic of the stable ABI, most API designs will be able to go
through a process where they're first introduced as part of the full CPython
API (allowing changes between beta releases), and only promoted to the stable
ABI once developers are confident that the interface is genuinely stable.
It's only in rare cases where an API serves no useful purpose outside the
stable ABI that it may make sense to publish an alpha release containing a
provisional stable ABI addition rather than iterating on the design in the
provisional CPython API instead.
Implications for Python library development
-------------------------------------------
By using the "beta" labelling rather than the incremental feature release
numbering proposed in PEP 598, the hope would be that consumers of these
new rolling releases would realise that they're likely going to need to build
their own wheel archives from source, and will generally be more prone to
encountering library compatibility issues when updating to a new release.
Library authors who actually want to support the beta stream would have the
option of testing against the latest beta release in their pre-merge test
matrices (just as they test against the latest maintenance release of previously
published versions), with the CPython nightly builds offered by some CI
providers used solely in an advisory capacity for early detection of potential
compatibility problems.
Having a rolling beta release stream available may also make it more feasible
for more CI providers to offer a "CPython beta release" testing option. At the
moment, this feature is only available from CI providers that are willing and
able to put the necessary time and effort into creating, testing, and publishing
their own builds from the CPython master branch (e.g. [6_]).
Implications for the proposed Scientific Python ecosystem support period
------------------------------------------------------------------------
Based on discussions at SciPy 2019, NEP (NumPy Enhancement Proposal) 29 has
been drafted [3_] to propose a common convention across the Scientific Python
ecosystem for dropping support for older Python versions.
While the exact formulation of that policy is still being discussed, the initial
proposal is very simple: support any Python feature release published within
the last 42 months.
For an 18 month feature release cadence, that works out to always supporting at
least the two most recent feature releases, and then dropping support for all
X.Y.Z releases around 6 months after X.(Y+2).0 is released. This means there is
a 6 month period roughly every other year where the three most recent feature
releases are supported.
For a 12 month release cadence, it would work out to always supporting at
least the three most recent feature releases, and then dropping support for all
X.Y.Z releases around 6 months after X.(Y+3).0 is released. This means that
for half of each year, the four most recent feature releases would be supported.
For a 24 month release cadence, a 42 month support cycle works out to always
supporting at least the most recent feature release, and then dropping support
for all X.Y.Z releases around 18 months after X.(Y+1).0 is released.
This means there is a 6 month period every other year where only one feature
release is supported. Under the proposal in this PEP, that period would
correspond to the final few rolling beta releases and the release candidate
phase for the upcoming stable feature release.
Release cycle alignment for core development sprints
----------------------------------------------------
With the proposal in this PEP, it is expected that the focus of core
development sprints would shift slightly based on the current location
in the two year cycle.
In release years, the timing of PyCon US is suitable for new contributors to
work on bug fixes and smaller features before the first release candidate goes
out, while the Language Summit and core developer discussions can focus on
plans for the next release series.
The post-release core development sprint in release years will provide an
opportunity to incorporate feedback received on the release, either as part of
the next maintenance release (for bug fixes and feedback on provisional APIs),
or as part of the next release series. These sprints would also likely
correspond with the Steering Council elections for the next release cycle.
In non-release years, the focus for both events would just be on the upcoming
maintenance and beta releases. These less intense years would hopefully provide
an opportunity to tackle various process changes and infrastructure upgrades
without impacting the release candidate preparation process.
Release cycle alignment for prominent Linux distributions
---------------------------------------------------------
Some rolling release Linux distributions (e.g. Arch, Gentoo) may be in a
position to consume the new rolling beta releases proposed in this PEP, but it
is expected that most distributions would continue to use the established
releases.
The specific dates for those releases proposed in this PEP are chosen to align
with the feature freeze schedules for the annual October releases of the Ubuntu
and Fedora Linux distributions.
For both Fedora and Ubuntu, it means that the release candidate phase aligns
with the development period for a distro release, which is the ideal time for
them to test a new version and provide feedback on potential regressions and
compatibility concerns.
For Ubuntu, this also means that their April LTS releases will have benefited
from a full short-term release cycle using the new system Python version, while
still having that CPython release be open to upstream bug fixes for most of the
time until the next Ubuntu LTS release.
The one Linux release cycle alignment that is likely to be consistently poor
with the specific proposal in this PEP is with Debian, as that has been released
in the first half of odd-numbered years since 2005 (roughly 12 months offset
from Ubuntu LTS releases).
With the annual release proposal in PEP 602, both Debian and Ubuntu LTS would
consistently get a system Python version that is around 6 months old, but
would also consistently select different Python versions from each other.
With a two year cadence, and CPython releases in the latter half of the year,
they're likely to select the same version as each other, but one of them will
be choosing a CPython release that is more than 18 months behind the latest beta
releases by the time the Linux distribution ships.
If that situation does occur, and is deemed undesirable (but not sufficiently
undesirable for *Debian* to choose to adjust their release timing), then that's
where the additional complexity of the "incremental feature release" proposal
in PEP 598 may prove worthwhile.
(Moving CPython releases to the same half of the year as the Debian and Ubuntu
LTS releases would potentially help mitigate the problem, but also creates
new problems where a slip in the CPython release schedule could directly affect
the release schedule for a Linux distribution, or else result in a distribution
shipping a Python version that is *more* than 18 months old)
Implications for simple deployment environments
-----------------------------------------------
For the purposes of this PEP, a "simple" deployment environment is any use case
where it is straightforward to ensure that all target environments are updated
to a new Python release at the same time (or at least in advance of the rollout
of new higher level application versions), and any pre-release testing that
occurs need only target a single Python micro version.
The simplest such case would be scripting for personal use, where the testing
and target environments are the exact same environment.
Similarly simple environments would be containerised web services, where the
same Python container is used in the CI pipeline as is used on deployment, and
any application that bundles its own Python runtime, rather than relying on a
pre-existing Python deployment on the target system.
For these use cases, there is a straightforward mechanism to minimise the
impact of this PEP: continue using the stable releases, and ignore the rolling
beta releases.
To actually adopt the rolling beta releases in these environments, the main
challenge will be handling the potential for extension module segfaults if the
CPython ABI changes in an incompatible way between beta releases.
If all extension modules in use target the stable ABI, then there's no problem,
and everything will work just as smoothly as it does on the stable releases.
Alternatively, "rebuild and recache all extension modules" could become a
standard activity undertaken as part of updating to each new beta release.
Finally, it would also be reasonable to just not worry about it until something
actually breaks, and then handle it like any other library compatibility issue
found in a new beta release.
Aside from extension module ABI compatibilty, the other main point of additional
complexity when using the rolling beta releases would be "roll-back"
compatibility for independently versioned features, such as pickle and SQLite,
where use of new or provisional features in the beta stream may create files
that are not readable by the stable release. Applications that use these
kinds of features and also require the ability to reliably roll-back to a
previous stable CPython release would, as today, be advised to avoid adopting
pre-release versions.
Implications for complex deployment environments
------------------------------------------------
For the purposes of this PEP, "complex" deployment environments are use cases
which don't meet the "simple deployment" criteria above. They may involve
multiple distinct versions of Python, use of a personalised build of Python,
or "gatekeepers" who are required to approve use of a new version prior to
deployment.
For example, organisations that install Python on their users' machines as part
of a standard operating environment fall into this category, as do those that
provide a standard build environment. Distributions such as conda-forge or
WinPython that provide collections of consistently built and verified packages
are impacted in similar ways.
These organisations tend to either prefer high stability (for example, all of
those who are happily using the system Python in a stable Linux distribution
like Debian, RHEL/CentOS, or Ubuntu LTS as their preferred Python environment)
or fast turnaround (for example, those who regularly contribute toward the
latest CPython pre-releases).
In some cases, both usage models may exist within the same organisation for
different purposes, such as:
* using a stable Python environment for mission critical systems, but allowing
data scientists to use the latest available version for ad hoc data anaylsis
* a hardware manufacturer deploying a stable Python version as part of their
production firmware, but using the latest available version in the development
and execution of their automated integration tests
Under any release model, each new release of Python generates work for these
organisations. This work may involve legal, security or technical reviews of
Python itself, assessment and verification of impactful changes, reapplication
of patches, recompilation and testing of third-party dependencies, and
only then deployment.
Organisations that can take updates quickly should be able to make use of the
more frequent beta releases. While each update will still require similar
investigative work to what they require today, the volume of work required per
release should be reduced as each release will be more similar to the previous
than it is under the present model. One advantage of the proposed
release-every-2-months model is that organisations can choose their own adoption
cadence from adopting every beta release, to adopting one per quarter, or one
every 6 months, or one every year. Beyond that, it would likely make more sense
to continue using the stable releases instead.
For organisations with stricter evaluations or a preference for stability, the
longer release cycle for stable releases will reduce the annual effort required
to update, the longer release candidate period will allow more time to do
internal testing before the X.Y.0 release, and the greater use by others
during the beta period will provide more confidence in the initial releases.
Meanwhile, the organisation can confidently upgrade through maintenance
releases for a longer time without fear of breaking changes.
Acknowledgements
================
Thanks to Łukasz Langa for creating PEP 602 and prompting this discussion of
possible improvements to the CPython release cadence, and to Kyle Stanley
and h-vetinari for constructive feedback on the initial draft of this PEP.
References
==========
.. [1] Steve Dower's initial "Fast and Stable releases" proposal
(https://discuss.python.org/t/pep-602-annual-release-cycle-for-python/2296/20)
.. [2] Paul Moore's initial comments on Steve's proposal
(https://discuss.python.org/t/pep-602-annual-release-cycle-for-python/2296/37)
.. [3] NEP 29 proposes a common policy for dropping support of old Python versions
(https://numpy.org/neps/nep-0029-deprecation_policy.html)
.. [4] Example implementation for a pre-release SOABI flag
(https://github.com/ncoghlan/cpython/pull/3)
.. [5] CPython stable ABI documentation
(https://docs.python.org/3/c-api/stable.html)
.. [6] Travis CI nightly CPython builds
(https://docs.travis-ci.com/user/languages/python/#nightly-build-support)
Copyright
=========
This document is placed in the public domain or under the CC0-1.0-Universal
license, whichever is more permissive.
..
Local Variables:
mode: indented-text
indent-tabs-mode: nil
sentence-end-double-space: t
fill-column: 80
coding: utf-8
End: