Subject: Re: bug#76027: PyPy is Broken

From: Simon Tournier <[email-masked]>
Date: Mon, 10 Mar 2025 19:08:03 +0100

Hi jgart,

On Mon, 03 Feb 2025 at 09:18, "jgart" via Bug reports for GNU Guix <[email-masked]> wrote:

> ltrace -e getenv pypy -c "import django"
…
> libpypy3.10-c.so->getenv("PYTHONPATH")                                                           = nil

[…]

> If instead I run the following commands I don't get an error response from ltrace:

Not sure the test’s the relevant. :-)
I get this:

--8<---------------cut here---------------start------------->8---
$ guix shell -C python python-django strace ltrace \
       -- ltrace -e getenv python3 -c "import django" 2>&1 \
       | grep PYTHONPATH
libpython3.10.so.1.0->getenv("PYTHONPATH")       = nil
--8<---------------cut here---------------end--------------->8---

Anyway.

> I am thinking that it might not be as trivial as setting the
> native-search-paths in the pypy package record.
>
> I tried already and it didn't resolve the python paths.

Yes, it’s about search paths.

--8<---------------cut here---------------start------------->8---
$ guix shell -C pypy python-django --search-paths
export PATH="/gnu/store/r2419kgd4ajcic5w5mgp1pn93dv1by47-profile/bin${PATH:+:}$PATH"

$ guix shell -C python python-django --search-paths
export PATH="/gnu/store/98fvbjbj3yz7b8hidn2m7hs28wh4fjgk-profile/bin${PATH:+:}$PATH"
export GUIX_PYTHONPATH="/gnu/store/98fvbjbj3yz7b8hidn2m7hs28wh4fjgk-profile/lib/python3.10/site-packages${GUIX_PYTHONPATH:+:}$GUIX_PYTHONPATH"
--8<---------------cut here---------------end--------------->8---

And considering the current implementation, the behaviour you report is
expected: the package pypy does not trigger GUIX_PYTHONPATH search
paths.  For example, this tweak allows to add python-django in the
search paths

--8<---------------cut here---------------start------------->8---
diff --git a/gnu/packages/pypy.scm b/gnu/packages/pypy.scm
index 90986ac096..f142cd1199 100644
--- a/gnu/packages/pypy.scm
+++ b/gnu/packages/pypy.scm
@@ -35,6 +35,7 @@ (define-module (gnu packages pypy)
   #:use-module (gnu packages tls)
   #:use-module (gnu packages xml)
   #:use-module (guix gexp)
+  #:use-module (guix utils)
   #:use-module (guix packages)
   #:use-module (guix download)
   #:use-module (guix build-system gnu))
@@ -194,6 +195,13 @@ (define-public pypy
            tk
            xz
            zlib))
+    (native-search-paths
+     (list (search-path-specification
+            (variable "PYTHONPATH")
+            (files (list (string-append
+                          "lib/python"
+                          (version-major+minor (package-version python))
+                          "/site-packages"))))))
     (home-page "https://www.pypy.org/")
     (synopsis "Python implementation with just-in-time compilation")
     (description "PyPy is a faster, alternative implementation of the Python
--8<---------------cut here---------------end--------------->8---

Then, let run:

--8<---------------cut here---------------start------------->8---
./pre-inst-env guix shell -C pypy python-django \
       -- pypy -c "import django; import this"
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
--8<---------------cut here---------------end--------------->8---

Well, the next step is to rely on GUIX_PYTHONPATH via sitecustomize.py,
IMHO.

Cheers,
simon