You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When creating a component and pipeline with a return value using the DSL, you get a type error since the decorator changes the return type.
For example, a simple add(a: float, b: float) -> float component will always cause a type error, since the decorator makes the function return a dsl.PipelineTask or Unknown instead. Pipelines also always return a Callable or Unknown:
fromkfpimportdsl, locallocal.init(runner=local.DockerRunner())
@dsl.component(base_image="python:3.8-slim")defadd(a: float, b: float) ->float:
returna+b@dsl.pipeline() # call the decorator with (), otherwise the pipeline type is Unknowndefadd_pipeline(a: float, b: float) ->float:
t1=add(a=a, b=b)
returnt1.output# ^^^ Cannot access member "output" for type "float"p=add_pipeline(a=1.0, b=2.0)
assertp.output==3.0# ^^^ Cannot access member "output" for type "float"
Expected result
Components and pipelines should return the output that the user specifies, and not have it wrapped in an output class.
fromtypingimportCallable, Generic, ParamSpec, TypeVarT=TypeVar("T")
classPipelineTask(Generic[T]):
def__init__(self, item: T):
self.item: T=item@propertydefoutput(self) ->T:
returnself.itemP=ParamSpec("P")
R=TypeVar("R")
# does not support arguments, but it can be extended for thisdefmy_component(f: Callable[P, R]) ->Callable[P, PipelineTask[R]]:
defwrapper(*args: P.args, **kwargs: P.kwargs) ->PipelineTask[R]:
returnPipelineTask(f(*args, **kwargs))
returnwrapper@my_componentdefadd(a: float, b: float) ->float:
returna+bout=add(1.0, 2.0) # type PipelineTask[float]assertout.output==3.0# no type errors
Environment
Steps to reproduce
When creating a component and pipeline with a return value using the DSL, you get a type error since the decorator changes the return type.
For example, a simple
add(a: float, b: float) -> float
component will always cause a type error, since the decorator makes the function return adsl.PipelineTask
orUnknown
instead. Pipelines also always return aCallable
orUnknown
:Expected result
Components and pipelines should return the output that the user specifies, and not have it wrapped in an output class.
Alternatively, in order to still return the custom output classes and not introduce breaking changes and a large refactor in the code base, it is possible to make use of
TypeVar
andGeneric
magic. Based on help from https://stackoverflow.com/questions/65936408/typing-function-when-decorator-change-generic-return-type, I've created this simple proof of concept:Materials and Reference
Impacted by this bug? Give it a 👍.
The text was updated successfully, but these errors were encountered: