Skip to content

python3.buildEnv: support extending NIX_PYTHONPATH#261801

Open
yajo wants to merge 1 commit intoNixOS:stagingfrom
moduon:python-nested-venv
Open

python3.buildEnv: support extending NIX_PYTHONPATH#261801
yajo wants to merge 1 commit intoNixOS:stagingfrom
moduon:python-nested-venv

Conversation

@yajo
Copy link
Contributor

@yajo yajo commented Oct 18, 2023

Allow devshells to extend $NIX_PYTHONPATH, to effectively support nested virtualenvs.

@moduon MT-1075

Description of changes

I'm trying to set up a devshell where:

  • Most python dependencies are pure.
  • Some python modules I'm developing in a meta-repo are impure.

In this specific scenario, some pure dependencies depend on impure ones.

For example, I'm developing odoo and some addons, but while doing so I want to have click-odoo-contrib at my fingertips while developing. Thus, I add it to my devshell. Sounds nice, but when I try to execute it, I get an ImportError:

➤ click-odoo-listdb --help
Traceback (most recent call last):
  File "/nix/store/p8ivjzvbbkm6jqc9vyvhh6r6p4qvv2qj-python3.10-click-odoo-contrib-1.17.0/bin/.click-odoo-listdb-wrapped", line 6, in <module>
    from click_odoo_contrib.listdb import main
  File "/nix/store/r6djzp9sdnmgpaz9k413y1jdhn9aizr5-odoo-dev-16.0-python3-3.10.12-env/lib/python3.10/site-packages/click_odoo_contrib/listdb.py", line 6, in <module>
    import click_odoo
  File "/nix/store/r6djzp9sdnmgpaz9k413y1jdhn9aizr5-odoo-dev-16.0-python3-3.10.12-env/lib/python3.10/site-packages/click_odoo/__init__.py", line 4, in <module>
    from .compat import odoo  # noqa
  File "/nix/store/r6djzp9sdnmgpaz9k413y1jdhn9aizr5-odoo-dev-16.0-python3-3.10.12-env/lib/python3.10/site-packages/click_odoo/compat.py", line 11, in <module>
    import odoo
ModuleNotFoundError: No module named 'odoo'

That's expected. Odoo is installed as an editable dependency in an impure venv, because I'm developing it.

How could one pure package, packaged by nix, such as click-odoo-contrib, import an impure one installed in a venv in editable mode? The solution is to customize the site. It turns out that's already handled by Nix in these lines:

paths = os.environ.pop('NIX_PYTHONPATH', None)
if paths:
functools.reduce(lambda k, p: site.addsitedir(p, k), paths.split(':'), site._init_pathinfo())

As you can see in that code, it supports multiple paths separated by colon.

However, without this patch, any binary produced from a Nix python environment will ignore any NIX_PYTHONPATH variable and replace it with what it wants.

Now, after this is done, I can just add to my devshell an environment variable in the shape of NIX_PYTHONPATH = "$PRJ_ROOT_DIR/.venv/${python.sitePackages}", and magically click-odoo-listdb will be able to import odoo if it is installed into that venv.

Things done

  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandbox = true set in nix.conf? (See Nix manual)
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 23.11 Release Notes (or backporting 23.05 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

@yajo yajo requested a review from FRidh as a code owner October 18, 2023 10:38
@github-actions github-actions bot added the 6.topic: python Python is a high-level, general-purpose programming language. label Oct 18, 2023
@ofborg ofborg bot added 10.rebuild-darwin: 501+ This PR causes many rebuilds on Darwin and should normally target the staging branches. 10.rebuild-darwin: 5001+ This PR causes many rebuilds on Darwin and must target the staging branches. 10.rebuild-linux: 501+ This PR causes many rebuilds on Linux and should normally target the staging branches. 10.rebuild-linux: 5001+ This PR causes many rebuilds on Linux and must target the staging branches. labels Oct 18, 2023
@wegank wegank added the 2.status: merge conflict This PR has merge conflicts with the target branch label Apr 5, 2024
@yajo
Copy link
Contributor Author

yajo commented Apr 17, 2024

Fixed in #297628 using a different strategy.

@yajo yajo closed this Apr 17, 2024
@yajo yajo deleted the python-nested-venv branch April 17, 2024 10:07
@yajo yajo restored the python-nested-venv branch August 2, 2024 12:44
@yajo yajo reopened this Aug 2, 2024
@yajo yajo requested a review from natsukium as a code owner August 2, 2024 12:46
@yajo yajo force-pushed the python-nested-venv branch from 36918fa to 983e53c Compare August 2, 2024 12:47
@yajo
Copy link
Contributor Author

yajo commented Aug 2, 2024

I see that #297628 was reverted in #302385, and there's a new attempt to fix it in #326094. Therefore, I think this alternate proposal still is relevant and I reopened and rebased.

@yajo yajo mentioned this pull request Aug 2, 2024
@ofborg ofborg bot added 10.rebuild-darwin-stdenv This PR causes stdenv to rebuild on Darwin and must target a staging branch. and removed 2.status: merge conflict This PR has merge conflicts with the target branch labels Aug 2, 2024
@yajo
Copy link
Contributor Author

yajo commented Aug 8, 2024

Answering to #326094 (comment) here to avoid polluting that other thread too much:

well, I am not sure

Fair point 😆

Well, let's be more accurate and say it fixed the problem for me while not presenting any incompatibilities, and I tested the fix in depth.

Of course, if you happen to be exporting a NIX_PYTHONPATH variable in your devshell, then yes, this will alter the behavior. But if you were doing that, then it's maybe because you were hoping it fixed this problem, so the side effect would still probably be that we'd fix something, which should be a good thing too.

FWIW, in my case I can export that variable in a devshell pointing to python dependencies from nix, and still create a venv, install editable packages on it, and be able to work, mixing all nix and impure dependencies in the venv.

OTOH I can't find a reason why NIX_PYTHONPATH should be set instead of prefixed. 🤔

@FRidh
Copy link
Member

FRidh commented Aug 8, 2024

To not break with nested environments. When you use prefixing or suffixing you can mix packages causing breakage.

Check the sitecustomize.py. It also unsets the variables because they should not leak further.

@yajo
Copy link
Contributor Author

yajo commented Aug 11, 2024 via email

@FRidh
Copy link
Member

FRidh commented Aug 11, 2024

That's why this cannot go in. It is set on purpose.

The NIX_PYTHONPATH is an internal implementation, it is not meant to be exposed. Users can just set the regular PYTHONPATH if they wish to do so.

@yajo
Copy link
Contributor Author

yajo commented Sep 4, 2024

Sorry I don't understand that last comment. Do you mean that not supporting nested python environments is a feature? Could you please explain the benefits of not being able to do this?

{python3, ...}: let
  py3 = python3.withPackages (ps: [ps.ansible])
in
  py3.withPackages (ps: [ps.werkzeug])

@phanirithvij
Copy link
Member

This should target staging branch as it is causing a mass rebuild.

Read the links I provided here #334825 (comment)
I suggest going through https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md fully.

@yajo yajo changed the base branch from master to staging December 11, 2024 09:35
@yajo yajo force-pushed the python-nested-venv branch from 19bd170 to d70454e Compare December 11, 2024 09:35
@yajo
Copy link
Contributor Author

yajo commented Dec 11, 2024

Thanks, done.

@nix-owners nix-owners bot requested a review from mweinelt December 11, 2024 09:37
@github-actions github-actions bot removed 10.rebuild-darwin-stdenv This PR causes stdenv to rebuild on Darwin and must target a staging branch. 10.rebuild-darwin: 501+ This PR causes many rebuilds on Darwin and should normally target the staging branches. 10.rebuild-linux: 501+ This PR causes many rebuilds on Linux and should normally target the staging branches. labels Dec 11, 2024
@ofborg ofborg bot added 10.rebuild-darwin-stdenv This PR causes stdenv to rebuild on Darwin and must target a staging branch. 10.rebuild-darwin: 501+ This PR causes many rebuilds on Darwin and should normally target the staging branches. 10.rebuild-linux: 501+ This PR causes many rebuilds on Linux and should normally target the staging branches. labels Dec 12, 2024
@wegank wegank added the 2.status: merge conflict This PR has merge conflicts with the target branch label Apr 7, 2025
@nixpkgs-ci nixpkgs-ci bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jun 25, 2025
Allow devshells to extend `$NIX_PYTHONPATH`, to effectively support nested virtualenvs.

@moduon MT-1075

python3.buildEnv: beautify makeWrapper

Co-authored-by: Sandro <sandro.jaeckel@gmail.com>
@yajo yajo force-pushed the python-nested-venv branch from d70454e to 2c5f9e6 Compare November 7, 2025 08:39
@yajo
Copy link
Contributor Author

yajo commented Nov 7, 2025

Conflicts solved. This is still relevant IMHO.

@nixpkgs-ci nixpkgs-ci bot removed 2.status: merge conflict This PR has merge conflicts with the target branch 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md labels Nov 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

6.topic: python Python is a high-level, general-purpose programming language. 10.rebuild-darwin: 501+ This PR causes many rebuilds on Darwin and should normally target the staging branches. 10.rebuild-darwin: 5001+ This PR causes many rebuilds on Darwin and must target the staging branches. 10.rebuild-darwin-stdenv This PR causes stdenv to rebuild on Darwin and must target a staging branch. 10.rebuild-linux: 501+ This PR causes many rebuilds on Linux and should normally target the staging branches. 10.rebuild-linux: 5001+ This PR causes many rebuilds on Linux and must target the staging branches.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants