Skip to content

Commit

Permalink
Consider regex match when issuing "unrecognized flow operation warnin…
Browse files Browse the repository at this point in the history
…g. (#804)

* Consider regex match when issuing "unrecognized flow operation warning.

* Update change log.

* Attempt to increase test coverage.

---------

Co-authored-by: Corwin Kerr <[email protected]>
  • Loading branch information
joaander and cbkerr authored Feb 16, 2024
1 parent a5648af commit f3cf4ac
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 29 deletions.
6 changes: 5 additions & 1 deletion changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Changelog
The **signac-flow** package follows `semantic versioning <https://semver.org/>`_.
The numbers in brackets denote the related GitHub issue and/or pull request.

Version 0.27
Version 0.28
============

[next] -- not yet released
Expand All @@ -20,6 +20,7 @@ Fixed
+++++

- Generate correct SLURM scripts on SDSC Expanse (#810).
- Suppress warning for regex operation names that match groups (#804).

Changed
+++++++
Expand All @@ -33,6 +34,9 @@ Removed

- Remove Zenodo (#816).

Version 0.27
============

[0.27.0] -- 2024-01-15
----------------------

Expand Down
46 changes: 19 additions & 27 deletions flow/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -2676,14 +2676,6 @@ def _fetch_status(
only has to occur one time.
"""
if names is not None:
absent_ops = (set(self._groups.keys()) ^ set(names)) & set(names)
if absent_ops:
print(
f"Unrecognized flow operation(s): {', '.join(absent_ops)}",
file=sys.stderr,
)

if status_parallelization not in ("thread", "process", "none"):
raise RuntimeError(
"Configuration value status_parallelization is invalid. "
Expand Down Expand Up @@ -3645,13 +3637,6 @@ def run(
)
if names is None:
names = list(self.operations)
else:
absent_ops = (set(self._groups.keys()) ^ set(names)) & set(names)
if absent_ops:
print(
f"Unrecognized flow operation(s): {', '.join(absent_ops)}",
file=sys.stderr,
)

# Get default directives
default_directives = self._get_default_directives()
Expand Down Expand Up @@ -3731,7 +3716,7 @@ def select(operation):
# Generate _JobOperation instances for selected groups and aggregates.
with self._buffered():
operations = []
run_groups = set(self._gather_executable_flow_groups(names))
run_groups = set(self._gather_executable_flow_groups(names, i_pass))
for (
aggregate_id,
aggregate,
Expand Down Expand Up @@ -3793,7 +3778,7 @@ def key_func_by_job(operation):
operations, pretend=pretend, np=np, timeout=timeout, progress=progress
)

def _gather_selected_flow_groups(self, names=None):
def _gather_selected_flow_groups(self, names=None, i_pass=1):
r"""Grabs :class:`~.FlowGroup`\ s that match any of a set of names.
The provided names can be any regular expression that fully matches a group name.
Expand All @@ -3803,6 +3788,8 @@ def _gather_selected_flow_groups(self, names=None):
names : iterable of :class:`str`
Only select groups that match the provided set of names (interpreted as regular
expressions), or all if the argument is None. (Default value = None)
i_pass : int
The current pass in `run`. Used to print the warning message only once.
Returns
-------
Expand All @@ -3813,6 +3800,7 @@ def _gather_selected_flow_groups(self, names=None):
if names is None:
return list(self._groups.values())
operations = {}
absent_ops = []
for name in names:
if name in operations:
continue
Expand All @@ -3821,11 +3809,21 @@ def _gather_selected_flow_groups(self, names=None):
for group_name, group in self.groups.items()
if re.fullmatch(name, group_name)
]

if i_pass == 1 and len(groups) == 0:
absent_ops.append(name)

for group in groups:
operations[group.name] = group

if len(absent_ops) > 0:
print(
f"Unrecognized flow operation(s): {', '.join(absent_ops)}",
file=sys.stderr,
)
return list(operations.values())

def _gather_executable_flow_groups(self, names=None):
def _gather_executable_flow_groups(self, names=None, i_pass=1):
r"""Grabs immediately executable flow groups that match any given name.
The provided names can be any regular expression that fully match a group name.
Expand All @@ -3841,6 +3839,8 @@ def _gather_executable_flow_groups(self, names=None):
names : iterable of :class:`str`
Only select groups that match the provided set of names (interpreted as regular
expressions), or all singleton groups if the argument is None. (Default value = None)
i_pass : int
The current pass in `run`. Used to print the warning message only once.
Returns
-------
Expand All @@ -3850,7 +3850,7 @@ def _gather_executable_flow_groups(self, names=None):
"""
if names is None:
return [self._groups[op_name] for op_name in self.operations]
operations = self._gather_selected_flow_groups(names)
operations = self._gather_selected_flow_groups(names, i_pass)
# Have to verify no overlap to ensure all returned groups are
# simultaneously executable.
if not FlowProject._verify_group_compatibility(operations):
Expand Down Expand Up @@ -4189,14 +4189,6 @@ def submit(
Additional keyword arguments forwarded to :meth:`~.ComputeEnvironment.submit`.
"""
if names is not None:
absent_ops = (set(self._groups.keys()) ^ set(names)) & set(names)
if absent_ops:
print(
f"Unrecognized flow operation(s): {', '.join(absent_ops)}",
file=sys.stderr,
)

aggregates = self._convert_jobs_to_aggregates(jobs)

# Regular argument checks and expansion
Expand Down
2 changes: 1 addition & 1 deletion tests/test_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -1042,7 +1042,7 @@ def test_run_with_operation_selection(self):
project.run(names=["op1", "non-existent-op"])
assert all(job.isfile("world.txt") for job in even_jobs)
assert not any(job.doc.get("test") for job in project)
project.run(names=["op[^4]", "non-existent-op"])
project.run(names=["op[^4]", "non-existent-op", "non-existent.*"])
assert all(job.isfile("world.txt") for job in even_jobs)
assert all(job.doc.get("test") for job in project)
assert all("dynamic" not in job.doc for job in project)
Expand Down

0 comments on commit f3cf4ac

Please sign in to comment.