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

do not export PYTHONPATH by default in Flux commands #6597

Merged
merged 9 commits into from
Feb 4, 2025

Conversation

grondo
Copy link
Contributor

@grondo grondo commented Feb 1, 2025

This PR attempts to fix #6594 while preserving a bit of backwards compatibility and ensuring that Python subcommands get a sys.path that will load the correct version of the Flux Python bindings. The steps taken to accomplish this were the following:

  • save the current PYTHONPATH before executing the py-runner.py Python subcommand wrapper so that PYTHONPATH can be modified before running the wrapper. The wrapper script then reestablishes the original PYTHONPATH after sys.path is internally set up correctly. This is necessary so that py-runner.py imports the correct _flux cffi modules, from which it derives other necessary paths.
  • Only modify PYTHONPATH in flux env and flux python (in addition to the case above). Thus, PYTHONPATH is no longer modified in the environment of jobs or flux start.
  • Since PYTHONPATH no longer has the path to the build tree Python bindings in the testsuite, even under flux start, modify PYTHONPATH for sharness tests in sharness.d/01-setup.sh so that non-Flux subcommand Python scripts run as part of the testsuite use the builddir Python bindings and not system bindings.

@grondo
Copy link
Contributor Author

grondo commented Feb 3, 2025

Requesting a review from either @trws or @jameshcorbett to vet the changes here just to get someone with more Python experience to give their perspective - however it would be nice to get this fixed in tomorrow's release if this looks good.

Copy link
Member

@jameshcorbett jameshcorbett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to me like it requires more environment-variable / process-manipulation knowledge than Python knowledge, but anyway I looked through this and did some research to make sure there isn't another way to manipulate sys.path--I couldn't find one. This looks like a nice improvement to me.

Copy link
Member

@trws trws left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This all looks right to me and seems like it should solve that problem, though I admit I'm still chewing on two thoughts, both centered around whether we might actually want to set PYTHONPATH even less.

  1. We have classically set PYTHONPATH in flux env because that's how we set up the environment for any given flux command or flux run. Maybe better to have it be a separate change, or see what kind of fallout it would have, but I'm tempted to say we should remove it from there as well, or perhaps put it behind a --pythonpath flag or similar.
  2. How bad would it be to get the scripts run like flux python commands/scripts? I'm guessing that's a non-trivial amount of work, but setting PYTHONPATH for the whole test suite could hide issues where we need to wrap with our python runner or similar and forget.

@grondo
Copy link
Contributor Author

grondo commented Feb 4, 2025

Great points @trws and I was thinking about both of them as well.

For 1., I initially did not have flux env set PYTHONPATH, but I found this unfortunate note in our Python basics docs:

If you want to import the package from outside of a Flux instance, running /path/to/flux env | grep PYTHONPATH in your shell will show you what PYTHONPATH would be set to if you were running in a Flux instance built/installed at /path/to/flux.

So I figured we should keep it in flux env for now (perhaps to be removed in the next release)

Similar thinking for all the Python scripts in the testsuite. I agree with your assessment, and perhaps we should open an issue to remove the forced PYTHONPATH in the testsuite soon as well.

@trws
Copy link
Member

trws commented Feb 4, 2025

That all sounds right to me, maybe throw up an issue so we don't lose track of it referencing the docs and test suite?

@grondo
Copy link
Contributor Author

grondo commented Feb 4, 2025

Yeah, it also occurs to me that flux config builtin python_path is a better way to get the builtin python path too. Maybe we make a PYTHONPATH alias for that too so flux config builtin PYTHONPATH also works.

@grondo
Copy link
Contributor Author

grondo commented Feb 4, 2025

Ok, opened #6600

@grondo
Copy link
Contributor Author

grondo commented Feb 4, 2025

I'll set MWP now.

Problem: src/cmd/builtin/python.c includes "config.h" twice.

Remove the extraneous include.
Problem: The py-runner.py script is invoked by flux(1) for any Python
subcommand in order to ensure the subcommand has a sane sys.path
matching the currently invoked version of Flux. Ideally, this would
not require flux(1) to modify PYTHONPATH, which is then inherited by
the user's environment (e.g. in the case of `flux run`).  However,
`py-runner.py` does need the correct PYTHONPATH at startup so it can
`import flux`, so PYTHONPATH must be set.

In order to avoid polluting the user's environment, save the original
callers PYTHONPATH in FLUX_PYTHONPATH_ORIG in flux(1), then restore
it if set in `py-runner.py`. If FLUX_PYTHONPATH_ORIG is not set, this
means that the callers PYTHONPATH was empty, so unset the variable
in this case.
Problem: There are a few builtin subcommands that may make use
of the internal function that modifies PYTHONPATH in the environment.

Export builtin_env_add_pythonpath() in bultin.h.
Problem: Users that run Python programs using a different version or
installation of Python under `flux run` currently have to work around
the fact that `flux(1)` always prepends the path to the current Python
bindings to `PYTHONPATH`. This gets exported in the job environment
and the incorrect Flux Python bindings are loaded, causing errors.

The `flux(1)` command ostensibly prepends to `PYTHONPATH` to ensure
that Python subcommands use the right version of the bindings, but
the `py-runner.py` wrapper now takes care of that, so doing this is
actually no longer necessary.

Do not modify `PYTHONPATH` in `flux` unless `FLUX_PYTHONPATH_PREPEND`
is set. For backwards compatibility, continue to prepend the builtin
Python path in the `flux python` and `flux env` utilities.

Fixes flux-framework#6594

fixup! cmd: do not always prepend to `PYTHONPATH` in `flux(1)`
Problem: Some Flux manuals describe the `flux(1)` will modify
`PYTHONPATH`, but this is no longer true in most situations.

Update documentation to reflect reality.
Problem: The landing page for the Flux Python documentation notes
that pip can't be used to install the Python bindings, but this is
no longer true.

Update the note at the top to say there's a `flux-python` pip package
available.
Problem: The pyton/basics.rst documentation mentions that `flux`
will set `PYTHONPATH` in the environment of all commands, but this
is no longer true.

Remove the outdated statement.
Problem: Now that `flux(1)` no longer exports PYTHONPATH to everything,
some scripts in the teststuie that are not run under `flux python`
or as flux subcommands may fail because they load the wrong set of
Python modules.

Export PYTHONPATH to sharness scripts via sharness.d/01-setup.sh to
avoid this issue.
Problem: The testsuite does not ensure that PYTHONPATH is not exported
by default by flux(1), but is for the `python` and `env` subcommands.

Add tests to t1102-cmddriver.t that verify the expected handling of
PYTHONPATH by flux commands.
@mergify mergify bot merged commit fc051b9 into flux-framework:master Feb 4, 2025
35 checks passed
Copy link

codecov bot commented Feb 4, 2025

Codecov Report

Attention: Patch coverage is 89.13043% with 5 lines in your changes missing coverage. Please review.

Project coverage is 79.54%. Comparing base (e9f7fcd) to head (f770eff).
Report is 10 commits behind head on master.

Files with missing lines Patch % Lines
src/cmd/py-runner.py 71.42% 2 Missing ⚠️
src/cmd/builtin/env.c 90.00% 1 Missing ⚠️
src/cmd/builtin/python.c 88.88% 1 Missing ⚠️
src/cmd/flux.c 95.00% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master    #6597   +/-   ##
=======================================
  Coverage   79.53%   79.54%           
=======================================
  Files         531      531           
  Lines       88170    88213   +43     
=======================================
+ Hits        70130    70165   +35     
- Misses      18040    18048    +8     
Files with missing lines Coverage Δ
src/cmd/builtin/env.c 93.33% <90.00%> (-1.67%) ⬇️
src/cmd/builtin/python.c 94.11% <88.88%> (-5.89%) ⬇️
src/cmd/flux.c 86.05% <95.00%> (+0.58%) ⬆️
src/cmd/py-runner.py 94.11% <71.42%> (-5.89%) ⬇️

... and 9 files with indirect coverage changes

@grondo grondo deleted the issue#6594 branch February 4, 2025 04:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

don't prepend builtin PYTHONPATH for all commands in flux(1)
3 participants