-
-
Notifications
You must be signed in to change notification settings - Fork 15k
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
pythonPackages: Switch to lib.makeScope for overrideScope
support
#67422
Conversation
This provides convenient and consistent dependency overrides. However, the main problem seems to be that there will be a conflict between python packages if the |
@veprbl Yeah that is a problem (not a main one), and this PR doesn't solve this (if this can be solved at all). The biggest reason I made this PR is to make it much more convenient to do transitive overrides, which is possible for a lot of other package sets already because of their use of |
What about the case where I need two packages, one needs jsonschema==2.* and the other needs jsonschema>=3. Won't the buildEnv still create a PYTHONPATH that has both versions on it? Example of a shell.nix:
|
@jonringer Yeah I think that would create such a conflicting env because of how {
buildInputs = [
jupyterlab_server
(python3.withPackages (p: [ p.jsonschema ]))
];
} |
What is the point of doing such an override if you cannot put multiple
packages in an env anyway?
…On Sun, Aug 25, 2019, 23:14 Silvan Mosberger ***@***.***> wrote:
@jonringer <https://github.com/jonringer> Yeah I think that would create
such a conflicting env because of how buildInputs treats python packages,
but if you do this it should work:
{
buildInputs = [
jupyterlab_server
(python3.withPackages (p: [ p.jsonschema ]))
];
}
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#67422?email_source=notifications&email_token=AAQHZ32COESAP6BJ3GZGVCLQGLY47A5CNFSM4IPH2SOKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD5C33EI#issuecomment-524664209>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAQHZ346GCJYZLQJTYNKKQ3QGLY47ANCNFSM4IPH2SOA>
.
|
@FRidh For jupyterlab to build at all. See the PR description for what would be needed to make it build without this change. |
I guess this is mostly useful for getting end-user applications to build correctly |
@infinisil in applications, there's a lot more freedom to change python versions, because there's a good guarantee that that the python packages will be wrapped and isolated from other python packages. A common example is the aws-sam-cli package. |
With notebook and jupyterlab we should separate the kernel from the
application, that is, you should simply be able to build it as an app and
then add a withPackages kernel. I recall this actually already being done.
…On Mon, Aug 26, 2019, 17:54 Jon ***@***.***> wrote:
@infinisil <https://github.com/Infinisil> in applications, there's a lot
more freedom to change python versions, because there's a good guarantee
that that the python packages will be wrapped and isolated from other
python packages. A common example is the aws-sam-cli package
<https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/tools/aws-sam-cli/default.nix>
.
However, I think your scope example is a lot more concise than the
aws-sam-cli/override example :) 👍
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#67422?email_source=notifications&email_token=AAQHZ3ZNF3BQHRSJPV3I7IDQGP4DVA5CNFSM4IPH2SOKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD5EZPQY#issuecomment-524916675>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAQHZ3YEO4B3KCOLPGAIDE3QGP4DVANCNFSM4IPH2SOA>
.
|
Hm I'm not sure I'm getting what you're saying @FRidh, but maybe it's that if I define I still feel like this functionality could be useful though, and it's already built into the |
Correct. |
@FRidh Alright, then let's use that to get jupyterlab to build. You onboard with merging this just for the sake of uniformity of package sets in nixpkgs? |
In general I am of the opinion that we need an RFC first to detail how the various package sets should look. I do not see any benefit feature-wise of this PR, although uniformity is absolutely desirable. It cannot cause any regressions either so that's good. However, the use case you had in mind cannot be dealt with in this way as discussed. By merging this change I expect more PR's with Given that there's a lot of other ways to do bad things that's not a good enough reason, so I'd say go ahead with it. Just update the commit message to change the |
This change allows previously ~final package sets to be overridden with overlays , e.g. you can do `pkgs.python.pkgs.overrideScope' (self: super: { ... })` whereas previously only `pkgs.python.override { packageOverrides = (self: super: { ... })` was possible. This therefore also allows packages definitions to transitively override dependencies. So e.g. if jupyterlab_server requires jsonschema >= 3, but the rest of the packages should still use jsonschema == 2, you can define it as such: jupyterlab_server = (python.pkgs.overrideScope' (self: super: { jsonschema = self.jsonschema3; })).callPackage ../development/python-modules/jupyterlab_server { }; This applies the overlay to the whole dependency closure, whereas jupyterlab_server = python.pkgs.callPackage ../development/python-modules/jupyterlab_server { jsonschema = self.jsonschema3; }; would only make it apply to jupyterlab_server itself, but not its dependencies, resulting in build-time errors. To get the desired effect without this change, this would be needed for this specific case: jupyterlab_server = python.pkgs.callPackage ../development/python-modules/jupyterlab_server { jsonschema = self.jsonschema3; notebook = self.notebook.override { nbformat = self.nbformat.override { jsonschema = self.jsonschema3; }; nbconvert = self.nbconvert.override { nbformat = self.nbformat.override { jsonschema = self.jsonschema3; }; }; }; };
c5f7278
to
97a7887
Compare
I updated the commit message to change I wouldn't really know where to put docs for this however, and given that this functionality might be needed in some cases (maybe even in the python package set), I wouldn't want to tell people to not use it. Unless you insist on docs I'd like this to be merged so the jupyterlab update can be merged too. |
The section |
Is this just waiting on documentation? |
Also, for fun (wanting to experiment with mirroring Nixpkgs's structure in a NUR repo), you can actually do this on today's Nixpkgs with a bit of backing horror: Uncommented, abridged, and slightly modified code taken from let
# pkgs = self;
pkgs' = let
inherit (pkgs) lib;
pkgsScope = lib.makeScope pkgs.newScope (_: pkgs);
pythonScopeOverrides = self: super: {
pythonInterpreters = super.pythonInterpreters.override (o: {
pkgs = o.pkgs // {
callPackage = fn: args: o.pkgs.callPackage fn (let
packageOverrides = pySelf: pySuper:
pySuper.__extends__ or
(let pyScope = lib.makeScope self.newScope (self: pySuper // {
inherit (self) callPackage;
}); in if args ? packageOverrides then
pyScope.overrideScope' args.packageOverrides
else
pyScope);
f = if lib.isFunction fn then fn else import fn;
in if (lib.functionArgs f) ? packageOverrides then
args // { inherit packageOverrides; }
else
args);
};
});
inherit (self.pythonInterpreters) python37;
python37Packages = self.python37.pkgs;
python3 = self.python37;
python3Packages = self.python3.pkgs;
};
in pkgsScope.overrideScope' pythonScopeOverrides;
in { inherit (pkgs'.python3Packages.overrideScope' (self: super: {
jsonschema = self.jsonschema3;
jupyterlab = self.callPackage ../applications/editors/jupyterlab { };
jupyterlab_server = self.callPackage ../servers/jupyterlab { };
})) jupyterlab jupyterlab_server; } |
Neat and hacky! Yeah I think the only thing missing here is docs wanted by @FRidh, but I'm frightened by xml. Imo leaving out docs for this isn't too bad, because nobody would even know they could now use |
If you don't want to point it out, why add it? |
It's still useful when you need it (such as for jupyterlab and probably more cases as well), even without docs. Docs would be nice yeah, but I don't even use python or jupyterlab, so I don't really have much motivation for this. |
If anybody else feels like doing this, feel free to use the patch in this PR |
Agreed, the azure-cli python package list would have been a good candidate
|
Am bummed that this never merged; it would have been a nice solution for composable Python overrides. |
@mikepurvis let
inherit (builtins) hasAttr listToAttrs map;
flow = f: g: x: g (f x);
mapAttr = name: f: set: set // { ${name} = f set.${name}; };
mapAttrOr = name: f: nul: set: if hasAttr name set then mapAttr name f set else nul;
mapAttrOrElse = name: f: nulF: set: mapAttrOr name f (nulF name set) set;
isOverridable = hasAttr "override";
isScope = hasAttr "overrideScope";
in
pkgsFinal: pkgsPrev: let
inherit (pkgsFinal.lib) composeExtensions makeOverridable;
attachScope = f: genFinal:
let final = genFinal final // {
overrideScope = g: attachScope (composeExtensions f g) genFinal;
overrideScopeGenFinal = g: attachScope f (g genFinal);
scopeGenFinal = genFinal;
scopeOverrides = f;
}; in final;
attachEmptyScope = attachScope (final: prev: { });
in {
pythonInterpreters = let
pyInterpsPrev = pkgsPrev.pythonInterpreters;
in if isScope pyInterpsPrev then pyInterpsPrev else attachEmptyScope (final:
pyInterpsPrev.override (mapAttr "pkgs" (pkgs':
mapAttr "callPackage" (callPackage:
fn: flow (mapAttrOrElse "overrides" (overrides:
pkgs'.lib.composeExtensions final.scopeOverrides overrides
) (pyFinal: pyPrev: pyPrev)) (callPackage fn)
) pkgs'
))
);
} |
Motivation for this change
This change allows previously ~final package sets to be overridden with
overlays , e.g. you can do
pkgs.python.pkgs.overrideScope' (self: super: { ... })
whereas previously only
pkgs.python.override { packageOverrides = (self: super: { ... })
was possible.This therefore also allows packages definitions to transitively override
dependencies. So e.g. if jupyterlab_server requires jsonschema >= 3, but
the rest of the packages should still use jsonschema == 2, you can
define it as such:
This applies the overlay to the whole dependency closure, whereas
would only make it apply to jupyterlab_server itself, but not its
dependencies, resulting in build-time errors. To get the desired effect without
this change, this would be needed for this specific case:
Ping @FRidh @JonathanReeve @jonringer @veprbl
Things done