-
-
Notifications
You must be signed in to change notification settings - Fork 15.5k
[RFC] Python library wrappers #53816
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
Conversation
Note it's not a wrapper, but a function that injects code.
I think the direction we should go is that packages declare their requirements on the environment and what they offer. E.g., in this case, |
Yeah I'm playing a bit loose with the terminology here. Although it may not be accurate to the letter, I think it communicates the intention and is in line with the naming of similar functions in nixpkgs.
Is wrapping any easier? How does one wrap a library module without changing the way it is imported and without messing with automated tooling detecting docs etc.? I forgot about shebangs. How do those interact with module docstrings? The python docs state that they have to occur first in the file, are shebangs exempt from this? Why do
I agree, I was thinking in a similar direction. This would play nice with your "declarative wrapper" idea. |
Yes and no. In principle the utility we have for it makes it easy, however, before
A library can't be wrapped, we can only inject code in it. That's why we patch references to executables to make them absolute paths.
From the Python docs:
The items are thus in the following order:
When injecting code, it needs to be done after a |
For the purposes of this PR only working for executables is kind of a non-starter.
Oh I didn't know that. Though those were just normal imports.
I think I managed to put together a good solution using pythons I've run out of time for now, but I'll polish and test that when I have more time. |
@FRidh what do you think? https://github.com/timokau/python-inject It injects a call to |
@timokau that tool looks quite nice. I suppose we could put the code to inject in |
I don't understand the point about executables. Why wouldn't We could just use |
Then you're going to need two components, a Nix function that creates the file, and a bash function that injects the code. |
Right. The point is that it is agnostic to where the file is stored.
Why would that be problematic in the binary case? It could still be put in |
In which of the nix phases are the |
This library might be useful: https://github.com/google/pasta |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/declarative-wrappers-another-idea/6661/1 |
I marked this as stale due to inactivity. → More info |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/low-effort-and-high-impact-tasks/21095/41 |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/terminal-emulator-leaks-environment-variables-to-shell/33673/11 |
Motivation for this change
Some python libraries require specific environment variables to be set. One example are those that use gtk libraries. On most other distros, those environment variables would either be set in the global environment or the dependencies would be found in standard paths. Since that is not the case for nixos, we need to hardcode those environment variables into the libraries.
We have
makeWrapper
for binaries. Here I try (purely as a proof of concept, kept as simple as possible) to add amakePythonWrapper
function that does the same for python libraries. In particular, this would make the gtk3 matplotlib backend usable without usingnix-shell
and without manually setting environment variables.Should now succeed. This works because python always executes all parent modules before importing a module. So by adding some code to the top of the topmost module (taking care to leave module docstrings in tact), we can set environment variables as soon as a module is imported.
Some next steps/improvements would be:
makePythonWrapper
makeWrapper
provides__init__.py
to modifyWhat do you think?
CC @jtojnar @FRidh
(This is not about enabling the gtk backend in matplotlib by default, that is just for easier testing)