Декоратор подсказки типа, который вводит значение, но также поддерживает передачу значения.Python

Программы на Python
Anonymous
Декоратор подсказки типа, который вводит значение, но также поддерживает передачу значения.

Сообщение Anonymous »

Я пытаюсь реализовать декоратор, который внедряет DBConnection. Проблема, с которой я столкнулся, заключается в том, что я хотел бы поддержать оба: передачу аргумента и в зависимости от декоратора для его внедрения. Я пытался сделать это с помощью @overload, но не получилось. Вот воспроизводимый код:
from functools import wraps
from typing import Awaitable, Callable, Concatenate, ParamSpec, TypeVar

from typing_extensions import reveal_type

class DBConnection:
...

T = TypeVar("T")
P = ParamSpec("P")

def inject_db_connection(
f: Callable[Concatenate[DBConnection, P], Awaitable[T]]
) -> Callable[P, Awaitable[T]]:
@wraps(f)
async def inner(*args: P.args, **kwargs: P.kwargs) -> T:
signature = inspect.signature(f).parameters
passed_args = dict(zip(signature, args))
if "db_connection" in kwargs or "db_connection" in passed_args:
return await f(*args, **kwargs)

return await f(DBConnection(), *args, **kwargs)

return inner

@inject_db_connection
async def get_user(db_connection: DBConnection, user_id: int) -> dict:
assert db_connection
return {"user_id": user_id}

async def main() -> None:
# ↓ No issue, great!
user1 = await get_user(user_id=1)

# ↓ Understandably fails with:
# `Unexpected keyword argument "db_connection" for "get_user" [call-arg]`
# but I would like to support passing `db_connection` explicitly as well.
db_connection = DBConnection()
user2 = await get_user(db_connection=db_connection, user_id=1)

# ↓ Revealed type is "builtins.dict[Any, Any]", perfect.
reveal_type(user1)
# ↓ Revealed type is "builtins.dict[Any, Any]", perfect.
reveal_type(user2)```



Подробнее здесь: https://stackoverflow.com/questions/775 ... ing-the-va

Вернуться в «Python»