refactor(graph): move the validation walk into dependency_graph.collect_errors - #544
Merged
Merged
Conversation
…ct_errors Container._walk_errors was the only consumer of the walk's event types outside dependency_graph, and it pulled eight names from that module into container.py. The walk now lives next to the events it matches on, and Container.validate calls collect_errors(self). Closes #536.
There was a problem hiding this comment.
Benchmark
Details
| Benchmark suite | Current: c10dbf3 | Previous: a324645 | Ratio |
|---|---|---|---|
benchmarks/test_guard_by_type.py::test_g16_resolve_by_type |
3879663.6952339234 iter/sec (stddev: 9.140498264801621e-9) |
3487208.6222819886 iter/sec (stddev: 1.6866072468572677e-8) |
0.90 |
benchmarks/test_guard_by_type.py::test_g17_resolve_by_type_large_registry |
3847085.580690999 iter/sec (stddev: 1.1779629421298373e-8) |
3478393.713962888 iter/sec (stddev: 2.5288091962078263e-8) |
0.90 |
benchmarks/test_guard_cold.py::test_g8_cold_first_resolve |
17913.529622302416 iter/sec (stddev: 0.000051318767321870626) |
15495.645030450161 iter/sec (stddev: 0.00006109304292965719) |
0.87 |
benchmarks/test_guard_cold.py::test_g8b_cold_first_resolve_cached |
15171.528759565816 iter/sec (stddev: 0.00013931550396566582) |
13013.676096400704 iter/sec (stddev: 0.0001412755967184869) |
0.86 |
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[1] |
497.93733058288103 iter/sec (stddev: 0.000037040719290879074) |
374.8261817484961 iter/sec (stddev: 0.00010874486815227522) |
0.75 |
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[2] |
468.266792211976 iter/sec (stddev: 0.00002936553583402235) |
357.3724058607998 iter/sec (stddev: 0.00013858022845116602) |
0.76 |
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[4] |
422.28183447847476 iter/sec (stddev: 0.00011727004186672103) |
329.0107566345924 iter/sec (stddev: 0.00014557533792018413) |
0.78 |
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[1] |
1676.052209864542 iter/sec (stddev: 0.0002237893539089371) |
1478.1564324391036 iter/sec (stddev: 0.0002392316542320992) |
0.88 |
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[2] |
1467.6249099541644 iter/sec (stddev: 0.00017651812239734033) |
1221.2978343280963 iter/sec (stddev: 0.00024729429484636353) |
0.83 |
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[4] |
1031.8627878395607 iter/sec (stddev: 0.0001997980541039297) |
847.2282532354639 iter/sec (stddev: 0.00028247565834591025) |
0.82 |
benchmarks/test_guard_concurrency.py::test_g15b_concurrent_first_resolve_sibling_children[1] |
1477.146730572983 iter/sec (stddev: 0.0013069305356307114) |
1234.2242992958365 iter/sec (stddev: 0.0016211315341404478) |
0.84 |
benchmarks/test_guard_concurrency.py::test_g15b_concurrent_first_resolve_sibling_children[2] |
1310.0193412344922 iter/sec (stddev: 0.00018906088961628999) |
1060.0306954887758 iter/sec (stddev: 0.00032095727684094705) |
0.81 |
benchmarks/test_guard_concurrency.py::test_g15b_concurrent_first_resolve_sibling_children[4] |
844.3436567057553 iter/sec (stddev: 0.0002168047021646993) |
665.7575746998305 iter/sec (stddev: 0.00036024012466687617) |
0.79 |
benchmarks/test_guard_lifecycle.py::test_g6_build_child_container |
813199.3145637609 iter/sec (stddev: 3.963318722000515e-8) |
788970.5234656611 iter/sec (stddev: 9.484223391782856e-8) |
0.97 |
benchmarks/test_guard_lifecycle.py::test_g6b_build_child_container_auto_scope |
743387.6136384744 iter/sec (stddev: 1.4619854131155884e-7) |
715171.5692083471 iter/sec (stddev: 4.815302438977803e-8) |
0.96 |
benchmarks/test_guard_lifecycle.py::test_g7_request_lifecycle_batch |
2479.01835873484 iter/sec (stddev: 0.0000487544148745425) |
2429.264129387182 iter/sec (stddev: 0.000011202848205415609) |
0.98 |
benchmarks/test_guard_lifecycle.py::test_g7c_event_loop_floor_control |
58659.921860027585 iter/sec (stddev: 0.0000019196495823206577) |
57191.07429995937 iter/sec (stddev: 0.0000021750260248608014) |
0.97 |
benchmarks/test_guard_lifecycle.py::test_g13_teardown_at_scale |
46438.194099809756 iter/sec (stddev: 0.00000289817401687082) |
43540.05597346128 iter/sec (stddev: 0.0000021820092774815705) |
0.94 |
benchmarks/test_guard_lifecycle.py::test_g13b_teardown_at_scale_async_no_finalizers |
628.7375252444701 iter/sec (stddev: 0.00006339464634494698) |
561.5006937878361 iter/sec (stddev: 0.00002505044399750245) |
0.89 |
benchmarks/test_guard_resolve.py::test_g1_transient_resolve |
2334132.190070908 iter/sec (stddev: 3.1197865872471324e-8) |
2156077.9432966453 iter/sec (stddev: 2.899760252099538e-8) |
0.92 |
benchmarks/test_guard_resolve.py::test_g2_cached_resolve |
3745852.732319375 iter/sec (stddev: 9.134222425116083e-9) |
3276618.4537722347 iter/sec (stddev: 2.0817515756959605e-8) |
0.87 |
benchmarks/test_guard_resolve.py::test_g3_deep_chain |
830848.5250339668 iter/sec (stddev: 4.435921291654024e-8) |
711825.1128164383 iter/sec (stddev: 7.484690789204477e-8) |
0.86 |
benchmarks/test_guard_resolve.py::test_g4_wide_resolve |
484968.03975725145 iter/sec (stddev: 3.60685139406087e-7) |
461696.48248650023 iter/sec (stddev: 3.759030085236763e-7) |
0.95 |
benchmarks/test_guard_resolve.py::test_g5_cross_scope |
2203324.916453447 iter/sec (stddev: 2.8700265922846043e-8) |
1858217.968928989 iter/sec (stddev: 4.497840005869342e-8) |
0.84 |
benchmarks/test_guard_resolve.py::test_g9_context_resolve |
1190438.1744012316 iter/sec (stddev: 1.7533107171884601e-7) |
1060758.2713874592 iter/sec (stddev: 2.0465904597179856e-7) |
0.89 |
benchmarks/test_guard_resolve.py::test_g12_override_active_resolve |
824846.7259500753 iter/sec (stddev: 8.012042240617132e-8) |
693384.1205018064 iter/sec (stddev: 7.278305868639698e-8) |
0.84 |
benchmarks/test_guard_resolve.py::test_g18_alias_hop |
2606071.134587685 iter/sec (stddev: 9.585619326111566e-9) |
2042195.1833653012 iter/sec (stddev: 1.4270316268674222e-8) |
0.78 |
benchmarks/test_guard_validate.py::test_g10_validate_deep_chain |
26788.723233401644 iter/sec (stddev: 0.00003092394557808863) |
22617.677741632695 iter/sec (stddev: 0.000028080947620640477) |
0.84 |
benchmarks/test_guard_validate.py::test_g11_validate_wide |
15932.461319266726 iter/sec (stddev: 0.00002812467851069047) |
13885.312777986277 iter/sec (stddev: 0.00002933321378046146) |
0.87 |
This comment was automatically generated by workflow using github-action-benchmark.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #536.
Container._walk_errorsmoves todependency_graph.collect_errors(container), unchanged line for line apart fromselfbecomingcontainer.Container.validatecalls it and keeps the memo check and theValidationFailedErrorraise.What it changes in
container.pydependency_graphimport drops from eight names to three:DependencyGraphandbuild_cycle_errorstay for_handle_recursion_error, andcollect_errorsjoins them.matchleaves the class whose other jobs are lifecycle and the two resolve entry points.Import direction
dependency_graph.pymust not importContainerat runtime, becausecontainer.pyimports it.collect_errorstakes the container as an argument and the annotation stays underTYPE_CHECKING, so nothing changes there.Behaviour
None.
validate()is boot-time only,_walk_errorswas private with no caller outsidevalidate, and the test that pinned the walk order (test_walk_errors_returns_flat_list_in_walk_order) is the same test renamed and callingcollect_errorsdirectly.Checks
ruff format,ruff check,eof-fixerclean.ty checkreports only the pre-existing unused-ignore attests/providers/test_factory.py:454.