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

bazel-runfiles module always throws ValueError #1631

Closed
AndrewGuenther opened this issue Dec 18, 2023 · 12 comments · Fixed by #1634
Closed

bazel-runfiles module always throws ValueError #1631

AndrewGuenther opened this issue Dec 18, 2023 · 12 comments · Fixed by #1634
Labels
Can Close? Will close in 30 days if there is no new activity

Comments

@AndrewGuenther
Copy link

AndrewGuenther commented Dec 18, 2023

🐞 bug report

Affected Rule

bazel-runfiles ackage

Is this a regression?

Appears to be, we were using bazel-runfiles on v0.12.0 with no issue

Description

When running a py_binary target, the main file is executed from within the runfiles tree, but everything imported points back to the original workspace. As a result of this, if you try to use bazel-runfiles, you're always met with this ValueError:

ValueError: /home/andrew/workspace/rules_python_runfiles_repro/my_module/__init__.py does not lie under the runfiles root /home/andrew/.cache/bazel/_bazel_andrew/43e798d9071ddd30271aac70168abdc4/execroot/_main/bazel-out/k8-fastbuild/bin/hello_world.runfiles

🔬 Minimal Reproduction

https://github.com/AndrewGuenther/rules_python_1631_repro

Minimal reproduction repository linked above.

🔥 Exception or Error


ValueError: /home/andrew/workspace/rules_python_runfiles_repro/my_module/__init__.py does not lie under the runfiles root /home/andrew/.cache/bazel/_bazel_andrew/43e798d9071ddd30271aac70168abdc4/execroot/_main/bazel-out/k8-fastbuild/bin/hello_world.runfiles

🌍 Your Environment

Operating System:

  
Ubuntu
  

Output of bazel version:

  
6.4.0
  

Rules_python version:

  
0.27.1
  

Anything else relevant?

@fmeum
Copy link
Contributor

fmeum commented Dec 18, 2023

@rickeylev Happy to help, but I would need to know whether there have been any intentional changes to the way Python imports are resolved.

@rickeylev
Copy link
Collaborator

The only thing I can think of relating to imports is some changes to py_proto_library. It was changed to add "virtual imports" (basically the directory where files are put when strip_prefix is used) to the path.

@AndrewGuenther
Copy link
Author

I can confirm that this issue only occurs when bzlmod is enabled. The imports still point to the local workspace, but the ValueError is not thrown from bazel-runfiles

@AndrewGuenther
Copy link
Author

Just pushed a branch called workspace to the repro repo to demonstrate.

@AndrewGuenther
Copy link
Author

Sorry for the comment spam, but I've added some additional logging and have a few more findings to share:

The import behavior is the same in both WORKSPACE and MODULE.bazel modes, what differs however is the result of this check:

https://github.com/bazelbuild/rules_python/blob/main/python/runfiles/runfiles.py#L137-L141

        if source_repo is None and self._repo_mapping:
            # Look up runfiles using the repository mapping of the caller of the
            # current method. If the repo mapping is empty, determining this
            # name is not necessary.
            source_repo = self.CurrentRepository(frame=2)

In both WORKSPACE and MODULE.bazel mode, source_repo is None, but self._repo_mapping is only non-empty in MODULE.bazel mode. The ValueError being thrown is coming from inside this check. Commenting out this check (not saying that's the right fix) causes both WORKSPACE and MODULE.bazel modes to return the same result. So this is something that was valid behavior before, but is not when bzlmod is enabled.

I'm not sure what the "right" thing to do is here since I presume there's an argument that the behavior in WORKSPACE mode is also wrong and the import behavior could be a regression.

@AndrewGuenther
Copy link
Author

Just verified that this import behavior can be observed as far back as the 0.5.0 release of rules_python. I couldn't get earlier versions to work at all, but the point is more that this is not new behavior.

I also verified that the ValueError is thrown in every version of rules_python that supports bzlmod (starting in 0.14.0)

@aignas
Copy link
Collaborator

aignas commented Dec 19, 2023

Thanks for this investigation!

@fmeum
Copy link
Contributor

fmeum commented Dec 19, 2023

When I run the reproducer, the sys.path looks like this:

['/home/fhenneke/tmp/rules_python_1631_repro', '/home/fhenneke/.cache/bazel/_bazel_fhenneke/8c09f903aff88728a492063a5dce0a79/execroot/_main/bazel-out/k8-fastbuild/bin/hello_world.runfiles', ...]

This is why the import in hello_world.py resolves as it does: into the source root, not the runfiles directory.

Traceback (most recent call last):
  File "/home/fhenneke/.cache/bazel/_bazel_fhenneke/8c09f903aff88728a492063a5dce0a79/execroot/_main/bazel-out/k8-fastbuild/bin/hello_world.runfiles/_main/hello_world.py", line 6, in <module>
    import my_module
  File "/home/fhenneke/tmp/rules_python_1631_repro/my_module/__init__.py", line 6, in <module>
    r.Rlocation("_main/my_module/test.txt")
  File "/home/fhenneke/.cache/bazel/_bazel_fhenneke/8c09f903aff88728a492063a5dce0a79/execroot/_main/bazel-out/k8-fastbuild/bin/hello_world.runfiles/rules_python~0.27.1~pip~pip_38_bazel_runfiles/site-packages/runfiles/runfiles.py", line 141, in Rlocation
    source_repo = self.CurrentRepository(frame=2)
  File "/home/fhenneke/.cache/bazel/_bazel_fhenneke/8c09f903aff88728a492063a5dce0a79/execroot/_main/bazel-out/k8-fastbuild/bin/hello_world.runfiles/rules_python~0.27.1~pip~pip_38_bazel_runfiles/site-packages/runfiles/runfiles.py", line 215, in CurrentRepository
    raise ValueError(
ValueError: /home/fhenneke/tmp/rules_python_1631_repro/my_module/__init__.py does not lie under the runfiles root /home/fhenneke/.cache/bazel/_bazel_fhenneke/8c09f903aff88728a492063a5dce0a79/execroot/_main/bazel-out/k8-fastbuild/bin/hello_world.runfiles

@aignas @rickeylev Is this expected? I always assumed that rules_python would not add the source root to sys.path as that could result in non-hermetic behavior (imports resolving when they shouldn't). I could adapt the runfiles logic to this if this really is the expected behavior.

@rickeylev
Copy link
Collaborator

What version of Python is being used? This sounds like the "script dir is added to sys.path" behavior: https://docs.python.org/3/using/cmdline.html#cmdoption-P

Not doing that behavior requires Python 3.11+

@fmeum
Copy link
Contributor

fmeum commented Dec 19, 2023

I was using Python 3.10. That makes sense.

@rickeylev I can look into handling this case in the runfiles library for compatibility with Python 3.10 and lower if those versions are meant to be supported.

github-merge-queue bot pushed a commit that referenced this issue Dec 21, 2023
…h is needed (#1637)

Before this PR there was a typo, that was actually causing the
patching function to not use the provided patches. With this change
we are finally correctly doing it. After fixing this bug I noticed
that `repository_ctx.patch` results in files with `CRLF` on Windows,
which made me make the `RECORD` mismatch to be a warning rather than
a hard failure to make the CI happy and allow users on Windows to
patch wheels but see a warning if they have a multi-platform bazel
setup.

The `CRLF` endings on Windows issue is fixed in
bazelbuild/bazel@07e0d31

Related #1631, #1639.
Copy link

This issue has been automatically marked as stale because it has not had any activity for 180 days. It will be closed if no further activity occurs in 30 days.
Collaborators can add an assignee to keep this open indefinitely. Thanks for your contributions to rules_python!

@github-actions github-actions bot added the Can Close? Will close in 30 days if there is no new activity label Jun 16, 2024
Copy link

This issue was automatically closed because it went 30 days without a reply since it was labeled "Can Close?"

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Jul 17, 2024
github-merge-queue bot pushed a commit that referenced this issue Aug 15, 2024
#1634)

When using Python 3.10 or earlier, the first `sys.path` entry is the
directory containing the script. This can result in modules being loaded
from the source root rather than the runfiles root, which the runfiles
library previously didn't support.

Fixes #1631

---------

Co-authored-by: Ignas Anikevicius <[email protected]>
Co-authored-by: Richard Levasseur <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Can Close? Will close in 30 days if there is no new activity
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants