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

Add a new entry_point for xtriggers #5831

Merged
merged 8 commits into from
Jan 2, 2024

Conversation

ColemanTom
Copy link
Contributor

@ColemanTom ColemanTom commented Nov 21, 2023

This creates a clean way to add xtriggers from python packages. xtriggers no longer need to be directly in the PYTHONPATH but can instead be from a general installation location using an entry_point cylc.xtriggers. Similar could be done for other things perhaps, like Jinja2Globals, although I have not looked.

I do not have an Issue for this, but I think it may be or at least relate to #3456, although I do not add the built in xtriggers with this PR, perhaps they should be but I think that can be a bit of work for someone else.

Check List

  • I have read CONTRIBUTING.md and added my name as a Code Contributor.
  • Contains logically grouped changes (else tidy your branch by rebase).
  • Does not contain off-topic changes (use other PRs for other changes).
  • Applied any dependency changes to both setup.cfg (and conda-environment.yml if present).
  • Tests are included (or explain why tests are not needed).
  • CHANGES.md entry included if this is a change that can affect users
  • Cylc-Doc pull request opened Add documentation for xtriggers entry_point cylc-doc#671

I've not added tests as I've not looked at how it coudl be done (can it cleanly?). I'll update CHANGES and cylc doc only if/when this is agreed to.

Example of use below, but note that with this approach, you do not actually need to have a file per xtrigger with a function in it with the same name as the filename.

def xtriggers():
    return {
        'xtrig1': xtrig1.xtrig1,
        'xtrig2': xtrig2.xtrig2,
        'abc': abc.abc,
    }

Then in pyproject.toml

[project.entry-points."cylc.xtriggers"]
my_package = "my_package.cylc_configure:xtriggers"

@ColemanTom
Copy link
Contributor Author

If this approach is agreed to and you want it into 8.2.X I can backport it to that instead.

@MetRonnie MetRonnie added the question Flag this as a question for the next Cylc project meeting. label Nov 21, 2023
@MetRonnie MetRonnie added this to the cylc-8.x milestone Nov 21, 2023
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.

Happy with using entry points for xtriggers.

We started using entry points with Cylc 8 and have been slowly propagating them.

Features should target the next minor release (8.3.0) so this shouldn't be backported.

cylc/flow/scripts/install.py Outdated Show resolved Hide resolved
cylc/flow/subprocpool.py Outdated Show resolved Hide resolved
@oliver-sanders
Copy link
Member

Note, the commit seems to be associated with a different GitHub account, this is ok, but please make sure the .mailmap file maps both addresses against your name, if this is done correctly the git shortlog -se command should only list your name once. (it's legal stuff to do with the CLA)

@oliver-sanders
Copy link
Member

From #3456:

To close this issue (the Cylc Flow side of things)

  • Implement the cylc.plugins.xtriggers entry point.
  • Register the built-in Xtriggers via this mechanism.

@ColemanTom
Copy link
Contributor Author

  • Register the built-in Xtriggers via this mechanism.

I've added a new file xtrigger_entry_point.py, but contemplated adding the entry_point into xtrigger_mgr.py. Happy to do whatever you want here.

@ColemanTom
Copy link
Contributor Author

Note, the commit seems to be associated with a different GitHub account, this is ok, but please make sure the .mailmap file maps both addresses against your name, if this is done correctly the git shortlog -se command should only list your name once. (it's legal stuff to do with the CLA)

Things appear to map correctly.

@ColemanTom
Copy link
Contributor Author

@oliver-sanders how about CHANGES.md? I can't see an 8.3.0 entry in there, or does it get automatically generated now (if so, should that tick box be removed from the list of things to tick off?)

@ColemanTom
Copy link
Contributor Author

I don't really know what I'm doing with rst, but I've tried to make updates to cylc-doc

@oliver-sanders
Copy link
Member

how about CHANGES.md? I can't see an 8.3.0 entry in there, or does it get automatically generated now

Use towncrier to create a changelog entry, the changelog itself gets built at release time.

The contributor page has been updated with an example command:

https://github.com/cylc/cylc-flow/blob/master/CONTRIBUTING.md#contribute-code

@oliver-sanders
Copy link
Member

Looks good to me.

The tests are looking a bit unhappy, I think something's gone wrong with the trigger loading, here's some traceback extracted from the functional test failure:

    Traceback (most recent call last):
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/subprocpool.py", line 86, in get_func
        mod_by_name = __import__(mod_name, fromlist=[mod_name])
    ModuleNotFoundError: No module named 'wall_clock'
    During handling of the above exception, another exception occurred:
    Traceback (most recent call last):
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/xtrigger_mgr.py", line 263, in validate_xtrigger
        func = get_func(fname, fdir)
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/subprocpool.py", line 94, in get_func
        _XTRIG_FUNCS[func_name] = entry_point.resolve()
    AttributeError: 'EntryPoint' object has no attribute 'resolve'
    During handling of the above exception, another exception occurred:
    Traceback (most recent call last):
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/scheduler.py", line 641, in run_scheduler
        await self.main_loop()
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/scheduler.py", line 1755, in main_loop
        self.process_queued_task_messages()
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/scheduler.py", line 894, in process_queued_task_messages
        self.task_events_mgr.FLAG_RECEIVED, submit_num
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/task_events_mgr.py", line 699, in process_message
        itask, event_time, self.JOB_FAILED):
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/task_events_mgr.py", line 1132, in _process_message_failed
        self._retry_task(itask, timer.timeout)
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/task_events_mgr.py", line 1098, in _retry_task
        os.getenv("CYLC_WORKFLOW_RUN_DIR")
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/xtrigger_mgr.py", line 324, in add_trig
        self.validate_xtrigger(label, fctx, fdir)
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/xtrigger_mgr.py", line 274, in validate_xtrigger
        f"'{fname}' not found in xtrigger module '{fname}'",
    cylc.flow.exceptions.XtriggerConfigError: [_cylc_retry_1/foo] 'wall_clock' not found in xtrigger module 'wall_clock'

We could also do with a functional test to ensure that the old PYTHONPATH based mechanism continues to work as it would be quite easy for us to break it accidentally now that the built-in xtriggers are properly registered via entry-points.

@ColemanTom
Copy link
Contributor Author

The tests are looking a bit unhappy, I think something's gone wrong with the trigger loading, here's some traceback extracted from the functional test failure:

    Traceback (most recent call last):
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/subprocpool.py", line 86, in get_func
        mod_by_name = __import__(mod_name, fromlist=[mod_name])
    ModuleNotFoundError: No module named 'wall_clock'
    During handling of the above exception, another exception occurred:
    Traceback (most recent call last):
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/xtrigger_mgr.py", line 263, in validate_xtrigger
        func = get_func(fname, fdir)
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/subprocpool.py", line 94, in get_func
        _XTRIG_FUNCS[func_name] = entry_point.resolve()
    AttributeError: 'EntryPoint' object has no attribute 'resolve'
    During handling of the above exception, another exception occurred:
    Traceback (most recent call last):
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/scheduler.py", line 641, in run_scheduler
        await self.main_loop()
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/scheduler.py", line 1755, in main_loop
        self.process_queued_task_messages()
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/scheduler.py", line 894, in process_queued_task_messages
        self.task_events_mgr.FLAG_RECEIVED, submit_num
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/task_events_mgr.py", line 699, in process_message
        itask, event_time, self.JOB_FAILED):
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/task_events_mgr.py", line 1132, in _process_message_failed
        self._retry_task(itask, timer.timeout)
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/task_events_mgr.py", line 1098, in _retry_task
        os.getenv("CYLC_WORKFLOW_RUN_DIR")
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/xtrigger_mgr.py", line 324, in add_trig
        self.validate_xtrigger(label, fctx, fdir)
      File "/home/runner/work/cylc-flow/cylc-flow/cylc/flow/xtrigger_mgr.py", line 274, in validate_xtrigger
        f"'{fname}' not found in xtrigger module '{fname}'",
    cylc.flow.exceptions.XtriggerConfigError: [_cylc_retry_1/foo] 'wall_clock' not found in xtrigger module 'wall_clock'

Do entry points get resolved for the tests? If so, how? Is there anything I need to add to have entry points added which are defined in the setup.cfg file?

We could also do with a functional test to ensure that the old PYTHONPATH based mechanism continues to work as it would be quite easy for us to break it accidentally now that the built-in xtriggers are properly registered via entry-points.

That should be doable easily enough, but similar question to above, do I need to do anythnig special to add in the entry points to ensure they are resolved correctly?

@oliver-sanders
Copy link
Member

oliver-sanders commented Nov 27, 2023

Do entry points get resolved for the tests?

Yes, we pip install Cylc before running the tests so any commands, plugins and now xtriggers defined in the cylc-flow package will be available.

To debug, you can run the failing tests locally, e.g:

$ pytest -vv tests/unit/test_xtrigger_mgr.py::test_add_xtrigger
$ etc/bin/run-functional-tests -v  tests/f/retries/01-submission-retry.t

@ColemanTom
Copy link
Contributor Author

ColemanTom commented Nov 30, 2023

To debug, you can run the failing tests locally, e.g:

I hate to say this as its very cliche, but... the tests don't fail locally for me.

  • I've created a conda environment from the conda-environment.yml file
  • I activate the conda environment
  • I do pip install --no-deps . from the Cylc repo
  • I then try tests/unit/test_xtrigger_mgr.py::test_add_xtrigger and it passes
  • I try one of the failing functional tests, tests/f/runahead/06-release-update.t, all tests pass

EDIT:

🤦‍♂️ - I didn't have my branch checked out, I had a different branch open, tests correctly fail now, will have a look

This creates a clean way to add xtriggers from python packages.
xtriggers no longer need to be directly in the PYTHONPATH,
but instead can be added via a cylc.xtriggers entry point.

Local cylc-flow xtriggers are defined via a new entry_point.
@ColemanTom
Copy link
Contributor Author

I've pushed some fixes. Not sure how it was working before this, unless I had some changes I didn't commit and lost when I did a different piece of work.

Running a few of the failed tests all had them passing now.

I'll look at an extra functional test next week (unless I can get one done within a few minutes, but I doubt it).

@oliver-sanders
Copy link
Member

Please ignore tests/integration/tui test failures for now, we've been having a bad run of CI failure issues but should get things back on track soon.

@ColemanTom
Copy link
Contributor Author

ColemanTom commented Dec 6, 2023

@oliver-sanders having a look at this, adding xtriggres via the PYTHONPATH does not work as the PYTHONPATH is removed. I'm guessing you're meaning CYLC_PYTHONPATH instead?

Also, docs on custom xtriggers probably need updating

they can be located either:

  • in /lib/python/;
  • or anywhere in your Python library path.

Ensures that xtrggers in your CYLC_PYTHONPATH
are respected above entry_point xtriggers.
@ColemanTom
Copy link
Contributor Author

Functional test for CYLC_PYTHONPATH added in be3e277 @oliver-sanders

@oliver-sanders oliver-sanders removed the question Flag this as a question for the next Cylc project meeting. label Dec 6, 2023
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.

Thanks @ColemanTom

I've got a few suggestions

cylc/flow/subprocpool.py Outdated Show resolved Hide resolved
tests/functional/xtriggers/04-respect-cylc-pythonpath.t Outdated Show resolved Hide resolved
tests/functional/xtriggers/04-respect-cylc-pythonpath.t Outdated Show resolved Hide resolved
tests/functional/xtriggers/04-respect-cylc-pythonpath.t Outdated Show resolved Hide resolved
ColemanTom and others added 5 commits December 14, 2023 08:06
Co-authored-by: Ronnie Dutta <61982285+MetRonnie@users.noreply.github.com>
Co-authored-by: Ronnie Dutta <61982285+MetRonnie@users.noreply.github.com>
Co-authored-by: Ronnie Dutta <61982285+MetRonnie@users.noreply.github.com>
Co-authored-by: Ronnie Dutta <61982285+MetRonnie@users.noreply.github.com>
Co-authored-by: Ronnie Dutta <61982285+MetRonnie@users.noreply.github.com>
@ColemanTom
Copy link
Contributor Author

Thanks @MetRonnie - I added all your suggestions.

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.

👍

@oliver-sanders
Copy link
Member

(re-opened to kick the tests)

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.

LGTM, cheers!

@oliver-sanders oliver-sanders merged commit b8a55d8 into cylc:master Jan 2, 2024
35 of 38 checks passed
wxtim added a commit to wxtim/cylc that referenced this pull request Jan 9, 2024
* upstream/master: (350 commits)
  Apply suggestions from code review [skip ci]
  Added missing union type import (cylc#5906)
  set CYLC_DEBUG env var when set-verbosity DEBUG (cylc#5854)
  coverage: exclude report-timings and set 90% as the lower limit
  lint: Warn users that `CYLC_VERSION={{CYLC_VERSION}}` is deprecated (cylc#5890)
  Add a new entry_point for xtriggers (cylc#5831)
  Update copyright year
  Tests: fix cached datetime arithmetic contamination between tests using different calendar modes
  Replace cyclers functional reftests with integration reftests
  Simplify integration reftest
  Replace pre-initial functional reftests with integration reftests
  Integration tests: add a simpler reftest fixture
  auto update syntax files
  id: catch traceback in ID parsing
  actions: downgrade macos runners to macos 11 (cylc#5892)
  Feat.lint obsolete vars (cylc#5879)
  dump: restrict window to n=0 (cylc#5600)
  Add chained offset logic for FCP (cylc#5885)
  Test.example replace a reftest (cylc#5860)
  GH Actions artifact name fixes
  ...
wxtim added a commit to wxtim/cylc that referenced this pull request Jan 11, 2024
* upstream/master: (81 commits)
  Apply suggestions from code review [skip ci]
  Added missing union type import (cylc#5906)
  coverage: exclude report-timings and set 90% as the lower limit
  lint: Warn users that `CYLC_VERSION={{CYLC_VERSION}}` is deprecated (cylc#5890)
  Add a new entry_point for xtriggers (cylc#5831)
  Tests: fix cached datetime arithmetic contamination between tests using different calendar modes
  Replace cyclers functional reftests with integration reftests
  Simplify integration reftest
  Replace pre-initial functional reftests with integration reftests
  Integration tests: add a simpler reftest fixture
  auto update syntax files
  Feat.lint obsolete vars (cylc#5879)
  dump: restrict window to n=0 (cylc#5600)
  Test.example replace a reftest (cylc#5860)
  GH Actions artifact name fixes
  Bump actions/upload-artifact from 3 to 4
  Bump actions/download-artifact from 3 to 4
  tests/i: update tui screenshot
  Update .github/workflows/test_fast.yml
  actions: add non-utc job to fast tests
  ...
wxtim added a commit to wxtim/cylc that referenced this pull request Jan 12, 2024
* upstream/master: (81 commits)
  Apply suggestions from code review [skip ci]
  Added missing union type import (cylc#5906)
  coverage: exclude report-timings and set 90% as the lower limit
  lint: Warn users that `CYLC_VERSION={{CYLC_VERSION}}` is deprecated (cylc#5890)
  Add a new entry_point for xtriggers (cylc#5831)
  Tests: fix cached datetime arithmetic contamination between tests using different calendar modes
  Replace cyclers functional reftests with integration reftests
  Simplify integration reftest
  Replace pre-initial functional reftests with integration reftests
  Integration tests: add a simpler reftest fixture
  auto update syntax files
  Feat.lint obsolete vars (cylc#5879)
  dump: restrict window to n=0 (cylc#5600)
  Test.example replace a reftest (cylc#5860)
  GH Actions artifact name fixes
  Bump actions/upload-artifact from 3 to 4
  Bump actions/download-artifact from 3 to 4
  tests/i: update tui screenshot
  Update .github/workflows/test_fast.yml
  actions: add non-utc job to fast tests
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants