Правильно набрать декоратор Python с Paramspec и Concatenate, который позволяет создавать произвольное позиционирование Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Правильно набрать декоратор Python с Paramspec и Concatenate, который позволяет создавать произвольное позиционирование

Сообщение Anonymous »

новичок в Python. Я пытаюсь обновить набор для использования ParamSpec и concatenate , поскольку текущая реализация не типа, но я застрял.
Вот текущая реализация:
def ensure_conn(func: Callable[..., Coroutine[Any, Any, R]]) -> Callable[..., Coroutine[Any, Any, R]]:
"""Ensure the function has a conn argument. If conn is not provided, generate a new connection and pass it to the function."""

async def wrapper(*args: Any, **kwargs: Any) -> R:
# Get named keyword argument conn, or find an AsyncConnection in the args
kwargs_conn = kwargs.get("conn")
conn_arg: AsyncConnection[Any] | None = None
if isinstance(kwargs_conn, AsyncConnection):
conn_arg = kwargs_conn
elif not conn_arg:
for arg in args:
if isinstance(arg, AsyncConnection):
conn_arg = arg
break
if conn_arg:
# If conn is provided, call the method as is
return await func(*args, **kwargs)
else:
# If conn is not provided, generate a new connection and pass it to the method
db_driver = DbDriver()
async with db_driver.connection() as conn:
return await func(*args, **kwargs, conn=conn)

return wrapper
< /code>
Текущее использование: < /p>
@ensure_conn
async def get_user(user_id: UUID, conn: AsyncConnection):
async with conn.cursor() as cursor:
// do stuff
< /code>
...but I can call this and it won't fail typechecking:

get_user('519766c5-af86-47ea-9fa9-cee0c0de66b1', conn, arg_that_should_fail_typing)
< /code>
Here's the closest current implementation I've gotten to with ParamSpec и concatenate :
def ensure_conn_decorator[**P, R](func: Callable[Concatenate[AsyncConnection[Any], P], R]) -> Coroutine[Any, Any, R]:
"""Ensure the function has a conn argument. If conn is not provided, generate a new connection and pass it to the function."""
async def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
# Get named keyword argument conn, or find an AsyncConnection in the args
kwargs_conn = kwargs.get("conn")
conn_arg: AsyncConnection[Any] | None = None
if isinstance(kwargs_conn, AsyncConnection):
conn_arg = kwargs_conn
elif not conn_arg:
for arg in args:
if isinstance(arg, AsyncConnection):
conn_arg = arg
break
if conn_arg:
# If conn is provided, call the method as is
return await func(*args, **kwargs)
else:
# If conn is not provided, generate a new connection and pass it to the method
db_driver = DbDriver()
async with db_driver.connection() as conn:
return await func(*args, **kwargs, conn=conn)

return wrapper
< /code>
Problems are
  • Conn must be 1st method argument instead of having an arbitrary position - it's usually been the last argument after an arbitrary X number of args
  • Can't quite figure out the proper return type :(
Expression of type "(**P@ensure_conn_decorator) -> Coroutine[Any, Any, R@ensure_conn_decorator]" is incompatible with return type "Coroutine[Any, Any, R@ensure_conn_decorator]"
"function" is incompatible with "Coroutine[Any, Any, R@ensure_conn_decorator]"


Подробнее здесь: https://stackoverflow.com/questions/795 ... -allows-fo
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

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