CaptainAni187 opened a new pull request, #72703: URL: https://github.com/apache/airflow/pull/72703
Closes: #72694 `td_format` renders a negative duration as a large positive one: ```python td_format(timedelta(seconds=-3752)) # '29d:22h:57M:28s' td_format(timedelta(days=-5)) # '25d' td_format(-3752) # '<1s' ``` The last two lines are the same duration expressed two ways and they disagree. ### Cause The day-to-month conversion uses `divmod`, which floors: ```python months, delta.days = divmod(delta.days, 30) ``` so a `relativedelta` of `days=-1` becomes `months=-1, days=+29`. `_format_part` skips any component below 1, which drops the `-1 month` that would have cancelled the `+29 days` and leaves the days behind. The numeric branch differs because `relativedelta(seconds=-3752)` keeps a single negative `seconds` field instead of borrowing a day, so every component is dropped and the empty result falls through to `<1s`. ### Change Format the magnitude, then re-apply the sign. This keeps the existing output for non-negative durations untouched and makes the two input types agree: ```python td_format(timedelta(seconds=-3752)) # '-1h:2M:32s' td_format(timedelta(days=-5)) # '-5d' td_format(-3752) # '-1h:2M:32s' ``` A magnitude below one second still reads `<1s` regardless of sign, since prefixing a sign onto `<1s` would not tell the reader anything useful. ### Tests Adds `test_td_format_negative` alongside the existing `test_td_format`, covering both input types, the sub-second case, and the agreement between the two branches. It fails on `main` with `'29d:22h:57M:28s' != '-1h:2M:32s'`. I also checked the sign invariant `td_format(-x) == "-" + td_format(x)` over 20,000 randomly generated durations for both input types, along with cross-type agreement — no violations. That sweep is not included in the test file, since the explicit cases cover the behaviour and are easier to read. `ruff check` and `ruff format` are clean at the pinned 0.16.4, and the `shared/timezones` suite passes (31 passed). -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
