Skip to content

Commit

Permalink
Fix uv runtime environment hook if sys.argv is changed by user script (
Browse files Browse the repository at this point in the history
…#50597)

<!-- Thank you for your contribution! Please review
https://github.com/ray-project/ray/blob/master/CONTRIBUTING.rst before
opening a pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

This fixes an issue @erictang000 was running into while using the uv
runtime env hook for https://github.com/hiyouga/LLaMA-Factory. LLaMA
Factory modifies sys.argv before calling ray.init (and therefore the
hook), which broke the original logic. We instead use the value from
`/proc/{pid}/cmdline` and add a test that we can tolerate changes of
sys.argv.

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've signed off every commit(by using the -s flag, i.e., `git
commit -s`) in this PR.
- [ ] I've run `scripts/format.sh` to lint the changes in this PR.
- [ ] I've included any doc changes needed for
https://docs.ray.io/en/master/.
- [ ] I've added any new APIs to the API Reference. For example, if I
added a
method in Tune, I've added it in `doc/source/tune/api/` under the
           corresponding `.rst` file.
- [ ] I've made sure the tests are passing. Note that there might be a
few flaky tests, see the recent failures at https://flakey-tests.ray.io/
- Testing Strategy
   - [ ] Unit tests
   - [ ] Release tests
   - [ ] This PR is not tested :(
  • Loading branch information
pcmoritz authored and israbbani committed Feb 25, 2025
1 parent 8f3c745 commit c7c719e
Showing 1 changed file with 16 additions and 5 deletions.
21 changes: 16 additions & 5 deletions python/ray/_private/runtime_env/uv_runtime_env_hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,20 @@ def hook(runtime_env: Optional[Dict[str, Any]]) -> Dict[str, Any]:

runtime_env = runtime_env or {}

# uv spawns the python process as a child process, so to determine if
# we are running under 'uv run', we check the parent process commandline.
parent = psutil.Process().parent()
cmdline = parent.cmdline()
if os.path.basename(cmdline[0]) != "uv" or cmdline[1] != "run":
# This means the driver was not run with 'uv run' -- in this case
# we leave the runtime environment unchanged
return runtime_env

# Extract the arguments of 'uv run' that are not arguments of the script
uv_run_args = cmdline[: len(cmdline) - len(sys.argv)]
# Extract the arguments of 'uv run' that are not arguments of the script.
# First we get the arguments of this script (without the executable):
script_args = psutil.Process().cmdline()[1:]
# Then, we remove those arguments from the parent process commandline:
uv_run_args = cmdline[: len(cmdline) - len(script_args)]

# Remove the "--directory" argument since it has already been taken into
# account when setting the current working directory of the current process
Expand Down Expand Up @@ -90,10 +95,16 @@ def hook(runtime_env: Optional[Dict[str, Any]]) -> Dict[str, Any]:
return runtime_env


# This __main__ is used for unit testing if the runtime_env_hook picks up the
# right settings.
if __name__ == "__main__":
import json

# This is used for unit testing if the runtime_env_hook picks up the
# right settings.
runtime_env = json.loads(sys.argv[1])
test_parser = argparse.ArgumentParser()
test_parser.add_argument("runtime_env")
args = test_parser.parse_args()
# We purposefully modify sys.argv here to make sure the hook is robust
# against such modification.
sys.argv.pop(1)
runtime_env = json.loads(args.runtime_env)
print(json.dumps(hook(runtime_env)))

0 comments on commit c7c719e

Please sign in to comment.