The usual principles of respecting existing conventions and making sure that your changes are in line with the overall product design apply when contributing code to Pyenv.
We are limited to Bash 3.2 features
That's because that's the version shipped with MacOS. (They didn't upgrade past it and switched to Zsh because later versions are covered by GPLv3 which has additional restrictions unacceptable for Apple.)
You can still add performance optimizations etc that take advantage of newer Bash features as long as there is a fallback execution route for Bash 3.
Be extra careful when submitting logic specific for the Apple Silicon platform
As of this writing, Github Actions do not support it and only one team member has the necessary hardware. So we may be unable to test your changes and may have to take your word for it.
We strive to keep commit history one-concern-per-commit to keep it meaningful and easy to follow. If a pull request (PR) addresses a single concern (the typical case), we usually squash commits from it together when merging so its commit history doesn't matter. If however a PR addresses multiple separate concerns, each of them should be presented as a separate commit. Adding multiple new Python releases of the same flavor is okay with either a single or multiple commits.
The easiest way to add support for a new Python release is to copy the script from the previous one and adjust it as necessary. In many cases, just changing version numbers, URLs and hashes is enough. Do pay attention to other "magic numbers" that may be present in a script -- e.g. the set of architectures and OS versions supported by a release -- since those change from time to time, too.
Make sure to also copy any patches for the previous release that still apply to the new one. Typically, a patch no longer applies if it addresses a problem that's already fixed in the new release.
For prereleases, we only create an entry for the latest prerelease in a specific version line. When submitting a newer prerelease, replace the older one.
We accept fixes to issues in specific Python releases that prevent users from using them with Pyenv.
In the default configuration for a Python release, we strive to provide as close to vanilla experience as practical, to maintain the principle of the least surprise. As such, any such fixes:
Generally, version-specific fixes belong in the scripts for the affected releases and/or patches for them -- this guarantees that their effect is limited to only those releases.
Usually, this is the easiest way to backport a fix for a problem that is fixed in a newer release.
patch
or git am
) and commitgit format-patch
We do not provide official support for EOL releases and environments or otherwise provide any kind of extended support for old Python releases.
We do however accept fixes from interested parties that would allow running older, including EOL, releases in environments that they do not officially support. In addition to the above requirements for release-specific fixes,
python-build
that has to be kept there indefinitely)
An installation script is sourced from python-build
. All installation scripts are based on the same logic:
Select the source to download and other variable parameters as needed.
This includes showing an error if the user's environment (OS, architecture) is not supported by the release. Binary releases that only officially support specific distro(s) typically show a warning in other distros instead.
Run one of the install_*
shell functions
install_*
shell functions defined in python-build
install Python from different kinds of sources -- compressed package (binary or source), upstream installation script, VCS checkout. Pick one that's the most appropriate for your packaging.
Each of them accepts a couple of function-specific arguments which are followed by arguments that constitute the build sequence. Each <argument>
in the build sequence corresponds to the install_*_<argument>
function in python-build
. Check what's available and add any functions with logic specific to your flavor if needed.
We strive to keep out of python-build
parts of build logic that are release-specific and/or tend to change abruptly between releases -- e.g. sets of supported architectures and other software's versions. This results in logic duplication between installation scripts -- but since old releases never change once released, this doesn't really add to the maintenance burden. As a rule of thumb, python-build
can host parts of logic that are expected to stay the same for an indefinite amount of time -- for an entire Python flavor or release line.