v0.2.2 - 100% line coverage
Patch release. 100% line coverage. No API changes.
Test coverage
- 341 tests pass (was 232 in v0.2.1).
- Line coverage: 100%.
What's covered now
- Mode B (encrypted-mask) paths for every v0.2 metric port (per-rate
_difference/_ratiofamily, scoring disaggregations, regression disaggregations). - Every
validate_envelopenegative branch: tampered hash, bad schema version, allowed-metric mismatch, depth ceiling/non-integer, security-bits floor, age ceiling, op_counts non-mapping/non-int, unsigned signature block, RSA-instead-of-Ed25519 signature. - Every CLI subcommand:
verify(stdin, oversized, signed, RSA-key TypeError, unsigned-with-key, legacy-positional),inspect(legacymetricfield, missing key),schema,doctor(with both backends, with one missing). - Every
aggregate_difference/aggregate_ratiobranch: empty input,between_groups,to_overallwith explicit and defaultoverall, zero-ref, zero-value, unknown method. - All scoring-helper zero-division edges (f1, zero-one-loss).
- All plaintext fallback paths in
_per_rate_metricsand_fairness_metrics(when upstream Fairlearn lacks the helper). make_derived_metricreserved-arg, unknown-transform, sample-param, and group-min/group-max paths._regression_metricszero-weight-group branch._json_safeover numpy scalars + nested containers + repr fallback.- OpenFHE backend
sum_allwindow-clamp branch.
Pinned defensive branches
Three branches are marked # pragma: no cover with inline documentation:
CKKSContext.make_evaluator_context()OpenFHE branch — theKeyPairbinding is unpickleable; the branch is pinned in tests as an expectedTypeError. A future fix (wrapper class aroundKeyPair) flips the pin from passing to failing._pos_neg_countshasattrguard —positives/negativesare dataclass fields, so the guard only fires for manually-constructed malformed instances.build_contextfinalValueError— unreachable becauseget_backendvalidates the backend name first.
Backward compatibility
No breaking changes. pip install --upgrade fairlearn-fhe.