Make system-uchardet a Meson feature option (auto/enabled/disabled) - #64
Conversation
Add a `system-uchardet` option to build against the system installed `uchardet` library instead of building a bundled copy. This requires a git version of `uchardet` right now, and upstream did not increment the version yet, so the code is explicitly checking whether `uchardet_get_n_candidates` is available. Signed-off-by: Michał Górny <mgorny@gentoo.org>
Refine the system-uchardet switch from a hard boolean into a Meson
`feature` option so one switch serves more environments:
- enabled -> require the system library; hard fail if missing or too
old (what distro packaging wants).
- disabled -> always build the bundled copy (the default; unchanged
behaviour for the published wheels).
- auto -> use the system library when it is new enough, else fall
back to the bundled copy (handy for source installs on a
box that happens to have a recent-enough uchardet).
Passing the feature to dependency(..., required: system_uchardet) gives
the enabled/auto hard-fail-vs-fallback distinction for free. The existing
has_function('uchardet_get_n_candidates') probe still rejects a
found-but-too-old system library, and now only errors out under
`enabled` -- `auto` falls through to the bundled copy.
Also document the option for packagers in the README (the three states,
the --config-settings invocation, and the git-uchardet requirement), and
fix the option description ("chardet" -> "uchardet").
Validated with meson setup for all three states: disabled and auto (no
system lib) configure the bundled copy and the full test suite passes
(125 passed, 1 skipped); enabled with no system lib fails configuration
as intended.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BnTZQEXqpedyrFAgwRnbsA
The existing Tests workflow only builds the bundled uchardet default, so the system-uchardet path is never exercised in CI. Add a Linux job that builds uchardet from git, installs it, then builds cChardet with -Dsystem-uchardet=enabled and runs the test suite. The job also asserts (via ldd) that the built extension links the shared system libuchardet rather than silently falling back to the bundled sources, and checks that the system header exposes uchardet_get_n_candidates (the symbol the enabled/auto probe requires). Stacked on the system-uchardet feature-option change; the option it exercises does not exist on master yet. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BnTZQEXqpedyrFAgwRnbsA
CodeQL (actions/missing-workflow-permissions) flagged the workflow for not constraining the GITHUB_TOKEN. The job only checks out and builds the repository, so declare the minimal `contents: read` at the workflow level. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BnTZQEXqpedyrFAgwRnbsA
|
Measured what this branch does against current master, since it predates the 3.0.1 fixes. Summary: with MethodMerged this branch into master (
The system path links upstream's Nothing catches it
What does surviveThe UTF-8 fast path and the chunked-feeding fix for the long-input A fix that turned out not to workAn engine-independent guard in the Cython layer — reject a UTF-8 verdict the bytes contradict, fall through to the next candidate — looked like the cheap repair. Tested against the live library: of the 268 mislabeled documents, only 50 (19%) have a correct lower candidate. The overlay changes candidate generation, not just which candidate is picked, so there is no cheap substitute. Caveat on the numbers
Suggested path
Separately: I have two patches for uchardet's throughput problem (freedesktop uchardet #38, ~23x on the pathological case, no change in detection output). They do not help here — they fix speed, not the mislabel. The correctness fix is a second, independent upstream contribution. Generated by Claude Code |
system-uchardet is a new build-time feature rather than a fix, so the next release is a minor bump instead of 3.0.2. Both version sources move together: meson.build holds the value and src/cchardet/version.py mirrors it for cchardet.__version__. Also adds the 3.1.0 changelog entry describing the feature option, credits the original work, and records the detection-quality caveat for a system build so it is not only in the README. The 3.0.1 heading was still marked unreleased; it shipped on 2026-08-04. This branch was several weeks behind master, so master is merged in first to bring the 3.0.1 release the bump builds on. Verified: builds from source with both version sources reporting 3.1.0, 130 passed 1 skipped, CHANGES.rst parses as reStructuredText.
Implements the feature-flag suggestion from the review of #56 (#56 (comment)).
Builds on top of @mgorny's #56 (that commit is included here, unchanged) and refines the
system-uchardetswitch from a hard boolean into a Mesonfeatureoption, so one switch serves more environments.What changed
meson.options—type: 'boolean'→type: 'feature',value: false→value: 'disabled'. Also fixes the description typo (chardet→uchardet).src/cchardet/meson.build— three-way selection:-Dsystem-uchardet=disabled(default)enabledautoPassing the feature to
dependency('uchardet', required: system_uchardet)gives theenabled(hard-fail) vsauto(quiet fallback) distinction for free. The existinghas_function('uchardet_get_n_candidates')probe still rejects a found-but-too-old system library, and now onlyerror()s underenabled—autofalls through to bundled.README.md— a "Building against a systemuchardet" section for packagers: the three states, thepip install . --config-settings=setup-args=-Dsystem-uchardet=enabledinvocation, and the git-uchardet requirement. The# TODOto swaphas_function()for aversion:constraint once upstream tags a release is kept.Verification (local)
meson setupexercised for every state (submodule checked out, no system uchardet present):disabled(default) andauto→ configure the bundled copy; full build + test suite pass: 125 passed, 1 skipped.enabledwith no system library → configuration fails (exit 1) as intended:ERROR: Dependency "uchardet" not found.The whole
meson.buildparses (so the too-old-error()branch is syntax-checked), and the bundled extension compiles and links cleanly.Not included
-Dsystem-uchardet=enabledand runs the tests. I left it out to keep this PR focused and locally-verifiable — happy to add it as a follow-up commit here or a separate PR, whichever you prefer.Credit to @mgorny for the original
declare_dependencyrefactor and system-uchardet support in #56; this supersedes that PR.🤖 Generated with Claude Code
https://claude.ai/code/session_01BnTZQEXqpedyrFAgwRnbsA
Generated by Claude Code