repomatic.humanize module¶
Conversions between raw machine quantities and their human forms.
Byte counts, modification times and service timestamps reach the user through
more than one surface (the image-optimization summary, the repomatic cache
tables, every dependency report), and each surface should spell them the same
way. One home for those conversions keeps the wording consistent and keeps the
formatters out of the modules that merely happen to be the first consumer;
parse_iso_datetime() is the machine-to-datetime half the renderers
start from.
A leaf module with no project-internal imports, so any module can import it without risking a cycle.
- repomatic.humanize.MONTHS_PER_YEAR = 12¶
Months in a year.
- repomatic.humanize.SECONDS_PER_MINUTE = 60¶
Seconds in a minute.
- repomatic.humanize.SECONDS_PER_HOUR = 3600¶
Seconds in an hour.
- repomatic.humanize.SECONDS_PER_DAY = 86400¶
Seconds in a day: what turns an mtime delta into whole days.
- repomatic.humanize.SECONDS_PER_WEEK = 604800¶
Seconds in a week.
- repomatic.humanize.SECONDS_PER_MONTH = 2635200.0¶
Seconds in a mean month: past it,
format_relative()counts no weeks.
- repomatic.humanize.SECONDS_PER_YEAR = 31536000¶
Seconds in a common year.
- repomatic.humanize.parse_iso_datetime(value)[source]¶
Parse an ISO 8601 / RFC 3339 timestamp into a timezone-aware datetime.
The package-wide parser for any timestamp an external service writes:
repomatic.deps.reportreads PyPI upload times,repomatic.deps.lockfilelock timestamps,repomatic.cloudflare.apitoken expiries andrepomatic.github.job_timingsjob clocks through it, so every consumer tolerates the same shapes. A JSON or TOML lookup that found no value hands overNone, which reads as no timestamp.fromisoformat()reads aZsuffix and a nanosecond fraction since Python 3.11, and truncates the digitsdatetimecannot hold. An instant with no offset is read as UTC, the one zone the services above write in.
- repomatic.humanize.today_utc()[source]¶
Today’s date, in UTC.
The one read of the clock behind every date this package stamps: a release heading, a scan record, a cooldown reference. UTC, so a runner and a laptop in another timezone agree on the day. Callers that write the date out use
today_utc().isoformat(), which is theYYYY-MM-DDform.- Return type:
- repomatic.humanize.utc_midnight(day)[source]¶
The UTC instant day starts on.
What a date-granular datasource hands
format_countdown()andformat_elapsed(), which take instants so no caller can silently drop a precision it holds. A date holds none to drop: midnight is the whole of what it says.- Return type:
- repomatic.humanize.shift_months(instant, months)[source]¶
Move instant by months calendar months.
The day is clamped to the target month, so one month before March 31 is February 28, or 29 in a leap year. The time of day is kept.
- repomatic.humanize.format_relative(instant, reference)[source]¶
Phrase the gap from reference to instant:
in 5 hours,2 days ago.The buckets and their wording follow the
humanize()of arrow1.4. Under ten seconds the gap isjust now. Then come seconds,a minuteunder two, minutes,an hourunder two, hours,a dayunder two, and days under a week. Past a week, whole calendar months come first, up to a year, and a remainder past 14 days counts as one more month: 15 days already read asa month. When no month counts, the gap readsa week, or2 weeksonce it reaches 14 days. Past a year, it readsa yearunder two, then years. A count is truncated, never rounded, and starts at two: a single unit has its own phrase.
- repomatic.humanize.format_countdown(deadline, reference)[source]¶
Render deadline as a date, with a countdown to it.
The countdown measures the two instants, not their calendar dates. A deadline later today then reads
in 5 hours, where truncating to dates renderedjust now: a reader takes that for something already elapsed, the opposite of what the line reports.Both parameters are instants for that reason, and a
dateis rejected by the type checker. Every deadline this renders is computed at instant granularity (uv records a packageupload-timeto the second, and a cooldown cutoff isnow - span), so a caller holding that precision must not drop it. A date-granular datasource passes the UTC midnight its date starts on throughutc_midnight(), on both arguments: an instant measured against a midnight reference is off by up to a day.
- repomatic.humanize.format_elapsed(instant, reference)[source]¶
Render instant as a date, with how long ago it happened.
The mirror of
format_countdown(), for a date a reader looks back at rather than waits for: a package upload, a release, a recorded reading. The same precision rules apply, since the two read the same gap.Each drops the phrase in the direction it cannot speak for. A countdown says nothing about a deadline already passed, and this says nothing about an instant still ahead, where
in 3 dayswould contradict the column it sits in. Both then render the bare date.
- repomatic.humanize.format_file_size(size_bytes)[source]¶
Format a byte count as a human-readable string.
A thin binding of
click_extra.format_size()to the JEDEC unit style: binary powers with the customaryKB/MBsymbols.- Return type:
