Skip to content

buildPythonPackage, buildPythonApplication: support __structuredAttrs = true#347194

Merged
wolfgangwalther merged 14 commits intoNixOS:stagingfrom
ShamrockLee:build-python-structured-attrs
Jan 10, 2025
Merged

buildPythonPackage, buildPythonApplication: support __structuredAttrs = true#347194
wolfgangwalther merged 14 commits intoNixOS:stagingfrom
ShamrockLee:build-python-structured-attrs

Conversation

@ShamrockLee
Copy link
Contributor

@ShamrockLee ShamrockLee commented Oct 8, 2024

This PR refactors the setup hooks and wrap.sh that construct the two build helpers, making buildPythonPackage and buildPythonApplication support both __structuredAttrs = true and structuredAttrs = false.

The representation of the flags attributes as shell/environment variables for most Python building setup hooks are now the same as stdenv.mkDerivation and other build helpers -- they are space-separated environment variables when __structuredAttrs = false and Bash arrays when __structuredAttrs = true, and are concatenated to the command without Bash-evaluation. The following behaviour changes are introduced during the conversion:

  • The following flags are no longer Bash-expanded before concatenated to the command:

    • disabledTests and disabledTestPaths for pytestCheckHook. (disabledTestPaths used to be expanded twice before concatenation.)
    • setupPyBuildFlags and setupPyGlobalFlags for setuptoolsBuildHook.
  • pytestFlags and unittestFlags replaces pytestFlagsArray and unittestFlagsArray and become the new and conforming interface.

  • pytestFlagsArray and unittestFlagsArray are kept for compatibility purposes. They continue to be Bash-expanded before concatenated. Such compatibility layer would get removed in future releases.

Almost all the refactored scripts are linted with ShellCheck, except wrap.sh, which I don't know how to lint correctly.

Things done

  • Built on platform(s)
    • x86_64-linux
    • 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.11 Release Notes (or backporting 23.11 and 24.05 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.

@github-actions github-actions bot added 6.topic: python Python is a high-level, general-purpose programming language. 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: documentation This PR adds or changes documentation 8.has: changelog This PR adds or changes release notes labels Oct 8, 2024
@ofborg ofborg bot added 10.rebuild-darwin-stdenv This PR causes stdenv to rebuild on Darwin and must target a staging branch. 10.rebuild-darwin: 501+ This PR causes many rebuilds on Darwin and should normally target the staging branches. 10.rebuild-darwin: 5001+ This PR causes many rebuilds on Darwin and must target the staging branches. 10.rebuild-linux: 501+ This PR causes many rebuilds on Linux and should normally target the staging branches. 10.rebuild-linux: 5001+ This PR causes many rebuilds on Linux and must target the staging branches. labels Oct 8, 2024
@ShamrockLee ShamrockLee force-pushed the build-python-structured-attrs branch 3 times, most recently from f3bee93 to 46f8c8a Compare October 9, 2024 11:53
@ShamrockLee ShamrockLee marked this pull request as ready for review October 9, 2024 12:43
@ofborg ofborg bot added the 11.by: package-maintainer This PR was created by a maintainer of all the package it changes. label Oct 9, 2024
@ShamrockLee
Copy link
Contributor Author

Questions:

When passing makeWrapperArgs to buildPython* as an argument (attribute), it will be passed as an environment variable (containing a space-separated string) to the build script. However, people assume it would be a Bash array when changing it inside preFixup.

  • Should we adapt to it and transparently convert the values from the Nix derivation attribute to a Bash array as well, or should we fix the Nix expressions that treats them as arrays?
  • How should we fix the expressions mentioned above? Should we add __structuredAttrs = true to make makeWrapperArgs a Bash array, or should we use appendToVar to append elements to it? appendToVar inherently can't handle space-containing arguments. I'm unsure if adding __strucutredAttrs = true to a package expression would be considered backward-incompatible.

@wolfgangwalther wolfgangwalther self-requested a review October 9, 2024 15:22
@wolfgangwalther
Copy link
Contributor

Thanks for working on this! I intend to review this PR, but will not have much time the next two weeks.

@ShamrockLee ShamrockLee force-pushed the build-python-structured-attrs branch from 46f8c8a to 38943f3 Compare October 9, 2024 20:50
@ShamrockLee
Copy link
Contributor Author

@ofborg build python3Packages.six
@ofborg build python311Packages.tensorflow

Copy link
Contributor

@wolfgangwalther wolfgangwalther left a comment

Choose a reason for hiding this comment

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

This is not a full review, but it should be enough for a first iteration.

Most importantly I have not touched the question on how to deal with the compatibility things, yet, aside from giving a few more generic thoughts on the matter.

Maybe we can split some of the uncontroversial changes off (everything independent of compatHelpers) and merge separately?

@ShamrockLee ShamrockLee force-pushed the build-python-structured-attrs branch from 01ac9f7 to ae62db1 Compare October 27, 2024 17:57
@ShamrockLee
Copy link
Contributor Author

This confuses me. Why are we still using +=" ..." string concatenation for Phases at all? It seems like all hooks use xxxHooks+=(...) array syntax already, so maybe we should just do the same for Phases separately? Seems to be only preFixupPhases in ~8 files right now.

There used to be a lot of *Phase+=" somePhase" before #339117. #339117 also targets *Phases+=(somePhase), but some were not caught up as they are more challenging to discover using regular expression search.

It seems like all hooks use xxxHooks+=(...) array syntax already, so maybe we should just do the same for Phases separately?

When __structuredAttrs = false, The preFixupPhases = [ "foo" "bar" ] will pass to the build script as an environment variable preFixupPhases="foo bar". When someone does preFixupPhases+=("baz"), it will be transparently converted to preFixupPhases+=("foo bar" "baz"). Such value is semantically wrong but tolerated by the setup.sh implementation as it is accessed as "${preFixupPhases[*]}".

We should not rely on such implementation detail of setup.sh, but handle the *Phases correctly with prependToVar and appendToVar.

@ShamrockLee
Copy link
Contributor Author

This is not a full review, but it should be enough for a first iteration.

Thank you for reviewing!

Most importantly I have not touched the question on how to deal with the compatibility things, yet, aside from giving a few more generic thoughts on the matter.

Maybe we can split some of the uncontroversial changes off (everything independent of compatHelpers) and merge separately?

I'll split the easier part into another PR after we reach a consensus about how to add elements to *Phases. Or should we discuss it in the new PR?

@wolfgangwalther
Copy link
Contributor

There used to be a lot of *Phase+=" somePhase" before #339117. #339117 also targets *Phases+=(somePhase), but some were not caught up as they are more challenging to discover using regular expression search.

I wasn't aware of that PR. I see that doing the same for the last remaining *Phases here makes sense. But in that case, this should be a commit doing all of the remaining ones together? (grep -r 'Phases+=' pkgs still shows me ~8 more on your branch)

@ShamrockLee
Copy link
Contributor Author

ShamrockLee commented Oct 27, 2024

(grep -r 'Phases+=' pkgs still shows me ~8 more on your branch)

Oops! My bad.

I see that doing the same for the last remaining *Phases here makes sense. But in that case, this should be a commit doing all of the remaining ones together? (grep -r 'Phases+=' pkgs still shows me ~8 more on your branch)

I'll gather them into the same commit.

Update: Applied.

@ShamrockLee ShamrockLee force-pushed the build-python-structured-attrs branch 2 times, most recently from 21c6d04 to 9f8fa39 Compare October 27, 2024 19:05
@wegank wegank added the 2.status: merge conflict This PR has merge conflicts with the target branch label Dec 31, 2024
Copy link
Contributor

@wolfgangwalther wolfgangwalther left a comment

Choose a reason for hiding this comment

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

I did the following:

  • went through the PR line-by-line, except for a few nits the changes LGTM.
  • found no remaining uses of pytestFlagsArray or unittestFlagsArray in doc/*.
  • found no other setupPyGlobalFlags or setupPyBuildFlags depending on bash eval or passing spaces.
  • build some random python packages to confirm nothing is obviously broken.

@wegank wegank added 12.approvals: 1 This PR was reviewed and approved by one person. and removed 12.approvals: 1 This PR was reviewed and approved by one person. labels Jan 6, 2025
@wolfgangwalther
Copy link
Contributor

FTR: I built conda and tensorflow successfully on x86_64-linux, when applying this set of patches on master. Let's fix the nits / docs / merge-conflict and merge this, I'd say.

@ShamrockLee
Copy link
Contributor Author

Thank you both for reviewing! I'll address them next week (after the final exam of my uni).

@emilazy
Copy link
Member

emilazy commented Jan 8, 2025

Good luck with exams!

Add flag pytestFlags as the new, conforming interface
replacing pytestFlagsArray.

Stop Bash-expanding disabledTests and disabledTestPaths.

Handle disabledTestPaths with `pytest --ignore-glob <path>`
to keep globbing support.
Check if each path glob matches at least one path
using the `glob` module from the Python standard library.

Also make buildPythonPackage and buildPythonApplication
stop escaping the elements of disabledTests and disabledTestPaths.
Handle flags with appendToVar and concatTo.

Stop Bash-expanding elements of
setupPyGlobalFlags and setupPyBuildFlags.
…stically

Take unittestFlags as the new and conforming interface.

Keep unittestFlagsArray as is.
@ShamrockLee ShamrockLee force-pushed the build-python-structured-attrs branch from 66cf078 to 625cf90 Compare January 9, 2025 10:43
@ofborg ofborg bot removed the 2.status: merge conflict This PR has merge conflicts with the target branch label Jan 9, 2025
@ShamrockLee
Copy link
Contributor Author

Addressed the review suggestions and rebased!

@wolfgangwalther wolfgangwalther merged commit 3558a56 into NixOS:staging Jan 10, 2025
21 checks passed
@wolfgangwalther
Copy link
Contributor

Now we can start migrating pytestFlagsArray to pytestFlags. I'll add a TODO in the tracking issue

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

Labels

6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 6.topic: python Python is a high-level, general-purpose programming language. 8.has: changelog This PR adds or changes release notes 8.has: documentation This PR adds or changes documentation 10.rebuild-darwin: 501+ This PR causes many rebuilds on Darwin and should normally target the staging branches. 10.rebuild-darwin: 5001+ This PR causes many rebuilds on Darwin and must target the staging branches. 10.rebuild-darwin-stdenv This PR causes stdenv to rebuild on Darwin and must target a staging branch. 10.rebuild-linux: 501+ This PR causes many rebuilds on Linux and should normally target the staging branches. 10.rebuild-linux: 5001+ This PR causes many rebuilds on Linux and must target the staging branches. 11.by: package-maintainer This PR was created by a maintainer of all the package it changes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants