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

home-assistant: Respect nixpkgs Python package overrides instead of replacing them #104161

Closed
wants to merge 1 commit into from

Conversation

Shados
Copy link
Member

@Shados Shados commented Nov 18, 2020

Motivation for this change

Currently, home-assistant's definition replaces any existing Python package overrides instead of just layering on top of them, preventing HA from using any packages in existing overrides. This changes that.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • 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 nixpkgs-review --run "nixpkgs-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)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

@SuperSandro2000
Copy link
Member

Can you fix the eval errors of ofborg?

@Shados
Copy link
Member Author

Shados commented Nov 24, 2020

Oh, my bad. Amusingly I forgot to consider and test the normal case of not having any upstream Python packageOverrides. I've fixed that now.

@mweinelt
Copy link
Member

mweinelt commented Dec 6, 2020

Do you have an example to help me understand what does not work currently? I don't think I entirely grasp the problem.

@Shados
Copy link
Member Author

Shados commented Dec 18, 2020

@mweinelt Without this patch, any Python package overrides specified in a nixpkgs overlay won't make it into the python3 that HA uses, only those overrides explicitly provided to HA via its packageOverrides argument will.

e.g. overrides specified as per below won't be available to HA currently, but will with this patch:

{ ... }:
{
  nixpkgs.overlays = [
    (self: super: {
      python3 = super.python3.override { packageOverrides = ...; };
    })
  ];
}

@mweinelt
Copy link
Member

Sorry, I need @dotlambda, who came up with this construct, to review this. I understand the problem, but not the solution.

@mweinelt mweinelt added this to To do in Home Assistant via automation May 4, 2021
Copy link
Member

@dotlambda dotlambda left a comment

Choose a reason for hiding this comment

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

I thought about whether packageOverrides can be removed completely. Is the scenario that you have to override something in defaultOverrides likely to occur?

# Put packageOverrides at the start so they are applied after defaultOverrides
packageOverrides = lib.foldr lib.composeExtensions (self: super: { }) ([ packageOverrides ] ++ defaultOverrides);
};
py = python3.override(oa: {
Copy link
Member

@dotlambda dotlambda Jun 16, 2021

Choose a reason for hiding this comment

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

This is not how override works, is it? It doesn't expect a function, at least according to https://nixos.org/manual/nixpkgs/unstable/#sec-pkg-override.

Copy link
Member

Choose a reason for hiding this comment

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

Oh, after reading lib/customisation.nix it seems like this is possible:

makeOverridable = f: origArgs:
let
result = f origArgs;
# Creates a functor with the same arguments as f
copyArgs = g: lib.setFunctionArgs g (lib.functionArgs f);
# Changes the original arguments with (potentially a function that returns) a set of new attributes
overrideWith = newArgs: origArgs // (if lib.isFunction newArgs then newArgs origArgs else newArgs);
# Re-call the function but with different arguments
overrideArgs = copyArgs (newArgs: makeOverridable f (overrideWith newArgs));
# Change the result of the function call by applying g to it
overrideResult = g: makeOverridable (copyArgs (args: g (f args))) origArgs;
in
if builtins.isAttrs result then
result // {
override = overrideArgs;
overrideDerivation = fdrv: overrideResult (x: overrideDerivation x fdrv);
${if result ? overrideAttrs then "overrideAttrs" else null} = fdrv:
overrideResult (x: x.overrideAttrs fdrv);
}
else if lib.isFunction result then
# Transform the result into a functor while propagating its arguments
lib.setFunctionArgs result (lib.functionArgs result) // {
override = overrideArgs;
}
else result;

(pay attention to the if in the definition of overrideWIth)
But then I think we should use

Suggested change
py = python3.override(oa: {
py = python3.override (oldAttrs: {

because that's common naming.

Copy link
Member

@mweinelt mweinelt Jun 16, 2021

Choose a reason for hiding this comment

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

Not actually oldArgs?

Copy link
Member

@dotlambda dotlambda Jun 16, 2021

Choose a reason for hiding this comment

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

True, that makes even more sense. Or origArgs, as it's called above.

};
py = python3.override(oa: {
# Put packageOverrides at the start so they are applied after
# defaultOverrides and upstream overrides
Copy link
Member

Choose a reason for hiding this comment

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

Maybe

Suggested change
# defaultOverrides and upstream overrides
# defaultOverrides and overlay overrides

is a better wording?

packageOverrides = lib.foldr lib.composeExtensions (self: super: { }) (
[ packageOverrides ]
++ defaultOverrides
++ (lib.optional (oa ? packageOverrides) oa.packageOverrides));
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
++ (lib.optional (oa ? packageOverrides) oa.packageOverrides));
++ lib.optional (oa ? packageOverrides) oa.packageOverrides;

or

Suggested change
++ (lib.optional (oa ? packageOverrides) oa.packageOverrides));
++ oa.packageOverrides or [ ];

@dotlambda
Copy link
Member

I understand the problem, but not the solution.

If you override packageOverrides twice, its value from the second overriding, i.e. the one in pkgs/servers/home-assistant/default.nix is used. If we also want to respect existing packageOverrides from overlays, we need to add existing ones to the list of packageOverrides we pass to override.

@stale
Copy link

stale bot commented Jan 8, 2022

I marked this as stale due to inactivity. → More info

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jan 8, 2022
@mweinelt mweinelt moved this from Incoming to Needs work in Home Assistant Feb 12, 2022
@SuperSandro2000
Copy link
Member

Is this still relevant?

@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Nov 8, 2022
@mweinelt
Copy link
Member

Doesn't apply anymore since #182112 and I wonder if it is still required thereafter.

@mweinelt mweinelt closed this Feb 11, 2023
Home Assistant automation moved this from Needs work to Done Feb 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

Successfully merging this pull request may close these issues.

None yet

4 participants