Achieve 100% test coverage and require it in CI#320
Conversation
Add a dedicated test module exercising the previously-uncovered string-formatting paths in injector: - UnsatisfiedRequirement.__str__ (with and without an owner) - _describe (named objects, tuple/list, and the str() fallback) - _get_origin normalization of typing.List/typing.Dict aliases Kept separate from injector_test.py to avoid polluting the functional suite with coverage-driven edge cases. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add tests for the remaining uncovered error/edge-case branches: - Binder.provider_for raising UnknownProvider for an unbindable target - Module configuration re-raising NameError for an unresolvable forward reference in a @Provider return annotation - create_object wrapping a __new__ TypeError in a CallError - _infer_injected_bindings dropping Union members marked NoInject - Injector.get unwrapping a ScopeDecorator to its underlying scope Also mark the import-time logger-level guard with `# pragma: no branch`: its else-branch is only reachable on a fresh import with a pre-set level, which can't be exercised in-process without importlib.reload corrupting shared marker state for the rest of the suite. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Now that every line and branch in injector is exercised, raise the --cov-fail-under gate from 90 to 100 so coverage regressions fail PRs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
That's really surprising.. Why python package need testing on different ubuntu versions? That shouldn't be relevant at all.
|
|
FYI @davidparsson |
It's the same ubuntu version, but different Python versions. |
Summary
Brings
injector/__init__.pyto 100% line and branch coverage (previously ~97%) and raises the CI coverage gate to match, so future regressions fail PRs.The previously-uncovered code fell into two buckets — string-formatting helpers and rarely-hit edge-case/error branches — plus one import-time branch.
Changes
1. Cover string-formatting / representation helpers
UnsatisfiedRequirement.__str__— both the with-owner and without-owner branches_describe— named objects, the tuple/list case, and thestr()fallback_get_origin— normalization oftyping.List/typing.Dictaliases to builtins2. Cover edge-case exception / branch paths
Binder.provider_forraisingUnknownProviderfor an unbindable target@providerwith an unresolvable forward-reference return annotation re-raisingNameErrorat configure timecreate_objectwrapping a__new__TypeErrorin aCallError_infer_injected_bindingsdroppingUnionmembers markedNoInjectInjector.getunwrapping aScopeDecoratorto its underlying scope# pragma: no branchon the import-time logger-level guard — its else-branch is only reachable on a fresh import with a pre-set level, which can't be exercised in-process withoutimportlib.reloadcorrupting shared marker state for the rest of the suite3. Require 100% coverage
--cov-fail-underfrom90to100inpytest.iniNotes
The coverage-driven tests live in a dedicated
injector_100_percent_coverage_test.pyrather thaninjector_test.py, to keep the functional suite free of coverage-only edge cases.🤖 Generated with Claude Code