Skip to content

4.0: context values are required; ContextProvider(default=) replaces per-parameter runtime disposition #475

Description

@lesnik512

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions