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

Cylc to ignore PYTHONPATH: Use CYLC_PYTHONPATH for custom Python for Cylc #5727

Merged
merged 4 commits into from
Oct 25, 2023

Conversation

wxtim
Copy link
Member

@wxtim wxtim commented Sep 11, 2023

Closes #5124

  • Remove from sys.path anything in PYTHONPATH.

    • This prevents PYTHONPATH from breaking Cylc.
  • Add to sys.path anything in CYLC_PYTHONPATH.

    • This allows us to continue to install Cylc plugins via environment variable.

Check List

cylc/flow/etc/cylc Outdated Show resolved Hide resolved
@wxtim wxtim marked this pull request as draft September 11, 2023 14:30
@wxtim
Copy link
Member Author

wxtim commented Sep 11, 2023

I've put this back to draft - I have something else to try!

@wxtim wxtim added the bug Something is wrong :( label Sep 21, 2023
@oliver-sanders
Copy link
Member

oliver-sanders commented Sep 22, 2023

LGTM; the tests are failing as a few PYTHONPATH variables will need to be updated to CYLC_PYTHONPATH in the test code / workflows.

Manual testing is ok for this, but a basic automated test is possible, put this code in a function, then monkeypatch sys.path.

import sys

def patch_pythonpath():
    ...

def test_patch_pythonpath(monkeypatch):
     monkeypatch.setattr('sys.path', [])
     monkeypatch.setenv('PYTHONPATH', ...)
     monkeypatch.setenv('CYLC_PYTHONPATH', ...)
     patch_pythonpath()
     assert sys.path == [...]

Will need docs too, but should run this by @hjoliver first, explanation:

  • People often set PYTHONPATH to add stuff to environments.
  • This regularly breaks Cylc/Rose, especially when larger environments are loaded.
  • Tomek changed the job script to run user-script in subshells which protects the built-in cylc message usage which made this better, but errors can still arise from within user scripts.
  • Rose is much worse affected as you have to activate your environment before running rose {app,task}-run.
  • We're currently unable to run the UM test suite at MO due to environment conflicts :(
  • The best solution we've come up with is to get Cylc to ignore the PYTHONPATH completely, and add CYLC_PYTHONPATH to cover any legit uses e.g. job-runners, xtriggers, etc.
  • Note these use cases would generally be better handled by {pip,conda} install than PYTHONPATH mangling due to this sort of issue, but also lack of entry point functionality, dependency checking, etc.

@wxtim
Copy link
Member Author

wxtim commented Sep 25, 2023

Manual testing is ok for this, but a basic automated test is possible, put this code in a function, then monkeypatch sys.path.

I had considered this - I'll do it.

Existing test failures seem to be caused by the print statements I left in the new code.

@wxtim wxtim changed the title If set, cache PYTHONPATH to _PYTHONPATH for Rose to use later Cylc to ignore PYTHONPATH: Use CYLC_PYTHONPATH for custom Python for Cylc Sep 25, 2023
@wxtim wxtim marked this pull request as ready for review September 26, 2023 10:19
@wxtim
Copy link
Member Author

wxtim commented Sep 26, 2023

@hjoliver Please confirm that you are happy with this approach. 😄

@oliver-sanders
Copy link
Member

Hmmm:

ModuleNotFoundError: No module named 'argparse'

https://github.com/cylc/cylc-flow/actions/runs/6315139062/job/17147002345?pr=5727#step:7:19

This is in a task's job.err section where it was raised from cylc/flow/scripts/cylc.py, so presumably a cylc message call from the job script.

I think this suggests that the logic is removing the standard library from sys.path internally?

The previous diff (replacing PYTHONPATH with CYLC_PYTHONPATH) may have suppressed this by bypassing the removal logic?

@wxtim wxtim marked this pull request as draft October 11, 2023 13:24
@wxtim wxtim marked this pull request as ready for review October 11, 2023 15:31
Copy link
Member

@oliver-sanders oliver-sanders left a comment

Choose a reason for hiding this comment

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

Here's how I tested:

$ # create a virtual environment with an incompatible version of psutil
$ virtualenv venv
$ . venv/bin/activate
$ pip install psutil==4
$ # replicate the bug
$ conda activate cylc.dev
$ PYTHONPATH=venv/lib/python3.9/site-packages/ cylc vip generic -N
...
2023-10-16T12:02:07Z ERROR - Workflow shutting down - PluginError: Error in plugin cylc.main_loop.auto_restart
    VersionConflict: (psutil 4.4.2 (/var/tmp/tmp.f8Khmjq2Dp/create/lib/python3.9/site-packages),
    Requirement.parse('psutil>=5.6.0'))
$ # verify the fix
$ git -C ~/cylc-flow checkout wxtim/feature.cache_pythonpath
$ PYTHONPATH=venv/lib/python3.9/site-packages/ cylc vip generic -N
...
 ▪ ■  Cylc Workflow Engine 8.3.0.dev
 ██   Copyright (C) 2008-2023 NIWA
▝▘    & British Crown (Met Office) & Contributors
...
$ # all good!

changes.d/5727.feat.md Outdated Show resolved Hide resolved
@oliver-sanders
Copy link
Member

We could do with an entry in the references/changes section of cylc-doc explaining the problem and introducing the CYLC_PYTHONPATH workaround.

Copy link
Member

@MetRonnie MetRonnie left a comment

Choose a reason for hiding this comment

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

Does this close #5124?

@MetRonnie
Copy link
Member

There is no specification for this behaviour written in the PR which is making it difficult to understand what is supposed to be happening

@wxtim
Copy link
Member Author

wxtim commented Oct 24, 2023

@hjoliver , and

There is no specification for this behaviour written in the PR which is making it difficult to understand what is supposed to be happening

Fair Point:
I think this is what is making me somewhat uncertain. I'll ask @oliver-sanders to check that the following is the aim:

  1. If the user modifies PYTHONPATH do not allow these items to interfere with Cylc by removing them from sys.path. Leave the environment PYTHONPATH unchanged.
  2. If CYLC_PYTHONPATH is set add items in that variable to sys.path for Cylc to use.

What I am now unclear on is whether I want to save the original PYTHONPATH to CYLC_PYTHONPATH - I don't thing I do?

@oliver-sanders
Copy link
Member

oliver-sanders commented Oct 24, 2023

Yes.

Very simple:

  • Remove from sys.path anything in PYTHONPATH.
    • This prevents PYTHONPATH from breaking Cylc.
  • Add to sys.path anything in CYLC_PYTHONPATH.
    • This allows us to continue to install Cylc plugins via environment variable.

And nothing else!

What I am now unclear on is whether I want to save the original PYTHONPATH to CYLC_PYTHONPATH

No, there is no reason to do this. We are not changing any environment variables, only sys.path within Cylc Python sessions.

@oliver-sanders oliver-sanders marked this pull request as draft October 24, 2023 13:02
@wxtim wxtim force-pushed the feature.cache_pythonpath branch 2 times, most recently from b0fd9a0 to 1d78914 Compare October 24, 2023 13:45
Add CYLC_PYTHONPATH items to sys.path
@wxtim wxtim marked this pull request as ready for review October 24, 2023 14:15
cylc/flow/scripts/cylc.py Outdated Show resolved Hide resolved
cylc/flow/scripts/cylc.py Outdated Show resolved Hide resolved
Co-authored-by: Hilary James Oliver <[email protected]>
@wxtim wxtim requested a review from MetRonnie October 25, 2023 10:28
Copy link
Member

@hjoliver hjoliver left a comment

Choose a reason for hiding this comment

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

🎉

@hjoliver hjoliver dismissed dpmatthews’s stale review October 25, 2023 22:58

All comments addressed, two other approvals.

@hjoliver hjoliver merged commit 9f4d0fb into cylc:master Oct 25, 2023
20 of 23 checks passed
@wxtim wxtim deleted the feature.cache_pythonpath branch October 26, 2023 07:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something is wrong :(
Projects
None yet
Development

Successfully merging this pull request may close these issues.

wrapper script: consider clearing PYTHONPATH
5 participants