testing python is too hard / cannot use 'python3' / python transition will cause problems
Because we have multiple pythons and we want them to be co-installable, we have packages like:
- python-3.12-base
- python-3.12
- python-3.11-base
- python-3.11
The -base package provides basically everything and the python-3.11 package provides a symlink making 'python3' default to python 3.11 ( /usr/bin/python3 -> python3.11)
When we build packages, melange correctly identifies that a package that installs python files into /usr/lib/python3.12/site-packages/ depends on python-3.12-base. It does not depend on python-3.12 (it never uses that symlink. even the installed scripts have /usr/bin/python3.12).
The pipeline 'python/imports' pipeline takes a 'python' input, but if it is not provided it will use a shell snippet to find the right one (if there is only one installed).
That works well for the imports pipeline.
The problem is that anything that wants to run 'python3' in a test has to have a similar snippet of code.
Consider py3-async-generator.yaml.
It looks like this:
package:
name: py3-async-generator
version: 1.10
epoch: 1
description: Async generators and context managers for Python 3.5+
copyright:
- license: MIT OR Apache-2.0
dependencies:
runtime:
- python-3
...
test:
environment:
contents:
packages:
- python-3
pipeline:
- runs: |
python -c "import async_generator; print(async_generator.__version__)"
Two things to call out there
- It has 'python-3' as a runtime dep. The package built today will have the python-3.12 dep written by melange but will also have
python-3dep. In the future, when python-3.13 exists, python-3.13 will also provide python-3 and will be preferred to python-3.12. So installation of this package would install 2 python versions. Yikes. - It includes
python-3in the test environment in order to get apythonprogram to execute. But similarly to 1, that will install the wrong python in the future, and the test will begin to fail (it works today, but as soon as there is a python-3 package it will fail).
So, how should that test look? Do we have to copy a shell snippet like this:
python=$(m=/usr/bin/python3.*; set +x; set -- $m
[ $# -eq 1 -a -x "$1" ] && echo "$1" && exit 0
echo "found $# matches to $m"; exit 1;)
$python -c '...'
Here is one thought, in py3-pendelum.yaml. Similar to the multi-version building, we use a var and manually have to change that. Things to note:
- right now py3-typing does not provide py3.12-typing , as it just builds a single python version. Note below that this is providing py3.12-pendulum via 'provides'
- The test can directly execute
python${{vars.pyver}}which be changed by an external factor such as availabitly of python 3.13
package:
name: py3-pendulum
version: 3.0.0
epoch: 1
description: Python datetimes made easy
copyright:
- license: MIT
dependencies:
runtime:
- py${{vars.pyver}}-dateutil
- py${{vars.pyver}}-tzdata
- py3-typing
provides:
- py${{vars.pyver}}-pendulum
vars:
pyver: "3.12"
environment:
contents:
packages:
- build-base
- busybox
- ca-certificates-bundle
- py${{vars.pyver}}-maturin-bin
- py${{vars.pyver}}-pip
- py${{vars.pyver}}-wheel
- python-${{vars.pyver}}
- python-${{vars.pyver}}-dev
- rust
- wolfi-base
pipeline:
- uses: git-checkout
with:
repository: https://github.com/sdispater/pendulum
tag: ${{package.version}}
expected-commit: 0fcd10217af0469b3edda072f2b152d5273f3d58
- uses: py/pip-build-install
test:
pipeline:
- uses: python/import
with:
imports: |
import pendulum
- runs: |
# test verifies that timezone data is present.
python${{vars.pyver}} -c '
from pendulum import datetime
tor = datetime(2012, 1, 1, tz="America/Toronto")
van = datetime(2012, 1, 1, tz="America/Vancouver")
assert 3 == van.diff(tor).in_hours()
print("PASS: time zones check out")
'
I'm going to close this. the py/one-python really helps and most things being multi-versioned helps.