|
8 | 8 | # |
9 | 9 |
|
10 | 10 | import copy |
| 11 | +import datetime |
11 | 12 | import os |
| 13 | +import re |
12 | 14 |
|
13 | 15 | import reframe.utility.typecheck as types |
14 | 16 | from reframe.core.exceptions import user_deprecation_warning |
@@ -105,23 +107,32 @@ def __set__(self, obj, value): |
105 | 107 |
|
106 | 108 |
|
107 | 109 | class TimerField(TypedField): |
108 | | - '''Stores a timer in the form of a tuple ``(hh, mm, ss)``''' |
| 110 | + '''Stores a timer in the form of a :class:`datetime.timedelta` object''' |
109 | 111 |
|
110 | 112 | def __init__(self, fieldname, *other_types): |
111 | | - super().__init__(fieldname, types.Tuple[int, int, int], *other_types) |
| 113 | + super().__init__(fieldname, datetime.timedelta, str, |
| 114 | + types.Tuple[int, int, int], *other_types) |
112 | 115 |
|
113 | 116 | def __set__(self, obj, value): |
114 | 117 | self._check_type(value) |
115 | | - if value is not None: |
116 | | - # Check also the values for minutes and seconds |
| 118 | + if isinstance(value, tuple): |
| 119 | + user_deprecation_warning( |
| 120 | + "setting a timer field from a tuple is deprecated: " |
| 121 | + "please use a string '<days>d<hours>h<minutes>m<seconds>s'") |
117 | 122 | h, m, s = value |
118 | | - if h < 0 or m < 0 or s < 0: |
119 | | - raise ValueError('timer field must have ' |
120 | | - 'non-negative values') |
121 | | - |
122 | | - if m > 59 or s > 59: |
123 | | - raise ValueError('minutes and seconds in a timer ' |
124 | | - 'field must not exceed 59') |
| 123 | + value = datetime.timedelta(hours=h, minutes=m, seconds=s) |
| 124 | + |
| 125 | + if isinstance(value, str): |
| 126 | + time_match = re.match(r'^((?P<days>\d+)d)?' |
| 127 | + r'((?P<hours>\d+)h)?' |
| 128 | + r'((?P<minutes>\d+)m)?' |
| 129 | + r'((?P<seconds>\d+)s)?$', |
| 130 | + value) |
| 131 | + if not time_match: |
| 132 | + raise ValueError('invalid format for timer field') |
| 133 | + |
| 134 | + value = datetime.timedelta( |
| 135 | + **{k: int(v) for k, v in time_match.groupdict().items() if v}) |
125 | 136 |
|
126 | 137 | # Call Field's __set__() method, type checking is already performed |
127 | 138 | Field.__set__(self, obj, value) |
|
0 commit comments