-
Notifications
You must be signed in to change notification settings - Fork 539
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
Packages shadowed by other modules are no longer importable under bzlmod #1174
Comments
I have not tried, but I have had many problems with symlinks and Windows. So we may not want to go down this path. |
Directory symlinks aka junctions have been available on Windows for a long time and are relied upon by Bazel quite heavily. They could work here. A simple "solution" that is recommended for Bazel-aware Python packages is to move everything into a top-level directory with the desired name. Since repo roots are on the Python path, this should allow existing absolute imports to continue to work. |
@rickeylev in case you're not aware of this. We discussed this problem around a year ago I think, and I think your recommendation was to set up a PyPI-esque import dir merging all needed repos (and forgoing repo names altogether). Could that be adapted to help in @aschleck's case? Is this process documented? |
Not having the repo name in the import name is ideal, yes. That said, requiring that to switch to bzlmod is a rather big hurdle. Having the repo mapping available during analysis would open a few more options. Hmmm. There might be another way out, too. Not 100% sure on this. Basically, a user creates a directory with the desired import name. In that dir, they create an init.py file. They set the imports attribute of the target to Symlinks would also work. They'll require additional changes to the startup script, plus cleanup logic, though a user's main could also be written to do the equiv before running the real main module code. |
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. |
I no longer work at the company where this matters but it still is a thing |
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. |
Still a thing as far as I know |
Another idea: add something to the end of sys.path as a last-chance way to handle these. By adding to the end, we can minimize interfering with other import dirs. Could generate a dir with shim files (using Also, in case it wasn't clear: the main thing preventing progress on this issue is available time. There's several ideas, but someone has to try something to see how well it works or doesn't work. |
🐞 bug report
Affected Rule
The issue is caused by the rule: `py_binary`/`py_library` under bzlmodIs this a regression?
Yes, this works under the WORKSPACE model. It is only bzlmod that is broken.Description
When two Bazel workspaces (with one depending on the other) both define packages with the same name (
common
,core
,helpers
,private
,util
, ...) the outer one will shadow the inner one. Without bzlmod this has always been solvable by using absolute imports with the workspace name as the prefix. However, under bzlmod, these absolute imports no longer work: when a module is used as an outer repository the prefix is_main
but when a module is used as a dependency repository it is<module name>
. And even if that was fine, there are further problems caused bylocal_path_override
because it suffixes~override
onto the folders in the runfiles directory.From my perspective the best solution would be to make the generated
py_binary
wrapper script read the generated_repo_mapping
file and set up the path such that absolute imports work the same way they've always worked. One way to make that happen would be to have the wrapper script create a temporary directory, create symlinks with the correct names pointing to the real folders, and then add the temporary directory to the PYTHONPATH. I could imagine there is probably some cleaner way I can't think of.🔬 Minimal Reproduction
I put an example here: https://github.com/aschleck/bzlmod-shadow-python-problem (with another writeup in
README.md
.)This repository illustrates three situations:
core
. In this case, theouter
workspace importsdep
absolutely butdep
's import of itself fails due to being shadowed.dep
can always import itself with its workspace name as a prefix (likeimport dep.core.<whatever>
. Another solution would be to use relative imports, but those get unwieldy and annoying in large repos.rules_python
not respecting the_repo_mapping
file for imports. The absolute import ofdep
fromouter
fails because the folder in the runfiles is actuallydep~override
sincelocal_path_override
was used. Even if it was nameddep
, the code indep
itself could no longer assume thatimport dep
refers to itself (because when its rules are run directly it is_main
, and so it would need to doimport _main.core
notimport dep.core
.)🔥 Exception or Error
The error is what you'd expect: the import fails.
🌍 Your Environment
Operating System:
Output of
bazel version
:Rules_python version:
Anything else relevant?
Thank you for maintaining these rules! It's been amazing to see how well this all works on the whole.
The text was updated successfully, but these errors were encountered: