Merge pull request #2266 from kflynn/flynn/dev/gep-2257-tweaks

GEP-2257 tweaks
This commit is contained in:
Kubernetes Prow Robot 2024-08-16 13:46:39 -07:00 committed by GitHub
commit 1bc5b5e3a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -21,6 +21,11 @@ import durationpy
# really be a big deal.
reDuration = re.compile(r'^([0-9]{1,5}(h|m|s|ms)){1,4}$')
# maxDuration_ms is the maximum duration that GEP-2257 can support, in
# milliseconds.
maxDuration_ms = (((99999 * 3600) + (59 * 60) + 59) * 1_000) + 999
def parse_duration(duration) -> datetime.timedelta:
"""
Parse GEP-2257 Duration format to a datetime.timedelta object.
@ -32,10 +37,39 @@ def parse_duration(duration) -> datetime.timedelta:
See https://gateway-api.sigs.k8s.io/geps/gep-2257/ for more details.
Input: duration: string
Returns: datetime.timedelta
Raises: ValueError on invalid or unknown input
Examples:
>>> parse_duration("1h")
datetime.timedelta(seconds=3600)
>>> parse_duration("1m")
datetime.timedelta(seconds=60)
>>> parse_duration("1s")
datetime.timedelta(seconds=1)
>>> parse_duration("1ms")
datetime.timedelta(microseconds=1000)
>>> parse_duration("1h1m1s")
datetime.timedelta(seconds=3661)
>>> parse_duration("10s30m1h")
datetime.timedelta(seconds=5410)
Units are always required.
>>> parse_duration("1")
Traceback (most recent call last):
...
ValueError: Invalid duration format: 1
Floating-point and negative durations are not valid.
>>> parse_duration("1.5m")
Traceback (most recent call last):
...
ValueError: Invalid duration format: 1.5m
>>> parse_duration("-1m")
Traceback (most recent call last):
...
ValueError: Invalid duration format: -1m
"""
if not reDuration.match(duration):
@ -43,6 +77,7 @@ def parse_duration(duration) -> datetime.timedelta:
return durationpy.from_str(duration)
def format_duration(delta: datetime.timedelta) -> str:
"""
Format a datetime.timedelta object to GEP-2257 Duration format.
@ -59,12 +94,48 @@ def format_duration(delta: datetime.timedelta) -> str:
Raises: ValueError if the timedelta given cannot be expressed as a
GEP-2257 Duration.
Examples:
>>> format_duration(datetime.timedelta(seconds=3600))
'1h'
>>> format_duration(datetime.timedelta(seconds=60))
'1m'
>>> format_duration(datetime.timedelta(seconds=1))
'1s'
>>> format_duration(datetime.timedelta(microseconds=1000))
'1ms'
>>> format_duration(datetime.timedelta(seconds=5410))
'1h30m10s'
The zero duration is always "0s".
>>> format_duration(datetime.timedelta(0))
'0s'
Sub-millisecond precision is not allowed.
>>> format_duration(datetime.timedelta(microseconds=100))
Traceback (most recent call last):
...
ValueError: Cannot express sub-millisecond precision in GEP-2257: 0:00:00.000100
Negative durations are not allowed.
>>> format_duration(datetime.timedelta(seconds=-1))
Traceback (most recent call last):
...
ValueError: Cannot express negative durations in GEP-2257: -1 day, 23:59:59
"""
# Short-circuit if we have a zero delta.
if delta == datetime.timedelta(0):
return "0s"
# Check range early.
if delta < datetime.timedelta(0):
raise ValueError("Cannot express negative durations in GEP-2257: {}".format(delta))
if delta > datetime.timedelta(milliseconds=maxDuration_ms):
raise ValueError(
"Cannot express durations longer than 99999h59m59s999ms in GEP-2257: {}".format(delta))
# durationpy.to_str() is happy to use floating-point seconds, which
# GEP-2257 is _not_ happy with. So start by peeling off any microseconds
# from our delta.
@ -90,8 +161,4 @@ def format_duration(delta: datetime.timedelta) -> str:
delta_str += f"{delta_ms}ms"
if not reDuration.match(delta_str):
raise ValueError("Invalid duration format: {}".format(durationpy.to_str(delta)))
return delta_str