Skip to content

Give _FracTrim a __repr__ so format errors raise ValueError - #386

Merged
ariebovenberg merged 1 commit into
ariebovenberg:mainfrom
gaoflow:fix-fractrim-repr-error-rendering
Jul 6, 2026
Merged

Give _FracTrim a __repr__ so format errors raise ValueError#386
ariebovenberg merged 1 commit into
ariebovenberg:mainfrom
gaoflow:fix-fractrim-repr-error-rendering

Conversation

@gaoflow

@gaoflow gaoflow commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Problem

In the pure-Python implementation, a format-pattern error that references a
trimmed-fraction (F) field crashes with AttributeError instead of the
intended ValueError:

from whenever import Time, Date

Time(1, 2, 3, nanosecond=4).format("fF")   # duplicate nanos field
# AttributeError: '_FracTrim' object has no attribute 'pattern'
Date(2024, 3, 15).format("FFF")            # F unsupported for a date
# AttributeError: '_FracTrim' object has no attribute 'pattern'

_FracTrim inherits _Field.__repr__, which reads self.pattern. _FracTrim
never sets that instance attribute (pattern is a class-only annotation), so
rendering such a field inside an error message — duplicate-field detection or
unsupported-field rejection — raises AttributeError rather than the documented
ValueError. The Rust extension already renders these correctly, so this is a
pure-Python/Rust divergence.

Fix

Give _FracTrim a __repr__ returning its letter repeated by its width (e.g.
"FFF"), mirroring the sibling _FracExact. The error paths then render and
raise ValueError as intended.

Tests

TestFracTrimErrorRendering covers the __repr__ output and asserts a
ValueError (not AttributeError) for duplicate-nanos and unsupported-F
cases across compile_pattern, format, and parse.

Pure-Python suite tests/test_format_parse.py → 225 passed. ruff check clean.

In the pure-Python implementation, _FracTrim inherited _Field.__repr__, which
reads self.pattern. _FracTrim never sets that instance attribute (pattern is a
class-only annotation), so rendering such a field inside an error message -
duplicate-field detection or unsupported-field rejection - raised
AttributeError: '_FracTrim' object has no attribute 'pattern' instead of the
intended ValueError. The Rust extension already renders these correctly.

Add a __repr__ returning the field's letter repeated by its width (e.g. 'FFF'),
mirroring the sibling _FracExact, so the error paths render and raise ValueError.
@ariebovenberg

Copy link
Copy Markdown
Owner

@gaoflow thanks for taking the time to post this issue and fix it.

It makes me wonder if there are other patterns where this pops up 🤔

@ariebovenberg
ariebovenberg merged commit a1ec36b into ariebovenberg:main Jul 6, 2026
33 checks passed
@ariebovenberg

Copy link
Copy Markdown
Owner

Looks like only F format code was affected. Thanks again for the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants