Skip to content

refactor(log): remove the missing-extra logging fallback - #152

Merged
SkyeAv merged 1 commit into
mainfrom
remove-logging-fallback
Sep 14, 2026
Merged

SkyeAv merged 1 commit into
mainfrom
remove-logging-fallback

Conversation

@SkyeAv

@SkyeAv SkyeAv commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Removes the stdlib-backed logging fallback that stood in for loguru when the optional [log] extra is absent: a base install now produces no logs at all, and loguru (pip install "tablassert[log]") is the only supported logging path.

Logging

  • No-op logger: src/tablassert/log.py replaces _StdlibLogger (brace-format shim, append-mode file sink, level table, startup warning) with _NullLogger, which implements exactly the loguru surface tablassert calls — configure/bind/add/remove/info/warning/error/debug — and discards every record.
  • No artifacts: LOGASSERT.mkdir() moved inside the loguru branch, so a base install creates no .tablassert/log/, writes no tablassert.log, forwards nothing to the progress display, and emits no "loguru is not installed" warning.
  • Unchanged with the extra: the loguru configuration (category bind, 100 MB rotation, enqueue=True, append mode for multiprocessing workers) is untouched, and cli.run()'s logger.add(progress.log_sink, ...) / logger.remove(sink_id) pair keeps working.

Behavior change

  • Base installs lose log output. Anything tailing .tablassert/log/tablassert.log on a base install now finds no file, and build-kg --log has no effect. Deliberate: an optional extra should not be shadowed by a second, feature-poor logging implementation.
  • Still never fails. [log] remains un-preflighted (extras.require("log") is called nowhere); absence is silent rather than compensated.

Tests

  • Rewrote tests/test_log_extra.py around the new contract: the packaging check stays, and the poisoned-sys.modules["loguru"] reload (now also pointing utils.BASE at tmp_path) asserts no directory or file is created, every level is silent under capsys, add/remove are int-returning no-ops, unformattable brace fields cannot raise, and the import emits no logging records or console output. A surface test pins the eight methods tablassert calls so a future call site cannot AttributeError on a base install.
  • Updated the doc guards in tests/test_docs_source_of_truth.py: the LOGASSERT.is_dir() live fact is conditional on find_spec("loguru"), and the installation-guide guard pins "no logs" instead of "stdlib".

Docs

  • docs/installation.md, docs/cli.md (--log row), docs/tutorial.md, README.md, docs/api/utils.md, llms.txt, and a CHANGELOG.md ## Unreleased### Changed entry now describe logging as [log]-only; the historical entry that introduced the fallback is left intact.

Testing

  • uv sync --no-default-groups --group ci --extra qc --extra log then uv run pytest1337 passed, 43 skipped (src/tablassert/log.py at 100% coverage)
  • uv run ruff check .All checks passed!; uv run ruff format --check .88 files already formatted
  • uv run pyright0 errors, 0 warnings, 0 informations
  • Simulated base install (loguru made unimportable via a sys.meta_path blocker): logger is _NullLogger, console output empty, no .tablassert/log created (only .tablassert/store, which utils.py creates unconditionally)
  • Rust untouched: no Rust changes, so cargo gates are unaffected.

Questions for the reviewer

  • Version bump. Base installs lose .tablassert/log/tablassert.log and --log becomes inert — 19.0.0 material, or a minor since [log] installs are unaffected?

The optional [log] extra has until now been shadowed by a stdlib-backed
loguru mimic: when loguru was absent, tablassert.log still wrote
.tablassert/log/tablassert.log through _StdlibLogger and warned once at
startup about the missing extra. That is a second logging
implementation to maintain for an optional dependency, so it is gone: a
base install now produces no logs at all, and loguru (pip install
"tablassert[log]") is the only logging path.

_NullLogger implements exactly the loguru subset the pipeline calls
(configure/bind/add/remove/info/warning/error/debug) and discards every
record, so every entry point -- including cli.run()'s progress-sink
add/remove pair -- keeps working unchanged. LOGASSERT.mkdir moved inside
the loguru branch, so a base install no longer creates .tablassert/log/
either; the loguru configuration (category binding, 100 MB rotation,
enqueue=True, append mode for multiprocessing workers) is untouched.

The user-visible consequence is deliberate: base installs lose log
output, and build-kg --log has no effect without the extra. [log] still
never raises and is never preflighted; its absence is now silent instead
of partially compensated.

tests/test_log_extra.py is rewritten around the contract: silence under
capsys, no directory or file creation, add/remove as int-returning
no-ops, unformattable brace fields, no logging records on import, and a
surface guard pinning the eight methods tablassert calls so a future
call site cannot AttributeError on a base install. The doc guards in
tests/test_docs_source_of_truth.py follow: LOGASSERT.is_dir() is now
conditional on loguru, and the installation-guide pin asserts the
"no logs" wording. Docs (installation, cli, tutorial, README,
api/utils, llms.txt) and a CHANGELOG Unreleased entry describe logging
as [log]-only.

Testing:
- uv sync --no-default-groups --group ci --extra qc --extra log
- uv run pytest -> 1337 passed, 43 skipped (log.py at 100% coverage)
- uv run ruff check . -> All checks passed!
- uv run ruff format --check . -> 88 files already formatted
- uv run pyright -> 0 errors, 0 warnings, 0 informations
- simulated base install (loguru unimportable via a sys.meta_path
  blocker) -> _NullLogger, no console output, no .tablassert/log created
@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: d8ec7087-4572-4b08-a8ba-f86315ec7f2a


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@SkyeAv
SkyeAv merged commit 5a43a4d into main Sep 14, 2026
5 checks passed
SkyeAv added a commit that referenced this pull request Sep 15, 2026
Cut 19.0.0 and bump the package version in pyproject.toml, CITATION.cff,
and uv.lock.

Major: five breaking changes ship. The `tablassert` console command now
requires the optional `[cli]` extra, since `cyclopts` and `rich` left the
base install (#187). Level-one normalization redefines fullmap keys as
cleaned Unicode-lowercase, Porter2-normalized, byte-ordered token sets and
moves the database to schema v6, so every schema-v5 fullmap is rejected and
must be rebuilt (#171, #172, #174, #175, #176). `build-fullmap --aria2c`
is gone -- aria2c is used automatically whenever the `[aria2]` extra is
installed (#178) -- and `--taxon-allowlist` is gone because the built-in
top-100 experimental-taxon allowlist now applies to every build, guarding
both reuse paths by `META.taxon_allowlist` identity (#153). Logging now
requires the `[log]` extra and is fully disabled without it (#152).

Features: `tablassert.net` is a new stdlib-only transient/permanent
classification and retry seam shared by the agent and the BABEL downloader
(#163, #164), with one bounded jittered retry layer across the inner agent,
reflexion, and judge (#167) and machine-readable `error_code` values on
skipped checkpoint records (#166). `build-kg` gained an automatic ephemeral
shared-prefix TCode cache keyed by content-addressed XXH64 op digests
(#155-#159, #161). The `--distill` corpus became schema-uniform v2 with a
sibling `outcomes.ndjson`, a deterministic `RewardConfig`-tunable reward,
and the new zero-dependency `tablassert distill-weigh` command (#180-#183).
`CLASS_FIELD_OVERRIDES` grants the DAKP sparse qualifier stack on the pinned
association classes (#188).

Fixes: `distill-export` partitions its corpus by content and unions the
schema across record files, so a mixed v1/v2 directory no longer CastErrors
or silently stringifies a column (#184); BABEL retry warnings survive the
loguru sink; PMC downloads are idempotent, atomic, and bounded-parallel
(#165); reflexion and judge prompts are hard-bounded (#168).

Changelog:
- versioned the Unreleased section as 19.0.0 - 2026-09-15
- merged three duplicate `### Added` blocks into one
- moved the two `BREAKING:` entries from `### Changed` into
  `### Breaking Changes` and added a `**Migration:**` note to all five
- added PR links to all 17 entries, which carried none
- added the missing entries: the distill v2 corpus/reward/distill-weigh
  stack (#180-#183), the distill-export schema-drift fix (#184), the
  TCode run-cache detail (#155-#161), and the README badge removal (#154)

Docs: none needed here. Every shipped doc change landed with its own PR,
and the docs source-of-truth gate passes against the bumped tree.

Testing:
- make check -> exit 0
- uv run ruff check . -> All checks passed!
- uv run pyright -> 0 errors, 0 warnings, 0 informations
- uv run pytest -> 1622 passed, 52 skipped
- cargo test --manifest-path rust/Cargo.toml -> 156 passed, 0 failed
- cargo clippy --all-targets -- -D warnings -> clean
- uv lock --check -> resolved 169 packages, lock current
- uv run mkdocs build --strict -> exit 0
- docs SSOT + CLI coverage after the changelog edit -> 204 passed
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