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

buildPythonPackage, buildPythonApplication: make doCheck default less confusing #308377

Merged
merged 1 commit into from
Jul 3, 2024

Conversation

ShamrockLee
Copy link
Contributor

@ShamrockLee ShamrockLee commented May 1, 2024

Description of changes

Make it clear that argument doCheck of buildPythonPackage and buildPythonApplication defaults to true instead of false.

(For context, see #307838 (comment))

The current implementation of mk-python-derivation.nix appears to default doCheck config.doCheckByDefault or false, but effectively default it true.

{
  stdenv,
  ...
}:
{
  doCheck ? config.doCheckByDefault or false,
  ...
}@attrs:
stdenv.mkDerivation (removeAttrs attrs [ ... ]) {
  doCheck = false;
  doInstallCheck = attrs.doCheck or true; # ???
}

This PR resolves such confusion:

{
  stdenv,
  ...
}:
{
  doCheck ? true,
  ...
}@attrs:
stdenv.mkDerivation (removeAttrs attrs [ ... ]) {
  doCheck = false;
  # The doCheck argument determines the doInstallCheck attribute.
  doInstallCheck = doCheck;
}

Another confusion caused by argument doCheck determining attribute doInstallCheck should be resolved by instructing people to specify doInstallCheck instead of doCheck and installCheckPhase instead of checkPhase. That's a change of interface that needs more discussion, and is excluded from the scope of this PR.

This PR is a back-portable fix that brings no interface changes and no rebuilds.

Cc: @FRidh @afh

Things done

  • Built on platform(s)
    • x86_64-linux (no rebuild)
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandboxing enabled in nix.conf? (See Nix manual)
    • sandbox = relaxed
    • sandbox = true
  • 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/)
  • 24.05 Release Notes (or backporting 23.05 and 23.11 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.

Add a 👍 reaction to pull requests you find important.

@ofborg ofborg bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux labels May 1, 2024
@ShamrockLee ShamrockLee marked this pull request as ready for review May 2, 2024 10:21
@afh
Copy link
Member

afh commented May 4, 2024

@ShamrockLee, thanks for this. Apologies if my confusion about around the doCheck default for regular and python packages still persist. Maybe you could help clear it up. What is the motivation for doCheck to be true for python packages / applications opposed to it being false for the (majority?) of regular packages?

Also: should this information about what (doCheck and/or doInstallCheck) to use for python packages / applications find its way to the Python-specific section of the Nixpkgs manual?

@TomaSajt
Copy link
Contributor

TomaSajt commented May 4, 2024

I think this is the classic mistake of expecting the @attrs pattern to respect the ? pattern.

Example:

# a.nix
{ a ? "foo" }@attrs:
attrs.a or "bar"

When doing import ./a.nix {} this will evaluate to "bar" even though we told it that if a is unset set it to foo.
This is because attrs is actually just {}, exactly what we passed in.

@TomaSajt
Copy link
Contributor

TomaSajt commented May 4, 2024

Here's the change that broke/changed the old default of false to true: f7e28bf

@TomaSajt
Copy link
Contributor

TomaSajt commented May 4, 2024

We could also set config.doCheckByDefault or true as the default, so that it starts respecting the config value again.
This should not cause rebuilds, unless you have the config set to false, but then you're probably always expecting massive rebuilds anyway.

@ShamrockLee
Copy link
Contributor Author

@afh

What is the motivation for doCheck to be true for python packages / applications opposed to it being false for the (majority?) of regular packages?

I haven't inspect into the reason why it is enabled by default. The design choice has been made years ago. What I'm doing in this PR is to uncover it.

Besides, defaulting doCheck/doInstallCheck true isn't uncommon for build helpers. Searching the codebase with regular expression do(Install)?Check = .* or true, we can find similar defaults in language-specific build helpers of Crystal, Go, Haskell, PHP, and Rust, aside from Python. Such defaults are sensible when there are some default checks or some arguments that, if set, would enable certain pre-defined checks.

Also: should this information about what (doCheck and/or doInstallCheck) to use for python packages / applications find its way to the Python-specific section of the Nixpkgs manual?

It would be great to explain them in the Nixpkgs Manual. However, I plan to propose setting it directly via doInstallCheck and installCheckPhase to make it less ambiguous. The documentation will be added there.

@ShamrockLee
Copy link
Contributor Author

ShamrockLee commented May 4, 2024

@TomaSajt

Here's the change that broke/changed the old default of false to true: f7e28bf

Thanks a lot for finding it out! (#68244)

We could also set config.doCheckByDefault or true as the default, so that it starts respecting the config value again. This should not cause rebuilds, unless you have the config set to false, but then you're probably always expecting massive rebuilds anyway.

According to the documentation, config.doCheckByDefault is "default to false", and "changing the default may cause a mass rebuild." AFAIK, it is unexpected for doCheckByDefault = false to cause rebuild.

@TomaSajt
Copy link
Contributor

TomaSajt commented May 4, 2024

@TomaSajt

Here's the change that broke/changed the old default of false to true: f7e28bf

Thanks a lot for finding it out! (#68244)

We could also set config.doCheckByDefault or true as the default, so that it starts respecting the config value again. This should not cause rebuilds, unless you have the config set to false, but then you're probably always expecting massive rebuilds anyway.

According to the documentation, config.doCheckByDefault is "default to false", and "changing the default may cause a mass rebuild." AFAIK, it is unexpected for doCheckByDefault = false to cause rebuild.

Oh, I see. I didn't see that it was set by default.
I thought the docs would be something like: "either set this to true/false to force it to be true/false, or don't set it to leave the choice to the builder helpers".

I expected it to be this way, because every place that mentions this config option has an or false after it.

@FRidh
Copy link
Member

FRidh commented May 5, 2024 via email

Copy link
Member

@afh afh left a comment

Choose a reason for hiding this comment

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

With the information provided and my current understanding, I support this change. Someone more knowledgable may disagree and hopefully they decide to speak up and share their insight.

Thank you for putting this together, @ShamrockLee, much appreciated! And thank you everyone else for chiming in with your expertise.

@wegank wegank added the 12.approvals: 2 This PR was reviewed and approved by two reputable people label May 5, 2024
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/prs-already-reviewed/2617/1756

@afh
Copy link
Member

afh commented Jun 27, 2024

@JohnRTitor would you be willing to lend your expertise for review and if acceptable merge this PR?

@kirillrdy kirillrdy requested a review from natsukium June 27, 2024 20:40
@@ -309,7 +309,8 @@ let

# Python packages don't have a checkPhase, only an installCheckPhase
doCheck = false;
doInstallCheck = attrs.doCheck or true;
# The doCheck argument determines the doInstallCheck attribute.
doInstallCheck = doCheck;
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
doInstallCheck = doCheck;
doInstallCheck = attrs.doCheck;

Could you clarify this with attrs?
I think it is confusing since there is a doCheck = false right above it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can't test it right now, but IIRC if we use the @attrs pattern, the defaults set with ? will not be applied when accessing through attrs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Could you clarify this with attrs?

attrs does not consider the default value given by the set pattern of the build helper. It would be confusing to set a default value in the set pattern ({ doCheck ? true, ... }) but shadow it with another default when accessing (doInstallCheck = attrs.doCheck or true).

Copy link
Member

Choose a reason for hiding this comment

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

Hmmm, indeed, attrs seems to be empty, as @TomaSajt pointed out at the beginning.
Then I think attrs.doCheck or true would be easier to understand.

The confusion was originally caused by the fact that the argument, doCheck, actually evaluates to true even though it defaults to false, right?
Do we need to change this here?

Copy link
Contributor Author

@ShamrockLee ShamrockLee Jul 2, 2024

Choose a reason for hiding this comment

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

Hmmm, indeed, attrs seems empty, as @TomaSajt pointed out at the beginning. Then I think attrs.doCheck or true would be easier to understand.

It still shadows the default set by the set pattern, but it sounds like an acceptable trade-off, considering the increased readability.

IMO, the root cause of the readability issue is the choice to specify the doInstallCheck attribute with the doCheck argument. In subsequent PR, I propose unifying the name (as doInstallCheck).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed.

@@ -309,7 +309,8 @@ let

# Python packages don't have a checkPhase, only an installCheckPhase
doCheck = false;
doInstallCheck = attrs.doCheck or true;
# The doCheck argument determines the doInstallCheck attribute.
Copy link
Member

Choose a reason for hiding this comment

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

This comment explains what it does, but I don't think it's necessary because it's just what the code says.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed.

@ShamrockLee ShamrockLee force-pushed the build-python-docheck-quick branch from ced9eeb to 60cfc1e Compare July 2, 2024 15:41
Modify the set pattern to hint developers that the doInstallCheck
attribute of Python packages, specified by the doCheck argument of
buildPythonPackage and buildPythonApplication, defaults to true instead
of false.
@ShamrockLee ShamrockLee force-pushed the build-python-docheck-quick branch from 60cfc1e to 455314a Compare July 2, 2024 18:44
@ShamrockLee
Copy link
Contributor Author

I just rebased it onto the tip of the master branch.

Copy link
Member

@natsukium natsukium left a comment

Choose a reason for hiding this comment

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

Thanks for improving this. LGTM

@natsukium natsukium merged commit df6ca30 into NixOS:master Jul 3, 2024
21 checks passed
@ShamrockLee
Copy link
Contributor Author

Thanks for merging.

I created another PR #324124 proposing directly taking the installCheck-related arguments. Please take a look and leave some feedback if you are interested.

@ShamrockLee ShamrockLee deleted the build-python-docheck-quick branch July 3, 2024 19:48
@@ -144,7 +144,7 @@ in

, meta ? {}

, doCheck ? config.doCheckByDefault or false
, doCheck ? true
Copy link
Contributor

Choose a reason for hiding this comment

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

It's a bit late now, but I think this fix was not the one that needed to happen, since doCheck never gets used.
Only attrs.doCheck is ever referenced, which doesn't need this line.

Suggested change
, doCheck ? true

Should we open another PR that just removes this line?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, yes. Removing this line from the set pattern is a better solution to such confusion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
6.topic: python 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux 12.approvals: 2 This PR was reviewed and approved by two reputable people
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants