Skip to content

Hygiene: ship py.typed, fix testpaths, de-duplicate caching.py header - #81

Merged
thorwhalen merged 2 commits into
masterfrom
claude/hygiene-pytyped-testpaths-caching
Aug 4, 2026
Merged

Hygiene: ship py.typed, fix testpaths, de-duplicate caching.py header#81
thorwhalen merged 2 commits into
masterfrom
claude/hygiene-pytyped-testpaths-caching

Conversation

@thorwhalen

Copy link
Copy Markdown
Member

Three independent hygiene defects on the package that sits at the bottom of the dependency tree, plus a redundant metadata file. All four are packaging/config-level; no runtime behaviour of any public API changes.

1. The PEP 561 marker was missing

Without dol/py.typed, every downstream from dol import ... is type-checked as Any — silently, in every dependent.

Added the marker and declared the wheel/sdist contents explicitly so it is guaranteed to ship (packages + artifacts under [tool.hatch.build.targets.*]).

Verified end-to-end, not assumed. Built the distribution and confirmed dol/py.typed is inside both the wheel and the sdist, then type-checked a probe (from dol import Files; reveal_type(Files)) in two throwaway venvs:

dol installed mypy result
currently published wheel error: Skipping analyzing "dol": module is installed, but missing library stubs or py.typed marker, revealed type Any
wheel built from this branch revealed type def (*args: Any, delete_func: Any =, **kwargs: Any) -> dol.filesys.Files, no errors

2. Local pytest and CI pytest ran different suites

testpaths named a tests directory that does not exist. pytest emitted a config warning and silently fell back to recursive discovery with doctests off: a bare pytest collected 189 tests while CI collected ~500. The two runs also used different doctest flags. So on the package everything depends on, local-green did not imply CI-green.

  • testpaths = ["dol"] — the package dir is the test root (unit tests in dol/tests, doctests in the modules).
  • addopts = "--doctest-modules --ignore=dol/scrap" — a single source of truth for what gets collected, honoured by local runs and CI.
  • [tool.wads.ci.testing].exclude_paths = [] accordingly. Its old value ["examples", "scrap"] was resolved against the repo root and therefore matched nothing — which is why dol/scrap was being collected in CI despite the stated intent to exclude it.
  • doctest_optionflags = ["ELLIPSIS", "IGNORE_EXCEPTION_DETAIL"] — the exact flags the CI action passes via -o (which override the ini value anyway). CI notably does not pass NORMALIZE_WHITESPACE, so keeping it here would let whitespace-fragile doctests pass locally and fail in CI. Zero doctests needed fixing — all of them already pass without NORMALIZE_WHITESPACE.

Bare pytest and the CI invocation now report identical numbers (510 passed, 2 skipped), up from 189 passed, 2 skipped.

3. dol/caching.py defined its header twice

A second import/alias block redefined Instance, PropertyFunc, MethodName and Cache, and — the part that actually mattered — defined a second identity that shadowed the documented one. The live dol.caching.identity therefore carried a bare one-line docstring, so its three doctest examples were dead code that CI believed it was running.

Merged the two blocks into a single header. Care was needed: the second block was not a pure duplicate — it uniquely provided partial, wraps, Protocol (used by KeyStrategy), the TypeVar-based KT/VT/T, and the _NOT_FOUND sentinel, so a naive delete would have broken the module. dol.caching.identity is now collected as a live doctest (dol/caching.py::dol.caching.identity).

4. Deleted setup.cfg

A second metadata source of truth duplicating name/version/description. The version-bump and packaging tooling already prefer pyproject.toml and treat setup.cfg as optional legacy, so removing it also removes a class of "tag version != setup.cfg version" CI failures.

Tests

New: dol/tests/test_packaging_hygiene.py (marker present; every testpaths entry exists; addopts collects doctests; doctest flags match CI's) and header-integrity + live-doctest tests in dol/tests/test_caching.py.

All ten new tests fail on the parent commit and pass here — confirmed red first.

Dependents gate

dol is the most depended-on package in the ecosystem, so the full local dependent suite was run on this branch and every non-passing one was re-run on master to establish the baseline.

  • 55 / 65 pass on this branch.
  • The same 10 fail identically on master — all pre-existing and unrelated (missing system deps such as unixodbc, an absent chromedriver/selenium environment, unavailable DB servers, an unrelated import error).
  • Zero regressions.

Explicitly checked and passing: config2py, graze, py2store, tabled, xdol, mongodol, s3dol, plus lacing (677), ir (430), accompy (431), foley (608), an (302), nw (208), skill (192), ov (186), arioso (193), illustration (220), lookbook (152), enlace-auth (200), ek (333), newsmood (180), mixing (351) and others. dols and o are not in the runner's inventory; both were run manually and produce byte-identical pre-existing collection errors on master and on this branch.

https://claude.ai/code/session_01Kug7UUbVeCQgruvNXUq63c

Three independent defects on the package that sits at the bottom of the
dependency tree, plus a redundant metadata file.

1. PEP 561 marker was missing
   Without `dol/py.typed`, every downstream `from dol import ...` is
   type-checked as `Any`. Added the marker and declared the wheel/sdist
   contents explicitly so it is guaranteed to ship. Verified end-to-end:
   built the wheel and confirmed `dol/py.typed` is inside it, then
   type-checked `from dol import Files; reveal_type(Files)` against both the
   currently published wheel (mypy: "missing library stubs or py.typed
   marker", revealed type `Any`) and the new one (revealed type
   `dol.filesys.Files`, no errors).

2. Local pytest and CI pytest ran different suites
   `testpaths` named a `tests` directory that does not exist, so pytest
   silently fell back to recursive discovery with doctests OFF: a bare
   `pytest` collected 189 tests while CI collected ~500. The two runs also
   used different doctest flags, so local-green did not imply CI-green on
   the package everything depends on.

   - `testpaths = ["dol"]` -- the package dir is the test root (unit tests in
     dol/tests, doctests in the modules).
   - `addopts = "--doctest-modules --ignore=dol/scrap"` -- one source of
     truth for what gets collected, honoured by both local and CI runs.
     `[tool.wads.ci.testing].exclude_paths` is now `[]` accordingly; its old
     `["examples", "scrap"]` resolved against the repo root and matched
     nothing, which is why scrap was being collected in CI.
   - `doctest_optionflags = ["ELLIPSIS", "IGNORE_EXCEPTION_DETAIL"]` -- the
     exact flags the CI action passes via `-o` (it does NOT pass
     NORMALIZE_WHITESPACE, so configuring it here would let whitespace-
     fragile doctests pass locally and fail in CI). No doctests needed
     fixing: all of them already pass without NORMALIZE_WHITESPACE.

   Bare `pytest` now reports the same numbers as the CI invocation.

3. dol/caching.py defined its header twice
   A second import/alias block redefined Instance, PropertyFunc, MethodName
   and Cache and, more importantly, defined a second `identity` that shadowed
   the documented one -- so its three doctest examples were never executed
   despite being collected in CI's mind. Merged the two blocks into a single
   header (keeping `partial`, `wraps`, `Protocol`, the TypeVars and
   `_NOT_FOUND`, which the second block uniquely provided) and dropped the
   duplicates. `dol.caching.identity` is now collected as a live doctest.

4. Deleted setup.cfg, a second metadata source of truth duplicating
   name/version/description. Both the version-bump and packaging tooling
   already prefer pyproject.toml and treat setup.cfg as optional legacy.

Tests: added dol/tests/test_packaging_hygiene.py (py.typed marker present;
testpaths all exist; addopts collects doctests; doctest flags match CI) and
header-integrity + live-doctest tests in dol/tests/test_caching.py. All ten
fail on the parent commit and pass here.

Claude-Session: https://claude.ai/code/session_01Kug7UUbVeCQgruvNXUq63c
@thorwhalen
thorwhalen merged commit df79421 into master Aug 4, 2026
12 checks passed
@thorwhalen
thorwhalen deleted the claude/hygiene-pytyped-testpaths-caching branch August 4, 2026 13:37
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.

1 participant