Skip to content

Commit

Permalink
Add a new entry_point for xtriggers
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ColemanTom committed Nov 21, 2023
1 parent eb769d8 commit 065464c
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 9 deletions.
28 changes: 19 additions & 9 deletions cylc/flow/subprocpool.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from subprocess import DEVNULL, run # nosec
from typing import Any, Callable, List, Optional

from cylc.flow import LOG
from cylc.flow import LOG, iter_entry_points
from cylc.flow.cfgspec.glbl_cfg import glbl_cfg
from cylc.flow.cylc_subproc import procopen
from cylc.flow.exceptions import PlatformLookupError
Expand Down Expand Up @@ -69,29 +69,39 @@ def _killpg(proc, signal):
def get_func(func_name, src_dir):
"""Find and return an xtrigger function from a module of the same name.
Can be in <src_dir>/lib/python, CYLC_MOD_LOC, or in Python path.
Can be in <src_dir>/lib/python, in Python path, or defined via an
entry_point. Loctions checked are in this order.
Workflow source directory passed in as this is executed in an independent
process in the command pool and therefore doesn't know about the workflow.
"""
if func_name in _XTRIG_FUNCS:
return _XTRIG_FUNCS[func_name]

# First look in <src-dir>/lib/python.
sys.path.insert(0, os.path.join(src_dir, 'lib', 'python'))
mod_name = func_name
try:
mod_by_name = __import__(mod_name, fromlist=[mod_name])
except ImportError:
# Then look in built-in xtriggers.
mod_name = "%s.%s" % ("cylc.flow.xtriggers", func_name)
try:
mod_by_name = __import__(mod_name, fromlist=[mod_name])
except ImportError:
raise
# Look for xtriggers via entry_points for external sources.
# Do this after the lib/python and PYTHONPATH approaches to allow
# users to override entry_point definitions with local/custom
# implementations.
for entry_point in iter_entry_points('cylc.xtriggers'):
entries = entry_point.resolve()()
if func_name in entries:
_XTRIG_FUNCS[func_name] = entries[func_name]
return _XTRIG_FUNCS[func_name]

# Still unable to find anything so abort
raise

try:
_XTRIG_FUNCS[func_name] = getattr(mod_by_name, func_name)
except AttributeError:
# Module func_name has no function func_name.
# Module func_name has no function func_name, nor an entry_point entry.
raise
return _XTRIG_FUNCS[func_name]

Expand Down
30 changes: 30 additions & 0 deletions cylc/flow/xtriggers_entry_point.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# THIS FILE IS PART OF THE CYLC WORKFLOW ENGINE.
# Copyright (C) NIWA & British Crown (Met Office) & Contributors.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from cylc.flow.xtriggers import (
echo,
wall_clock,
workflow_state,
xrandom,
)

# Entry point:
def main():
return {
'echo': echo.echo,
'wall_clock': wall_clock.wall_clock,
'workflow_state': workflow_state.workflow_state,
'xrandom': xrandom.xrandom,
}
3 changes: 3 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ cylc.main_loop =
cylc.pre_configure =
cylc.post_install =
log_vc_info = cylc.flow.install_plugins.log_vc_info:main
# NOTE: Built-in xtriggers
cylc.xtriggers =
cylc_flow = cylc.flow.xtrigger_entry_point:main

[bdist_rpm]
requires =
Expand Down

0 comments on commit 065464c

Please sign in to comment.