From bd60db1c0b917b05d007ebf6c49e7db1c69d7aa6 Mon Sep 17 00:00:00 2001 From: GreedyC Date: Fri, 2 Oct 2026 14:50:52 +0300 Subject: [PATCH 1/2] fix(human.py): return zero for non-finite durations (fix #409) --- CHANGELOG.md | 1 + human.py | 3 ++- tests/human/unit-test/run | 10 ++++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70b3ad7..8f4d0db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * args.py: arguments with characters outside of ASCII arrive intact when the Icinga 2 agent for Windows starts the consumer * base.py: on Windows, what argparse writes to stderr no longer arrives with an empty line after every line * disk.py: `is_within()` with the filesystem root as a root +* human.py: `human2seconds()` returns zero for non-finite durations instead of raising an exception * logsource.py: `read()` names missing journal rights instead of passing on journalctl's hint * net.py: `FAMILIYSTR` names an IPv6 address "6" instead of "irda" on Windows * powershell.py, shell.py: `run_ps()` and `shell_exec()` return on time on Windows after a timeout, even when a child process keeps the output open diff --git a/human.py b/human.py index 2005f31..be5af43 100644 --- a/human.py +++ b/human.py @@ -488,7 +488,8 @@ def human2seconds(string): except (ValueError, TypeError): return 0 - return int(value * _UNIT_TO_SECONDS[unit]) + seconds = value * _UNIT_TO_SECONDS[unit] + return int(seconds) if math.isfinite(seconds) else 0 def humanduration2seconds(text): diff --git a/tests/human/unit-test/run b/tests/human/unit-test/run index ac7336a..ed07e2c 100755 --- a/tests/human/unit-test/run +++ b/tests/human/unit-test/run @@ -182,6 +182,16 @@ class TestHuman2Bytes(unittest.TestCase): class TestHuman2Seconds(unittest.TestCase): + def test_nonfinite_durations_return_zero(self): + for value in ('nans', 'NaNs', '+infs', '-infs', '1e309s', '1e308Y'): + with self.subTest(value=value): + self.assertEqual(human.human2seconds(value), 0) + + def test_finite_durations_keep_truncation(self): + self.assertEqual(human.human2seconds('-2.5h'), -9000) + self.assertEqual(human.human2seconds('0.5s'), 0) + self.assertEqual(human.human2seconds('1e300s'), int(1e300)) + def test_units(self): self.assertEqual(human.human2seconds('1h'), 3600) self.assertEqual(human.human2seconds('1d'), 86400) From d574be8b2501b4aee3c02c5e38a1fae7016f5049 Mon Sep 17 00:00:00 2001 From: Markus Frei Date: Fri, 2 Oct 2026 15:29:40 +0200 Subject: [PATCH 2/2] docs(CHANGELOG): shorten the human2seconds() entry to the function list --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f4d0db..34a2167 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,7 +47,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * args.py: arguments with characters outside of ASCII arrive intact when the Icinga 2 agent for Windows starts the consumer * base.py: on Windows, what argparse writes to stderr no longer arrives with an empty line after every line * disk.py: `is_within()` with the filesystem root as a root -* human.py: `human2seconds()` returns zero for non-finite durations instead of raising an exception +* human.py: `human2seconds()` ([#409](https://github.com/Linuxfabrik/lib/issues/409)) * logsource.py: `read()` names missing journal rights instead of passing on journalctl's hint * net.py: `FAMILIYSTR` names an IPv6 address "6" instead of "irda" on Windows * powershell.py, shell.py: `run_ps()` and `shell_exec()` return on time on Windows after a timeout, even when a child process keeps the output open