[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Supporting upstream supported Python versions
From: |
Ricardo Wurmus |
Subject: |
Re: Supporting upstream supported Python versions |
Date: |
Wed, 01 Jun 2022 09:50:39 +0200 |
User-agent: |
mu4e 1.6.10; emacs 28.1 |
Hi,
> From: jgart <jgart@dismail.de>
> To: Guix Devel <guix-devel@gnu.org>
> Subject: Supporting upstream supported Python versions
> Message-ID: <20220517003848.GB18763@gac>
[…]
> What is the opinion on supporting current upstream supported versions
> of python?
>
> The master branch only has 3.9 but I'd like to have substitutes available
> for 3.7, 3.8 and 3.10:
The Guix Past channel now also has python-3.8.
I recently needed to be able to build a profile with Python packages
that were built with Python 3.8, but without replacing each and every
instance of Python (because I don’t want to build librsvg, gtk+, etc).
Here’s the manifest I came up with:
--8<---------------cut here---------------start------------->8---
;;; Manifest to build the latest Python packages with Python 3.8.
(use-modules (guix packages) ; for "package", "package-arguments"...
(guix build-system python)
(guix utils)
(ice-9 match))
;; The list of Python packages (or rather specifications) that we want
;; to build with an older Python.
(define packages
(list "python-numpy"
"python-pytorch"
"python-matplotlib"
"python-scipy"
"python-scikit-learn"
"python-seaborn"))
(define old-python
(specification->package "python@3.8"))
(define old-python-wrapper
;; We use wrap-python3 to create a "python" executable. Python
;; itself only comes with "python3". Python 3.8 is available in the
;; guix-past channel.
((@@ (gnu packages python) wrap-python3) old-python))
(define (python-package? package)
(or (eq? python-build-system
(package-build-system package))
;; Special cases: packages that produce Python modules but don't
;; use the Python build system.
(member (package-name package)
(list "pybind11"))))
;; I'd love to just use modify-inputs here, but this python-wrapper vs
;; python complication forces me to do this manually.
(define (replace-python-in-inputs inputs python-wrapper python)
"Some packages have an explicit Python in the inputs, or use a
separate output of the Python package. We use PYTHON-WRAPPER wherever
the \"python\" executable may be needed and the plain PYTHON package
where we need selected outputs."
(map (match-lambda
(("python" package out) `("python" ,python ,out))
(("python" package) `("python" ,python-wrapper))
(anything anything))
inputs))
(define (package-with-different-python pkg python-wrapper python)
"Return a new package based on PKG that uses PYTHON during the build."
(package/inherit pkg
(arguments
(if (eq? (package-build-system pkg)
python-build-system)
(ensure-keyword-arguments
(package-arguments pkg)
`(#:python ,python-wrapper
#:tests? #false)) ;running tests is slow, so why bother?
(package-arguments pkg)))
(native-inputs
(replace-python-in-inputs (package-native-inputs pkg)
python-wrapper python))
(inputs
(replace-python-in-inputs (package-inputs pkg)
python-wrapper python))
(propagated-inputs
(replace-python-in-inputs (package-propagated-inputs pkg)
python-wrapper python))))
;; This is a recursive package transformer. When given a package
;; "pkg" it checks if it is a Python package by looking at its build
;; system; if that is the case, it will return a package variant that
;; is built with the old Python. It does this recursively, so all
;; dependencies are also modified.
(define use-old-python
(package-mapping
(lambda (pkg)
(if (python-package? pkg)
(let ((modified (package-with-different-python pkg
old-python-wrapper
old-python)))
(match (package-name pkg)
;; This package also needs a newer version of setuptools;
;; Python 3.8 comes with an older version of setuptools.
((or "python-importlib-metadata"
"python-ipython")
(package/inherit modified
(native-inputs
(modify-inputs (package-native-inputs modified)
(prepend (specification->package "python-setuptools"))))))
;; This package expects typing.py to export
;; _SpecialGenericAlias, but this version of Python does
;; not define it.
("python-typing-inspect"
(package/inherit modified
(arguments
(substitute-keyword-arguments (package-arguments modified)
((#:phases phases '%standard-phases)
`(modify-phases ,phases
(add-after 'unpack 'do-not-import-SpecialGenericAlias
(lambda _
(substitute* "typing_inspect.py"
(("_SpecialGenericAlias")
"_GenericAlias"))))))))))
;; The other packages don't need special treatment.
(else modified)))
pkg))
;; Stop recursion when we hit a package that is not considered a
;; Python package. This could be a package that uses Python or
;; Python modules as inputs but does not itself produce a Python
;; module. This is to avoid needlessly rebuilding big things like
;; GTK+.
(negate python-package?)
#:deep? #false))
;; Apply the transformer to the list of packages.
(define python-packages-with-old-python
(map (compose use-old-python specification->package)
packages))
;; Build a manifest from the list of modified packages and the old
;; Python variant itself.
(packages->manifest
(cons old-python
python-packages-with-old-python))
--8<---------------cut here---------------end--------------->8---
--
Ricardo
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: Supporting upstream supported Python versions,
Ricardo Wurmus <=