Skip to content

feat(container): truthful container with one validated write path (V8 S2) - #507

Merged
marlon-costa-dc merged 7 commits into
0.12.0-devfrom
feat/v8-s2-container
Sep 26, 2026
Merged

marlon-costa-dc merged 7 commits into
0.12.0-devfrom
feat/v8-s2-container

Conversation

@marlon-costa-dc

@marlon-costa-dc marlon-costa-dc commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Slice S2 of plan V8 (bead flext-4jtcb.2).

  • One write path for services, factories and resources: empty, reserved and duplicate names raise e.ValidationError (messages in c); internal core writes may only target reserved names.
  • Registration-record helpers exterminated (R27): _service_record/_factory_record/_resource_record only built Pydantic models from a loose M | raw union. The bootstrap spec now declares raw values only (t.RegisterableService, t.FactoryCallable, t.ResourceCallable); the container builds each record with the model itself; the spec delegates to bind/factory/resource; service_type is a computed field derived from the service.
  • Callers fixed to send the one declared type: scope() passed parent records into the spec (factories/resources failed; a service record was silently registered as the service value). It now passes record.service / record.factory.

Local pre-push gate (R23), GREEN on the committed head: make gen with a clean tree, make audit, make check (15 gates, mypy clean), make test (2709 passed). Runtime: examples.ex_08_flext_container passes its 77 checks.

🤖 Generated with Claude Code


Summary by cubic

Container registrations now pass through one validated write path: empty, duplicate, and reserved names raise e.ValidationError instead of being silently ignored. The string-keyed dependency_injector bridge (provide, wire, _di_* state, FlextRuntime.DependencyIntegration) and the _service_record/_factory_record/_resource_record registration helpers are removed.

  • Re-binding an existing name now raises and keeps the first value; previously the first write silently won.
  • Reserved core names (config, logger, context, command_bus) live in c.CONTAINER_RESERVED_NAMES; public writes reject them while internal core writes may use them.
  • scope() passes record.service / record.factory into the spec, fixing factories and resources that failed and services that were silently registered as their own record.
  • ServiceRegistrationSpec now declares raw values only (dropping SkipValidation), and the container builds each record itself.
  • shared(auto_register_factories=True) raises when the caller module cannot be resolved.

Migration

  • Catch e.ValidationError on container writes; duplicate and reserved names no longer pass silently.
  • Remove calls to provide, wire, initialize_di_components, sync_config_to_di, and register_existing_providers.

Written for commit f8726a5. Summary will update on new commits.

Review in cubic

Marlon Costa and others added 7 commits September 26, 2026 13:03
Empty, duplicate and reserved names raise e.ValidationError through one
private write path over a single registrations mapping; reserved core
names live in c.CONTAINER_RESERVED_NAMES. shared(auto_register_factories)
raises when the caller module cannot be resolved, and scanned factories
pass the validated factory record. The string-only dependency_injector
bridge (provide, wire, the _di_* state and FlextRuntime.DependencyIntegration)
is removed after a fleet-wide zero-use proof, and SkipValidation leaves the
container registration models. scope() binds its own core services and
keeps LOGGER internal.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…n fixed point

A class passed as a service value is recorded as a service, never mistaken for a ready registration; the type-mismatch path returns the typed failure without a cast. Examples and the architecture overview follow the truthful container. make mod removed test-suite __all__ declarations (ban-test-suite-module-all) and make gen reprojected the test inits.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
# Conflicts:
#	tests/unit/__init__.py
#	uv.lock
…ice record

A class object is never an instance of the ServiceRegistration model, so the extra isinstance(value, type) branch changed no behavior and broke mypy's narrowing (return-value: ServiceRegistration | type[object]). Caught by the local pre-push gate.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
t.RegisterableService admits type[object], and mypy keeps type[object] after isinstance(value, ServiceRegistration) because a class may be an instance through its metaclass. Excluding classes in the same condition keeps one construction path and gives mypy the exact narrowing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
_service_record, _factory_record and _resource_record only built Pydantic models and accepted either a raw value or a prebuilt record (m.X | t.Y) sorted out by isinstance. The bootstrap spec now declares raw values only (t.RegisterableService, t.FactoryCallable, t.ResourceCallable), the container builds each record with the model itself, the spec delegates to bind/factory/resource, and service_type is a computed field derived from the service. The spec test asserts raw declarations resolve and a prebuilt record is rejected at the boundary.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
scope() handed the parent's registration records to the bootstrap spec: factories and resources failed the raw-callable contract, and a service record was silently registered as the service value itself. The scope now passes record.service and record.factory, the one declared type. Runtime: examples.ex_08_flext_container passes its 77 checks.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@marlon-costa-dc
marlon-costa-dc merged commit 150f3c7 into 0.12.0-dev Sep 26, 2026
8 of 10 checks passed
@marlon-costa-dc
marlon-costa-dc deleted the feat/v8-s2-container branch September 26, 2026 18:27
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