sanic-org / sanic-ext

Extended Sanic functionality
https://sanic.dev/en/plugins/sanic-ext/getting-started.html
MIT License
50 stars 36 forks source link

[Bug] Problems with di built-in generics #262

Open owakira opened 15 hours ago

owakira commented 15 hours ago

Describe the bug I found an interesting bug: di doesn't work with built-in generics.

class Client:
    pass

class Service:
    def __init__(self, clients: list[Client]) -> None:
        self._clients = clients

def _get_clients() -> list[Client]:
    return [Client() for _ in range(3)]

def configure_di(app: Sanic) -> None:
    app.ext.add_dependency(list[Client], _get_clients)
    app.ext.add_dependency(Service)

It throws the following error:

File "/usr/local/lib/python3.11/site-packages/sanic_ext/extensions/injection/injector.py", line 37, in finalize_injections
     injection_registry.finalize(app, constant_registry, router_types)
File "/usr/local/lib/python3.11/site-packages/sanic_ext/extensions/injection/registry.py", line 42, in finalize
     constructor.prepare(
File "/usr/local/lib/python3.11/site-packages/sanic_ext/extensions/injection/constructor.py", line 111, in prepare
     raise InitError(
 sanic_ext.exceptions.InitError: Unable to resolve dependencies for 'Service'. Could not find the following dependencies:
   - clients: list[src.di.Client].
 Make sure the dependencies are declared using ext.injection. See https://sanicframework.org/en/plugins/sanic-ext/injection.html#injecting-services for more details.
 Not all workers acknowledged a successful startup. Shutting down.

Environment (please complete the following information):

owakira commented 15 hours ago

I found the issue in sanic_ext/extensions/injection/constructor.py:

if not isclass(annotation):
    missing.append((param, annotation))
    continue

The condition for list[Client] will always be True.
It is necessary to add a new check for built-in generics.

owakira commented 15 hours ago

Created pull request https://github.com/sanic-org/sanic-ext/pull/263