rules_py 2's native py_binary launcher passes argv and runfiles to hermetic-launcher but returns the merged venv/binary environment only through RunEnvironmentInfo. A built launcher invoked directly by another executable therefore loses its declared environment.
A concrete reproduction is NLTK_DATA: a corpus is in runfiles and the inner binary declares its location, but a local wrapper execs the binary directly and startup cannot find the corpus. A consumer-side launcher override works around this narrowly.
#993 contained the corresponding direct-execution regression and attempted to bake env through a shell launcher; that approach was correctly rejected over shell interpolation. #464 intentionally preserved Bazel/rules_python semantics that env must not leak into action tools. I do not think the existing env or env_inherit behavior should change silently.
Would an explicit opt-in launcher_env/direct_env contract be acceptable? It would need to:
- preserve literal values without shell evaluation (including quotes, backticks, dollars, and backslashes);
- distinguish runfiles-backed paths and resolve them at launch, including manifest-only runfiles;
- preserve venv/binary override ordering and contextual variables;
- never serialize inherited values or secrets;
- leave ordinary env/env_inherit and action-tool behavior unchanged.
A falsifying regression would declare a literal plus an rlocationpath data target on a py_binary, resolve and exec that binary from a sh_test after unsetting both keys, and assert the literal is unchanged and the data path exists. The previous shell-injection discussion is #993 (comment) and the native-launcher context is #1045 (comment).
— tamirdex
rules_py 2's native py_binary launcher passes argv and runfiles to hermetic-launcher but returns the merged venv/binary environment only through RunEnvironmentInfo. A built launcher invoked directly by another executable therefore loses its declared environment.
A concrete reproduction is NLTK_DATA: a corpus is in runfiles and the inner binary declares its location, but a local wrapper execs the binary directly and startup cannot find the corpus. A consumer-side launcher override works around this narrowly.
#993 contained the corresponding direct-execution regression and attempted to bake env through a shell launcher; that approach was correctly rejected over shell interpolation. #464 intentionally preserved Bazel/rules_python semantics that env must not leak into action tools. I do not think the existing env or env_inherit behavior should change silently.
Would an explicit opt-in launcher_env/direct_env contract be acceptable? It would need to:
A falsifying regression would declare a literal plus an rlocationpath data target on a py_binary, resolve and exec that binary from a sh_test after unsetting both keys, and assert the literal is unchanged and the data path exists. The previous shell-injection discussion is #993 (comment) and the native-launcher context is #1045 (comment).
— tamirdex