-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
- Loading branch information
1 parent
a8cca6c
commit b928337
Showing
13 changed files
with
396 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,108 @@ | ||
""" | ||
Pre- and post-hooks | ||
""" | ||
import contextlib | ||
import types | ||
import ast | ||
import inspect | ||
|
||
from . import utilities | ||
from . import function_wrapper, utilities | ||
from .step import Step | ||
|
||
|
||
def hook_from_string(step, type, num, command): # noqa: A002 | ||
name = f"{type}_hook{num:d}" | ||
def hook_from_string(step, hooktype, num, command): | ||
""" | ||
Generate hook from string, function, Step or Step instance | ||
step_class = None | ||
with contextlib.suppress(Exception): | ||
step_class = utilities.import_class(command, Step, step.config_file) | ||
Parameters | ||
---------- | ||
step : `stpipe.step.Step` | ||
Parent step instance to which this hook is attached, i.e. "self" | ||
hooktype : str, "pre" or "post" | ||
Type of hook pre-hook , or post-hook | ||
num : int | ||
The number, in order, of the pre- or post-hook in the list | ||
command : str or `stpipe.step.Step` instance | ||
if step_class is not None: | ||
return step_class(name, parent=step, config_file=step.config_file) | ||
Returns | ||
------- | ||
`stpipe.step.Step` | ||
""" | ||
name = f"{hooktype}_hook{num:d}" | ||
|
||
step_class = None | ||
step_func = None | ||
with contextlib.suppress(Exception): | ||
step_func = utilities.import_class( | ||
command, types.FunctionType, step.config_file | ||
) | ||
|
||
if step_func is not None: | ||
from . import function_wrapper | ||
# hook is a string of the fully-qualified name of a class or function | ||
if isinstance(command, str): | ||
try: | ||
# String points to a Step subclass | ||
step_class = utilities.import_class( | ||
command, subclassof=Step, config_file=step.config_file | ||
) | ||
except ImportError: | ||
# String is possibly a subproc, so handle this later | ||
pass | ||
except AttributeError: | ||
# String points to an instance of a Step | ||
# So import the class | ||
class_string, _, params = command.partition("(") | ||
step_class = utilities.import_class( | ||
class_string, subclassof=Step, config_file=step.config_file | ||
) | ||
# Then convert rest of string to args and instantiate the class | ||
kwargs_string = params.strip(")") | ||
expr = ast.parse(f"dict({kwargs_string}\n)", mode="eval") | ||
kwargs = {kw.arg: ast.literal_eval(kw.value) for kw in expr.body.keywords} | ||
return step_class(**kwargs) | ||
except TypeError: | ||
# String points to a function | ||
step_func = utilities.import_func(command) | ||
else: | ||
if step_class.class_alias is not None: | ||
name = step_class.class_alias | ||
return step_class(name, parent=step, config_file=step.config_file) | ||
|
||
# hook is a string of the fully-qualified name of a function | ||
if step_func is not None: | ||
return function_wrapper.FunctionWrapper( | ||
step_func, parent=step, config_file=step.config_file | ||
) | ||
|
||
return function_wrapper.FunctionWrapper( | ||
step_func, parent=step, config_file=step.config_file | ||
) | ||
# hook is an already-imported Step subclass | ||
if inspect.isclass(command) and issubclass(command, Step): | ||
step_class = command | ||
if step_class.class_alias is not None: | ||
name = step_class.class_alias | ||
return step_class(name, parent=step, config_file=step.config_file) | ||
|
||
# hook is an instance of a Step subclass | ||
if isinstance(command, Step): | ||
if command.class_alias is not None: | ||
command.name = command.class_alias | ||
else: | ||
command.name = name | ||
return command | ||
|
||
# hook is a command-line script or system call | ||
from .subproc import SystemCall | ||
|
||
return SystemCall(name, parent=step, command=command) | ||
|
||
|
||
def get_hook_objects(step, type_, hooks): | ||
return [hook_from_string(step, type_, i, hook) for i, hook in enumerate(hooks)] | ||
def get_hook_objects(step, hooktype, hooks): | ||
""" | ||
Get list of pre- or post-hooks for a step | ||
Parameters | ||
---------- | ||
step : `stpipe.step.Step` | ||
instance to which this is a hook | ||
hooktype : str, "pre" or "post" | ||
strings, to indicate whether it is a pre- or post-hook | ||
hooks : str or class | ||
path to executable script, or Step class to run as hook | ||
Returns | ||
------- | ||
list of callables that can be run as a hook | ||
""" | ||
return [hook_from_string(step, hooktype, i, hook) for i, hook in enumerate(hooks)] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import os | ||
from pathlib import Path | ||
|
||
import pytest | ||
|
||
|
||
@pytest.fixture() | ||
def tmp_cwd(tmp_path): | ||
"""Perform test in a pristine temporary working directory.""" | ||
old_dir = Path.cwd() | ||
os.chdir(tmp_path) | ||
try: | ||
yield tmp_path | ||
finally: | ||
os.chdir(old_dir) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.