docs: fix factual errors found in review - #547
Merged
Merged
Conversation
- Troubleshooting: positional-only params only fixable with a default; MaxScopeReachedError fix uses build_child_container with a one-member IntEnum; error samples regenerated from real output. - factories.md: scope the three escape routes. - design-decisions.md: generator-creator advice, missing-provider wording, tree-wide overrides and lock, plain async and Beta statements. - Migration: ThreadLocalSingleton workaround, to-3.x warning block and correction note. - Integrations: celery worker_init/worker_shutdown and *args TypeError, arq child close timing, flask, grpc, fastapi/typer API rows, faststream and taskiq FromDI signatures, litestar collisions, pytest overrides, writing-integrations facts. - index.md, contributing.md, errors-and-exceptions.md, good-and-bad-practices.md.
There was a problem hiding this comment.
Benchmark
Details
| Benchmark suite | Current: 8a17acb | Previous: 8ce868f | Ratio |
|---|---|---|---|
benchmarks/test_guard_by_type.py::test_g16_resolve_by_type |
6860220.469637784 iter/sec (stddev: 1.1350279026376358e-8) |
3442054.526547969 iter/sec (stddev: 2.143375745788722e-8) |
0.50 |
benchmarks/test_guard_by_type.py::test_g17_resolve_by_type_large_registry |
6634242.910004253 iter/sec (stddev: 1.1118838523911411e-8) |
3548434.840392541 iter/sec (stddev: 1.2827232048867815e-8) |
0.53 |
benchmarks/test_guard_cold.py::test_g8_cold_first_resolve |
20086.76388833524 iter/sec (stddev: 0.0002127862113507429) |
15518.545714422256 iter/sec (stddev: 0.00004698793690022765) |
0.77 |
benchmarks/test_guard_cold.py::test_g8b_cold_first_resolve_cached |
18162.24197549022 iter/sec (stddev: 0.000032183694633676134) |
13185.693699108479 iter/sec (stddev: 0.00010949077679688568) |
0.73 |
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[1] |
802.4842572229129 iter/sec (stddev: 0.00009788610786291962) |
404.3230311283974 iter/sec (stddev: 0.00007048845657185601) |
0.50 |
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[2] |
682.3258283587447 iter/sec (stddev: 0.00004926030062943845) |
383.4654873688378 iter/sec (stddev: 0.000046998100263502144) |
0.56 |
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[4] |
603.8768218237799 iter/sec (stddev: 0.00006520483457299476) |
352.2463486495161 iter/sec (stddev: 0.00009127243270054909) |
0.58 |
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[1] |
1992.770097231849 iter/sec (stddev: 0.0001333977483374318) |
1626.7073683300935 iter/sec (stddev: 0.0001986442227433345) |
0.82 |
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[2] |
1625.6971565124065 iter/sec (stddev: 0.00013948311717709868) |
1327.7632191013151 iter/sec (stddev: 0.00017288226483966492) |
0.82 |
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[4] |
970.6024731749375 iter/sec (stddev: 0.001315486110555091) |
960.0010675205933 iter/sec (stddev: 0.00017975799786761426) |
0.99 |
benchmarks/test_guard_concurrency.py::test_g15b_concurrent_first_resolve_sibling_children[1] |
2163.313434698019 iter/sec (stddev: 0.00013049710007195453) |
1407.057453110696 iter/sec (stddev: 0.0010831166068909466) |
0.65 |
benchmarks/test_guard_concurrency.py::test_g15b_concurrent_first_resolve_sibling_children[2] |
1439.2394483119317 iter/sec (stddev: 0.00015047467334073196) |
1175.7928128429965 iter/sec (stddev: 0.00021455490282242838) |
0.82 |
benchmarks/test_guard_concurrency.py::test_g15b_concurrent_first_resolve_sibling_children[4] |
957.3024442464645 iter/sec (stddev: 0.0001566678311087579) |
784.9046406926733 iter/sec (stddev: 0.00021119103540343572) |
0.82 |
benchmarks/test_guard_lifecycle.py::test_g6_build_child_container |
1268532.4262865619 iter/sec (stddev: 4.743103233469329e-8) |
826944.4808698264 iter/sec (stddev: 4.169575359621365e-8) |
0.65 |
benchmarks/test_guard_lifecycle.py::test_g6b_build_child_container_auto_scope |
1149102.8781506433 iter/sec (stddev: 3.822966211174696e-8) |
754895.2503574233 iter/sec (stddev: 3.0409338412035246e-8) |
0.66 |
benchmarks/test_guard_lifecycle.py::test_g7_request_lifecycle_batch |
3171.698285863586 iter/sec (stddev: 0.000007740096462751993) |
2421.0815300750833 iter/sec (stddev: 0.000020424490014428993) |
0.76 |
benchmarks/test_guard_lifecycle.py::test_g7c_event_loop_floor_control |
93277.60687478787 iter/sec (stddev: 0.00000100094982014164) |
58408.76624586848 iter/sec (stddev: 0.0000018447825779836061) |
0.63 |
benchmarks/test_guard_lifecycle.py::test_g13_teardown_at_scale |
63873.447433154484 iter/sec (stddev: 0.0000013026365585484084) |
43876.32191693938 iter/sec (stddev: 0.0000021012125198676007) |
0.69 |
benchmarks/test_guard_lifecycle.py::test_g13b_teardown_at_scale_async_no_finalizers |
806.807827234481 iter/sec (stddev: 0.00004342058717888897) |
553.8315819315635 iter/sec (stddev: 0.00011049984251667817) |
0.69 |
benchmarks/test_guard_resolve.py::test_g1_transient_resolve |
3751181.5049841 iter/sec (stddev: 3.642543373787177e-8) |
2179414.0503717246 iter/sec (stddev: 3.2116689283894473e-8) |
0.58 |
benchmarks/test_guard_resolve.py::test_g2_cached_resolve |
6474185.673742138 iter/sec (stddev: 1.1727614617152446e-8) |
3331944.800863088 iter/sec (stddev: 1.8996420430089775e-8) |
0.51 |
benchmarks/test_guard_resolve.py::test_g3_deep_chain |
1270769.8597294868 iter/sec (stddev: 4.8332149085018514e-8) |
728489.2646086639 iter/sec (stddev: 6.251243141025456e-8) |
0.57 |
benchmarks/test_guard_resolve.py::test_g4_wide_resolve |
764213.5894289435 iter/sec (stddev: 2.5539878049722226e-7) |
468680.21058674285 iter/sec (stddev: 3.2602527219035675e-7) |
0.61 |
benchmarks/test_guard_resolve.py::test_g5_cross_scope |
3550509.7289320664 iter/sec (stddev: 2.3962636628665118e-8) |
1866879.1921924949 iter/sec (stddev: 3.339221547534178e-8) |
0.53 |
benchmarks/test_guard_resolve.py::test_g9_context_resolve |
1768069.582736624 iter/sec (stddev: 1.2523246341256786e-7) |
1052288.8650783815 iter/sec (stddev: 1.333290563243788e-7) |
0.60 |
benchmarks/test_guard_resolve.py::test_g12_override_active_resolve |
1296090.013971847 iter/sec (stddev: 3.4713002666392195e-8) |
720244.7622185523 iter/sec (stddev: 6.1118782837122e-8) |
0.56 |
benchmarks/test_guard_resolve.py::test_g18_alias_hop |
4519560.54503975 iter/sec (stddev: 1.5636115066043727e-8) |
1889630.0710914063 iter/sec (stddev: 4.658060565489605e-8) |
0.42 |
benchmarks/test_guard_validate.py::test_g10_validate_deep_chain |
28760.641820904686 iter/sec (stddev: 0.0000154937778851691) |
22333.268360870607 iter/sec (stddev: 0.00003390432019260961) |
0.78 |
benchmarks/test_guard_validate.py::test_g11_validate_wide |
18381.735260884343 iter/sec (stddev: 0.000018514738717146934) |
14119.363707672732 iter/sec (stddev: 0.000028698284721104412) |
0.77 |
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.
Summary
Fixes docs claims that disagree with the code. Each item below names what was wrong and the source that shows it.
Changes
troubleshooting/unsupported-creator-parameter-error.md,providers/factories.md: the example creator was positional-only, but fordef f(items, /)thekwargsroute still raisesUnsupportedCreatorParameterErrorandskip_creator_parsingraisesCreatorCallError(types_parser.py:65-76, confirmed by running). Dropped the/from the example and stated that positional-only params need a default.introduction/design-decisions.md: aFactorysubclass raisesTypeError(resolver_compiler.py:48-57), so the generator-creator advice now points to a plain creator plusCacheSettings(finalizer=). A missing provider is anArgumentResolutionErrorfromvalidate()or resolve (factory.py:190), not a declaration-time error. Overrides use one tree-wide registry and the lock is per tree (container.py:116-126). The async and Beta statements are now plain.migration/from-that-depends.md,from-dependency-injector.md: a cachedFactorycaches one object per container, so theThreadLocalSingletonworkaround now uses an uncachedFactoryover a module-levelthreading.local()(tested with 3 threads).migration/to-3.x.md: added the blank line that ends the!!! warningblock, and removed the "an earlier version said" note.troubleshooting/max-scope-reached-error.md: usesbuild_child_container(scope=MyScope.SUBSTEP)with a one-memberIntEnumin place of the internalparent_container=(confirmed by running).troubleshooting/circular-dependency.md,missing-provider.md,context-not-set.md: sample output regenerated from real runs, now with the scope column and(module:line)(exceptions/rendering.py:42).index.md: Flask, gRPC and Typer don't close the root container (no shutdown hook), and pytest builds no child per test. Also "smallest example".dev/contributing.md: the gate isreport.fail_under = 100inpyproject.toml.providers/errors-and-exceptions.md:Group(scope=...)also raisesInvalidScopeTypeError(group.py:23).recipes/good-and-bad-practices.md: removed the history wording.modern-di-<name>repo:worker_init/worker_shutdown(main.py:37-40), plus the*args/**kwargsTypeError(main.py:68-75).@injecttasks the wrapper closes the child, andon_job_endonly closes it as a safety net (main.py:86-90,188-198).auto_inject,main.py:51-52).validate()never constructs anything, so the default only matters for resolving outside an RPC (confirmed by running).fetch_di_containerto the API table. typer: addedaction_scope(ctx).FromDIsignature and dropped "no longer". taskiq: addeduse_cache, and the child is built lazily viaTaskiqDepends.FromDIunderautowired_groupsraisesImproperlyConfiguredException.<4, Typer root lookup goes throughcontext_settings["obj"], decorator integrations do register connection providers, and notedauto_inject/DITaskand the extra modules in aiogram and pytest.providers/scopes.md:16. The FastAPI, Starlette, Litestar and aiohttp integrations do enter SESSION for websockets.Checklist
ruff)ty)uv build) if packaging or build config changeddescription, profile blurb) if this touches packagingjust lint-ci,just test-ci(100% coverage) andmkdocs build --strictall pass.