* Re: PYTHONPATH woes
2018-02-24 10:44 ` Hartmut Goebel
@ 2018-02-24 10:49 ` Hartmut Goebel
2018-02-27 11:43 ` PYTHONPATH issue analysis - part 1 (was: PYTHONPATH woes) Hartmut Goebel
` (2 subsequent siblings)
3 siblings, 0 replies; 49+ messages in thread
From: Hartmut Goebel @ 2018-02-24 10:49 UTC (permalink / raw)
To: Pjotr Prins; +Cc: guix-devel
Am 24.02.2018 um 11:44 schrieb Hartmut Goebel:
> you may read all of the mail as the techniques are a bit complex.
No offense meant, please ignore the sentence. When I started writing the
mail I though my explanation would be much more complex.
--
Regards
Hartmut Goebel
| Hartmut Goebel | h.goebel@crazy-compilers.com |
| www.crazy-compilers.com | compilers which you thought are impossible |
^ permalink raw reply [flat|nested] 49+ messages in thread
* PYTHONPATH issue analysis - part 1 (was: PYTHONPATH woes)
2018-02-24 10:44 ` Hartmut Goebel
2018-02-24 10:49 ` Hartmut Goebel
@ 2018-02-27 11:43 ` Hartmut Goebel
2018-03-13 21:54 ` PYTHONPATH issue analysis - part 1 Hartmut Goebel
2018-02-27 11:49 ` PYTHONPATH issue analysis - part 2 (was: PYTHONPATH woes) Hartmut Goebel
2018-03-11 21:47 ` PYTHONPATH issue analysis - part 3 " Hartmut Goebel
3 siblings, 1 reply; 49+ messages in thread
From: Hartmut Goebel @ 2018-02-27 11:43 UTC (permalink / raw)
To: Pjotr Prins; +Cc: guix-devel
Hi,
I'm going to analyse the PYTHONPATH issues systematically. This is part 1 of
the analysis.
Result
=======
PYTHONPATH intented (by upstream) for adding site-packages. PYTHONPATH
elements are added in front of essential packages, while site-packages are
added behind.
This means the way we are using PYTHONPATH should be changed.
Preliminary Proposal
=======================
This proposal is under the limitation of the current state of the
analysis. Further parts of the analysis may yield more
insights, and propose different solutions.
1. The search-path-specification PYTHONPATH should be replaced by
GUIX-PYTHON2-SITE-PACKAGES resp. GUIX-PYTHON3-SITE-PACKAGES (names
tbd).
2. 'site.py' will be patched to add theses entries to sys.path.
Limitations:
This only solves the issue related to version-specific site-packages. python
still thinks its "home" is in /gnu/store while it actually should be in the
guix-profile.
Rational
=================
According to the documentation [1,2,PEP370], sys.path is composed as
follows:
$PWD resp. dir containing the script
$PYTHONPATH elements
default search path PREFIX/lib/pythonX.Y
user site-packages ~/.local/lib/pythonX.Y/site-packages
system-site packages PREFIX/lib/python2.6/site-packages
The .pth-files are processed in user and system site-packages only,
but not in $PYTHONPATH.
[PEP370] explicitly says: "The […] site directory is added […] after
Python's search paths and PYTHONPATH. This setup […] prevents […]
overwriting a stdlib module. Stdlib modules can still be overwritten
with PYTHONPATH."
This means: PYTHONPATH is not intented to set system site-packages.
Example:
$ cd ~
$ PYTHONPATH=/tmp/aaa:/tmp/bbb /usr/bin/python -m site
sys.path = [
'/home/htgoebel,
'/tmp/aaa',
'/tmp/bbb',
'/usr/lib/python27.zip',
'/usr/lib64/python2.7',
'/usr/lib64/python2.7/plat-linux2',
'/usr/lib64/python2.7/lib-tk',
'/usr/lib64/python2.7/lib-old',
'/usr/lib64/python2.7/lib-dynload',
'/home/htgoebel/.local/lib/python2.7/site-packages',
'/usr/lib64/python2.7/site-packages',
'/usr/lib64/python2.7/site-packages/gtk-2.0',
'/usr/lib64/python2.7/site-packages/wx-3.0-gtk2',
'/usr/lib/python2.7/site-packages',
]
[1] https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPATH
[2] https://docs.python.org/3/library/site.html#module-site
[PEP370] https://www.python.org/dev/peps/pep-0370/#implementation
--
Regards
Hartmut Goebel
| Hartmut Goebel | h.goebel@crazy-compilers.com |
| www.crazy-compilers.com | compilers which you thought are impossible |
^ permalink raw reply [flat|nested] 49+ messages in thread
* PYTHONPATH issue analysis - part 2 (was: PYTHONPATH woes)
2018-02-24 10:44 ` Hartmut Goebel
2018-02-24 10:49 ` Hartmut Goebel
2018-02-27 11:43 ` PYTHONPATH issue analysis - part 1 (was: PYTHONPATH woes) Hartmut Goebel
@ 2018-02-27 11:49 ` Hartmut Goebel
2018-03-11 21:47 ` PYTHONPATH issue analysis - part 3 " Hartmut Goebel
3 siblings, 0 replies; 49+ messages in thread
From: Hartmut Goebel @ 2018-02-27 11:49 UTC (permalink / raw)
To: Pjotr Prins; +Cc: guix-devel
Hi,
nex part of the analysis:
Result
=======
The venv-hack I posted a few days ago works as expected only for
GUIX_PROFILE,
but not for virtual environments.
Preliminary Proposal
=======================
As it stands now, the venv-hack is not a valid solution. It may be the basis
for another solution, tough.
Rational
===========
I tried answering four questions:
A: Can virtual environments be stacked in stock Python?
No, they can not, see point 1. and 2. below.
C: Given PYTHONPATH is not set, do virtual environments in Guix use
the correct "site" packages (which is the ones in GUIX_PROFILE).
No, in guix venvs use the site-packages from
/gnu/store/…-python-3.6.3/. See points 3. and 4 below.
D: Would the venv-hack I posted a view days ago solve the issue?
No, it would not. It would work as expected for python in the
profile, but not for virtual environments based on this. See point
5. below.
1. Set up a virtual environemnt using the system installed python.
====================================================================
$ pyvenv-3.5 /tmp/venv-1
$ ls -l /tmp/venv-1/bin/python
… /tmp/venv-1/bin/python -> python3.5
$ ls /tmp/venv-1/bin/
activate activate.fish easy_install-3.5* pip3* python@
python3.5@
activate.csh easy_install* pip* pip3.5* python3@
$ ls -l /tmp/venv-1/bin/python*
… /tmp/venv-1/bin/python -> python3.5
… /tmp/venv-1/bin/python3 -> python3.5
… /tmp/venv-1/bin/python3.5 -> /usr/bin/python3.5
$ /tmp/venv-1/bin/python -m site
sys.path = [
'/home/hartmut',
'/usr/lib64/python35.zip',
'/usr/lib64/python3.5',
'/usr/lib64/python3.5/plat-linux',
'/usr/lib64/python3.5/lib-dynload',
'/tmp/venv-1/lib64/python3.5/site-packages',
'/tmp/venv-1/lib/python3.5/site-packages',
]
As expected there are only the venvs' site-packges in sys.path.
2. Now stack venv on top of venv-1. Use --system-site-packages to
(hopefully) make venv-1's site-packages available to venv-2.
====================================================================
$ which pyvenv-3.5
/bin/pyvenv-3.5
$ /tmp/venv-1/bin/python /bin/pyvenv-3.5 /tmp/venv-2 --system-site-packages
$ ls -l /tmp/venv-2/bin/python*
… /tmp/venv-2/bin/python -> /tmp/venv-1/bin/python
… /tmp/venv-2/bin/python3 -> python
$ ls /tmp/venv-2/bin/
activate activate.fish easy_install-3.5* pip3* python@
activate.csh easy_install* pip* pip3.5* python3@
$ /tmp/venv-2/bin/python -m site
sys.path = [
'/tmp',
'/usr/lib64/python35.zip',
'/usr/lib64/python3.5',
'/usr/lib64/python3.5/plat-linux',
'/usr/lib64/python3.5/lib-dynload',
'/tmp/venv-2/lib64/python3.5/site-packages',
'/tmp/venv-2/lib/python3.5/site-packages',
'/usr/lib64/python3.5/site-packages',
'/usr/lib/python3.5/site-packages',
]
As you can see (last two entries), the system site-packages are taken
from the real system installation, not from the stacked venv-1. This
means, venvs can not be stacked.
3. Now let's see how guix-profile installed python works. I used a
somewhat current HEAD (7e4e3df4e8) to ensure using the most current
wrappers etc.
====================================================================
$ ./pre-inst-env guix package -i python
…
3a. Do not set PYTHONPATH when setting up the venv.
----------------------------------------------------
$ ~/.guix-profile/bin/pyvenv-3.6 /tmp/venv-3a
…
$ /tmp/venv-3a/bin/python -m site
sys.path = [
'/tmp',
'/gnu/store/…-python-3.6.3/lib/python36.zip',
'/gnu/store/…-python-3.6.3/lib/python3.6',
'/gnu/store/…-python-3.6.3/lib/python3.6/lib-dynload',
'/tmp/venv-3a/lib/python3.6/site-packages',
]
As expected there are only the venvs' site-packges in sys.path.
3b. Set PYTHONPATH when setting up the venv.
----------------------------------------------------
$ PYTHONPATH="$HOME/.guix-profile/lib/python3.6/site-packages"
~/.guix-profile/bin/pyvenv-3.6 /tmp/venv-3b
…
$ /tmp/venv-3b/bin/python -m site
sys.path = [
'/tmp',
'/gnu/store/…-python-3.6.3/lib/python36.zip',
'/gnu/store/…-python-3.6.3/lib/python3.6',
'/gnu/store/…-python-3.6.3/lib/python3.6/lib-dynload',
'/tmp/venv-3b/lib/python3.6/site-packages',
]
Again there are only the venvs' site-packges in sys.path. This is
excpected, since PYTHONPATH only effects the run of pyenv-3.6
4. Same as 3, but use --system-site-packages
====================================================================
4a Don't set PYTHONPATH when setting up the venv.
----------------------------------------------------
$ ~/.guix-profile/bin/pyvenv-3.6 /tmp/venv-4a --system-site-package
…
$ /tmp/venv-4a/bin/python -m site
sys.path = [
'/tmp',
'/gnu/store/…-python-3.6.3/lib/python36.zip',
'/gnu/store/…-python-3.6.3/lib/python3.6',
'/gnu/store/…-python-3.6.3/lib/python3.6/lib-dynload',
'/tmp/venv-4a/lib/python3.6/site-packages',
'/gnu/store/…-python-3.6.3/lib/python3.6/site-packages',
]
This is *not* what what a Guix user would expect. For the Guix user's
perspective his/her "Python site-packages" are those in $GUIX_PROFILE.
Esp. since guix never installs into
/gnu/store/…-python-3.6.3/lib/python3.6/site-packages and thus this
path never contains additional "site" packages.
4b Set PYTHONPATH when setting up the venv.
----------------------------------------------------
$ PYTHONPATH="$HOME/.guix-profile/lib/python3.6/site-packages"
~/.guix-profile/bin/pyvenv-3.6 /tmp/venv-4b --system
$ /tmp/venv-4b/bin/python -m site
sys.path = [
'/tmp',
'/gnu/store/…-python-3.6.3/lib/python36.zip',
'/gnu/store/…-python-3.6.3/lib/python3.6',
'/gnu/store/…-python-3.6.3/lib/python3.6/lib-dynload',
'/tmp/venv-4b/lib/python3.6/site-packages',
'/gnu/store/…-python-3.6.3/lib/python3.6/site-packages',
]
Result is the same as for 4a), reason as in 3b).
5. Would the venv-hack I posted a view days ago solve the issue?
====================================================================
5a. Verify the venv-hack works
----------------------------------------------------
$ cp -r ~/.guix-profile /tmp/guix-profile
$ mkdir !$
mkdir /tmp/guix-profile
$ cp -r ~/.guix-profile/* /tmp/guix-profile
$ echo 'include-system-site-packages = false' > /tmp/guix-profile/pyvenv.cfg
$ /tmp/guix-profile/bin/python3 -m site
sys.path = [
'/tmp',
'/gnu/store/…-python-3.6.3/lib/python36.zip',
'/gnu/store/…-python-3.6.3/lib/python3.6',
'/gnu/store/…-python-3.6.3/lib/python3.6/lib-dynload',
'/tmp/guix-profile/lib/python3.6/site-packages',
]
As expected, the profile's site-packages are included in sys.path.
5b Build a venv based on this (hacked) profile
----------------------------------------------------
$ /tmp/guix-profile/bin/pyvenv-3.6 /tmp/venv-5b --system-site-packages
…
$ /tmp/venv-5b/bin/python -m site
sys.path = [
'/tmp',
'/gnu/store/…-python-3.6.3/lib/python36.zip',
'/gnu/store/…-python-3.6.3/lib/python3.6',
'/gnu/store/…-python-3.6.3/lib/python3.6/lib-dynload',
'/tmp/venv-5b/lib/python3.6/site-packages',
'/gnu/store/…-python-3.6.3/lib/python3.6/site-packages',
]
As in 4a, this is *not* what what a Guix user would expect. The
profile's site-packages should be in sys.path, not
/gnu/store/…-python-3.6.3/lib/python3.6/site-packages.
--
Regards
Hartmut Goebel
| Hartmut Goebel | h.goebel@crazy-compilers.com |
| www.crazy-compilers.com | compilers which you thought are impossible |
^ permalink raw reply [flat|nested] 49+ messages in thread
* PYTHONPATH issue analysis - part 3 (was: PYTHONPATH woes)
2018-02-24 10:44 ` Hartmut Goebel
` (2 preceding siblings ...)
2018-02-27 11:49 ` PYTHONPATH issue analysis - part 2 (was: PYTHONPATH woes) Hartmut Goebel
@ 2018-03-11 21:47 ` Hartmut Goebel
2018-03-13 21:23 ` PYTHONPATH issue analysis - part 3 Ludovic Courtès
` (2 more replies)
3 siblings, 3 replies; 49+ messages in thread
From: Hartmut Goebel @ 2018-03-11 21:47 UTC (permalink / raw)
To: Pjotr Prins; +Cc: guix-devel
Hi,
here is my third part of the analysis:
Result
==========
We can avoid all of the problems related to how Guix is using PYTHONPATH
quite simple. This will work for virtual environments, too.
Preliminary Proposal
=======================
To be able to install different minor versions of Python in the same
profile, any environment variable should contain the minor version, too.
E.g. …-3.5.
Option 2 (GUIX-PYTHONHOME-X.Y) should be implemented since it is simple.
If we can get option 3 (stop resolving sysmlinks at the correct
iteration) to work, this might be a better solution.
Rational
===========
1. Is setting GUIX-PYTHON-X.Y-SITE-PACKAGES enough?
This should work for most cases, but might break Python appications
expecting site-packages to be below sys.prefix. Thus setting
(GUIX-)PYTHONHOME-X.Y is a better solution.
2. Would GUIX-PYTHONHOME-2.7, …-3.4, …-3.5 work?
Yes, this would work, but still an environment variable would be
required.
3. Can we get without any environment variable?
Yes, if we manage to to resolving symlinks at the correct iteration.
This might be complicated to achieve.
4. How does Path-handling in Python's start-up sequence work?
See detailed analysis below.
1. How could GUIX-PYTHON-X.Y-SITE-PACKAGES be implemented?
=============================================================
Given the analysis below, it would be possible to patch site.py to make
it use these environment variables. I did not look at the details yet,
but since the site-package paths are only set by site.py, this should be
not much of an issue.
To be able to install different minor versions of Python in the same
profile, the variables should contain the minor version, too. E.g. …-3.5.
Drawbacks:
- sys.prefix and sys.exec_prefix would still point to the store, not to
the profile. This might break Python appications expecting
site-packages to be below sys.prefix.
2. How could GUIX-PYTHONHOME-X.Y be implemented?
=================================================
Given the analysis below, it should be okay to implement GUIX-PYTHONHOME-X.Y
like this:
- In Py_GetPythonHome() (Python/pythonrun.c), after checking for
PYTHONHOME, check for GUIX-PYTHONHOME-X.Y. This will effect below
step 2 for non-venvs and step 3 for venvs.
This should be save for virtual environments, too, since pyvenv.cfg is
searched based on argv0_path.
This should be save for stacked virtual environments, too, since
pyvenv.cfg will still point to the prior venv and sys.prefix and
sys.exec_prefix will be set correctly in site.py.
- Implement a "search-path" GUIX-PYTHONHOME-X.Y
- To be able to install different minor versions of Python in the same
profile, the variables should contain the minor version, too. E.g.
…-3.5.
Drawbacks:
- We need to ensure GUIX-PYTHONHOME-X.Y is a single path, not a list of
paths. Or we split the variable in Py_GetPythonHome().
- Requires GUIX-PYTHONHOME-X.Y to be set in the respective environment.
3. How to avoid GUIX-PYTHONHOME[23]?
=========================================
We could avoid GUIX-PYTHONHOME[23] if we stop resolving the symlinks at
the correct point in iteration. Something like this:
# resolve the symlink
last = progpath
while 1:
if (last.startswith('/gnu/store/') and \
last[43:52] == '-profile/'):
# links to a profile
break
try:
next = os.readlink(last)
except OSError:
# not a link anymore
break
if not next.startswith(SEP):
# Interpret relative to last
next = os.path.join(os.path.dirname(last), next)
if next == GUIX_PYTHON_OUTPUT: # out "/bin/python" compile-time
# "next" points to the python binary of the guix-output
break
last = next
argv0_path = last
Drawbacks:
- More complicated patch.
- More comparison within a look, this will slow down start-up a bit.
Open questions:
- Which are the correct paths to check to stop iteration?
- How to handle the "pythonX" -> "pythonX.Y" link?
- How to handle "python-wrapper", which links python -> python3
4. Path-handling in Python's start-up sequence
===============================================
No venv
------------
In getpath.c:
0. "progpath" will be set based on argv[0]. This is expected to be the
fully quallified path of the argv[0].
1. argv0_path is search based on progpath and all symlinks resolved.
2. prefix and exec_prefix are searched based on argv0_path *) **)
3. sys.path is set based on prefix and exec_prefix.
In sysmodule.c:
4. sys.executable is set to "progpath" (see step 0 above).
5. sys.prefix, sys.base_prefix, sys.exec_prefix and sys.base_exec_prefix
are set to prefix resp. exec_prefix evaluated in step 3 above.
In site.py;
6. When site.py is loaded, system site-packages are added from
sys.prefix and sys.exec_prefix.
*) There are two special cases, guix does not need to handle: If an
(embedding) application did call (Py_SetPythonHome) or "PYTHONHOME"
was set, this overrules argv0_path. But this is where
GUIX-PYTHONHOME-X.Y could step in.
**) If some "landmark" file is not found, the build-time PREFIX
resp. EXEC_PREFIX is used. For guix this should not happen.
For a venv:
--------------------
In getpath.c:
0. "progpath" will be set based on argv[0]. This is expected to be the
fully qualified path of the argv[0]. Try this in a venv::
$ lm -s /tmp/venv/bin/python /tmp/qqq
$ /tmp/qqq -S -c 'import sys; print(sys.executable)'
/tmp/qqq
1. argv0_path is search based on progpath and all symlinks resolved,
like above.
2. If pyvenf.cfg exists in argv0_path's directory or one level above,
argv0_path is taken from the "home" entry in this file.
3. prefix and exec_prefix are searched based on argv0_path (resp.
PYTHONHAOME, GUIX-PYTHONHOME-X.Y). Notably both are now pointing to
the "home" - not to the virtual env.
4. sys.path is set based on prefix and exec_prefix. Notably this is
adding the standard library based on "home". Try this in a venv (here
on a foreign distribution)::
$ /tmp/venv/bin/python -S -c 'import sys; print(sys.path)'
['', '/usr/lib64/python35.zip', '/usr/lib64/python3.5',
'/usr/lib64/python3.5/plat-linux',
'/usr/lib64/python3.5/lib-dynload']
In sysmodule.c:
5. sys.executable is set to "progpath" (see step 0 above).
6. sys.prefix, sys.base_prefix, sys.exec_prefix and sys.base_exec_prefix
are set to prefix resp. exec_prefix evaluated in step 3 above. All of
these are pointing to "home"! sys.prefix and sys.exec_prefix will be
adjusted in site.py.
Try this in a venv (here on a foreign distribution)::
$ /tmp/venv/bin/python -S -c 'import sys; print(sys.prefix)'
/usr
In site.py:
7. If pyvenf.cfg exists in the executable's directory or one level
above, site.py assumes a virtuel environment and will execute the
following steps.
8. When site.py is loaded, sys.prefix and sys.exec_prefix will be set
based on sys.executable - which is in the virtual env.
9. sys.base_prefix and sys.base_exec_prefix will not be changes and thus
always be the "real" prefixes of the Python installation - see step 3
above.
10. sys._home (not documented) will be set to the "home" entry from
pyvenv.cfg, if the entry exisits.
-> sys.base_prefix and sys.base_exec_prefix should should point to
GUIX_PROFILE
pyvenv.cfg - as of Python 3.5 venv
---------------------------------------
The "home" entry in pyvenv.cfg is based on sys.executable. This means if
you are stacking venvs, the "home" entry is pointing to the prior venv,
not to the original prefix.
Nevertheless, sys.path is based on the *orginal* prefix, not the "home":
At the beginning of site.py, the list of prefixes to be searched is set
to sys.prefix, which - see step 6 above - is the same as sys.base_prefix
and thus the orginal prefix, not the "home". site.py will change
sys.prefix later, but not the presets in the list of prefixes to be
searched.
From Modules/getpath.c
============================
* Before any searches are done, the location of the executable is
* determined. If argv[0] has one or more slashes in it, it is used
* unchanged. Otherwise, it must have been invoked from the shell's path,
* so we search $PATH for the named executable and use that. If the
* executable was not found on $PATH (or there was no $PATH environment
* variable), the original argv[0] string is used.
*
* Next, the executable location is examined to see if it is a symbolic
* link. If so, the link is chased (correctly interpreting a relative
* pathname if one is found) and the directory of the link target is used.
*
* Finally, argv0_path is set to the directory containing the executable
* (i.e. the last component is stripped).
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH issue analysis - part 3
2018-03-11 21:47 ` PYTHONPATH issue analysis - part 3 " Hartmut Goebel
@ 2018-03-13 21:23 ` Ludovic Courtès
2018-03-13 21:44 ` Pjotr Prins
` (3 more replies)
2018-03-15 19:30 ` PYTHONPATH issue explanation Hartmut Goebel
2018-04-16 14:21 ` PYTHONPATH - let's systematically tame the baest Hartmut Goebel
2 siblings, 4 replies; 49+ messages in thread
From: Ludovic Courtès @ 2018-03-13 21:23 UTC (permalink / raw)
To: Hartmut Goebel; +Cc: guix-devel
Hello,
Hartmut Goebel <h.goebel@crazy-compilers.com> skribis:
> Result
> ==========
>
> We can avoid all of the problems related to how Guix is using PYTHONPATH
> quite simple. This will work for virtual environments, too.
I may well have missed something (sorry about that!), but what are “the
problems related to how Guix is using PYTHONPATH”?
My first reaction is that Guix is not doing anything special with
PYTHONPATH, and only defining it as documented by upstream.
For example:
> Preliminary Proposal
> =======================
>
> To be able to install different minor versions of Python in the same
> profile, any environment variable should contain the minor version, too.
> E.g. …-3.5.
If you’re suggesting to have a ‘PYTHONPATH3-5’ environment variable
instead of ‘PYTHONPATH’, I agree it could be helpful if we are to
install different versions of Python in one profile. However, it’s a
choice for upstream to make, and upstream did not make that choice.
There’s one case where we went our way instead of following upstream,
and that is ‘GUIX_LOCPATH’. There are strong justifications, though.
Thanks,
Ludo’.
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH issue analysis - part 3
2018-03-13 21:23 ` PYTHONPATH issue analysis - part 3 Ludovic Courtès
@ 2018-03-13 21:44 ` Pjotr Prins
2018-03-13 22:02 ` Hartmut Goebel
2018-03-13 21:47 ` Hartmut Goebel
` (2 subsequent siblings)
3 siblings, 1 reply; 49+ messages in thread
From: Pjotr Prins @ 2018-03-13 21:44 UTC (permalink / raw)
To: Ludovic Courtès; +Cc: guix-devel
On Tue, Mar 13, 2018 at 10:23:08PM +0100, Ludovic Courtès wrote:
> > Preliminary Proposal
> > =======================
> >
> > To be able to install different minor versions of Python in the same
> > profile, any environment variable should contain the minor version, too.
> > E.g. …-3.5.
>
> If you’re suggesting to have a ‘PYTHONPATH3-5’ environment variable
> instead of ‘PYTHONPATH’, I agree it could be helpful if we are to
> install different versions of Python in one profile.
Another problem is that it does not cover special cases where, for
example you compile Python with SSL and without. You don't want them
to share user installed libs. That is why I stick in the Hash value.
Ruby example
https://gitlab.com/pjotrp/guix-notes/blob/master/scripts/ruby-guix-env
admittedly I no longer use that much. But I would if I just quickly
wanted to try a gem/module and make sure it is isolated.
> However, it’s a choice for upstream to make, and upstream did not
> make that choice.
Sometimes upstream can do with good ideas ;). The shared use of
PYTHONPATH between versions of Python2 and 3 is as brain dead as it
can be. I see people trip over it regularly, including myself. Great
time waster, if nothing else.
> There’s one case where we went our way instead of following upstream,
> and that is ‘GUIX_LOCPATH’. There are strong justifications, though.
Would not work with multiple versions in one profile though. Anyway,
Hartmut covered all that.
Pj.
--
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH issue analysis - part 3
2018-03-13 21:44 ` Pjotr Prins
@ 2018-03-13 22:02 ` Hartmut Goebel
2018-03-14 7:49 ` Pjotr Prins
0 siblings, 1 reply; 49+ messages in thread
From: Hartmut Goebel @ 2018-03-13 22:02 UTC (permalink / raw)
To: Pjotr Prins, Ludovic Courtès; +Cc: guix-devel
Am 13.03.2018 um 22:44 schrieb Pjotr Prins:
> Another problem is that it does not cover special cases where, for
> example you compile Python with SSL and without. You don't want them
> to share user installed libs.
Upstream does not handle this case, so I do not see a need to handle
this in guix. If we find a way, this would be find. But prior to solving
the optional we should solve the compulsory :-)
--
Regards
Hartmut Goebel
| Hartmut Goebel | h.goebel@crazy-compilers.com |
| www.crazy-compilers.com | compilers which you thought are impossible |
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH issue analysis - part 3
2018-03-13 22:02 ` Hartmut Goebel
@ 2018-03-14 7:49 ` Pjotr Prins
2018-03-14 9:04 ` Hartmut Goebel
2018-03-15 19:48 ` Hartmut Goebel
0 siblings, 2 replies; 49+ messages in thread
From: Pjotr Prins @ 2018-03-14 7:49 UTC (permalink / raw)
To: Hartmut Goebel; +Cc: guix-devel
On Tue, Mar 13, 2018 at 11:02:03PM +0100, Hartmut Goebel wrote:
> Am 13.03.2018 um 22:44 schrieb Pjotr Prins:
> > Another problem is that it does not cover special cases where, for
> > example you compile Python with SSL and without. You don't want them
> > to share user installed libs.
>
> Upstream does not handle this case, so I do not see a need to handle
> this in guix. If we find a way, this would be find. But prior to solving
> the optional we should solve the compulsory :-)
https://github.com/python/cpython/blob/master/configure#L1543
and there are many other options which define the behaviour of the
interpreter. We don't use them in GNU Guix, but it does not mean we
should not think about it/allow it.
I am nit picking a bit, but the problem is that we don't have a full
solution unless we can isolate the instances and the packages they can
install (themselves).
Using one PYTHONPATH is ultimately Python's failure - I agree with
Ludo that people should do what they want with it. Bringing in an
extra GUIX_PYTHONPATH_$VER will confuse things (and probably break it
for some people).
I propose we patch the interpreter to tell about the Guix paths. It
probably only needs to be done in one place. They should go after the
PYTHONPATH as it is done by Python itself, like you suggested earlier.
That is an acceptable approach. Just a little annoyance with every
Python upgrade.
Pj.
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH issue analysis - part 3
2018-03-14 7:49 ` Pjotr Prins
@ 2018-03-14 9:04 ` Hartmut Goebel
2018-03-14 18:21 ` Pjotr Prins
2018-03-15 19:48 ` Hartmut Goebel
1 sibling, 1 reply; 49+ messages in thread
From: Hartmut Goebel @ 2018-03-14 9:04 UTC (permalink / raw)
To: Pjotr Prins; +Cc: guix-devel
Hi Pjotr,
no offense meant, but I have the impression you did not read my analysis
and proposals, did you?
> I propose we patch the interpreter to tell about the Guix paths. It
> probably only needs to be done in one place. They should go after the
> PYTHONPATH as it is done by Python itself, like you suggested earlier.
See option 3 of my analysis part 3.
--
Regards
Hartmut Goebel
| Hartmut Goebel | h.goebel@crazy-compilers.com |
| www.crazy-compilers.com | compilers which you thought are impossible |
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH issue analysis - part 3
2018-03-14 9:04 ` Hartmut Goebel
@ 2018-03-14 18:21 ` Pjotr Prins
0 siblings, 0 replies; 49+ messages in thread
From: Pjotr Prins @ 2018-03-14 18:21 UTC (permalink / raw)
To: Hartmut Goebel; +Cc: guix-devel
On Wed, Mar 14, 2018 at 10:04:21AM +0100, Hartmut Goebel wrote:
> Hi Pjotr,
>
> no offense meant, but I have the impression you did not read my analysis
> and proposals, did you?
No offense taken. I did and do read them, but the analysis is not
exactly accessible for my small brain, especially when you go into
symlinks in part 3.
No need to over-analyse. Sometimes you just have to try and see what
breaks. We probably are talking at cross-purposes.
Pj.
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH issue analysis - part 3
2018-03-14 7:49 ` Pjotr Prins
2018-03-14 9:04 ` Hartmut Goebel
@ 2018-03-15 19:48 ` Hartmut Goebel
1 sibling, 0 replies; 49+ messages in thread
From: Hartmut Goebel @ 2018-03-15 19:48 UTC (permalink / raw)
To: Pjotr Prins; +Cc: guix-devel
[-- Attachment #1: Type: text/plain, Size: 1203 bytes --]
Am 14.03.2018 um 08:49 schrieb Pjotr Prins:
> On Tue, Mar 13, 2018 at 11:02:03PM +0100, Hartmut Goebel wrote:
>> Am 13.03.2018 um 22:44 schrieb Pjotr Prins:
>>> Another problem is that it does not cover special cases where, for
>>> example you compile Python with SSL and without. You don't want them
>>> to share user installed libs.
>> Upstream does not handle this case, so I do not see a need to handle
>> this in guix. If we find a way, this would be find. But prior to solving
>> the optional we should solve the compulsory :-)
> https://github.com/python/cpython/blob/master/configure#L1543
>
> and there are many other options which define the behaviour of the
> interpreter. We don't use them in GNU Guix, but it does not mean we
> should not think about it/allow it.
Now I understand you point: If there are two variants of e.g Python 3.5
available, but there is only one GUIX-PYTHONHOME-3.5 variable, this will
intermix the environments again.
You are right!
Adding the hash would indeed be a good solution :-)
--
Regards
Hartmut Goebel
| Hartmut Goebel | h.goebel@crazy-compilers.com |
| www.crazy-compilers.com | compilers which you thought are impossible |
[-- Attachment #2: Type: text/html, Size: 2159 bytes --]
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH issue analysis - part 3
2018-03-13 21:23 ` PYTHONPATH issue analysis - part 3 Ludovic Courtès
2018-03-13 21:44 ` Pjotr Prins
@ 2018-03-13 21:47 ` Hartmut Goebel
2018-03-14 9:41 ` Ludovic Courtès
2018-03-13 21:51 ` Hartmut Goebel
2018-03-14 0:10 ` Ricardo Wurmus
3 siblings, 1 reply; 49+ messages in thread
From: Hartmut Goebel @ 2018-03-13 21:47 UTC (permalink / raw)
To: Ludovic Courtès; +Cc: guix-devel
Am 13.03.2018 um 22:23 schrieb Ludovic Courtès:
> I may well have missed something (sorry about that!), but what are “the
> problems related to how Guix is using PYTHONPATH”?
In short:
We are using PYTHONPATH for something it is not meant for: PYTHONPATH is
NOT intended (by upstream) for adding site-packages. PYTHONPATH
elements are added in front of essential packages, while site-packages
are added behind.
Dor details please see part 1 of my analysis.
--
Regards
Hartmut Goebel
| Hartmut Goebel | h.goebel@crazy-compilers.com |
| www.crazy-compilers.com | compilers which you thought are impossible |
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH issue analysis - part 3
2018-03-13 21:47 ` Hartmut Goebel
@ 2018-03-14 9:41 ` Ludovic Courtès
0 siblings, 0 replies; 49+ messages in thread
From: Ludovic Courtès @ 2018-03-14 9:41 UTC (permalink / raw)
To: Hartmut Goebel; +Cc: guix-devel
Hartmut Goebel <h.goebel@crazy-compilers.com> skribis:
> Am 13.03.2018 um 22:23 schrieb Ludovic Courtès:
>> I may well have missed something (sorry about that!), but what are “the
>> problems related to how Guix is using PYTHONPATH”?
>
> In short:
>
> We are using PYTHONPATH for something it is not meant for: PYTHONPATH is
> NOT intended (by upstream) for adding site-packages. PYTHONPATH
> elements are added in front of essential packages, while site-packages
> are added behind.
Oh right, thanks for the reminder.
Ludo’.
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH issue analysis - part 3
2018-03-13 21:23 ` PYTHONPATH issue analysis - part 3 Ludovic Courtès
2018-03-13 21:44 ` Pjotr Prins
2018-03-13 21:47 ` Hartmut Goebel
@ 2018-03-13 21:51 ` Hartmut Goebel
2018-03-14 0:10 ` Ricardo Wurmus
3 siblings, 0 replies; 49+ messages in thread
From: Hartmut Goebel @ 2018-03-13 21:51 UTC (permalink / raw)
To: Ludovic Courtès; +Cc: guix-devel
[-- Attachment #1: Type: text/plain, Size: 747 bytes --]
Am 13.03.2018 um 22:23 schrieb Ludovic Courtès:
>> Preliminary Proposal
>> =======================
>>
>> To be able to install different minor versions of Python in the same
>> profile, any environment variable should contain the minor version, too.
>> E.g. …-3.5.
> If you’re suggesting to have a ‘PYTHONPATH3-5’ environment variable
> instead of ‘PYTHONPATH’, I agree it could be helpful if we are to
This suggestion is related to Guix-specific variables only, like
GUIX-PYTHONHOME-2.7. (I hae to admit that this is not clear enough).
--
Regards
Hartmut Goebel
| Hartmut Goebel | h.goebel@crazy-compilers.com |
| www.crazy-compilers.com | compilers which you thought are impossible |
[-- Attachment #2: Type: text/html, Size: 1399 bytes --]
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH issue analysis - part 3
2018-03-13 21:23 ` PYTHONPATH issue analysis - part 3 Ludovic Courtès
` (2 preceding siblings ...)
2018-03-13 21:51 ` Hartmut Goebel
@ 2018-03-14 0:10 ` Ricardo Wurmus
2018-03-15 9:09 ` Ludovic Courtès
3 siblings, 1 reply; 49+ messages in thread
From: Ricardo Wurmus @ 2018-03-14 0:10 UTC (permalink / raw)
To: Ludovic Courtès; +Cc: guix-devel
Ludovic Courtès <ludo@gnu.org> writes:
> I may well have missed something (sorry about that!), but what are “the
> problems related to how Guix is using PYTHONPATH”?
>
> My first reaction is that Guix is not doing anything special with
> PYTHONPATH, and only defining it as documented by upstream.
The problem might be that we are using PYTHONPATH at all. On other
distributions this is usually not required and thus doesn’t cause any
problems.
As outlined in my first email in this thread, our use of PYTHONPATH in
wrappers seems to not have the desired effect in the presence of
incompatible packages that are *later* in the PYTHONPATH.
We also have problems when PYTHONPATH includes modules for both Python 2
and 3, which happens automatically when these modules are installed into
the same Guix profile. Since merely installing packages for different
Python versions is not a problem on traditional distros (on my Fedora
workstation I have site-packages directories for 4 different versions of
Python) I think we should do better here.
--
Ricardo
GPG: BCA6 89B6 3655 3801 C3C6 2150 197A 5888 235F ACAC
https://elephly.net
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH issue analysis - part 3
2018-03-14 0:10 ` Ricardo Wurmus
@ 2018-03-15 9:09 ` Ludovic Courtès
0 siblings, 0 replies; 49+ messages in thread
From: Ludovic Courtès @ 2018-03-15 9:09 UTC (permalink / raw)
To: Ricardo Wurmus; +Cc: guix-devel
Hello,
Ricardo Wurmus <rekado@elephly.net> skribis:
> The problem might be that we are using PYTHONPATH at all. On other
> distributions this is usually not required and thus doesn’t cause any
> problems.
It’s not required because Python modules live at a fixed location, no?
How does pip deal with that? I suppose it needs to modify the search
path somehow.
> As outlined in my first email in this thread, our use of PYTHONPATH in
> wrappers seems to not have the desired effect in the presence of
> incompatible packages that are *later* in the PYTHONPATH.
>
> We also have problems when PYTHONPATH includes modules for both Python 2
> and 3, which happens automatically when these modules are installed into
> the same Guix profile. Since merely installing packages for different
> Python versions is not a problem on traditional distros (on my Fedora
> workstation I have site-packages directories for 4 different versions of
> Python) I think we should do better here.
I agree, though I must say that if PYTHONPATH is not up to the task, I’m
not sure what can be done on our side.
Thanks,
Ludo’.
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH issue explanation
2018-03-11 21:47 ` PYTHONPATH issue analysis - part 3 " Hartmut Goebel
2018-03-13 21:23 ` PYTHONPATH issue analysis - part 3 Ludovic Courtès
@ 2018-03-15 19:30 ` Hartmut Goebel
2018-03-17 1:41 ` 宋文武
2018-03-24 20:47 ` Chris Marusich
2018-04-16 14:21 ` PYTHONPATH - let's systematically tame the baest Hartmut Goebel
2 siblings, 2 replies; 49+ messages in thread
From: Hartmut Goebel @ 2018-03-15 19:30 UTC (permalink / raw)
To: Pjotr Prins; +Cc: guix-devel
Hi,
given the ongoing discussion around Python show that my explanation was
not good enough. I'll try to summarize and give more background.
With regard to Python, guix currently has a major issue, which my
proposals are addressing. There are other issues (like naming the
executables, the "wrapper" script", etc.) which are not addressed here.
When installing Python and some Python packages (e.g. python-simplejson)
in guix, the python interpreter will be linked to
GUIX_PROFILE/bin/pythonX.Y and the packages' files are linked into
GUIX_PROFILE/lib/python-X.Y/site-packages/…, which is perfectly okay.
This python interpreter does not find the site-packages in GUIX_PROFILE
since site-packages are search relative to "sys.base_prefix" (which is
the same as "sys.prefix" except in virtual environments).
"sys.base_prefix" is determined based on the executable's path (argv[0])
by resolving all symlinks.
The python interpreter assumes "site-packages" to be relative to "where
python is installed" - called "sys.base_prefix" (which is the same as
"sys.prefix" except in virtual environments). "sys.base_prefix" is
determined based on the executable's path (argv[0]) by resolving all
symlinks. For Guix this means: "sys.base_prefix" will always point to
/gnu/store/…-python-X.Y, not to GUIX_PROFILE. Thus the site-packages
installed into the guix profile will not be found.
This is why we currently (mis-) use PYTHONPATH: To make the
site-packages installed into the guix profile available.
Using PYTHONPATH for this woes since there is only one PYTHONPATH
variable for all versions of python. This is designed by upstream.
Additionally: When using PYTHONPATH the site-packages are added to the
search path ("sys.path") *in front* of the python standard library,
while they are expected to be added *behind*.
Part 3 of my analysis lists three solutions for this, where only number
2 and 3 are "good choices".
no. 2
suggests using a mechanism already implemented in python: Setting
"PYTHONHOME" will make the interpreter to use this as "sys.base_prefix"
unconditionally. Again there is only one PYTHONHOME variable for all
versions of python (designed by upstream). We could work around this
easily (while keeping upstream compatibility) by using
GUIX-PYTHONHOME-X.Y, to be evaluated just after PYTHONHOME.
This would be easy to implement using Guix's "search-path" capabilities
and a small patch to the python interpreter.
The drawback is: This is implemented using an environment variable,
which might not give the expected results in all cases. E.g. running
/gnu/store/…-profile/bin/python will not load the site-packages of that
profile. Also there might be issues implementing virtual environments.
(Thinking about this, I'm quite sure there will. Ouch!)
no.3
suggests changing the way the python interpreter is resolving symlinks
when searching for "sys.base_prefix". The idea is to stop "at the profile".
The hard part of this is to determine "at the profile". Also this needs
a larger patch. But if we manage to implement this, it would be perfect.
I could contribute a draft for this implemented in Python. The
C-implementation needs to be done by some C programmer.
Which way should we go?
--
Regards
Hartmut Goebel
| Hartmut Goebel | h.goebel@crazy-compilers.com |
| www.crazy-compilers.com | compilers which you thought are impossible |
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH issue explanation
2018-03-15 19:30 ` PYTHONPATH issue explanation Hartmut Goebel
@ 2018-03-17 1:41 ` 宋文武
2018-03-17 10:07 ` Ricardo Wurmus
` (2 more replies)
2018-03-24 20:47 ` Chris Marusich
1 sibling, 3 replies; 49+ messages in thread
From: 宋文武 @ 2018-03-17 1:41 UTC (permalink / raw)
To: Hartmut Goebel; +Cc: guix-devel
Hartmut Goebel <h.goebel@crazy-compilers.com> writes:
Hello,
> Hi,
>
> given the ongoing discussion around Python show that my explanation was
> not good enough. I'll try to summarize and give more background.
Thanks for the explanations and this one!
So I have more understanding of it and ideas...
>
> With regard to Python, guix currently has a major issue, which my
> proposals are addressing. There are other issues (like naming the
> executables, the "wrapper" script", etc.) which are not addressed
> here.
> [...]
Okay, the "major issue" is that we're using "PYTHONPATH", which will add
entries into "sys.path" before builtin ones. It's semantically wrong
and may (or had?) cause issues.
> Part 3 of my analysis lists three solutions for this, where only number
> 2 and 3 are "good choices".
Option 2, "GUIX_PYTHONHOME_X_Y" can not be used in the build-system
unless we make a union of python inputs, so I think we should go for 1
and optional (later) add 3 too:
- "GUIX_PYTHON_X_Y_SITE_PACKAGES" (X.Y is not a valid env identifier
in bash) is necessary for the "build" environment.
We don't make a union of all the inputs in the "build" environment, so
a PATH (contains multiples directories) like env have to be used to
let python find all its "site-packages" from inputs.
> Drawbacks: This might break Python appications expecting
> site-packages to be below sys.prefix.
We have a patch named "python-2.7-site-prefixes.patch" seems to handle
this, maybe we should do it for python3 too?
- Avoid any environment variable for the "profile" environment.
We have a union "profile" for all the python packages, so environment
variables can be totally avoided with the help of "venv".
> We could avoid GUIX-PYTHONHOME[23] if we stop resolving the symlinks
> at the correct point in iteration.
This is exactly what "venv" does! We only need to make the "profile"
a "venv" for python. For python3, a simple "pyvenv.cfg" file is
enough, for python2 I guess we have to make a union or copy files like
what "virtualenv" does.
I plan to implement option 1 by adding a "sitecustomize.py" (better
than modify "site.py") into the python packages, and modify
"search-path-specification" to use "GUIX_PYTHON_X_Y_SITE_PACKAGES".
How's that sound?
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH issue explanation
2018-03-17 1:41 ` 宋文武
@ 2018-03-17 10:07 ` Ricardo Wurmus
2018-03-17 22:46 ` Hartmut Goebel
2018-03-17 22:53 ` Hartmut Goebel
2018-03-17 11:18 ` [PATCH] gnu: python: Honor 'GUIX_PYTHON_X_Y_SITE_PACKAGES' 宋文武
2018-03-17 22:04 ` PYTHONPATH issue explanation Hartmut Goebel
2 siblings, 2 replies; 49+ messages in thread
From: Ricardo Wurmus @ 2018-03-17 10:07 UTC (permalink / raw)
To: 宋文武; +Cc: guix-devel
宋文武 <iyzsong@member.fsf.org> writes:
> Option 2, "GUIX_PYTHONHOME_X_Y" can not be used in the build-system
> unless we make a union of python inputs
For texlive we create a temporary union in the build system, so this
shouldn’t be an unsurmountable obstacle.
What I don’t like about this solution is that PYTHONHOME can only hold a
single directory, so composing profiles (that use the same Python
variant) would no longer work. I prefer the
GUIX_PYTHON_X_Y_SITE_PACKAGES solution, because it is an actual search
path.
> - "GUIX_PYTHON_X_Y_SITE_PACKAGES" (X.Y is not a valid env identifier
> in bash) is necessary for the "build" environment.
>
> We don't make a union of all the inputs in the "build" environment, so
> a PATH (contains multiples directories) like env have to be used to
> let python find all its "site-packages" from inputs.
I think this might be a good solution as it is a drop-in replacement for
our current use PYTHONPATH.
Hartmut wrote this:
> - sys.prefix and sys.exec_prefix would still point to the store, not to
> the profile. This might break Python appications expecting
> site-packages to be below sys.prefix.
Is this an actual problem? Do you know of applications that make this
assumption? If so, is this unfixable?
> We have a union "profile" for all the python packages, so environment
> variables can be totally avoided with the help of "venv".
>
> > We could avoid GUIX-PYTHONHOME[23] if we stop resolving the symlinks
> > at the correct point in iteration.
>
> This is exactly what "venv" does! We only need to make the "profile"
> a "venv" for python. For python3, a simple "pyvenv.cfg" file is
> enough, for python2 I guess we have to make a union or copy files like
> what "virtualenv" does.
I’m not too hopeful about this variant, but I’m rather ignorant about
venvs. My main concern is about whether it will still be possible for
users to create venvs from a subset of their installed packages when we
generate a pyvenv.cfg by default.
> I plan to implement option 1 by adding a "sitecustomize.py" (better
> than modify "site.py") into the python packages, and modify
> "search-path-specification" to use "GUIX_PYTHON_X_Y_SITE_PACKAGES".
>
> How's that sound?
This sounds good to me. Thank you and thanks again, Hartmut, for laying
out our options and analysing their advantages and drawbacks!
Before working on this, though, I would like to have the above question
answered to avoid wasting your time.
--
Ricardo
GPG: BCA6 89B6 3655 3801 C3C6 2150 197A 5888 235F ACAC
https://elephly.net
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH issue explanation
2018-03-17 10:07 ` Ricardo Wurmus
@ 2018-03-17 22:46 ` Hartmut Goebel
2018-03-17 22:53 ` Hartmut Goebel
1 sibling, 0 replies; 49+ messages in thread
From: Hartmut Goebel @ 2018-03-17 22:46 UTC (permalink / raw)
To: Ricardo Wurmus, 宋文武; +Cc: guix-devel
Am 17.03.2018 um 11:07 schrieb Ricardo Wurmus:
> What I don’t like about this solution is that PYTHONHOME can only hold a
> single directory, so composing profiles (that use the same Python
> variant) would no longer work. I prefer the
What exactly do you mean with "composing profiles"? This fails:
guix environment --ad-hoc python
echo $GUIX_ENVIRONMENT
# /gnu/store/0d8vp2h…-profile
echo $PYTHONPATH
# /gnu/store/0d8vp2h…-profile/lib/python3.5/site-packages
guix environment --ad-hoc python-simplejson
echo $GUIX_ENVIRONMENT
# /gnu/store/5xgfisg…-profile
echo $PYTHONPATH
# /gnu/store/0d8vp2h…-profile/lib/python3.5/site-packages
python3 -s -c 'import simplejson'
# import error
('-s' avoids leaking packages from §HOME/.local/…)
--
Regards
Hartmut Goebel
| Hartmut Goebel | h.goebel@crazy-compilers.com |
| www.crazy-compilers.com | compilers which you thought are impossible |
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH issue explanation
2018-03-17 10:07 ` Ricardo Wurmus
2018-03-17 22:46 ` Hartmut Goebel
@ 2018-03-17 22:53 ` Hartmut Goebel
1 sibling, 0 replies; 49+ messages in thread
From: Hartmut Goebel @ 2018-03-17 22:53 UTC (permalink / raw)
To: Ricardo Wurmus, 宋文武; +Cc: guix-devel
[-- Attachment #1: Type: text/plain, Size: 1062 bytes --]
Am 17.03.2018 um 11:07 schrieb Ricardo Wurmus:
>
>> - sys.prefix and sys.exec_prefix would still point to the store, not to
>> the profile. This might break Python appications expecting
>> site-packages to be below sys.prefix.
> Is this an actual problem? Do you know of applications that make this
> assumption? If so, is this unfixable?
I'm not aware of any actual problem.
> I’m not too hopeful about this variant, but I’m rather ignorant about
> venvs. My main concern is about whether it will still be possible for
> users to create venvs from a subset of their installed packages when we
> generate a pyvenv.cfg by default.
venvs never contain a "subset of installed packages". They either
include all system site-packages or none of them.
But as I've already written, generating a pyvenv.cfg for this case will
not work as we need it.
--
Regards
Hartmut Goebel
| Hartmut Goebel | h.goebel@crazy-compilers.com |
| www.crazy-compilers.com | compilers which you thought are impossible |
[-- Attachment #2: Type: text/html, Size: 1874 bytes --]
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH] gnu: python: Honor 'GUIX_PYTHON_X_Y_SITE_PACKAGES'.
2018-03-17 1:41 ` 宋文武
2018-03-17 10:07 ` Ricardo Wurmus
@ 2018-03-17 11:18 ` 宋文武
2018-03-17 21:53 ` Hartmut Goebel
2018-03-18 0:07 ` 宋文武
2018-03-17 22:04 ` PYTHONPATH issue explanation Hartmut Goebel
2 siblings, 2 replies; 49+ messages in thread
From: 宋文武 @ 2018-03-17 11:18 UTC (permalink / raw)
To: Hartmut Goebel; +Cc: guix-devel
[-- Attachment #1: Type: text/plain, Size: 219 bytes --]
> I plan to implement option 1 by adding a "sitecustomize.py" (better
> than modify "site.py") into the python packages, and modify
> "search-path-specification" to use "GUIX_PYTHON_X_Y_SITE_PACKAGES".
Patch coming:
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-gnu-python-2.7-python-3.6-Honor-GUIX_PYTHON_X_Y_SITE.patch --]
[-- Type: text/x-patch, Size: 4962 bytes --]
From d9c273c0ee8c5e87b12b37a325c649f8df808af3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=AE=8B=E6=96=87=E6=AD=A6?= <iyzsong@member.fsf.org>
Date: Sat, 17 Mar 2018 18:46:55 +0800
Subject: [PATCH] gnu: python-2.7, python-3.6: Honor
'GUIX_PYTHON_X_Y_SITE_PACKAGES'.
This replace the use of 'PYTHONPATH' as search path specification, as
suggested by Hartmut Goebel <h.goebel@crazy-compilers.com>. See
<https://lists.gnu.org/archive/html/guix-devel/2018-03/msg00178.html> for
details.
* gnu/packages/python.scm (python-guix-search-path-specification)
(python-guix-sitecustomize.py): New procedures.
(python-2.7, python-3.6):
[native-search-paths]: Use 'python-guix-search-path-specification'.
[arguments]: Add 'install-sitecustomize.py' phase.
---
gnu/packages/python.scm | 67 ++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 58 insertions(+), 9 deletions(-)
diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm
index 6639e6c9e..2ce8db710 100644
--- a/gnu/packages/python.scm
+++ b/gnu/packages/python.scm
@@ -136,6 +136,41 @@
#:use-module (guix build-system trivial)
#:use-module (srfi srfi-1))
+(define (python-guix-search-path-specification version)
+ "Return the search path specification for python VERSION."
+ (let* ((major.minor (version-major+minor version))
+ (variable (string-append
+ "GUIX_PYTHON_"
+ (string-replace-substring major.minor "." "_")
+ "_SITE_PACKAGES"))
+ (files (list (string-append
+ "lib/python" major.minor "/site-packages"))))
+ (search-path-specification
+ (variable variable)
+ (files files))))
+
+(define (python-guix-sitecustomize.py version)
+ "Return the content of @file{sitecustomize.py} for python VERSION."
+ (let* ((major.minor (version-major+minor version))
+ (variable (string-append
+ "GUIX_PYTHON_"
+ (string-replace-substring major.minor "." "_")
+ "_SITE_PACKAGES")))
+ (format #f "# Append module search paths for guix packages to sys.path.
+import os
+import site
+
+SITE_PACKAGES = os.environ.get('~a')
+
+if SITE_PACKAGES is None:
+ SITE_PACKAGES = []
+else:
+ SITE_PACKAGES = SITE_PACKAGES.split(os.pathsep)
+
+for i in SITE_PACKAGES:
+ site.addsitedir(i)
+" variable)))
+
(define-public python-2.7
(package
(name "python2")
@@ -304,6 +339,16 @@
"/site-packages")))
(install-file tkinter.so target)
(delete-file tkinter.so)))))
+ #t)))
+ (add-after 'install 'install-sitecustomize.py
+ (lambda* (#:keys outputs #:allow-other-keys)
+ (let* ((out (assoc-ref outputs "out"))
+ (sitedir (car (find-files out "^site-packages$"
+ #:directories #t))))
+ (with-output-to-file
+ (string-append sitedir "/sitecustomize.py")
+ (lambda ()
+ (display ,(python-guix-sitecustomize.py version))))
#t))))))
(inputs
`(("bzip2" ,bzip2)
@@ -318,9 +363,7 @@
(native-inputs
`(("pkg-config" ,pkg-config)))
(native-search-paths
- (list (search-path-specification
- (variable "PYTHONPATH")
- (files '("lib/python2.7/site-packages")))))
+ (list (python-guix-search-path-specification version)))
(home-page "https://www.python.org")
(synopsis "High-level, dynamically-typed programming language")
(description
@@ -427,13 +470,19 @@ data types.")
"-x" "(lib2to3|test/bad.*)"
,file)))
(find-files out "\\.py$")))
- (list '() '("-O") '("-OO"))))))))))
+ (list '() '("-O") '("-OO"))))))
+ (replace 'install-sitecustomize.py
+ (lambda* (#:keys outputs #:allow-other-keys)
+ (let* ((out (assoc-ref outputs "out"))
+ (sitedir (car (find-files out "^site-packages$"
+ #:directories #t))))
+ (with-output-to-file
+ (string-append sitedir "/sitecustomize.py")
+ (lambda ()
+ (display ,(python-guix-sitecustomize.py version))))
+ #t)))))))
(native-search-paths
- (list (search-path-specification
- (variable "PYTHONPATH")
- (files (list (string-append "lib/python"
- (version-major+minor version)
- "/site-packages"))))))))
+ (list (python-guix-search-path-specification version)))))
;; Current 3.x version.
(define-public python-3 python-3.6)
--
2.13.3
[-- Attachment #3: Type: text/plain, Size: 86 bytes --]
This targets 'core-updates' and will rebuild the world, I can't afford
to test it...
^ permalink raw reply related [flat|nested] 49+ messages in thread
* Re: [PATCH] gnu: python: Honor 'GUIX_PYTHON_X_Y_SITE_PACKAGES'.
2018-03-17 11:18 ` [PATCH] gnu: python: Honor 'GUIX_PYTHON_X_Y_SITE_PACKAGES' 宋文武
@ 2018-03-17 21:53 ` Hartmut Goebel
2018-03-18 0:04 ` 宋文武
2018-03-18 0:07 ` 宋文武
1 sibling, 1 reply; 49+ messages in thread
From: Hartmut Goebel @ 2018-03-17 21:53 UTC (permalink / raw)
To: 宋文武; +Cc: guix-devel
[-- Attachment #1: Type: text/plain, Size: 617 bytes --]
Am 17.03.2018 um 12:18 schrieb 宋文武:
>> I plan to implement option 1 by adding a "sitecustomize.py" (better
>> than modify "site.py") into the python packages, and modify
>> "search-path-specification" to use "GUIX_PYTHON_X_Y_SITE_PACKAGES".
Sorry, do say, but does not work in a virtual environment, since
GUIX_PYTHON_X_Y_SITE_PACKAGES will be added unconditionally. Also I
assume this will execute site.main() twice.
--
Regards
Hartmut Goebel
| Hartmut Goebel | h.goebel@crazy-compilers.com |
| www.crazy-compilers.com | compilers which you thought are impossible |
[-- Attachment #2: Type: text/html, Size: 1258 bytes --]
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] gnu: python: Honor 'GUIX_PYTHON_X_Y_SITE_PACKAGES'.
2018-03-17 21:53 ` Hartmut Goebel
@ 2018-03-18 0:04 ` 宋文武
0 siblings, 0 replies; 49+ messages in thread
From: 宋文武 @ 2018-03-18 0:04 UTC (permalink / raw)
To: Hartmut Goebel; +Cc: guix-devel
Hartmut Goebel <h.goebel@crazy-compilers.com> writes:
> Am 17.03.2018 um 12:18 schrieb 宋文武:
>
> I plan to implement option 1 by adding a "sitecustomize.py" (better
> than modify "site.py") into the python packages, and modify
> "search-path-specification" to use "GUIX_PYTHON_X_Y_SITE_PACKAGES".
>
> Sorry, do say, but does not work in a virtual environment, since GUIX_PYTHON_X_Y_SITE_PACKAGES will be added unconditionally. Also I assume this will execute site.main
> () twice.
Okay, and maybe it actually works? :-)
It turns out that 'sitecustomize.py' will be imported (executed) at most
once, and won't be added unconditionally:
- with "include-system-site-packages = false", a python3 created venv
will have a "sys.path" like:
['',
'/gnu/store/pppycfhs5gc7dsx7g099l9p6ncw3m6d9-python-3.6.4/lib/python36.zip',
'/gnu/store/pppycfhs5gc7dsx7g099l9p6ncw3m6d9-python-3.6.4/lib/python3.6',
'/gnu/store/pppycfhs5gc7dsx7g099l9p6ncw3m6d9-python-3.6.4/lib/python3.6/lib-dynload',
'/tmp/venv36/lib/python3.6/site-packages']
Since "sitecustomize.py" is in
"/gnu/store/pppycfhs5gc7dsx7g099l9p6ncw3m6d9-python-3.6.4/lib/python3.6/site-packages",
it's not executed at all.
- with "include-system-site-packages = true", the python3 created venv
will have a "sys.path" like:
['',
'/gnu/store/pppycfhs5gc7dsx7g099l9p6ncw3m6d9-python-3.6.4/lib/python36.zip',
'/gnu/store/pppycfhs5gc7dsx7g099l9p6ncw3m6d9-python-3.6.4/lib/python3.6',
'/gnu/store/pppycfhs5gc7dsx7g099l9p6ncw3m6d9-python-3.6.4/lib/python3.6/lib-dynload',
'/tmp/lib/python3.6/site-packages',
'/gnu/store/pppycfhs5gc7dsx7g099l9p6ncw3m6d9-python-3.6.4/lib/python3.6/site-packages',
...... (entries added by GUIX_PYTHON_3_6_SITE_PACKAGES)]
I think this is the wanted result.
I haven't try "virtualenv" and python2 (need time to build...), but
I guess the results should be the same?
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH] gnu: python: Honor 'GUIX_PYTHON_X_Y_SITE_PACKAGES'.
2018-03-17 11:18 ` [PATCH] gnu: python: Honor 'GUIX_PYTHON_X_Y_SITE_PACKAGES' 宋文武
2018-03-17 21:53 ` Hartmut Goebel
@ 2018-03-18 0:07 ` 宋文武
1 sibling, 0 replies; 49+ messages in thread
From: 宋文武 @ 2018-03-18 0:07 UTC (permalink / raw)
To: Hartmut Goebel; +Cc: guix-devel
[-- Attachment #1: Type: text/plain, Size: 428 bytes --]
iyzsong@member.fsf.org (宋文武) writes:
>> I plan to implement option 1 by adding a "sitecustomize.py" (better
>> than modify "site.py") into the python packages, and modify
>> "search-path-specification" to use "GUIX_PYTHON_X_Y_SITE_PACKAGES".
>
> Patch coming:
>
> [patch with typo...]
>
>
> This targets 'core-updates' and will rebuild the world, I can't afford
> to test it...
Updated with typo fixed:
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-gnu-python-2.7-python-3.6-Honor-GUIX_PYTHON_X_Y_SITE.patch --]
[-- Type: text/x-patch, Size: 4962 bytes --]
From d9c273c0ee8c5e87b12b37a325c649f8df808af3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=AE=8B=E6=96=87=E6=AD=A6?= <iyzsong@member.fsf.org>
Date: Sat, 17 Mar 2018 18:46:55 +0800
Subject: [PATCH] gnu: python-2.7, python-3.6: Honor
'GUIX_PYTHON_X_Y_SITE_PACKAGES'.
This replace the use of 'PYTHONPATH' as search path specification, as
suggested by Hartmut Goebel <h.goebel@crazy-compilers.com>. See
<https://lists.gnu.org/archive/html/guix-devel/2018-03/msg00178.html> for
details.
* gnu/packages/python.scm (python-guix-search-path-specification)
(python-guix-sitecustomize.py): New procedures.
(python-2.7, python-3.6):
[native-search-paths]: Use 'python-guix-search-path-specification'.
[arguments]: Add 'install-sitecustomize.py' phase.
---
gnu/packages/python.scm | 67 ++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 58 insertions(+), 9 deletions(-)
diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm
index 6639e6c9e..2ce8db710 100644
--- a/gnu/packages/python.scm
+++ b/gnu/packages/python.scm
@@ -136,6 +136,41 @@
#:use-module (guix build-system trivial)
#:use-module (srfi srfi-1))
+(define (python-guix-search-path-specification version)
+ "Return the search path specification for python VERSION."
+ (let* ((major.minor (version-major+minor version))
+ (variable (string-append
+ "GUIX_PYTHON_"
+ (string-replace-substring major.minor "." "_")
+ "_SITE_PACKAGES"))
+ (files (list (string-append
+ "lib/python" major.minor "/site-packages"))))
+ (search-path-specification
+ (variable variable)
+ (files files))))
+
+(define (python-guix-sitecustomize.py version)
+ "Return the content of @file{sitecustomize.py} for python VERSION."
+ (let* ((major.minor (version-major+minor version))
+ (variable (string-append
+ "GUIX_PYTHON_"
+ (string-replace-substring major.minor "." "_")
+ "_SITE_PACKAGES")))
+ (format #f "# Append module search paths for guix packages to sys.path.
+import os
+import site
+
+SITE_PACKAGES = os.environ.get('~a')
+
+if SITE_PACKAGES is None:
+ SITE_PACKAGES = []
+else:
+ SITE_PACKAGES = SITE_PACKAGES.split(os.pathsep)
+
+for i in SITE_PACKAGES:
+ site.addsitedir(i)
+" variable)))
+
(define-public python-2.7
(package
(name "python2")
@@ -304,6 +339,16 @@
"/site-packages")))
(install-file tkinter.so target)
(delete-file tkinter.so)))))
+ #t)))
+ (add-after 'install 'install-sitecustomize.py
+ (lambda* (#:keys outputs #:allow-other-keys)
+ (let* ((out (assoc-ref outputs "out"))
+ (sitedir (car (find-files out "^site-packages$"
+ #:directories #t))))
+ (with-output-to-file
+ (string-append sitedir "/sitecustomize.py")
+ (lambda ()
+ (display ,(python-guix-sitecustomize.py version))))
#t))))))
(inputs
`(("bzip2" ,bzip2)
@@ -318,9 +363,7 @@
(native-inputs
`(("pkg-config" ,pkg-config)))
(native-search-paths
- (list (search-path-specification
- (variable "PYTHONPATH")
- (files '("lib/python2.7/site-packages")))))
+ (list (python-guix-search-path-specification version)))
(home-page "https://www.python.org")
(synopsis "High-level, dynamically-typed programming language")
(description
@@ -427,13 +470,19 @@ data types.")
"-x" "(lib2to3|test/bad.*)"
,file)))
(find-files out "\\.py$")))
- (list '() '("-O") '("-OO"))))))))))
+ (list '() '("-O") '("-OO"))))))
+ (replace 'install-sitecustomize.py
+ (lambda* (#:keys outputs #:allow-other-keys)
+ (let* ((out (assoc-ref outputs "out"))
+ (sitedir (car (find-files out "^site-packages$"
+ #:directories #t))))
+ (with-output-to-file
+ (string-append sitedir "/sitecustomize.py")
+ (lambda ()
+ (display ,(python-guix-sitecustomize.py version))))
+ #t)))))))
(native-search-paths
- (list (search-path-specification
- (variable "PYTHONPATH")
- (files (list (string-append "lib/python"
- (version-major+minor version)
- "/site-packages"))))))))
+ (list (python-guix-search-path-specification version)))))
;; Current 3.x version.
(define-public python-3 python-3.6)
--
2.13.3
^ permalink raw reply related [flat|nested] 49+ messages in thread
* Re: PYTHONPATH issue explanation
2018-03-17 1:41 ` 宋文武
2018-03-17 10:07 ` Ricardo Wurmus
2018-03-17 11:18 ` [PATCH] gnu: python: Honor 'GUIX_PYTHON_X_Y_SITE_PACKAGES' 宋文武
@ 2018-03-17 22:04 ` Hartmut Goebel
2018-03-18 0:57 ` 宋文武
2 siblings, 1 reply; 49+ messages in thread
From: Hartmut Goebel @ 2018-03-17 22:04 UTC (permalink / raw)
To: 宋文武; +Cc: guix-devel
Hi,
I agree with Ricardo: We first should agree on what we want to implement.
I created a pad at [1] for collecting all test-cases and the expected
results. Please add you test-cases there. Thanks!
[1] https://semestriel.framapad.org/p/guix-python-site-packages-test-cases
Am 17.03.2018 um 02:41 schrieb 宋文武:
> - "GUIX_PYTHON_X_Y_SITE_PACKAGES" […] is necessary for the "build" environment.
For the build environment we could easily work around using PYTHONPATH.
Since the build-system is clearly defined and does not interfere with
any user-definitions, this is save to do.
> - Avoid any environment variable for the "profile" environment.
>
> We have a union "profile" for all the python packages, so environment
> variables can be totally avoided with the help of "venv".
[…]
> We only need to make the "profile"
> a "venv" for python. For python3, a simple "pyvenv.cfg" file is
> enough, for python2 I guess we have to make a union or copy files like
> what "virtualenv" does.
This would be a very elegant solution. Unfortunately this does not work
as shown in part 2 of my analysis, esp. point 4a.
> > We could avoid GUIX-PYTHONHOME[23] if we stop resolving the symlinks
> > at the correct point in iteration.
>
> This is exactly what "venv" does!
Unfortunately venv works quite different: system site-packages are
always taken from sys.base_exec. See part 3 of my analysis, esp. the
"pyvenv.cfg" section.
> I plan to implement option 1 by adding a "sitecustomize.py" (better
> than modify "site.py") into the python packages, and modify
> "search-path-specification" to use "GUIX_PYTHON_X_Y_SITE_PACKAGES".
When implementing this in sitecustomize.py, you will end up
re-implementing the complete venv mechanism.
When going the GUIX_PYTHON_X_Y_SITE_PACKAGES route, we should look where
the best place will be: Maybe site.PREFIXES, maybe
site.getsitepackages(), maybe site.venv().
--
Regards
Hartmut Goebel
| Hartmut Goebel | h.goebel@crazy-compilers.com |
| www.crazy-compilers.com | compilers which you thought are impossible |
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH issue explanation
2018-03-17 22:04 ` PYTHONPATH issue explanation Hartmut Goebel
@ 2018-03-18 0:57 ` 宋文武
2018-03-18 10:05 ` 宋文武
0 siblings, 1 reply; 49+ messages in thread
From: 宋文武 @ 2018-03-18 0:57 UTC (permalink / raw)
To: Hartmut Goebel; +Cc: guix-devel
Hartmut Goebel <h.goebel@crazy-compilers.com> writes:
> Hi,
>
> I agree with Ricardo: We first should agree on what we want to
> implement.
Okay.
>
> I created a pad at [1] for collecting all test-cases and the expected
> results. Please add you test-cases there. Thanks!
>
> [1] https://semestriel.framapad.org/p/guix-python-site-packages-test-cases
I have append some text, it's available to all in realtime?
not sure how it works...
>
> Am 17.03.2018 um 02:41 schrieb 宋文武:
>
>> - "GUIX_PYTHON_X_Y_SITE_PACKAGES" […] is necessary for the "build" environment.
> For the build environment we could easily work around using PYTHONPATH.
> Since the build-system is clearly defined and does not interfere with
> any user-definitions, this is save to do.
Yes, but if "GUIX_PYTHON_X_Y_SITE_PACKAGES" does works (i hope so) in
the "profile" side, it's better to replace PYTHONPATH for consistent.
>
>> - Avoid any environment variable for the "profile" environment.
>>
>> We have a union "profile" for all the python packages, so environment
>> variables can be totally avoided with the help of "venv".
> […]
>> We only need to make the "profile"
>> a "venv" for python. For python3, a simple "pyvenv.cfg" file is
>> enough, for python2 I guess we have to make a union or copy files like
>> what "virtualenv" does.
>
> This would be a very elegant solution. Unfortunately this does not work
> as shown in part 2 of my analysis, esp. point 4a.
A workaround for the broke case maybe tell the user to create a
"sitecustomize.py" in the created venv, and add the search paths of
profile himself.
I'd like do more tests with the GUIX_PYTHON_X_Y_SITE_PACKAGES option
(patch sent), hope it works :-)
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH issue explanation
2018-03-18 0:57 ` 宋文武
@ 2018-03-18 10:05 ` 宋文武
0 siblings, 0 replies; 49+ messages in thread
From: 宋文武 @ 2018-03-18 10:05 UTC (permalink / raw)
To: Hartmut Goebel; +Cc: guix-devel
[-- Attachment #1: Type: text/plain, Size: 464 bytes --]
iyzsong@member.fsf.org (宋文武) writes:
> [...]
>
> I'd like do more tests with the GUIX_PYTHON_X_Y_SITE_PACKAGES option
> (patch sent), hope it works :-)
Hello, I have write a shell script to do some tests, it looks good to me!
Updated 'GUIX_PYTHON_X_Y_SITE_PACKAGES' patch, target 'core-updates' at
commit 171a117c (you also have to comment out the "manual-database"
profile hook in the "guix/profiles.scm", as it's broken in that commit):
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-gnu-python-2.7-python-3.6-Honor-GUIX_PYTHON_X_Y_SITE.patch --]
[-- Type: text/x-patch, Size: 4858 bytes --]
From d807306d02aab0a84de4fa3ff457a5b97ac15520 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=AE=8B=E6=96=87=E6=AD=A6?= <iyzsong@member.fsf.org>
Date: Sat, 17 Mar 2018 18:46:55 +0800
Subject: [PATCH] gnu: python-2.7, python-3.6: Honor
'GUIX_PYTHON_X_Y_SITE_PACKAGES'.
This replace the use of 'PYTHONPATH' as search path specification, as
suggested by Hartmut Goebel <h.goebel@crazy-compilers.com>. See
<https://lists.gnu.org/archive/html/guix-devel/2018-03/msg00178.html> for
details.
* gnu/packages/python.scm (python-guix-search-path-specification)
(python-guix-sitecustomize.py): New procedures.
(python-2.7, python-3.6):
[native-search-paths]: Use 'python-guix-search-path-specification'.
[arguments]: Add 'install-sitecustomize.py' phase.
---
gnu/packages/python.scm | 65 +++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 57 insertions(+), 8 deletions(-)
diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm
index f3a75c30e..45de8c527 100644
--- a/gnu/packages/python.scm
+++ b/gnu/packages/python.scm
@@ -136,6 +136,41 @@
#:use-module (guix build-system trivial)
#:use-module (srfi srfi-1))
+(define (python-guix-search-path-specification version)
+ "Return the search path specification for python VERSION."
+ (let* ((major.minor (version-major+minor version))
+ (variable (string-append
+ "GUIX_PYTHON_"
+ (string-replace-substring major.minor "." "_")
+ "_SITE_PACKAGES"))
+ (files (list (string-append
+ "lib/python" major.minor "/site-packages"))))
+ (search-path-specification
+ (variable variable)
+ (files files))))
+
+(define (python-guix-sitecustomize.py version)
+ "Return the content of @file{sitecustomize.py} for python VERSION."
+ (let* ((major.minor (version-major+minor version))
+ (variable (string-append
+ "GUIX_PYTHON_"
+ (string-replace-substring major.minor "." "_")
+ "_SITE_PACKAGES")))
+ (format #f "# Append module search paths for guix packages to sys.path.
+import os
+import site
+
+SITE_PACKAGES = os.environ.get('~a')
+
+if SITE_PACKAGES is None:
+ SITE_PACKAGES = []
+else:
+ SITE_PACKAGES = SITE_PACKAGES.split(os.pathsep)
+
+for i in SITE_PACKAGES:
+ site.addsitedir(i)
+" variable)))
+
(define-public python-2.7
(package
(name "python2")
@@ -304,6 +339,16 @@
"/site-packages")))
(install-file tkinter.so target)
(delete-file tkinter.so)))))
+ #t)))
+ (add-after 'install 'install-sitecustomize.py
+ (lambda* (#:key outputs #:allow-other-keys)
+ (let* ((out (assoc-ref outputs "out"))
+ (sitedir (car (find-files out "^site-packages$"
+ #:directories? #t))))
+ (with-output-to-file
+ (string-append sitedir "/sitecustomize.py")
+ (lambda ()
+ (display ,(python-guix-sitecustomize.py version))))
#t))))))
(inputs
`(("bzip2" ,bzip2)
@@ -318,9 +363,7 @@
(native-inputs
`(("pkg-config" ,pkg-config)))
(native-search-paths
- (list (search-path-specification
- (variable "PYTHONPATH")
- (files '("lib/python2.7/site-packages")))))
+ (list (python-guix-search-path-specification version)))
(home-page "https://www.python.org")
(synopsis "High-level, dynamically-typed programming language")
(description
@@ -428,13 +471,19 @@ data types.")
,file)))
(find-files out "\\.py$")))
(list '() '("-O") '("-OO")))
+ #t)))
+ (replace 'install-sitecustomize.py
+ (lambda* (#:key outputs #:allow-other-keys)
+ (let* ((out (assoc-ref outputs "out"))
+ (sitedir (car (find-files out "^site-packages$"
+ #:directories? #t))))
+ (with-output-to-file
+ (string-append sitedir "/sitecustomize.py")
+ (lambda ()
+ (display ,(python-guix-sitecustomize.py version))))
#t)))))))
(native-search-paths
- (list (search-path-specification
- (variable "PYTHONPATH")
- (files (list (string-append "lib/python"
- (version-major+minor version)
- "/site-packages"))))))))
+ (list (python-guix-search-path-specification version)))))
;; Current 3.x version.
(define-public python-3 python-3.6)
--
2.13.3
[-- Attachment #3: Type: text/plain, Size: 31 bytes --]
And here is the test script:
[-- Attachment #4: test-python-site-packages.sh --]
[-- Type: application/x-sh, Size: 3483 bytes --]
[-- Attachment #5: Type: text/plain, Size: 32 bytes --]
Do I miss something? Thanks!
^ permalink raw reply related [flat|nested] 49+ messages in thread
* Re: PYTHONPATH issue explanation
2018-03-15 19:30 ` PYTHONPATH issue explanation Hartmut Goebel
2018-03-17 1:41 ` 宋文武
@ 2018-03-24 20:47 ` Chris Marusich
1 sibling, 0 replies; 49+ messages in thread
From: Chris Marusich @ 2018-03-24 20:47 UTC (permalink / raw)
To: Hartmut Goebel; +Cc: guix-devel
[-- Attachment #1: Type: text/plain, Size: 8558 bytes --]
Hi Hartmut,
Awesome analysis! Thank you for taking point on this. I will offer
some feedback. I hope it is useful.
The short version is: I think Python should let us explicitly tell it
where its system site directory is. If Python provided such a feature,
then I think we could use it and avoid all these problems. I think this
would be better than modifying the heuristics that Python uses for
finding its system site during start-up (although I think that is a good
back-up plan), since those heuristics are complicated and difficult to
control. It would just be simpler if we could explicitly tell Python
where its site directory is, instead of indirectly arranging for Python
to find its site directory via its module-lookup Rube-Goldberg machine.
Hartmut Goebel <h.goebel@crazy-compilers.com> writes:
> This python interpreter does not find the site-packages in GUIX_PROFILE
> since site-packages are search relative to "sys.base_prefix" (which is
> the same as "sys.prefix" except in virtual environments).
> "sys.base_prefix" is determined based on the executable's path (argv[0])
> by resolving all symlinks.
I am familiar with this problem. Any time you want to deploy Python and
its libraries by building up a symlink tree, and you put Python in a
part of the file system that lives far away from the libraries
themselves, Python will punish you cruelly with this behavior. It is no
fun at all. :-( You always have to come up with silly hacks to work
around it, and those hacks don't work generally in every case.
Question: Why does Python insist on canonicalizing its executable path?
It always seemed to me like if Python just used the original path, these
problems would not occur. People who use symlink trees to deploy Python
would be happy. Perhaps I am missing some information. What is the
intent behind Python's decision to canonicalize the executable path?
What problems occur if Python doesn't do that?
> The python interpreter assumes "site-packages" to be relative to "where
> python is installed" - called "sys.base_prefix" (which is the same as
> "sys.prefix" except in virtual environments). "sys.base_prefix" is
> determined based on the executable's path (argv[0]) by resolving all
> symlinks. For Guix this means: "sys.base_prefix" will always point to
> /gnu/store/…-python-X.Y, not to GUIX_PROFILE. Thus the site-packages
> installed into the guix profile will not be found.
Yes. This is a problem. As you know, this heuristic fails
spectacularly when you try to deploy Python in a symlink tree.
Question: Why does Python not supply a way to "inject" the system site
directory? In Guix-deployed systems, we are the masters of reality. We
control ALL the paths. We can tell Python exactly where its "system
site" is - we can build a symlink tree of its system site in the store
and then tell Python to use that site specifically. For example, if
Python would let us specify this path via a PYTHON_SYSTEM_SITE
environment variable, then I think it would solve many (all?) of our
problems. Perhaps this is similar to what you are suggesting regarding
GUIX_PYTHON_X.Y_SITE_PACKAGES and GUIX_PYTHONHOME_X.Y.
> This is why we currently (mis-) use PYTHONPATH: To make the
> site-packages installed into the guix profile available.
I agree that this is a mis-use. People do it because Python doesn't
provide any better way. And then people find out about all its terrible
down-sides, like for example the fact that .pth files will not be
processed if they appear on the PYTHONPATH. And then they do stuff like
hack site.py to walk the PYTHONPATH and evaluate all the .pth files,
which is gross but sort of works. Just thinking about the pain I have
experienced with this stuff makes my blood boil.
> no. 2
> suggests using a mechanism already implemented in python: Setting
> "PYTHONHOME" will make the interpreter to use this as "sys.base_prefix"
> unconditionally. Again there is only one PYTHONHOME variable for all
> versions of python (designed by upstream). We could work around this
> easily (while keeping upstream compatibility) by using
> GUIX-PYTHONHOME-X.Y, to be evaluated just after PYTHONHOME.
Are there legitimate use cases where a user wants to set their own
PYTHONHOME? If so, would our use of PYTHONHOME prevent them from doing
that? If so, that seems bad.
In the past, I have used PYTHONUSERBASE (or maybe it was PYTHONUSERSITE,
I can't remember exactly which) to make Python find libraries in a
symlink tree. However, because that is intended for users to use, I
don't think it's a good solution for us here. If we co-opt these
environment variables, then users would not be able to use them.
> The drawback is: This is implemented using an environment variable,
> which might not give the expected results in all cases. E.g. running
> /gnu/store/…-profile/bin/python will not load the site-packages of that
> profile. Also there might be issues implementing virtual environments.
> (Thinking about this, I'm quite sure there will. Ouch!)
I wouldn't be surprised if that's true, but right now, I can't think of
any specific virtualenv-related problems that would occur by using
PYTHONHOME.
> no.3
> suggests changing the way the python interpreter is resolving symlinks
> when searching for "sys.base_prefix". The idea is to stop "at the profile".
>
> The hard part of this is to determine "at the profile". Also this needs
> a larger patch. But if we manage to implement this, it would be perfect.
> I could contribute a draft for this implemented in Python. The
> C-implementation needs to be done by some C programmer.
This seems a little tricky, mainly because it's going to rely again on
heuristics that may not always be accurate. As I mentioned above, in
Guix we are the masters of reality, so why can't we just tell Python
exactly where its system site path is? If Python needs to be taught how
to be informed of such things, perhaps that is the patch we should
write: a patch that enables us to tell Python exactly where its system
site directory will be found.
> Which way should we go?
I think we should figure out a way to tell Python EXACTLY where its
system site directory is. If that isn't viable, then I think the next
best thing will be to adjust the site-finding heuristics (your proposal
No. 3).
Hartmut Goebel <h.goebel@crazy-compilers.com> writes:
> As it stands now, the venv-hack is not a valid solution. It may be the basis
> for another solution, tough.
I agree. We need a solution that allows users to use virtualenv the way
they would normally on any other foreign distro, if they want to.
> 1. How could GUIX-PYTHON-X.Y-SITE-PACKAGES be implemented?
> =============================================================
>
> [...]
>
> 2. How could GUIX-PYTHONHOME-X.Y be implemented?
> =================================================
How do these two methods (GUIX-PYTHON-X.Y-SITE-PACKAGES
vs. GUIX-PYTHONHOME-X.Y) differ? They seem to serve basically the same
purpose.
> 3. How to avoid GUIX-PYTHONHOME[23]?
> =========================================
>
> We could avoid GUIX-PYTHONHOME[23] if we stop resolving the symlinks at
> the correct point in iteration.
>
> [...]
>
> Drawbacks:
>
> - More complicated patch.
>
> - More comparison within a look, this will slow down start-up a bit.
>
> Open questions:
>
> - Which are the correct paths to check to stop iteration?
> - How to handle the "pythonX" -> "pythonX.Y" link?
> - How to handle "python-wrapper", which links python -> python3
Instead of modifying Python's heuristics for finding its site, it'd be
better if Python just exposed a way for us to explicitly tell it where
its site directory is.
However, if we really want to modify the heuristics, I can think of some
possible ideas for how to do it:
* Don't canonicalize the path in the first place.
* Stop just before the first path that is in the store.
* Stop at the first path that is in the store.
* Stop at a path that matches a special pattern that we control,
like "guix-python-site" or something. We could create
> 4. Path-handling in Python's start-up sequence
As you've shown, the way Python handles paths when it starts up is quite
complicated. This is another reason why I would prefer not to change
the heuristics, but instead to expose a way for us to explicitly tell
Python where its site is.
--
Chris
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply [flat|nested] 49+ messages in thread
* PYTHONPATH - let's systematically tame the baest
2018-03-11 21:47 ` PYTHONPATH issue analysis - part 3 " Hartmut Goebel
2018-03-13 21:23 ` PYTHONPATH issue analysis - part 3 Ludovic Courtès
2018-03-15 19:30 ` PYTHONPATH issue explanation Hartmut Goebel
@ 2018-04-16 14:21 ` Hartmut Goebel
2018-04-17 1:47 ` 宋文武
2018-04-18 8:34 ` Ricardo Wurmus
2 siblings, 2 replies; 49+ messages in thread
From: Hartmut Goebel @ 2018-04-16 14:21 UTC (permalink / raw)
To: Pjotr Prins; +Cc: guix-devel
Hi,
let's pick up on this issue and systematically design the test-cases to
benchmark the proposed solutions. I already prepared a test-script to
simplify this and will provide a full description as later.
**Please comment if any relevant case is missing or if any case can be
skipped**
1) Test-cases
For all environments (see below) these cases must give the expected
output - which is defined by what a "foreign distribution's" python
would do:
- "installed" python
- venv with and without --system-site-packages
- stacked venv with and without --system-site-packages
2) Environments to be tested.
The proposed solution must pass the test-suite in all of these environments:
2.1 guix environment:
guix environment --ad-hoc python -- python3 testit
--> Expected outcome: site-packages from GUIX_ENVIRONEMENT
2.2 guix environment with container:
guix environment -C --ad-hoc python -- python3 testit
--> Expected outcome: site-packages from GUIX_ENVIRONEMENT
2.3 Installed package *without setting the environment variables!*
guix package -i python && ~/.guix-profile/bin/python3 testit
--> Expected outcome: site-packages from ~/.guix-profile/
--> Shall this work, too? Is it nice-to-have or useless?
2.4 running from /gnu/store (directly)
$(readlink -f ~/.guix-profile/bin/python3) testit
--> Expected outcome: site-packages from /gnu/store
--> What is the expected outcome? What is the expected
2.5 running from /gnu/store (via link)
ln -s $(readlink -f ~/.guix-profile/bin/python3)
/tmp/test-guix-pythonA.exe ;
/tmp/test-guix-pythonA.exe testit
--> Expected outcome: site-packages from /gnu/store
2.6 Installed in GuixSD
--> Do we need to test this? Or is this already covered by one of
the other cases?
--
Regards
Hartmut Goebel
| Hartmut Goebel | h.goebel@crazy-compilers.com |
| www.crazy-compilers.com | compilers which you thought are impossible |
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH - let's systematically tame the baest
2018-04-16 14:21 ` PYTHONPATH - let's systematically tame the baest Hartmut Goebel
@ 2018-04-17 1:47 ` 宋文武
2018-04-17 7:03 ` Hartmut Goebel
2018-04-18 8:34 ` Ricardo Wurmus
1 sibling, 1 reply; 49+ messages in thread
From: 宋文武 @ 2018-04-17 1:47 UTC (permalink / raw)
To: Hartmut Goebel; +Cc: guix-devel
Hartmut Goebel <h.goebel@crazy-compilers.com> writes:
> Hi,
Hello!
>
> let's pick up on this issue and systematically design the test-cases to
> benchmark the proposed solutions. I already prepared a test-script to
> simplify this and will provide a full description as later.
>
> **Please comment if any relevant case is missing or if any case can be
> skipped**
>
> 1) Test-cases
>
> For all environments (see below) these cases must give the expected
> output - which is defined by what a "foreign distribution's" python
> would do:
> - "installed" python
> - venv with and without --system-site-packages
> - stacked venv with and without --system-site-packages
We should consider both python2 and python3, and virtual environments
created by the 'virtualenv' package.
>
> 2) Environments to be tested.
>
> The proposed solution must pass the test-suite in all of these environments:
>
> 2.1 guix environment:
>
> guix environment --ad-hoc python -- python3 testit
> --> Expected outcome: site-packages from GUIX_ENVIRONEMENT
>
> 2.2 guix environment with container:
>
> guix environment -C --ad-hoc python -- python3 testit
> --> Expected outcome: site-packages from GUIX_ENVIRONEMENT
>
> 2.3 Installed package *without setting the environment variables!*
>
> guix package -i python && ~/.guix-profile/bin/python3 testit
> --> Expected outcome: site-packages from ~/.guix-profile/
> --> Shall this work, too? Is it nice-to-have or useless?
Yeah, it's nice to have (to avoid introducing an environment variable),
but not necessary.
>
> 2.4 running from /gnu/store (directly)
>
> $(readlink -f ~/.guix-profile/bin/python3) testit
> --> Expected outcome: site-packages from /gnu/store
> --> What is the expected outcome? What is the expected
I think if we use environment variable to specify all the site-packages,
it should be the same as running from profile. It maybe different if we
resolve site-packages by the executable location...
>
> 2.5 running from /gnu/store (via link)
>
> ln -s $(readlink -f ~/.guix-profile/bin/python3)
> /tmp/test-guix-pythonA.exe ;
> /tmp/test-guix-pythonA.exe testit
> --> Expected outcome: site-packages from /gnu/store
True when we're not use the environment variable.
>
> 2.6 Installed in GuixSD
>
> --> Do we need to test this? Or is this already covered by one of
> the other cases?
For this, there is nothing special about GuixSD.
Had you review my 'GUIX_PYTHON_X_Y_SITE_PACKAGES' patch? I think it's
enough to support both python2 and python3 in the same profile:
http://lists.gnu.org/archive/html/guix-devel/2018-03/msg00238.html
Thanks!
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH - let's systematically tame the baest
2018-04-17 1:47 ` 宋文武
@ 2018-04-17 7:03 ` Hartmut Goebel
0 siblings, 0 replies; 49+ messages in thread
From: Hartmut Goebel @ 2018-04-17 7:03 UTC (permalink / raw)
To: 宋文武; +Cc: guix-devel
Am 17.04.2018 um 03:47 schrieb 宋文武:
> Had you review my 'GUIX_PYTHON_X_Y_SITE_PACKAGES' patch? I think it's
> enough to support both python2 and python3 in the same profile:
Yes I had. But we should first decide on he expected results, then
decide which solution is adequate :-)
--
Regards
Hartmut Goebel
| Hartmut Goebel | h.goebel@crazy-compilers.com |
| www.crazy-compilers.com | compilers which you thought are impossible |
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: PYTHONPATH - let's systematically tame the baest
2018-04-16 14:21 ` PYTHONPATH - let's systematically tame the baest Hartmut Goebel
2018-04-17 1:47 ` 宋文武
@ 2018-04-18 8:34 ` Ricardo Wurmus
1 sibling, 0 replies; 49+ messages in thread
From: Ricardo Wurmus @ 2018-04-18 8:34 UTC (permalink / raw)
To: Hartmut Goebel; +Cc: guix-devel
Hi Hartmut,
> let's pick up on this issue and systematically design the test-cases to
> benchmark the proposed solutions. I already prepared a test-script to
> simplify this and will provide a full description as later.
Thank you for picking up the work on this!
In all of the tests do we only care about the reported value of
site-packages? Should the tests include loading non-trivial packages
that have other Python packages as dependencies?
> 2.3 Installed package *without setting the environment variables!*
>
> guix package -i python && ~/.guix-profile/bin/python3 testit
> --> Expected outcome: site-packages from ~/.guix-profile/
> --> Shall this work, too? Is it nice-to-have or useless?
2.3b is to install the package into a separate profile with
guix package -p /path/to/somewhere -i python
> 2.4 running from /gnu/store (directly)
>
> $(readlink -f ~/.guix-profile/bin/python3) testit
> --> Expected outcome: site-packages from /gnu/store
> --> What is the expected outcome? What is the expected
>
> 2.5 running from /gnu/store (via link)
>
> ln -s $(readlink -f ~/.guix-profile/bin/python3)
> /tmp/test-guix-pythonA.exe ;
> /tmp/test-guix-pythonA.exe testit
> --> Expected outcome: site-packages from /gnu/store
I think these two cases should yield the same result.
> 2.6 Installed in GuixSD
>
> --> Do we need to test this? Or is this already covered by one of
> the other cases?
I don’t think we need to test this as GuixSD does not have any special
behaviour for Python and the system profile is just another profile.
This would be the same as 2.3b.
--
Ricardo
^ permalink raw reply [flat|nested] 49+ messages in thread