admin管理员组文章数量:1316023
For context I am using prefect
, which is a workflow orchestration engine that uses function decorates to tag functions for use. Their approach is very similar to dask in the creation of work flows.
Say I want to apply a decorator (in this case a prefect.task
) to a function defined out of scope, say from an external module, I can do something like:
from prefect import task, Task
from some_module import foo
# task is the decorate, and returns an instance of Task
task_foo = task(foo)
@task
def task_bar(a: int, b: float) -> float:
return a * b
in the case of task_bar
my environment in vscode is able to resolve the function parameters to (a: int, b: float) -> float
.
In the case of task_foo
is it not: (...) -> None
.
Is there a way to apply some typing.ParamSpec
to appropriately provide the type inference?
import typing
P = typing.ParamSpec('P', bound=foo)
task_foo: Task[P] = task(foo)
I realise that ParamSpec(..., bound=foo)
is not the answer here, but I am hoping it highlights the intent here.
I have not been able to spot the right thing to do here. I have found:
Which is getting very close to the problem I am describing. Playing around with ParamSpec
I am falling just a little short.
Edit:
Alright, not I think I am misunderstanding something, though this does not surprise me. Doing something as simple as:
from typing import ParamSpec, TypeVar
from prefect import task, Task
from some_module import foo
P = ParamSpec('P')
R = TypeVar('R')
task_foo: Task[P,R] = task(foo)
behaves exactly I want it to. But I am left very confused where the information is bubbled up from. The Task
class does have similar type P
R
parameters attached to its methods. Is it just a case that the types are being 'returned' and captured into the type variables P and R?
Hope this makes sense!
For context I am using prefect
, which is a workflow orchestration engine that uses function decorates to tag functions for use. Their approach is very similar to dask in the creation of work flows.
Say I want to apply a decorator (in this case a prefect.task
) to a function defined out of scope, say from an external module, I can do something like:
from prefect import task, Task
from some_module import foo
# task is the decorate, and returns an instance of Task
task_foo = task(foo)
@task
def task_bar(a: int, b: float) -> float:
return a * b
in the case of task_bar
my environment in vscode is able to resolve the function parameters to (a: int, b: float) -> float
.
In the case of task_foo
is it not: (...) -> None
.
Is there a way to apply some typing.ParamSpec
to appropriately provide the type inference?
import typing
P = typing.ParamSpec('P', bound=foo)
task_foo: Task[P] = task(foo)
I realise that ParamSpec(..., bound=foo)
is not the answer here, but I am hoping it highlights the intent here.
I have not been able to spot the right thing to do here. I have found:
https://github/python/typing/issues/1027
Which is getting very close to the problem I am describing. Playing around with ParamSpec
I am falling just a little short.
Edit:
Alright, not I think I am misunderstanding something, though this does not surprise me. Doing something as simple as:
from typing import ParamSpec, TypeVar
from prefect import task, Task
from some_module import foo
P = ParamSpec('P')
R = TypeVar('R')
task_foo: Task[P,R] = task(foo)
behaves exactly I want it to. But I am left very confused where the information is bubbled up from. The Task
class does have similar type P
R
parameters attached to its methods. Is it just a case that the types are being 'returned' and captured into the type variables P and R?
Hope this makes sense!
Share Improve this question edited Jan 30 at 12:46 InSync 10.9k4 gold badges17 silver badges56 bronze badges asked Jan 30 at 5:54 user29426864user29426864 314 bronze badges 2 |1 Answer
Reset to default -1There are plenty ways how to achieve this:
1.
from typing import ParamSpec, TypeVar
from prefect import task, Task
from some_module import foo
P = ParamSpec('P')
R = TypeVar('R')
task_foo: Task[P, R] = task(foo)
from typing import Callable, ParamSpec, TypeVar
from prefect import task, Task
P = ParamSpec("P")
R = TypeVar("R")
def typed_task(fn: Callable[P, R], **task_kwargs) -> Task[P, R]:
return task(fn, **task_kwargs)
from some_module import foo
task_foo = typed_task(foo)
reveal_type(task_foo)
from typing import Protocol, ParamSpec, TypeVar
P = ParamSpec("P")
R = TypeVar("R")
class TaskLike(Protocol[P, R]):
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R: ...
def submit(self, *args: P.args, **kwargs: P.kwargs) -> R: ...
def typed_task(fn: Callable[P, R]) -> TaskLike[P, R]:
return task(fn)
from typing import cast
task_foo = cast(Task[(int, str), float], task(foo))
from typing import ParamSpec, TypeVar
from prefect import task, Task
from some_module import foo
P = ParamSpec('P')
R = TypeVar('R')
task_foo: Task[P, R] = task(foo)
本文标签: pythonType annotating an inline decorated wrapped functionStack Overflow
版权声明:本文标题:python - Type annotating an inline decorated wrapped function - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741983882a2408558.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
some_module.foo
type-annotated? – dROOOze Commented Jan 30 at 6:35