Skip to content

fix: open per-request child container for modern-di 3.x mandatory-open - #5

Merged
lesnik512 merged 4 commits into
mainfrom
chore/modern-di-3x
Jul 20, 2026
Merged

fix: open per-request child container for modern-di 3.x mandatory-open#5
lesnik512 merged 4 commits into
mainfrom
chore/modern-di-3x

Conversation

@lesnik512

Copy link
Copy Markdown
Member

Brings modern-di-flask onto modern-di 3.x. Part of the 12-package wave; unlike most sibling adapters, this one had a genuine adapter bug under the new mandatory-open lifecycle (approved by the maintainer, TDD: existing suite reproduces).

  • Bumps modern-di to >=3,<4 (drops 2.x support).
  • Adapter fix: _enter_request builds the per-request REQUEST child in before_request and a separate teardown_appcontext hook closes it later — two hooks, no enclosing with block. Under modern-di 3.0 the child was never opened, so every resolve raised ContainerClosedError. Fixed by calling child.open() right after building it.
  • Root-container policy (maintainer ruling): caller owns opening the root. setup_di still does not open the root container — Flask has no application-startup hook to attach that to, and this stays symmetric with the pre-existing caller-owned-teardown contract. The test fixture and README now open the root container explicitly (with Container(...) as container: ... / container.open()) before calling setup_di, so the suite exercises the real path.

Release notes in planning/releases/3.0.0.md; change bundle in planning/changes/2026-07-20.01-open-request-child-container.md; architecture/dependency-injection.md updated to match.

🤖 Generated with Claude Code

modern-di 3.0 makes container opening mandatory (resolving from, or
building a child of, an unopened container raises ContainerClosedError).
_enter_request builds the REQUEST child in the before_request hook and a
separate teardown_appcontext hook closes it later, so there is no enclosing
`with` block to open the child implicitly. Under modern-di 3.0's
mandatory-open lifecycle this left the child unopened, and every resolve
against it raised ContainerClosedError. Open it right after building.
setup_di still does not open the root container it's given — Flask has no
application-startup hook to attach that to, and the maintainer ruled root
lifecycle (open and close alike) stays the caller's responsibility,
symmetric with the existing caller-owned teardown contract. README and the
architecture doc now say so explicitly; the test fixture and the two inline
Container(...) constructions in test_middleware.py open the root container
via `with` so the suite exercises the real path.
@lesnik512
lesnik512 merged commit ca2b8e5 into main Jul 20, 2026
6 checks passed
@lesnik512
lesnik512 deleted the chore/modern-di-3x branch July 20, 2026 18:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant