Simple library to keep useful Python utilities in one place.
Project description
hv-utils
Typed utility library for consolidating reusable Python helpers. The project is in early alpha; the current public
surface includes the cron expression parser (parse_cron) exported from hv_utils.__init__.
What you need
- Python 3.12+. Keep 3.13 and 3.14 available if you want to run the full matrix locally.
- uv for dependency management.
- Runtime stays standard-library only; dev tools live in the
devdependency group.
Quick start
- Install dev tools:
uv sync --group dev - Ensure you work from the repo root so
src/is discoverable. - Try it out:
- Cron parse:
uv run python - <<'PY'\nfrom hv_utils import parse_cron\nprint(parse_cron('*/15 0-12/6 1,15 1-3 MON-FRI'))\nPY - Cron match:
uv run python - <<'PY'\nfrom datetime import UTC, datetime\nfrom hv_utils import cron_matches\nprint(cron_matches('0 12 15 * 1', datetime(2025, 1, 13, 12, 0, tzinfo=UTC)))\nPY
- Cron parse:
- Extras: install cron utilities via
pip install hv-utils[cron](orhv-utils[all]for all extras; currently the same set).
Cron utility
- Parse:
hv_utils.parse_cron(expression: str) -> CronSchedule— expands a 5-field cron string into concrete minute, hour, day-of-month, month, and day-of-week tuples. Supports literals, ranges, steps (*/n), comma lists, and case-insensitive month/day names. Day-of-week treats both0and7as Sunday; invalid input raisesValueErrorwith a consistent message. - Match:
hv_utils.cron_matches(expression: str | CronSchedule, when: datetime) -> bool— checks whether a datetime satisfies a schedule. Day-of-month and day-of-week use cron OR semantics: if both are restricted, a match occurs when either field matches (all other fields must also match). If one is a wildcard, only the other is considered. - Schedule helpers:
CronSchedule.from_exp(expr: str)— convenience constructor aroundparse_cron.CronSchedule.matches(dt: datetime) -> bool— instance wrapper overcron_matches.CronSchedule.next(start: datetime, *, inclusive: bool = False, max_lookahead_days: int = 366) -> datetime— returns the next occurrence afterstart, optionally includingstart, bounded bymax_lookahead_days.CronSchedule.iter(start: datetime, *, inclusive: bool = False, max_lookahead_days: int = 366) -> Iterable[datetime]— yields successive matching datetimes; callers should consume responsibly to avoid unbounded iteration.
How we work
- Functional-first utilities; keep state to a minimum.
- Standard library only at runtime. If an optional dependency is unavoidable, add an extra in
pyproject.toml, guard the import withtry/except ImportError, and raise a friendly install hint. - Absolute imports only. Expose public helpers from
src/hv_utils/__init__.py. - Always type everything and keep
mypy --strictgreen. - TDD over heroics: write or update tests before implementing behavior, cover edge cases, and keep functions small and composable.
- Follow
ruff/PEP 8 style (line length 120).
Common commands
- Format:
uv run ruff format . - Lint (autofix):
uv run ruff check --fix . - Type-check:
uv run mypy src tests - Tests (current Python):
uv run pytest - Tests on a specific interpreter:
uv run --python 3.13 pytest - Full matrix (requires those interpreters installed):
uv run --python 3.12 pytestuv run --python 3.13 pytestuv run --python 3.14 pytest
Changelog
- Generate/update
CHANGELOG.mdfrom conventional commits with git-cliff (dev dependency):- Preview unreleased notes:
uv run --locked --group dev git-cliff --config pyproject.toml --unreleased - Write the changelog file:
uv run --locked --group dev git-cliff --config pyproject.toml --unreleased --output CHANGELOG.md
- Preview unreleased notes:
Pre-commit
- Install hooks:
pre-commit install(uses your machine-level pre-commit) - Run all hooks manually:
pre-commit run --all-files - Hooks auto-add the BSD-3 header (via
python -m tools.copyright_header), then run the same uv-powered format, lint, type-check, and test commands listed above.
Contributing
- Keep PRs small and focused on one utility or fix.
- Add tests, docstrings, and
__init__exports alongside new utilities. - Run format, lint, mypy, and pytest before opening a PR; for compatibility-sensitive changes, run the full matrix.
- Note: uv commands may need escalated permission in some environments. I will ask for escalation before running
uvso tasks can proceed. The uv cache directory is already configured inpyproject.toml; no need to setUV_CACHE_DIRmanually.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
hv_utils-0.0.1.1.tar.gz
(8.8 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hv_utils-0.0.1.1.tar.gz.
File metadata
- Download URL: hv_utils-0.0.1.1.tar.gz
- Upload date:
- Size: 8.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ba02bf55caf7b5743073ba2c8c871e650583ba977e738c1c4f84174760e0c2c9
|
|
| MD5 |
57653fe6a71dbe8fc7bfd876b383caec
|
|
| BLAKE2b-256 |
59a98f28faba3a354c04c002a7147f7d298f71d9428438ac4be8d05624a7731e
|
File details
Details for the file hv_utils-0.0.1.1-py3-none-any.whl.
File metadata
- Download URL: hv_utils-0.0.1.1-py3-none-any.whl
- Upload date:
- Size: 8.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b0645855884ecf1782c6409d28659d15b61d6945457119c23139a8f8c8bf042c
|
|
| MD5 |
2481fb66bc5557572ca0b68eefa8621a
|
|
| BLAKE2b-256 |
35adb6279ac4d9b138bae1e2a8075719dc426495c3b4089e7e2952161ec375ed
|