Repository navigation
docs: rework the providers: context, container, alias, advanced api pages - #661
Merged
Merged
Conversation
There was a problem hiding this comment.
Benchmark
Details
| Benchmark suite | Current: ea3e336 | Previous: 395e8fb | Ratio |
|---|---|---|---|
benchmarks/test_guard_by_type.py::test_g16_resolve_by_type |
5193249.108505582 iter/sec (stddev: 4.832700798314597e-9) |
6139935.138982263 iter/sec (stddev: 1.8605923146541302e-8) |
1.18 |
benchmarks/test_guard_by_type.py::test_g17_resolve_by_type_large_registry |
5148485.408253094 iter/sec (stddev: 1.0361519279891035e-8) |
6205832.315667191 iter/sec (stddev: 1.3805592208773412e-8) |
1.21 |
benchmarks/test_guard_cold.py::test_g8_cold_first_resolve |
33004.76952906015 iter/sec (stddev: 0.000035626795976427125) |
32024.886577255867 iter/sec (stddev: 0.000030238944431934) |
0.97 |
benchmarks/test_guard_cold.py::test_g8b_cold_first_resolve_cached |
26259.227630119076 iter/sec (stddev: 0.00011349031197513305) |
24960.133332489408 iter/sec (stddev: 0.00011886986138363566) |
0.95 |
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[1] |
664.069314290154 iter/sec (stddev: 0.000010501312195968394) |
775.0388204206938 iter/sec (stddev: 0.00004473754687217169) |
1.17 |
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[2] |
648.20108657088 iter/sec (stddev: 0.000027028471386647455) |
764.2436132277375 iter/sec (stddev: 0.0001144571715558005) |
1.18 |
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[4] |
610.7716553740476 iter/sec (stddev: 0.00003652858922399275) |
680.0345534095648 iter/sec (stddev: 0.0000803400475442327) |
1.11 |
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[1] |
18939.710797303036 iter/sec (stddev: 0.000006178882028073279) |
10419.935559673875 iter/sec (stddev: 0.00001230746171334532) |
0.55 |
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[2] |
9099.930431059862 iter/sec (stddev: 0.000014584247599831315) |
5634.100392630293 iter/sec (stddev: 0.00003435893765767916) |
0.62 |
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[4] |
4958.980757545409 iter/sec (stddev: 0.000030113170236992703) |
2968.9836953557647 iter/sec (stddev: 0.000061919224501018) |
0.60 |
benchmarks/test_guard_concurrency.py::test_g15b_concurrent_first_resolve_sibling_children[1] |
13780.172261725564 iter/sec (stddev: 0.000005907434769069808) |
12389.480670083722 iter/sec (stddev: 0.000019500905757513246) |
0.90 |
benchmarks/test_guard_concurrency.py::test_g15b_concurrent_first_resolve_sibling_children[2] |
5118.570840453977 iter/sec (stddev: 0.00004911548898671997) |
4843.535831204409 iter/sec (stddev: 0.00003981695650002605) |
0.95 |
benchmarks/test_guard_concurrency.py::test_g15b_concurrent_first_resolve_sibling_children[4] |
2689.32874354108 iter/sec (stddev: 0.0000664608000410762) |
1868.0290700812566 iter/sec (stddev: 0.00007765838735564648) |
0.69 |
benchmarks/test_guard_concurrency.py::test_g15c_worker_pool_floor_control[1] |
52820.52816992293 iter/sec (stddev: 0.0000027049146471823743) |
24896.9783783031 iter/sec (stddev: 0.000017881784016521047) |
0.47 |
benchmarks/test_guard_concurrency.py::test_g15c_worker_pool_floor_control[2] |
20498.489091280735 iter/sec (stddev: 0.000010474826103190854) |
11645.85197075752 iter/sec (stddev: 0.000015482573556939863) |
0.57 |
benchmarks/test_guard_concurrency.py::test_g15c_worker_pool_floor_control[4] |
8182.27490151447 iter/sec (stddev: 0.00003549769115035338) |
5052.235696391264 iter/sec (stddev: 0.000048475453192008314) |
0.62 |
benchmarks/test_guard_lifecycle.py::test_g6_build_child_container |
2191179.89836369 iter/sec (stddev: 2.664977325949408e-8) |
2335541.2567186337 iter/sec (stddev: 3.860763352243666e-8) |
1.07 |
benchmarks/test_guard_lifecycle.py::test_g6b_build_child_container_auto_scope |
2359945.216195241 iter/sec (stddev: 1.8543654286122994e-8) |
2505907.6773532387 iter/sec (stddev: 3.905850495221895e-8) |
1.06 |
benchmarks/test_guard_lifecycle.py::test_g7_request_lifecycle_batch |
4327.2244601093535 iter/sec (stddev: 0.000005836165471820058) |
3317.2697581338502 iter/sec (stddev: 0.000052891745120707064) |
0.77 |
benchmarks/test_guard_lifecycle.py::test_g7c_event_loop_floor_control |
75973.05414011616 iter/sec (stddev: 0.0000012935977206743153) |
83100.58991551855 iter/sec (stddev: 0.0000014527703096612033) |
1.09 |
benchmarks/test_guard_lifecycle.py::test_g7b_request_cycle_sync |
522667.911308588 iter/sec (stddev: 5.936322345202273e-8) |
468518.9908558271 iter/sec (stddev: 8.515899938405845e-8) |
0.90 |
benchmarks/test_guard_lifecycle.py::test_g13_teardown_at_scale |
82931.07378505087 iter/sec (stddev: 9.841393149813524e-7) |
78785.45603292529 iter/sec (stddev: 0.0000017671089125152717) |
0.95 |
benchmarks/test_guard_lifecycle.py::test_g13b_teardown_at_scale_async_no_finalizers |
746.3619648998294 iter/sec (stddev: 0.0010258310266080847) |
586.9668417253587 iter/sec (stddev: 0.0013708543619692236) |
0.79 |
benchmarks/test_guard_resolve.py::test_g1_transient_resolve |
3048979.6475114 iter/sec (stddev: 2.5260577130181994e-8) |
3091773.339921797 iter/sec (stddev: 3.1905368666696455e-8) |
1.01 |
benchmarks/test_guard_resolve.py::test_g2_cached_resolve |
4987641.870338065 iter/sec (stddev: 5.2076781642349365e-9) |
5585002.481125255 iter/sec (stddev: 1.7326975696337195e-8) |
1.12 |
benchmarks/test_guard_resolve.py::test_g3_deep_chain |
1013994.3386634365 iter/sec (stddev: 3.0204017517021995e-8) |
1053634.7223852123 iter/sec (stddev: 4.376268176758002e-8) |
1.04 |
benchmarks/test_guard_resolve.py::test_g4_wide_resolve |
607734.7864826723 iter/sec (stddev: 3.41578665705509e-7) |
602475.4027370019 iter/sec (stddev: 3.669391702377282e-7) |
0.99 |
benchmarks/test_guard_resolve.py::test_g5_cross_scope |
2730082.1058545928 iter/sec (stddev: 1.4888265276725142e-8) |
2722743.1964451196 iter/sec (stddev: 2.2608711961763022e-8) |
1.00 |
benchmarks/test_guard_resolve.py::test_g9_context_resolve |
2050711.3225539043 iter/sec (stddev: 1.285977942500552e-7) |
2095884.4060996436 iter/sec (stddev: 1.4539795764318154e-7) |
1.02 |
benchmarks/test_guard_resolve.py::test_g12_override_active_resolve |
1055069.3444233427 iter/sec (stddev: 3.65894966499322e-8) |
1056924.0255533508 iter/sec (stddev: 4.539064934432262e-8) |
1.00 |
benchmarks/test_guard_resolve.py::test_g18_alias_hop |
4977322.324047423 iter/sec (stddev: 6.584826655971779e-9) |
5564689.374851157 iter/sec (stddev: 1.595292015837515e-8) |
1.12 |
benchmarks/test_guard_validate.py::test_g10_validate_deep_chain |
55211.49693481896 iter/sec (stddev: 0.000015206195340001708) |
23951.926949647954 iter/sec (stddev: 0.000031960404140896095) |
0.43 |
benchmarks/test_guard_validate.py::test_g11_validate_wide |
31184.045419594546 iter/sec (stddev: 0.000021337896687603556) |
21724.253571453744 iter/sec (stddev: 0.00003130808206721572) |
0.70 |
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.
Reworks four provider pages (context, container, alias, advanced API) the same way the Quickstart, Introduction and Providers pages were done. I checked every behavioural claim with a script against the checkout, and every example now asserts its result and runs under Sybil.
What was wrong
scope=Scope.APP. The default is unset, so the provider takes its group's default scope and falls back to APP only when the group sets none. Withclass G(Group, scope=Scope.REQUEST),G.cp.scopeis REQUEST.ContextProviders. arq, Celery and Typer register none (grep of the sibling repos, and their own pages say so). gRPC registers its provider whenDIInterceptoris constructed.dict[str, str], so it registered under baredict, and the result was a comment instead of an assert.fastapiis on conftest's uninstalled list, andtest-docs-integrationscovers onlydocs/integrations.Containerparameter gets the container that is resolving it. It actually gets the container at the factory's own scope: an APP factory resolved from a REQUEST child receives the APP container. Onlyresolve(Container)returns the calling container.str, and their results were comments.validate()raisesAliasSourceNotRegisteredErrorandCircularDependencyError. It raisesValidationFailedError, and those errors sit in.exceptions. Onlyresolve()raises them directly.AbstractProviderappears inkwargs=, but that parameter is typeddict[str, Any]. The signatures that do name it areresolve_provider,resolve_dependency,override,reset_override,find_providerandadd_providers. Themodern_di.providersbullet also left outAbstractProvider, which is in its__all__.What was added
bound_typedoes: it defaults tocontext_type, andNonemakes the provider reference-only. Values are still keyed bycontext_type.Container(context=...)on the root.context=entry with no declared provider registers nothing, so resolving it raisesProviderNotRegisteredError.add_providersraisesDuplicateProviderTypeErroron a duplicate type and clears the validated state.container_provideris always APP-scoped and ignores a group default.scope=and ignores a group default; it resolves at its source's scope.bound_typeis not checked against the source.kwargs, and can be reference-only.with container.override(...)form restores the prior state.ValidationFailedErrorexample.DuplicateProviderTypeError.Structure
Requestclass, withadd_providersstanding in forsetup_di()) replace the FastAPI blocks. The integration pages keep the real FastAPI code and run it undertest-docs-integrations.validate()ordering are now two sentences that link towriting-integrations.md#lifecycle-rulesandlifecycle.md#validation.Anchors kept
All of the following still resolve:
context.md#framework-context-objects,#context-propagation,#optional-parameters,#when-no-value-is-set,#optional-context-default,#basic-usage;container.md#registering-providers-after-construction,#looking-up-a-provider;advanced-api.md#what-is-public,#container-navigation. "Which container you get" is now an h3 with the same slug, and nothing linked to it.Checks
just test-docs: 163 passed, 19 skippedjust docs-build: no WARNING linesjust lint-ci: cleandocsandREADME.md: 0 errorsLibrary bugs found (not fixed here)
Registering the same provider object twice gives a misleading
DuplicateProviderTypeError.The error lists the same Factory twice and suggests
bound_type=Noneon one of them, which cannot help because both entries are one object. The docs describe the current behaviour.Alias.scopeand its repr report APP whatever the source's scope is. For an alias of a REQUEST factory,G.a.scopeisScope.APPand the repr showsscope=<Scope.APP: 1>, yet resolving it from APP raisesScopeNotInitializedError. TheAbstractProvider.scopedocstring acknowledges this. Low severity.Follow-ups outside this PR
mkdocs.ymlllmstxt description forproviders/container.mdis now stale. A possible replacement: "The Container API: building containers, a map of its methods, and injecting the container itself".troubleshooting/context-not-set.mdcause 1 repeats the propagation warning almost word for word, and its code comment still says "registry". It could become a link tocontext.md#context-propagation.troubleshooting/duplicate-type-error.mdandrecipes/multi-group.mddon't mention the group-and-subclass case.