Add parse_nanoseconds for sub-microsecond duration parsing - #49
Merged
Conversation
parse_timedelta accumulated sub-microsecond values by building a
microsecond-resolution timedelta and *separately* stashing the
sub-microsecond remainder, then adding both back on resolve(). For
microsecond, millisecond, and second values that double-counted the
fractional part -- e.g. parse_timedelta('1.6 µs') resolved to 3µs
instead of 2µs.
Rework _Saved_NS so td holds only whole microseconds and nanoseconds
holds the exact sub-microsecond remainder, with resolve() rounding the
combined total. This corrects the rounding and, because the full value
is now retained, lets total_nanoseconds reconstruct the parsed value at
sub-microsecond precision.
Expose that via a new parse_nanoseconds() returning a Decimal count of
nanoseconds, for callers -- such as pytest-perf comparing sub-microsecond
timeit results -- that need finer resolution than a timedelta can hold.
Ref jaraco/pytest-perf#18.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds
parse_nanoseconds(str) -> Decimal, returning a duration as aDecimalcount of nanoseconds so callers can retain sub-microsecond resolution thatparse_timedeltanecessarily rounds away (adatetime.timedeltaonly has microsecond resolution).Bug fix along the way
Reworking the internals surfaced a latent bug:
_Saved_NSbuilt a microsecond-resolutiontimedeltaand separately stashed the sub-microsecond remainder, then added both back onresolve()— double-counting the fractional part for microsecond, millisecond, and second values:_Saved_NSnow keeps whole microseconds intdand the exact sub-microsecond remainder innanoseconds, andresolve()rounds the combined total. Because the full value is retained,total_nanosecondscan reconstruct it at full precision — which is whatparse_nanosecondsexposes.Motivation
Requested by jaraco/pytest-perf#18: pytest-perf compares timeit results, and sub-microsecond timings (e.g. python/importlib_metadata#533) were rounded to
timedelta(0), collapsing its variance calculation. pytest-perf will consumeparse_nanoseconds.Coverage is via doctests (
coh test, all green).🤖 Generated with Claude Code