Skip to content

Commit

Permalink
Merge pull request #5664 from oliver-sanders/5659
Browse files Browse the repository at this point in the history
cycling exclusions: supress spurious warning for exclusion points
  • Loading branch information
hjoliver authored Sep 7, 2023
2 parents 9198b94 + 221f340 commit e8d0ddb
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 10 deletions.
38 changes: 32 additions & 6 deletions cylc/flow/cycling/iso8601.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,14 @@ def build_exclusions(self, excl_points):
for point in excl_points:
try:
# Try making an ISO8601Sequence
exclusion = ISO8601Sequence(point, self.exclusion_start_point,
self.exclusion_end_point)
exclusion = ISO8601Sequence(
point,
self.exclusion_start_point,
self.exclusion_end_point,
# disable warnings which are logged when exclusion is a
# time point
zero_duration_warning=False,
)
self.exclusion_sequences.append(exclusion)
except (AttributeError, TypeError, ValueError):
# Try making an ISO8601Point
Expand All @@ -284,7 +290,20 @@ class ISO8601Sequence(SequenceBase):

"""A sequence of ISO8601 date time points separated by an interval.
Note that an ISO8601Sequence object (may) contain
ISO8601ExclusionSequences"""
ISO8601ExclusionSequences
Args:
dep_section:
The full sequence expression.
context_start_point:
Sequence start point from the global context.
context_end_point:
Sequence end point from the global context.
zero_duration_warning:
If `False`, then zero-duration recurrence warnings will be turned
off. This is set for exclusion parsing.
"""

TYPE = CYCLER_TYPE_ISO8601
TYPE_SORT_KEY = CYCLER_TYPE_SORT_KEY_ISO8601
Expand All @@ -303,8 +322,13 @@ def get_async_expr(cls, start_point=None):
return "R1"
return "R1/" + str(start_point)

def __init__(self, dep_section, context_start_point=None,
context_end_point=None):
def __init__(
self,
dep_section,
context_start_point=None,
context_end_point=None,
zero_duration_warning=True,
):
SequenceBase.__init__(
self, dep_section, context_start_point, context_end_point)
self.dep_section = dep_section
Expand Down Expand Up @@ -344,7 +368,9 @@ def __init__(self, dep_section, context_start_point=None,
# Parse_recurrence returns an isodatetime TimeRecurrence object
# and a list of exclusion strings.
self.recurrence, excl_points = self.abbrev_util.parse_recurrence(
dep_section)
dep_section,
zero_duration_warning=zero_duration_warning,
)

# Determine the exclusion start point and end point
try:
Expand Down
25 changes: 21 additions & 4 deletions cylc/flow/time_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,23 @@ def parse_recurrence(
self,
expression: str,
context_start_point: Optional['TimePoint'] = None,
context_end_point: Optional['TimePoint'] = None
context_end_point: Optional['TimePoint'] = None,
zero_duration_warning: bool = True,
) -> Tuple[TimeRecurrence, list]:
"""Parse an expression in abbrev. or full ISO recurrence format."""
"""Parse an expression in abbrev. or full ISO recurrence format.
Args:
expression:
The recurrence expression to parse.
context_start_point:
Sequence start point from the global context.
context_end_point:
Sequence end point from the global context.
zero_duration_warning:
If `False`, then zero-duration recurrence warnings will be
turned off. This is set for exclusion parsing.
"""
expression, exclusions = parse_exclusion(str(expression))

if context_start_point is None:
Expand Down Expand Up @@ -301,8 +315,11 @@ def parse_recurrence(
repetitions += 1
end_point = None

if not interval and repetitions != 1 and (
(format_num != 1 or start_point == end_point)
if (
zero_duration_warning
and not interval
and repetitions != 1
and (format_num != 1 or start_point == end_point)
):
LOG.warning(
"Cannot have more than 1 repetition for zero-duration "
Expand Down
23 changes: 23 additions & 0 deletions tests/unit/cycling/test_iso8601.py
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,29 @@ def test_multiple_exclusions_extensive(set_cycling_type):
assert sequence.get_prev_point(point_4) == point_1


def test_exclusion_zero_duration_warning(set_cycling_type, caplog, log_filter):
"""It should not log zero-duration warnings for exclusion points.
Exclusions may either be sequences or points. We first attempt to parse
them as sequences, if this fails, we attempt to parse them as points.
The zero-duration recurrence warning would be logged if we attempted to
parse a point as a sequence. To avoid spurious warnings this should be
turned off for exclusion parsing.
"""
# parsing a point as a sequences causes a zero-duration warning
set_cycling_type(ISO8601_CYCLING_TYPE, "+05")
with pytest.raises(Exception):
ISO8601Sequence('3000', '2999')
assert log_filter(caplog, contains='zero-duration')

# parsing a point in an exclusion should not
caplog.clear()
ISO8601Sequence('P1Y ! 3000', '2999')
assert not log_filter(caplog, contains='zero-duration')


def test_simple(set_cycling_type):
"""Run some simple tests for date-time cycling."""
set_cycling_type(ISO8601_CYCLING_TYPE, "Z")
Expand Down

0 comments on commit e8d0ddb

Please sign in to comment.