From 04cd8a1088a57b90a02718aec3f29dc2224bacc0 Mon Sep 17 00:00:00 2001 From: Gaven Lan Ren Date: Wed, 28 Oct 2026 14:25:07 -0400 Subject: [PATCH] fix: format float timezone offsets as integer fields `altz_to_utctz_str` accepts float seconds, but floor division preserves their float type. Formatting `19800.0` therefore emitted `-5.030.0` rather than Git's `-0530` offset. Compute whole minutes as an integer and split them with `divmod`, preserving existing sign and sub-minute truncation behavior. Add six regressions covering zero, positive/negative offsets and fractional seconds. All six fail before the fix and pass afterward; applicable pre-commit checks pass. Assisted-by: OpenAI Codex (model: unknown, autonomous) --- git/objects/util.py | 3 +-- test/test_util.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/git/objects/util.py b/git/objects/util.py index e24aeb6ae..f648a2509 100644 --- a/git/objects/util.py +++ b/git/objects/util.py @@ -161,8 +161,7 @@ def altz_to_utctz_str(altz: float) -> str: :param altz: Timezone offset in seconds west of UTC. """ - hours = abs(altz) // 3600 - minutes = (abs(altz) % 3600) // 60 + hours, minutes = divmod(int(abs(altz) // 60), 60) sign = "-" if altz >= 60 else "+" return "{}{:02}{:02}".format(sign, hours, minutes) diff --git a/test/test_util.py b/test/test_util.py index acbff17b7..13e856d73 100644 --- a/test/test_util.py +++ b/test/test_util.py @@ -280,6 +280,17 @@ def __repr__(self): return f"{type(self).__name__}({self.name!r})" +@pytest.mark.parametrize( + "offset, expected", + [(0.0, "+0000"), (19800.0, "-0530"), (-19800.0, "+0530"), (34200.9, "-0930"), (60.1, "-0001"), (-59.9, "+0000")], +) +def test_altz_to_utctz_str_accepts_float_seconds(offset, expected): + result = altz_to_utctz_str(offset) + assert result == expected + assert verify_utctz(result) == result + assert utctz_to_altz(result) == utctz_to_altz(expected) + + @ddt.ddt class TestUtils(TestBase): """Tests for most utilities in :mod:`git.util`."""