Problem
When a factory parameter is backed by a ContextProvider and the context value is absent at resolve time, the resolver decides per parameter, per resolve, whether to omit the argument (creator default applies), inject None (nullable annotation), or raise. That single feature is why the wiring plan has a context bucket next to the provider bucket, why the compiler template carries a context-fold block that loops at resolve time, why absent_disposition is consulted at plan time and again at run time, and why ArgumentResolutionError has a registry-less variant with no suggestions. Ablated in the research behind #470, it is the largest remaining single source of complexity in the resolve path.
Proposal
A context value is required at its scope. ContextProvider becomes an ordinary dependency: its resolver reads the context registry and raises ContextValueNotSetError when unset. Optional context is spelled once, on the provider: ContextProvider(Request, default=None), a compile-time constant returned when the value is unset. A factory whose parameter has a creator default and no provider is unchanged (that is plan-time, not run-time).
What it deletes
The context bucket of the wiring plan and its special case in the explicit-kwargs overlay; the context-fold template block; the run-time use of the absent-disposition enum; the registry-less branch of the argument-resolution error. Roughly 80 lines and one concept ("runtime disposition") from the glossary.
What it changes for users
A factory parameter that today receives None or its default when the context value is absent will raise ContextValueNotSetError (naming the type, not the parameter) unless the ContextProvider declares default=. 13 tests in the context-provider and factory suites describe the current semantics and would be rewritten to the new rule. Migration is one argument on the provider.
Measured
G9 (context resolve, the request-injection path every integration takes) −7% with the fold removed. The motive is simplicity, not speed.
Decision needed
Whether default= covers the real optional-context use cases (a handler usable outside a request is the one the tests describe), and whether the error should name the parameter as well as the type. Ships in 4.0 only.
Related
ADR-0011 declined folding the context registry into the container; this proposal is about the disposition rule, not the registry, and does not reopen it.
Problem
When a factory parameter is backed by a
ContextProviderand the context value is absent at resolve time, the resolver decides per parameter, per resolve, whether to omit the argument (creator default applies), injectNone(nullable annotation), or raise. That single feature is why the wiring plan has a context bucket next to the provider bucket, why the compiler template carries a context-fold block that loops at resolve time, whyabsent_dispositionis consulted at plan time and again at run time, and whyArgumentResolutionErrorhas a registry-less variant with no suggestions. Ablated in the research behind #470, it is the largest remaining single source of complexity in the resolve path.Proposal
A context value is required at its scope.
ContextProviderbecomes an ordinary dependency: its resolver reads the context registry and raisesContextValueNotSetErrorwhen unset. Optional context is spelled once, on the provider:ContextProvider(Request, default=None), a compile-time constant returned when the value is unset. A factory whose parameter has a creator default and no provider is unchanged (that is plan-time, not run-time).What it deletes
The context bucket of the wiring plan and its special case in the explicit-kwargs overlay; the context-fold template block; the run-time use of the absent-disposition enum; the registry-less branch of the argument-resolution error. Roughly 80 lines and one concept ("runtime disposition") from the glossary.
What it changes for users
A factory parameter that today receives
Noneor its default when the context value is absent will raiseContextValueNotSetError(naming the type, not the parameter) unless theContextProviderdeclaresdefault=. 13 tests in the context-provider and factory suites describe the current semantics and would be rewritten to the new rule. Migration is one argument on the provider.Measured
G9 (context resolve, the request-injection path every integration takes) −7% with the fold removed. The motive is simplicity, not speed.
Decision needed
Whether
default=covers the real optional-context use cases (a handler usable outside a request is the one the tests describe), and whether the error should name the parameter as well as the type. Ships in 4.0 only.Related
ADR-0011 declined folding the context registry into the container; this proposal is about the disposition rule, not the registry, and does not reopen it.