Hi,
General advice, not specific to Python: I always recommend against
using inheritance, except in the very simplest cases. It quickly
becomes very hard to understand and change, as it is now with our
Python packages.
But the python project is *actually* building on an earlier python
version's source code, inheriting its legacy (among which is its
source code and its way of building things).
I'm almost always against inheritance (since it's so overused in
industry for things where it makes no sense at all)--but this
here is literally inheritance.
It is very likely that the upstream project does not rewrite
everything every release--so phases that we had for the earlier
version indeed will be necessary for the newer versions, too.
Where it does make a mess, we can always not inherit then.
But in general, using the form "inherit" exactly for what
"inherit" means in real life seems fine?
What are the downsides? What did you experience?
If it's only guix's implementation details that prevent it
from working, let's change those so it's less annoying.
I just tried the following:
(define-public python-3.13
(package
(inherit python-3.12)
(version "3.13.2")
(source
(origin
(inherit (package-source python-3.12))
(sha256 (base32
"0mpbb6hkzdphyin861ywqnxibh5i4gjl5vvxdyralz6ngk2vr16r"))
(patches (search-patches "python-3-deterministic-build-info.patch"
"python-3.13-fix-tests.patch"
"python-3-hurd-configure.patch"))))))
and it indeed downloads 3.12.2 because the URL is gonna be from
python-3.12 because no one changed "uri" in the source code of
python-3.13.
That seems to be entirely expected with lexical binding (since the
"name"
and "version" that were literally in the source code close-by when the
"origin" of python-3.12 was evaluated were bound and are continuing to
be
bound to that--even now.
No one changed that origin's uri--so we get the old one).
It will fail the hash check, though--as it should.
So, works as intended?
------
A weirdness that seems really strange for a repl-based language:
For example if we do decide to drop the older python later,
it should be possible to just (before dropping anything)
repr-print the newest python-next on the guix repl and then
put that output into guix's scm file instead, replacing all
the other pythons.
But I just tested it--it doesn't work. Sigh. Why not?
scheme@(guix-user)> ,use (gnu packages python)
scheme@(guix-user)> python-3.13
$1 = #<package python-next@3.13.2
/home/dannym/src/guix/gnu/packages/python.scm:1053 7f2a237589a0>
I expected the following output:
(package
(name "python-next")
(version "3.13.2")
...)
Even Python has __repr__--and it works fine and does what one
would expect:
from collections import namedtuple
A = namedtuple('A', ['x', 'y', 'z'])
B = namedtuple('B', ['q', 'r', 's'])
a = A(x=5, y=3, z=B(q='hello', r=3.2, s=5+2j))
a
A(x=5, y=3, z=B(q='hello', r=3.2, s=(5+2j)))
I guess it's guix's records that don't do it.
Could they be made to do it (correctly ;) ), either by
reconstructing the macro call from the expansion
automatically using pattern matching (good luck with
that) or by setting the record's __repr__ to a custom
procedure that manually does it, and emitting a
suitable procedure definition from the macro?
P.S.:
$ guix repl
(package-arguments (specification->package "python-next"))
does print the repr (of that part) as it should.