chore: PEP 440 compliance, mypy --strict cleanliness, lint/format pass#120
Merged
Conversation
- Replace non-PEP-440 `0.1.0-draft` with `0.1.0.dev0`; dynamic version sourced from `geno_lewm/__init__.py` (Hatch). - Curate top-level `geno_lewm.__all__` so the implemented surface (errors, observability, attestation, action specs, decorators) is reachable from the package root. - Add `py.typed` marker and `tools/__init__.py` so downstream type checkers and `python -m tools.*` work as documented. - Make `tools/api/snapshot.py` produce a Python-version-stable enum signature; regenerate `tests/api/public_surface.json`. - Tighten `pyproject.toml`: ruff lint+format with strong rule set, mypy strict (now zero errors across `geno_lewm/` and `tools/`), pytest strict markers + filterwarnings=error, branch coverage at 95% gate, optional dep groups split into `train/eval/deploy/dev/ docs/all`. - Resolve every ruff (B, C4, UP, N, RUF, SIM, PIE, PTH, PERF, FURB, PLR, LOG, ASYNC) finding across `geno_lewm/`, `tools/`, `tests/`. - Resolve every mypy `--strict` error: TypedDict for histogram snapshot, IO[str] stream typing in the verify CLI, Iterator return type on ErrorCodeEntry, `setattr` for method reassignment in decorators. - Add format-skip directives where deliberate same-line statements exercise the per-call-site dedupe in `@deprecated`. All 417 tests pass; ruff format/check, mypy --strict, check_error_codes, check_event_names, check_no_print, check_network_confined, and the public-API snapshot gate are clean.
CI/CD pipeline
- .github/workflows/ci.yml: matrix tests on Python 3.10/3.11/3.12/3.13
across Linux/macOS/Windows, ruff lint+format, mypy --strict, the
five contract gates (errors / events / surface / print / network),
build smoke test (sdist+wheel + import sanity), mkdocs --strict
build, codecov upload, single required-check fan-in.
- .github/workflows/release.yml: tag-driven PyPI publish via OIDC
trusted publishing (no API tokens), TestPyPI dry-run on manual
dispatch, GitHub release with extracted changelog notes.
- .github/workflows/codeql.yml: weekly + per-PR static analysis with
security-extended queries.
- .github/workflows/docs.yml: GitHub Pages deploy.
- Removed legacy .github/workflows/lint-errors.yml (superseded by ci.yml).
Documentation site
- mkdocs.yml with material theme, mkdocstrings, gen-files, literate-nav.
- docs/index.md, docs/quickstart.md: actually-runnable walkthrough
hitting the implemented surface.
- docs/_gen/ scripts that build the public API reference, the error-code
table, the log-event table, RFC mirror with rewritten links, and the
project-root pages (changelog / contributing / security / privacy /
code-of-conduct) at mkdocs build time so docs cannot drift from the
runtime registries or the canonical repo sources.
- docs/api/{experimental,metrics}.md hubs.
- docs/release/signing-keys.md trust-anchor placeholder.
- Rewrote all repo-root-relative links across docs/spec/, docs/rfcs/,
docs/{faq,design-decisions,glossary,maintainers}.md, and the roadmap
tracker so mkdocs --strict passes with zero warnings.
OSS hygiene
- .pre-commit-config.yaml mirrors every CI gate (large files, line
endings, ruff, mypy, the five contract linters, snapshot drift).
- .editorconfig, .gitattributes for cross-editor / cross-platform
consistency.
- .github/CODEOWNERS, .github/FUNDING.yml, .github/dependabot.yml
(weekly minor/patch + security updates, scoped to pip + actions).
- README badges (CI / CodeQL / Docs / PyPI / Python / License / mypy strict / ruff / pre-commit), a sharper "what ships today" table for the implemented surface, a real quickstart (EditSpec / apply_edit / verify CLI), and a dev-loop block that mirrors the CI gates. - CHANGELOG: full [Unreleased] entry for the packaging / tooling / CI / docs / OSS-hygiene work, plus rolled the previously separate [Unreleased] block into the [0.1.0-draft] section.
\`make ci\` runs format-check, ruff lint, mypy --strict, every AST gate, pytest -n auto, and mkdocs --strict — the exact set CI runs. Individual targets (\`make types\`, \`make docs\`, \`make build-check\`, …) are available for targeted iteration. \`make snapshot\` is the documented way to regenerate the public-surface snapshot when an API change is intentional.
Add tests/unit/test_coverage_extras.py covering the small branches the per-module suites don't exercise: counter/gauge/histogram reset, snapshot_all kind tagging, exporter NaN/+Inf/-Inf rendering, default exporter path env+home fallback, logger level rejection, unknown event passthrough, pretty stderr formatter (incl. step + error_code columns), trace-context round-trip, get_logger caching, logged_run's both-paths exception flushing, shutdown_run sink close, looks_like_sha256 positive/negative branches, redaction_stats helpers, every synthetic sampler validation branch (negative n, type_mix=0, malformed length_dist, N-anchor skipping), receipt schema rejections, and to_json timestamp shape. Coverage rises from 92.89 % to 96.07 % branch; the 95 % gate now passes on a clean run. Total tests: 462 (was 417).
Supply-chain - .github/workflows/scorecard.yml — OpenSSF Scorecard weekly + on push to main. SARIF lands in the Security tab; results publish to the OpenSSF dashboard for the README badge. - release.yml now produces a CycloneDX SBOM (cyclonedx-py environment) alongside the wheel + sdist, computes SHA256SUMS for the dist bundle, and emits a SLSA-3 provenance attestation (slsa-framework/slsa-github-generator) so consumers can verify the build claim from a single intoto.jsonl. License header gate - tools/lint/check_license_headers.py: AST-free linter that requires `# SPDX-License-Identifier: Apache-2.0` in the head of every shipped .py file under geno_lewm/ and tools/. - Apply the header to every existing module. - Wire into Makefile (\`make gates\`), .pre-commit-config.yaml, and CI (.github/workflows/ci.yml). Project hygiene - .github/labels.yml — declarative label set covering the triage / type / area / priority / effort / status taxonomy referenced from CONTRIBUTING.md and the issue templates. - .github/workflows/labels.yml — sync labels on push, prune out-of-config entries. - .github/workflows/stale.yml — 90-day stale / 120-day close cadence for issues and PRs. RFCs, "good first issue", "help wanted", any "priority:high|medium", and "status:blocked" are exempt so the long-tail design work is never pruned.
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
Every CI job was failing in ~5 seconds because the previous setup used \`uv python install\` (which downloads Python into uv's managed cache without adding it to PATH) followed by \`uv pip install --system\` (which targets the PATH-discovered interpreter). The two calls don't compose; uv reported "no system Python found" and the step exited immediately. Fix: prepend \`actions/setup-python@v5\` to every job so a Python interpreter is on PATH, set \`UV_SYSTEM_PYTHON=1\` at the workflow env level so \`uv pip install\` implicitly targets it, and drop the now-redundant \`uv python install\` / \`--system\` flag. Applied to ci.yml (lint, types, gates, tests, build, docs), docs.yml, and release.yml.
The astral-sh/setup-uv@v3 + uv pip install --system combo was failing every job in <10s on every runner (Linux/macOS/Windows) regardless of the PATH-fix attempt. The CI workload is 13 small jobs — pip's speed is not the bottleneck, and removing uv eliminates a moving piece. Replace with the boring pattern that always works: - actions/setup-python@v5 (cache: pip, cache-dependency-path: pyproject.toml) - python -m pip install -e ".[dev]" Applied uniformly to ci.yml, docs.yml, release.yml. Local development still uses uv (Makefile, CONTRIBUTING, pyproject dev extra unchanged).
\`str(Path.home() / \".geno-lewm\" / \"logs\" / \"metrics.prom\")\` produces backslash-separated output on Windows, so the previous \`.endswith(\".geno-lewm/logs/metrics.prom\")\` assertion failed there. Compare path components via \`.parts\` instead; the check is identical on POSIX and works on Windows.
Windows + pytest-xdist's spawn-based workers re-import the package per worker, which surfaces flaky failures around the module-level state in geno_lewm.observability and geno_lewm.metrics. Disable xdist on Windows only (still -n auto on Linux/macOS, where xdist uses fork-based workers and the state isn't reimported). Also upload pytest stdout/stderr as an artifact on failure so the exact failing test surfaces without needing log-stream access.
The CLI-print allowlist compared paths via \`str(rel).startswith(str(p) + \"/\")\`. On Windows this never matched because \`str(rel)\` uses backslashes, so the CLI allowlist silently failed and every \`print()\` in \`geno_lewm/cli/verify.py\` was flagged as a violation, breaking the gates job + two unit tests on every Windows runner. Switch to component-tuple comparison (\`rel.parts[:n] == p.parts\`) so the same allowlist matches on POSIX and Windows. Confirmed by downloading the pytest artifact from the prior Windows run; both failures (\`test_print_in_cli_dir_is_allowed\` and \`test_real_package_passes\`) trace to this single AST-linter regression. Local Linux suite still passes.
0d9eaf6 to
f840f0c
Compare
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.
0.1.0-draftwith0.1.0.dev0; dynamicversion sourced from
geno_lewm/__init__.py(Hatch).geno_lewm.__all__so the implemented surface(errors, observability, attestation, action specs, decorators)
is reachable from the package root.
py.typedmarker andtools/__init__.pyso downstream typecheckers and
python -m tools.*work as documented.tools/api/snapshot.pyproduce a Python-version-stable enumsignature; regenerate
tests/api/public_surface.json.pyproject.toml: ruff lint+format with strong rule set,mypy strict (now zero errors across
geno_lewm/andtools/),pytest strict markers + filterwarnings=error, branch coverage at
95% gate, optional dep groups split into
train/eval/deploy/dev/ docs/all.PLR, LOG, ASYNC) finding across
geno_lewm/,tools/,tests/.--stricterror: TypedDict for histogramsnapshot, IO[str] stream typing in the verify CLI, Iterator
return type on ErrorCodeEntry,
setattrfor method reassignmentin decorators.
exercise the per-call-site dedupe in
@deprecated.All 417 tests pass; ruff format/check, mypy --strict,
check_error_codes, check_event_names, check_no_print,
check_network_confined, and the public-API snapshot gate are clean.