Skip to content

docs(deferred): the resolve-by-type 3.10 blocker is verified fixable - #416

Merged
lesnik512 merged 1 commit into
mainfrom
docs/resolve-by-type-blocker-verified
Aug 3, 2026
Merged

docs(deferred): the resolve-by-type 3.10 blocker is verified fixable#416
lesnik512 merged 1 commit into
mainfrom
docs/resolve-by-type-blocker-verified

Conversation

@lesnik512

Copy link
Copy Markdown
Member

Why

planning/deferred/2026-08-01-resolve-by-type-inline.md listed two blockers. One of them -- the CPython 3.10 coverage-gate failure -- was described with the right mechanism and a prescribed fix, but nobody had checked that the prescription works. Leaving that unverified means the eventual ruling has to re-derive it.

Design

Documentation only; no code. Records the verification and narrows the revisit trigger.

The item prescribed "add a test that reaches that handler by reference rather than through resolve()". Tested on CPython 3.10 with coverage: a by-reference cycle (container.resolve_provider(provider) on a mutual Factory cycle) records container.py:229, 5 runs out of 5. The prescription works.

The mechanism is now stated as general rather than local to this item, because it bit twice: a RecursionError tears down the trace function, so below 3.12 -- where coverage traces instead of using sys.monitoring -- anything executing after the unwind in the same frame goes unrecorded. The same effect hit tests/providers/test_alias.py during 3.2.0 and was fixed there by asserting through pytest.raises(match=) so no line follows the recursion.

Net effect: that bullet costs ~10 lines of test, and the item reduces to its one real question -- whether a duplicated 8-line body is an acceptable standing maintenance cost for ~30 ns per by-type resolve. The revisit trigger now names that as the sole gate.

Non-goals

  • Does not implement the inline. The remaining blocker is your judgement call, not a defect I can clear.
  • Does not add the by-reference test to the suite. It only earns its place alongside the inline it protects; adding it now would be a test for a line already covered by other means.

Verification

just lint-ci: clean, including the planning frontmatter validator and the Markdown link checker. just index renders the revised summary.


Before merging

  • Behaviour changed? No code in this PR.
  • Rejected an alternative? None.
  • Found real work you are not doing now? Already filed -- this PR sharpens that filing.
  • just lint-ci passes; just test-ci unaffected (docs only).

The item already named the mechanism (a RecursionError tears down the trace
function, and below 3.12 coverage traces rather than using sys.monitoring) and
prescribed the fix. What was untested was whether the prescription works: a
by-reference cycle records container.py:229 on 3.10, 5 runs of 5.

That leaves the duplicated 8-line body as the sole gate, which is a judgement
call rather than a defect, so the revisit trigger now says so.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Details
Benchmark suite Current: 34a1512 Previous: 10e4197 Ratio
benchmarks/test_guard_by_type.py::test_g16_resolve_by_type 2064385.127846483 iter/sec (stddev: 2.4004145219812455e-7) 2664934.4327533874 iter/sec (stddev: 2.0453924587934402e-7) 1.29
benchmarks/test_guard_by_type.py::test_g17_resolve_by_type_large_registry 2639590.943192231 iter/sec (stddev: 5.495991074498385e-8) 3397207.3008231083 iter/sec (stddev: 3.515253036642124e-8) 1.29
benchmarks/test_guard_cold.py::test_g8_cold_first_resolve 24438.630315565366 iter/sec (stddev: 0.00001927031159193012) 34457.92219890785 iter/sec (stddev: 0.00001250363996556651) 1.41
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[1] 433.5030893308696 iter/sec (stddev: 0.00005055000968049431) 558.1100634972859 iter/sec (stddev: 0.00003091000939193654) 1.29
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[2] 333.4783003645876 iter/sec (stddev: 0.0003057140533577134) 519.8167188978247 iter/sec (stddev: 0.00002291786749641334) 1.56
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[4] 373.77639061561035 iter/sec (stddev: 0.00004323759553087591) 487.5283154134495 iter/sec (stddev: 0.000024275221844047625) 1.30
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[1] 2354.136985739392 iter/sec (stddev: 0.000023407765344366104) 3156.219614815241 iter/sec (stddev: 0.000019244990000459958) 1.34
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[2] 1667.1410145958066 iter/sec (stddev: 0.0003199433825698524) 2257.523026171822 iter/sec (stddev: 0.0002606590779334005) 1.35
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[4] 1183.92205436033 iter/sec (stddev: 0.00003768170938956927) 1606.7510322547134 iter/sec (stddev: 0.00002783438307573802) 1.36
benchmarks/test_guard_lifecycle.py::test_g6_build_child_container 674839.2444032873 iter/sec (stddev: 4.675021321916907e-7) 822037.5157239352 iter/sec (stddev: 3.1891795312478927e-7) 1.22
benchmarks/test_guard_lifecycle.py::test_g6b_build_child_container_auto_scope 657156.5142697517 iter/sec (stddev: 4.1069711512516813e-7) 771336.8122861808 iter/sec (stddev: 3.1678881771787854e-7) 1.17
benchmarks/test_guard_lifecycle.py::test_g7_request_lifecycle_batch 2354.2483317098254 iter/sec (stddev: 0.00002542889305555835) 2993.4020982555853 iter/sec (stddev: 0.000007253408199680305) 1.27
benchmarks/test_guard_lifecycle.py::test_g7c_event_loop_floor_control 62881.611715612926 iter/sec (stddev: 0.0000018394011401584951) 79708.79137273741 iter/sec (stddev: 0.000001039243454664696) 1.27
benchmarks/test_guard_lifecycle.py::test_g13_teardown_at_scale 46460.42034740414 iter/sec (stddev: 0.0000024645242486111925) 56257.952885391795 iter/sec (stddev: 0.0000013465812775314434) 1.21
benchmarks/test_guard_resolve.py::test_g1_transient_resolve 1319295.9407439134 iter/sec (stddev: 4.979991785781972e-7) 1747734.83507298 iter/sec (stddev: 2.8841851032267993e-7) 1.32
benchmarks/test_guard_resolve.py::test_g2_cached_resolve 3356699.199250291 iter/sec (stddev: 4.408708169677978e-8) 4357961.233786322 iter/sec (stddev: 2.6410877546784392e-8) 1.30
benchmarks/test_guard_resolve.py::test_g3_deep_chain 503695.38403794623 iter/sec (stddev: 6.958598765035056e-7) 673594.2354822385 iter/sec (stddev: 3.4804824265902755e-7) 1.34
benchmarks/test_guard_resolve.py::test_g4_wide_resolve 326086.2365644157 iter/sec (stddev: 6.776927342690324e-7) 417391.54305801156 iter/sec (stddev: 4.911643485201084e-7) 1.28
benchmarks/test_guard_resolve.py::test_g5_cross_scope 1160404.9824932516 iter/sec (stddev: 3.2672185919541476e-7) 1508296.1372473787 iter/sec (stddev: 4.283170787265259e-7) 1.30
benchmarks/test_guard_resolve.py::test_g9_context_resolve 642681.4091393034 iter/sec (stddev: 4.7396182471017046e-7) 820287.3021842263 iter/sec (stddev: 3.6388032293586744e-7) 1.28
benchmarks/test_guard_resolve.py::test_g12_override_active_resolve 392052.60010961426 iter/sec (stddev: 4.3099263567186966e-7) 524806.0302587249 iter/sec (stddev: 2.423278963003047e-7) 1.34
benchmarks/test_guard_validate.py::test_g10_validate_deep_chain 27172.95583668484 iter/sec (stddev: 0.000005186062509984844) 39734.771986512744 iter/sec (stddev: 0.0000018412134968865806) 1.46
benchmarks/test_guard_validate.py::test_g11_validate_wide 17266.677771805742 iter/sec (stddev: 0.000004230999884202067) 23576.896559038214 iter/sec (stddev: 0.0000026237038454077014) 1.37

This comment was automatically generated by workflow using github-action-benchmark.

@lesnik512
lesnik512 merged commit ff2df17 into main Aug 3, 2026
9 checks passed
@lesnik512
lesnik512 deleted the docs/resolve-by-type-blocker-verified branch August 3, 2026 12:18
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