blob: 38c5e72ecc0d39a4fa3d0d9d8b5673da4dd50ee6 [file] [log] [blame] [view]
<!-- mdformat off(templates not supported) -->
{% set rfcid = "RFC-0129" %}
{% include "docs/contribute/governance/rfcs/_common/_rfc_header.md" %}
# {{ rfc.name }}: {{ rfc.title }}
<!-- SET the `rfcid` VAR ABOVE. DO NOT EDIT ANYTHING ELSE ABOVE THIS LINE. -->
<!-- mdformat on -->
<!-- This should begin with an H2 element (for example, ## Summary).-->
## Summary
This RFC defines the Python versioning and script requirements for Python
sources within the Fuchsia project.
## Motivation
On the host, not all Python scripts in the tree are executed in a deterministic
manner. Some scripts assume a vendored prebuilt interpreter, others are left to
the system Python. Further, there is no consistency with respect to the version
of Python supported on a per-script basis.
The lack of a deterministic Python environment causes scripts to occasionally
break when environmental changes are made (for example, removing the
/usr/bin/python symlink). This requires the user to either restore the local
environment to the expected state, or make local modifications to the script(s)
in question to be compatible with their environment.
Lastly, as of January 1st, 2020, Python 2.x has been officially
[sunset](https://www.python.org/doc/sunset-python-2/) by
[python.org](http://python.org).
## Design
This design replaces the user's local host environment with a vendored prebuilt
Python interpreter for all Fuchsia Project Python sources. This vendored Python
SHALL be the supported Python language revision.
The current vendored Python version SHALL be kept within a current
[python.org](http://python.org) support window. As the version of Python is
updated, a reasonable transition period will be granted to allow sources to be
made compatible with the new language version.
For Fuchsia Project Python sources, this RFC terminates support for Python
language versions prior to 3.8
* Python 2.7 is henceforth deprecated.
* Backwards compatibility prior to 3.8 is not required.
### Python Sources as Scripts
A Python source file may be invoked as a script by (for example) invoking it on
the command line or supplying it as an argument to an invocation of the Python
interpreter. Scripts are denoted by those runtime environments whose module
[`__name__`](https://docs.python.org/3/library/__main__.html) is set
equal to `"__main__"`.
Executable Python sources are REQUIRED to defer to the vendored Python for
execution. This may be accomplished using different means:
* Through documentation, instruct users to directly invoke the vendored
interpreter supplying the candidate script as an interpreter argument.
* Defer to the vendored Python using a wrapping script or other mechanism which
contains logic sufficient to invoke the interpreter (e.g. using something like
`//scripts/hermetic-env`).
* Assuming a script interpreter source directive (i.e. shebang) which ultimately
causes the script to be executed using the vendored interpreter.
### Python Shebang
Python scripts intended to be directly invoked MUST contain a shebang which
ultimately references the vendored Python. The appropriate shebang line to use
is:
```bash
#!/usr/bin/env fuchsia-vendored-python
```
As the use of a shebang implies a dependency on the host environment, this
shebang is intentionally selected to meet the following hermetic-driven goals:
* Be less-likely to collide with an existing tool, alias, or macro in the user's
host environment.
* Be agnostic to the ordering by which the user added `//.jiri_root/bin` to
their `$PATH`.
### Hermetic Python Environments
Tools such as [venv](https://docs.python.org/3/library/venv.html) and
[vpython](https://chromium.googlesource.com/infra/infra/+/refs/heads/main/doc/users/vpython.md)
serve to assemble an ephemeral and hermetic Python environment. Packages
installed are local to these hermetic environments and do not affect the local
system installation base. The use of hermetic Python tools is permitted with the
stipulation that they are derived from the vendored Python.
#### Python VirtualEnv (venv)
A venv may be instantiated by invoking the vendored Python interpreter with the
args of `-m venv my_venv`. This will assemble a venv in the local directory
`my_venv`. The venv may then be activated and interacted with per typical venv
usage. Installing venv-local packages is permitted.
#### Chromium vpython
The vpython utility is another form of hermetic Python environment manager. It
sources its interpreter from the `$PATH` and assumes the first interpreter whose
`--version` is compatible with the input `vpython.Spec` protobuf. To use
vpython, ensure the vendored Python is configured in the `$PATH` at the time
vpython is invoked. Further, the `vpython.Spec` protobuf must reflect the
current supported language version. Use of vpython wheels is permitted to the
extent they comply with the current supported language version.
## Implementation
All Python sources in Fuchsia Project repositories will be updated to language
version 3.8 by end of Q3 2021. Those sources that are meant to be directly
invoked will have their shebang point to the vendored Python according to the
semantics below.
To facilitate a vendored Python interpreter as the shebang target, the following
will be modified:
1. To `//.jiri_root/bin`, a new `fuchsia-vendored-python` symlink will be added
which links to `//scripts/fuchsia-vendored-python`.
1. To `//scripts`, a new `fuchsia-vendored-python` symlink will be added which
links to `//scripts/fuchsia-vendored-python3.8`.
1. The `fuchsia-vendored-python3.8` script will be added to `//scripts` and be
implemented as:
```bash
#!/bin/bash
hermetic-env python3.8 "$@"
```
Assuming `//.jiri_root/bin` is among the host environment's `PATH` (an assumed
environmental configuration), this will dispatch to the prebuilt interpreter
regardless of what interpreter version(s) are installed on the host.
If `//.jiri_root/bin` is not part of the host environment's path, it will be
necessary to symlink `//.jiri_root/bin/fuchsia-vendored-python` to an
appropriate location (e.g. `~/bin` or similar).
It is expected that new Python versions will occasionally need to be rolled in
via `//integration`. The procedure for doing this is straightforward:
1. Via `//integration`, download and install the prebuilt binaries to their
appropriate locations.
1. Add a new bootstrapping script (e.g. `fuchsia-vendored-python3.9`) to
`//scripts`.
1. Move the `//scripts/fuchsia-vendored-python` symlink to the new
bootstrapping script.
1. (optionally) delete the old bootstrapping script(s).
## Performance
N/A
## Ergonomics
Ergonomically, a deterministic Python language version, and vendored prebuilt
interpreter will much more comfortable of an experience. Users will not be
bogged down by the class of problems caused by relying on their host
environment.
## Backwards Compatibility
Backwards compatibility for Python language version 2.x is no longer required,
and this RFC terminates support for Python language version 2.x. The intent of
this RFC is to eliminate the maintenance burden from Python 2 backwards
compatibility.
## Security considerations
[python.org](http://python.org) has sunset Python 2.x as end-of-life, and ceased
all maintenance, including security fixes. The Fuchsia project no longer
supports Python language version 2.x.
Security is improved by migrating to a maintained Python distribution (version
3.8+) and the more strict typing between byte and character array
types present in the newer Python language versions.
Additionally, having assumed an exact prebuilt version rather than arbitrary
host system installation will reduce maintenance burden and developer
frustration due to version skew and local installation variations.
## Privacy considerations
N/A
## Testing
N/A
## Documentation
The following documentation will need to be updated to reflect the policy here:
* `//docs/development/build/build_system/policies.md`
* `//docs/development/languages/python/python_style.md`
* `//docs/get-started/get_fuchsia_source.md`
## Drawbacks, alternatives, and unknowns
Sun-setting a programming language revision in a backwards-incompatible manner
can be problematic during migration. Not all users will anticipate this change,
and some may not have themselves moved on from Python 2.x.
However, the industry has been aware of the need to migrate from 2.7 to Python
3.x for multiple years now, and this change shouldn't be unexpected.
## Prior art and references
* [Sunsetting Python 2](https://www.python.org/doc/sunset-python-2/)
* [Python VirtualEnv](https://docs.python.org/3/library/venv.html)
* [Chromium vpython](https://chromium.googlesource.com/infra/infra/+/refs/heads/main/doc/users/vpython.md)