From 72aa6101655802968c4aed93b8085a78b392aa66 Mon Sep 17 00:00:00 2001 From: Bedram Tamang Date: Fri, 24 Jul 2026 16:54:05 -0700 Subject: [PATCH] fix(typing): make Provider.boot() pattern static-analysis clean Type Provider.app as Application[AppConfig] instead of the bare, generic Application so basedpyright/pyright resolves self.app concretely instead of Application[Unknown]. This stops the Unknown type from cascading into every self.app.* access (fastapi, use_base_path, include_router) inside provider boot()/register() methods. Give Container.bind an explicit signature. It now returns None (it never needs to be chained), so callers no longer see a partially-unknown member and the example provider can call self.app.bind(...) directly without capturing an unused result. Update the container test to assert the new None contract. --- .../src/fastapi_startkit/container/container.py | 8 ++------ .../src/fastapi_startkit/support/providers/provider.py | 5 +++-- fastapi_startkit/tests/core/test_container.py | 4 ++-- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/fastapi_startkit/src/fastapi_startkit/container/container.py b/fastapi_startkit/src/fastapi_startkit/container/container.py index c3549b27..61335703 100644 --- a/fastapi_startkit/src/fastapi_startkit/container/container.py +++ b/fastapi_startkit/src/fastapi_startkit/container/container.py @@ -1,6 +1,7 @@ """Core of the IOC Container.""" import inspect +from typing import Any from ..exceptions import ( ContainerError, @@ -42,15 +43,12 @@ def __init__(self): self.swaps = {} self._remembered = {} - def bind(self, name, class_obj): + def bind(self, name: str, class_obj: Any) -> None: """Bind classes into the container with a key value pair. Arguments: name {string} -- Name of the key you want to bind the object to class_obj {object} -- The object you want to bind - - Returns: - self """ if inspect.ismodule(class_obj): raise StrictContainerException( @@ -63,8 +61,6 @@ def bind(self, name, class_obj): self.fire_hook("bind", name, class_obj) self.objects.update({name: class_obj}) - return self - def unbind(self, name): """Unbind classes from the container from a key. diff --git a/fastapi_startkit/src/fastapi_startkit/support/providers/provider.py b/fastapi_startkit/src/fastapi_startkit/support/providers/provider.py index e980abfc..7d5572b4 100644 --- a/fastapi_startkit/src/fastapi_startkit/support/providers/provider.py +++ b/fastapi_startkit/src/fastapi_startkit/support/providers/provider.py @@ -5,13 +5,14 @@ if TYPE_CHECKING: from fastapi_startkit.application import Application + from fastapi_startkit.config import AppConfig class Provider: provider_key: str = None - def __init__(self, application: "Application", config: dict = None): - self.app: "Application" = application + def __init__(self, application: "Application[AppConfig]", config: dict = None): + self.app: "Application[AppConfig]" = application self.config = config or {} if self.provider_key is None: diff --git a/fastapi_startkit/tests/core/test_container.py b/fastapi_startkit/tests/core/test_container.py index f20354b8..aae18b5a 100644 --- a/fastapi_startkit/tests/core/test_container.py +++ b/fastapi_startkit/tests/core/test_container.py @@ -75,9 +75,9 @@ def test_bind_and_make_object_instance(self, container): container.bind("service_a", svc) assert container.make("service_a") is svc - def test_bind_returns_self_for_chaining(self, container): + def test_bind_returns_none(self, container): result = container.bind("x", 42) - assert result is container + assert result is None def test_bind_overrides_existing_key_by_default(self, container): container.bind("key", "first")