You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Python uses sys.path in a similar manner to how bash uses the path variable. There are two relevant entries here.
sys.path[0] contains the directory of the script being run. This allows you to write imports relative to the binary being run.
sys.path[1] is set to RUNFILES_DIR. This allows you to write imports relative to the workspace root. For example, you would import @foo//bar:baz as from foo.bar import baz.
The unfortunate side effect of the former is that because the path of the script being run is relative to the workspace, not the output directory, you are able to import any python file, not just ones you declared as dependencies.
It is my opinion that the former is an antipattern, and the latter is the only correct way to perform imports (for first party libraries), as if you have the binaries //foo:bin and //bar:bin both importing a library //baz:lib, if baz then writes import blah, then foo attempts to import //foo:blah, while bar attempts to import //bar:blah. However, it must be recognised that this is a common use case, and will not be feasible.
I suggest that we instead provide a flag allowing you to disable the first entry in sys.path to prevent python from importing outside your runfiles. It would:
If enabled, remove sys.path[0]
If disabled, still remove sys.path[0], but replace it with RUNFILES_DIR / sys.path[0].relative_to(workspace_root). This should still allow you to perform relative imports, but remove the ability to import files you haven't declared a dependency on.
I can implement this myself if required, but I don't know where the correct place to modify the sys.path would be.
🐞 bug report
Affected Rule
py_binary/library/test
Is this a regression?
No
Description
Python uses sys.path in a similar manner to how bash uses the path variable. There are two relevant entries here.
sys.path[0]
contains the directory of the script being run. This allows you to write imports relative to the binary being run.sys.path[1]
is set to RUNFILES_DIR. This allows you to write imports relative to the workspace root. For example, you would import@foo//bar:baz
asfrom foo.bar import baz
.The unfortunate side effect of the former is that because the path of the script being run is relative to the workspace, not the output directory, you are able to import any python file, not just ones you declared as dependencies.
It is my opinion that the former is an antipattern, and the latter is the only correct way to perform imports (for first party libraries), as if you have the binaries
//foo:bin
and//bar:bin
both importing a library//baz:lib
, if baz then writesimport blah
, then foo attempts to import//foo:blah
, while bar attempts to import//bar:blah
. However, it must be recognised that this is a common use case, and will not be feasible.I suggest that we instead provide a flag allowing you to disable the first entry in
sys.path
to prevent python from importing outside your runfiles. It would:sys.path[0]
sys.path[0]
, but replace it withRUNFILES_DIR / sys.path[0].relative_to(workspace_root)
. This should still allow you to perform relative imports, but remove the ability to import files you haven't declared a dependency on.I can implement this myself if required, but I don't know where the correct place to modify the
sys.path
would be.🔬 Minimal Reproduction
https://github.com/matts1/rules_python/blob/implicit_deps_repro/examples/bzlmod/demo/test.py
🔥 Exception or Error
None
🌍 Your Environment
Operating System:
Output of
bazel version
:Rules_python version:
Anything else relevant?
The text was updated successfully, but these errors were encountered: