From mboxrd@z Thu Jan 1 00:00:00 1970 From: ludo@gnu.org (Ludovic =?UTF-8?Q?Court=C3=A8s?=) Subject: bug#22437: Fixing package-with-python2 Date: Wed, 03 Feb 2016 09:47:15 +0100 Message-ID: <87twlqxjsc.fsf__16062.2113886804$1454489304$gmane$org@gnu.org> References: <87vb68nkyb.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:45056) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aQt6b-0005Om-Jf for bug-guix@gnu.org; Wed, 03 Feb 2016 03:48:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aQt6Y-0005kl-9n for bug-guix@gnu.org; Wed, 03 Feb 2016 03:48:05 -0500 Received: from debbugs.gnu.org ([208.118.235.43]:48858) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aQt6Y-0005kW-6H for bug-guix@gnu.org; Wed, 03 Feb 2016 03:48:02 -0500 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84) (envelope-from ) id 1aQt6X-0007xj-UX for bug-guix@gnu.org; Wed, 03 Feb 2016 03:48:01 -0500 Sender: "Debbugs-submit" Resent-Message-ID: In-Reply-To: <87vb68nkyb.fsf@gnu.org> ("Ludovic \=\?utf-8\?Q\?Court\=C3\=A8s\=22'\?\= \=\?utf-8\?Q\?s\?\= message of "Mon, 01 Feb 2016 23:07:40 +0100") List-Id: Bug reports for GNU Guix List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-guix-bounces+gcggb-bug-guix=m.gmane.org@gnu.org Sender: bug-guix-bounces+gcggb-bug-guix=m.gmane.org@gnu.org To: guix-devel , 22437@debbugs.gnu.org --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable ludo@gnu.org (Ludovic Court=C3=A8s) skribis: > An idea I haven=E2=80=99t taken the time to test yet would be to use > =E2=80=98properties=E2=80=99: > > (define python-foobar ;with Python 3 > (package > (name "foobar") > ;; Specify which Python 2 variant to use. > (properties `((python2-variant . ,(delay python2-foobar)))))) > > (define python2-foobar > (package (inherit python-foobar) > ;; =E2=80=A6 stuff beyond the mechanical python 2=E2=86=923 switch= =E2=80=A6 > )) > > =E2=80=98package-with-python2=E2=80=99 would honor this =E2=80=98python2-= variant=E2=80=99 property. Here=E2=80=99s a first stab at this. As an example, I modified =E2=80=98python-matplotlib=E2=80=99 to use that f= eature, so we can test that =E2=80=98python2-scipy=E2=80=99 is using the right =E2=80=98p= ython2-matplotlib=E2=80=99: --8<---------------cut here---------------start------------->8--- $ ./pre-inst-env guix build python2-matplotlib -d 2>/dev/null /gnu/store/07zr2pqg61b742czb2aqyisml2i90r4a-python2-matplotlib-1.4.3.drv $ ./pre-inst-env guix build python2-scipy -d 2>/dev/null /gnu/store/8yhxdbyjvx2xwynpqqcrj9ilksd2pb01-python2-scipy-0.16.0.drv $ guix gc --references /gnu/store/8yhxdbyjvx2xwynpqqcrj9ilksd2pb01-python2-= scipy-0.16.0.drv | grep python2-matplotlib /gnu/store/07zr2pqg61b742czb2aqyisml2i90r4a-python2-matplotlib-1.4.3.drv --8<---------------cut here---------------end--------------->8--- This will trigger rebuilds (but with an identical result) because in manually-written variants we would use =E2=80=9Cpython2-foo=E2=80=9D as the= label of inputs, whereas the automatic transformations keeps the original =E2=80=9Cpython-foo=E2=80=9D label. What do people think? I can apply this patch of the approach sounds good to you. I think we should probably do one commit per rewrite for clarity. We should probably start with the lowest level, like python2-pycairo and python2-pygobject and even python itself, because if we fix them then some of the higher-level stuff won=E2=80=99t even need their own =E2=80=98python2-variant=E2=80=99 property. For instance, if python, pycai= ro, and pygobject have their =E2=80=98python2-variant=E2=80=99 set, then we no long= er need this: --8<---------------cut here---------------start------------->8--- (define-public python2-matplotlib (let ((matplotlib (package-with-python2 %python-matplotlib))) (package (inherit matplotlib) ;; Make sure to use special packages for Python 2 instead ;; of those automatically rewritten by package-with-python2. (propagated-inputs `(("python2-pycairo" ,python2-pycairo) ("python2-pygobject-2" ,python2-pygobject-2) ("python2-tkinter" ,python-2 "tk") ,@(fold alist-delete (package-propagated-inputs matplotlib) '("python-pycairo" "python-pygobject" "python-tkinter"))))= ))) --8<---------------cut here---------------end--------------->8--- =E2=80=A6 and as a consequence, we don=E2=80=99t need a =E2=80=98python2-va= riant=E2=80=99 in =E2=80=98python-matplotlib=E2=80=99. Does that make sense? Any takers? (This can be done incrementally.) Thanks, Ludo=E2=80=99. --=-=-= Content-Type: text/x-patch Content-Disposition: inline diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm index 48f65b5..b43f539 100644 --- a/gnu/packages/python.scm +++ b/gnu/packages/python.scm @@ -2913,7 +2913,7 @@ is designed to have a low barrier to entry.") (define-public python2-rq (package-with-python2 python-rq)) -(define-public python-cython +(define %python-cython (package (name "python-cython") (version "0.23.4") @@ -2946,8 +2946,13 @@ programming language and the extended Cython programming language. It makes writing C extensions for Python as easy as Python itself.") (license asl2.0))) +(define-public python-cython + (package + (inherit %python-cython) + (properties `((python2-variant . ,(delay python2-cython)))))) + (define-public python2-cython - (package (inherit (package-with-python2 python-cython)) + (package (inherit (package-with-python2 %python-cython)) (name "python2-cython") (inputs `(("python-2" ,python-2))))) ; this is not automatically changed @@ -3117,13 +3122,7 @@ association studies (GWAS) on extremely large data sets.") ,phases))))))) (define-public python2-numpy - (let ((numpy (package-with-python2 python-numpy))) - (package (inherit numpy) - ;; Make sure we use exactly PYTHON2-MATPLOTLIB, which is customized for - ;; Python 2. - (inputs `(("python2-matplotlib" ,python2-matplotlib) - ,@(alist-delete "python-matplotlib" - (package-inputs numpy))))))) + (package-with-python2 python-numpy)) (define-public python-pyparsing (package @@ -3247,7 +3246,7 @@ transcendental functions).") ,@(alist-delete "python-numpy" (package-propagated-inputs numexpr))))))) -(define-public python-matplotlib +(define %python-matplotlib (package (name "python-matplotlib") (version "1.4.3") @@ -3323,7 +3322,7 @@ transcendental functions).") (lambda (port) (format port "[directories]~% basedirlist = ~a,~a~% -[rc_options]~% + [rc_options]~% backend = TkAgg~%" (assoc-ref inputs "tcl") (assoc-ref inputs "tk")))))) @@ -3372,8 +3371,13 @@ ipython shell, web application servers, and six graphical user interface toolkits.") (license psfl))) +(define-public python-matplotlib + (package + (inherit %python-matplotlib) + (properties `((python2-variant . ,(delay python2-matplotlib)))))) + (define-public python2-matplotlib - (let ((matplotlib (package-with-python2 python-matplotlib))) + (let ((matplotlib (package-with-python2 %python-matplotlib))) (package (inherit matplotlib) ;; Make sure to use special packages for Python 2 instead ;; of those automatically rewritten by package-with-python2. @@ -3549,15 +3553,7 @@ routines such as routines for numerical integration and optimization.") (license bsd-3))) (define-public python2-scipy - (let ((scipy (package-with-python2 python-scipy))) - (package (inherit scipy) - ;; Use packages customized for python-2. - (propagated-inputs - `(("python2-matplotlib" ,python2-matplotlib) - ("python2-numpy" ,python2-numpy) - ,@(alist-delete "python-matplotlib" - (alist-delete "python-numpy" - (package-propagated-inputs scipy)))))))) + (package-with-python2 python-scipy)) (define-public python-sqlalchemy (package diff --git a/guix/build-system/python.scm b/guix/build-system/python.scm index 9a80bd6..74ec854 100644 --- a/guix/build-system/python.scm +++ b/guix/build-system/python.scm @@ -65,12 +65,19 @@ extension, such as '.tar.gz'." (let ((python (resolve-interface '(gnu packages python)))) (module-ref python 'python-2))) -(define (package-with-explicit-python python old-prefix new-prefix) +(define* (package-with-explicit-python python old-prefix new-prefix + #:key variant-property) "Return a procedure of one argument, P. The procedure creates a package with the same fields as P, which is assumed to use PYTHON-BUILD-SYSTEM, such that it is compiled with PYTHON instead. The inputs are changed recursively accordingly. If the name of P starts with OLD-PREFIX, this is replaced by -NEW-PREFIX; otherwise, NEW-PREFIX is prepended to the name." +NEW-PREFIX; otherwise, NEW-PREFIX is prepended to the name. + +When VARIANT-PROPERTY is present, it is used as a key to search for +pre-defined variants of this transformation recorded in the 'properties' field +of packages. The property value must be the promise of a package. This is a +convenient way for package writers to force the transformation to use +pre-defined variants." (define transform ;; Memoize the transformations. Failing to do that, we would build a huge ;; object graph with lots of duplicates, which in turns prevents us from @@ -90,26 +97,34 @@ NEW-PREFIX; otherwise, NEW-PREFIX is prepended to the name." ((name content . rest) (append (list name (rewrite-if-package content)) rest))))) - (if (eq? (package-build-system p) python-build-system) - (package - (inherit p) - (location (package-location p)) - (name (let ((name (package-name p))) - (string-append new-prefix - (if (string-prefix? old-prefix name) - (substring name - (string-length old-prefix)) - name)))) - (arguments - (let ((python (if (promise? python) - (force python) - python))) - (ensure-keyword-arguments (package-arguments p) - `(#:python ,python)))) - (inputs (map rewrite (package-inputs p))) - (propagated-inputs (map rewrite (package-propagated-inputs p))) - (native-inputs (map rewrite (package-native-inputs p)))) - p))))) + (cond + ;; If VARIANT-PROPERTY is present, use that. + ((and variant-property + (assoc-ref (package-properties p) variant-property)) + => force) + + ;; Otherwise build the new package object graph. + ((eq? (package-build-system p) python-build-system) + (package + (inherit p) + (location (package-location p)) + (name (let ((name (package-name p))) + (string-append new-prefix + (if (string-prefix? old-prefix name) + (substring name + (string-length old-prefix)) + name)))) + (arguments + (let ((python (if (promise? python) + (force python) + python))) + (ensure-keyword-arguments (package-arguments p) + `(#:python ,python)))) + (inputs (map rewrite (package-inputs p))) + (propagated-inputs (map rewrite (package-propagated-inputs p))) + (native-inputs (map rewrite (package-native-inputs p))))) + (else + p)))))) transform) @@ -118,7 +133,8 @@ NEW-PREFIX; otherwise, NEW-PREFIX is prepended to the name." ;; of packages is accessed to avoid a circular dependency when evaluating ;; the top-level of (gnu packages python). (package-with-explicit-python (delay (default-python2)) - "python-" "python2-")) + "python-" "python2-" + #:variant-property 'python2-variant)) (define* (lower name #:key source inputs native-inputs outputs system target --=-=-=--