rules_nixpkgs icon indicating copy to clipboard operation
rules_nixpkgs copied to clipboard

Python toolchain is inhermetic: Uses user site packages

Open aherrmann opened this issue 4 years ago • 4 comments

Describe the bug A rules_nixpkgs provided Python toolchain will look for Python modules in user site packages, if present, e.g. ~/.local/lib/python3.6/site-packages. This is an inhermeticity: The contents of user site packages are neither pinned by Bazel nor by Nix.

To Reproduce

  • Checkout rules_nixpkgs at 6178f2aae7a90370f2132abafa977701afc6fb4e.
  • Add the following to tests/BUILD.bazel
    py_binary(
      name = "foo",
     srcs = ["foo.py"]
    )
    genrule(
      name = "gen",
      outs = ["out"],
      cmd = "$(location :foo) $@",
      tools = [":foo"],
    )
    
  • Add a new file tests/foo.py
    import sys
    with open(sys.argv[1], "w") as out:
        for item in sys.path:
            out.write(item + "\n");
    
  • Run bazel build //tests:gen
  • Inspect the output cat bazel-bin/tests/out
    /home/usr/src/rules_nixpkgs/tests
    /home/user/.cache/bazel/_bazel_aj/cf7431ac3fb5fc6f4c6a5569d7b55e4a/sandbox/linux-sandbox/2/execroot/io_tweag_rules_nixpkgs/bazel-out/host/bin/tests/foo.runfiles
    /home/user/.cache/bazel/_bazel_aj/cf7431ac3fb5fc6f4c6a5569d7b55e4a/sandbox/linux-sandbox/2/execroot/io_tweag_rules_nixpkgs/bazel-out/host/bin/tests/foo.runfiles/io_tweag_rules_nixpkgs
    /nix/store/hy65mn4wjswqih75gfr6g4q3xgqdm325-python3-3.6.6/lib/python36.zip
    /nix/store/hy65mn4wjswqih75gfr6g4q3xgqdm325-python3-3.6.6/lib/python3.6
    /nix/store/hy65mn4wjswqih75gfr6g4q3xgqdm325-python3-3.6.6/lib/python3.6/lib-dynload
    /home/user/.local/lib/python3.6/site-packages  # user site packages!
    /nix/store/hy65mn4wjswqih75gfr6g4q3xgqdm325-python3-3.6.6/lib/python3.6/site-packages
    

Expected behavior Python should not inspect user site packages.

Environment

  • OS name + version: Ubuntu 20.10
  • Version of the code: Current master 6178f2aae7a90370f2132abafa977701afc6fb4e

Additional context This is an instance of the following upstream issue: https://github.com/bazelbuild/bazel/issues/4939

Thanks @guibou for reporting this.

aherrmann avatar Feb 15 '21 09:02 aherrmann

A possible workaround is described in the upstream issue: https://github.com/tweag/rules_nixpkgs/issues/153.

Defining a Python wrapper in Nix that always sets PYTHONNOUSERSITE=nonempty would be another possible workaround.

aherrmann avatar Feb 15 '21 09:02 aherrmann

@aherrmann Did you mean to link another issue? #153 is this issue.

~This is because the system binary is used over the nix one. There's an issue with bazel, genrules and PATHs: https://github.com/bazelbuild/bazel/issues/12049~

~For the offending code, see py3wrapper.sh. The following is a work around:~

genrule(
    name = "gen",
    outs =
        ["out"],
    cmd =
    ("ln -s python `dirname $(location @python39//:bin/python)`/python3;" + 
    " PATH=`dirname $(location @python39//:bin/python)`:$$PATH $(location :foo)"),
    tools =
        [
            ":foo",
            "@python39//:bin/python",
        ],
)

Edit: Nevermind, I forgot to pass in the --host_platform flag. I cannot replicate this otherwise- it might be particular to Darwin (still https://github.com/bazelbuild/bazel/issues/12049)

dmadisetti avatar May 03 '22 20:05 dmadisetti

@aherrmann Did you mean to link another issue? #153 is this issue.

Oops, yes that must have been a clipboard failure. It's been a while, so I don't remember, but I guess I was referring to this one: https://github.com/bazelbuild/bazel/issues/4939#issuecomment-657678874

I see that since then someone also suggested this approach: https://github.com/bazelbuild/bazel/issues/4939#issuecomment-1101823251 Though I'm not sure if that would work on Darwin.

I cannot replicate this otherwise- it might be particular to Darwin (still https://github.com/bazelbuild/bazel/issues/12049)

Hmm, at least at the time I was able to reproduce it on Linux. It's possible that the work on setting stub_shebang impacted this issue.

aherrmann avatar May 04 '22 06:05 aherrmann

@aherrmann I have been trying to reproduce the issue (accordingly to step provided in the description). As long as one is using python from toolchain bootstrapped by rules_nixpkgs, the leakage does not seem to appear.

Setups on which I have tested:

  • Bazel 5.1.1 from Bazelisk on Ubuntu 22.04 and RHEL 8
  • Bazel 5.1.1 from nixpkgs on NixOS 21.11 and Ubuntu 22.04

Excerpt of the generated py_runtime (by rules_nixpkgs python toolchain):

py_runtime(
    name = "runtime",
    interpreter_path = "/nix/store/5bh6rpya1ar6l49vrhx1rg58dsa42906-python3-3.9.6/bin/python",
    python_version = "PY3",
    stub_shebang = "#! /nix/store/5bh6rpya1ar6l49vrhx1rg58dsa42906-python3-3.9.6/bin/python",

    visibility = ["//visibility:public"],
)

The nix-provided python interpreter seems not to be so eager to look into user site packages.

However, the issue largely remains on python provided "as-is" by Bazel by default.

Hope this helps!

AleksanderGondek avatar May 27 '22 15:05 AleksanderGondek