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 22, 2023
1 parent eb769d8 commit 3c36a6a
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 9 deletions.
27 changes: 18 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,38 @@ 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'):
if func_name == entry_point.name:
_XTRIG_FUNCS[func_name] = entry_point.resolve()
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
6 changes: 6 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ 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 =
echo = cylc.flow.xtriggers.echo:echo
wall_clock = cylc.flow.xtriggers.wall_clock:wall_clock
workflow_state = cylc.flow.xtriggers.workflow_state:workflow_state
xrandom = cylc.flow.xtriggers.xrandom

[bdist_rpm]
requires =
Expand Down

0 comments on commit 3c36a6a

Please sign in to comment.