Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix neovim PYTHONPATH handling #43388

Merged
merged 3 commits into from Aug 30, 2018
Merged

Conversation

symphorien
Copy link
Member

Motivation for this change

These are two more or less independent improvements to the neovim wrapper.
1st commit:

nix-shell -p pythonPackages.numpy
nvim
:!python -c "import numpy"

this will fail to see numpy.
This is because the neovim wrapper unsets PYTHONPATH.

With this fix, I checked that :checkhealth is fine with and without extraPythonPackages and within and out of a nix-shell modifying the PYTHONPATH.

2nd commit:
During testing the above fix, I built my system config with an overlay using the neovim from my nixpkgs checkout. I override this wrapper with a few extraPythonPackages. But these packages disappeared completely. They were not even a dependency of neovim. Indeed, a python module from stable will be silently ignored by unstable python.buildEnv.

# Check whether a derivation provides a Python module.
hasPythonModule = drv: (hasAttr "pythonModule" drv) && ( (getAttr "pythonModule" drv) == python);
# Get list of required Python modules given a list of derivations.
requiredPythonModules = drvs: let
filterNull = list: filter (x: !isNull x) list;
conditionalGetRecurse = attr: condition: drv: let f = conditionalGetRecurse attr condition; in
(if (condition drv) then unique [drv]++(concatMap f (filterNull(getAttr attr drv))) else []);
_required = drv: conditionalGetRecurse "propagatedBuildInputs" hasPythonModule drv;
in [python] ++ (unique (concatMap _required (filterNull drvs)));

paths = requiredPythonModules (extraLibs ++ [ python ] ) ;

python.withPackages is just as powerful as python.buildEnv but not so treacherous, and I lost enough time with this, so I switched to python.withPackages.

This changes the type of extraPython{,3}Packages but in a backward compatible way.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nox --run "nox-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Fits CONTRIBUTING.md.

@symphorien symphorien changed the title Neovim python env Fix neovim PYTHONPATH handling Jul 11, 2018
@symphorien
Copy link
Member Author

cc @manveru @garbas @rvolosatovs as maintainers

@manveru
Copy link
Contributor

manveru commented Jul 11, 2018

I love this change, thanks for fixing this, since I couldn't figure out a sane way to solve this issue.

@FRidh
Copy link
Member

FRidh commented Jul 12, 2018

This wiping is necessary for the python providers, though, otherwise a
python2 nix-shell will make the python3 provider read python2 files.

Why set PYTHONPATH to begin with? I mean, isn't it expected behaviour that PYTHONPATH can break things. How about using nix-shell -p "python.withPackages(ps: with ps; numpy)" which is the recommended solution? Would the issue then still exist?

I think overall it is a good change, and I don't object to it.

@manveru
Copy link
Contributor

manveru commented Jul 12, 2018

There are a lot of neovim plugins written in python, and that was the only way I could get them to work more or less reliably, no matter what python version was in my environment at the time.

Copy link
Member

@garbas garbas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good for me.

blind-review

};
pythonEnv = pythonPackages.python.withPackages(ps:
(if withPyGUI then [ ps.neovim_gui ] else [ ps.neovim ])
++ (extraPythonPackagesFun ps) ++ pluginPythonPackages);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will not work yet with pluginPythonPackages since ps is not passed to pluginPythonPackages. pluginPythonPackages also does not work with vim's own package manager. We only have one plugin that is using this mechanism - should it be removed for the moment? It is also not implemented for vim8.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum I think it still works, but indeed adding a plugin from stable will not work with neovim from unstable. I'll try to adapt it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum does anyone have an example of how to use the configure argument of the wrapper ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@symphorien
Copy link
Member Author

Why set PYTHONPATH to begin with? I mean, isn't it expected behaviour that PYTHONPATH can break things. How about using nix-shell -p "python.withPackages(ps: with ps; numpy)" which is the recommended solution? Would the issue then still exist?

Indeed this way the issue disappears. But for example, I discovered this issue with pypi2nix, so current tooling sometimes uses PYTHONPATH.

@symphorien
Copy link
Member Author

I pushed a commit making ensime-vim.pythonDependencies a function as well.
This was tested with this vim config:

let
  pkgs = import ./default.nix {};
  config = {
    packages.myVimPackage = with pkgs.vimPlugins; {
      start = [ ensime-vim ];
    };
  };
  neovim = pkgs.neovim.override {
    configure = config;
  };
in
  neovim

Note that this didn't work before, python dependencies were only taken into account for vam and pathogen plugins.
besides, it seems ensime switched to python3.

This solves the following bug:
opening neovim in nix-shell -p pythonPackages.numpy does not enable to
run successfully
:!python -c "import numpy"
because the PYTHONPATH is wiped by the neovim wrapper.

This wiping is necessary for the python providers, though, otherwise a
python2 nix-shell will make the python3 provider read python2 files.

We wrap the providers only, instead of neovim as whole.
They are both as powerful, but buildEnv is treacherous: if you pass a
package which depends on another python (for example the one of unstable
when you are on stable) it will be *silently* dropped, leading to hair
pulling.

Use case:
override neovim from unstable, but still keep stable's pythonPackages.
@symphorien
Copy link
Member Author

I have resolved the merge conflict and but only tested a little.

A function of the same signature as the argument of python.withPackages
@symphorien
Copy link
Member Author

Anything I should change or can this be merged ?

Copy link
Member

@matthewbauer matthewbauer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! I'll let someone with more familiarity with neovim merge though.

@Mic92
Copy link
Member

Mic92 commented Aug 17, 2018

cc @FRidh

@xeji
Copy link
Contributor

xeji commented Aug 30, 2018

@GrahamcOfBorg build vimPlugins.ensime-vim neovim-qt

@GrahamcOfBorg
Copy link

Failure on aarch64-linux (full log)

Attempted: vimPlugins.ensime-vim, neovim-qt

Partial log (click to expand)

        [C]: in function 'match'
        /build/source/src/nvim/generators/gen_declarations.lua:255: in main chunk
        [C]: at 0x00405660
make[2]: *** [src/nvim/CMakeFiles/nvim.dir/build.make:379: src/nvim/auto/ex_cmds.c.generated.h] Error 1
make[1]: *** [CMakeFiles/Makefile2:2865: src/nvim/CMakeFiles/nvim.dir/all] Error 2
make: *** [Makefile:152: all] Error 2
builder for '/nix/store/8wlprfis36fzvqd5a8shbxi0rp6qrshv-neovim-unwrapped-0.3.1.drv' failed with exit code 2
cannot build derivation '/nix/store/a1b5hvm78zx5d1k5vcnkv3dq6cxihc1x-neovim-0.3.1.drv': 1 dependencies couldn't be built
cannot build derivation '/nix/store/4292n7x7fwqgp2g0qhx9pav86wjd30av-neovim-qt-0.2.9.drv': 1 dependencies couldn't be built
error: build of '/nix/store/4292n7x7fwqgp2g0qhx9pav86wjd30av-neovim-qt-0.2.9.drv' failed

@GrahamcOfBorg
Copy link

Success on x86_64-darwin (full log)

Attempted: vimPlugins.ensime-vim, neovim-qt

Partial log (click to expand)

-- Installing: /nix/store/5gbxqi5lqxkv4srr9qx62a38l43jsk7q-neovim-qt-0.2.9/bin/nvim-qt.app/Contents/Resources/runtime/doc/nvim_gui_shim.txt
-- Installing: /nix/store/5gbxqi5lqxkv4srr9qx62a38l43jsk7q-neovim-qt-0.2.9/bin/nvim-qt.app/Contents/Resources/runtime/doc/tags
-- Installing: /nix/store/5gbxqi5lqxkv4srr9qx62a38l43jsk7q-neovim-qt-0.2.9/bin/nvim-qt.app/Contents/Resources/neovim.icns
-- Installing: /nix/store/5gbxqi5lqxkv4srr9qx62a38l43jsk7q-neovim-qt-0.2.9/bin/nvim-qt.app/Contents/Info.plist
post-installation fixup
strip is /nix/store/df6k4mgdjxciy0f637lryp7c9ln7n1m3-cctools-binutils-darwin/bin/strip
patching script interpreter paths in /nix/store/5gbxqi5lqxkv4srr9qx62a38l43jsk7q-neovim-qt-0.2.9
postPatchMkspecs
/nix/store/ignjgbp7yypzvxz3iq6g4wrdj43i3fqs-vimplugin-ensime-vim-2018-04-21
/nix/store/5gbxqi5lqxkv4srr9qx62a38l43jsk7q-neovim-qt-0.2.9

@GrahamcOfBorg
Copy link

Success on x86_64-linux (full log)

Attempted: vimPlugins.ensime-vim, neovim-qt

Partial log (click to expand)

post-installation fixup
shrinking RPATHs of ELF executables and libraries in /nix/store/62ird20c2bgki2l2g866f173kns15qmj-neovim-qt-0.2.9
shrinking /nix/store/62ird20c2bgki2l2g866f173kns15qmj-neovim-qt-0.2.9/bin/.nvim-qt-wrapped
strip is /nix/store/h0lbngpv6ln56hjj59i6l77vxq25flbz-binutils-2.30/bin/strip
stripping (with command strip and flags -S) in /nix/store/62ird20c2bgki2l2g866f173kns15qmj-neovim-qt-0.2.9/bin
patching script interpreter paths in /nix/store/62ird20c2bgki2l2g866f173kns15qmj-neovim-qt-0.2.9
checking for references to /build in /nix/store/62ird20c2bgki2l2g866f173kns15qmj-neovim-qt-0.2.9...
postPatchMkspecs
/nix/store/m9qz81fbrx3k74n6330gxj62g0n1yd2b-vimplugin-ensime-vim-2018-04-21
/nix/store/62ird20c2bgki2l2g866f173kns15qmj-neovim-qt-0.2.9

@xeji
Copy link
Contributor

xeji commented Aug 30, 2018

failure on aarch64 is unrelated, has been there for a while: https://hydra.nixos.org/job/nixpkgs/trunk/neovim-unwrapped.aarch64-linux

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants