This is a potential follow-up to my earlier questi...
# ask-the-community
This is a potential follow-up to my earlier question: Are annotated `FlyteFile`s supposed to be used as input parameters of a task? I have attached an example workflow in the thread, where I'm defining a type alias for an annotated FlyteFile with a
, which for consistency's sake I'd like to also use as the input parameter for a second task. However doing so results in an error message that looks quite similar to the behavior I had described in my original post above (and probably has the same cause - if that's the case, I'm happy to provide a PR). I can see why allowing annotations on both an task output and a task input may lead to weird semantics questions (what function would the
on the input argument serve?), but I like the consistent typing between outputs and inputs and could see the data scientists in our org stumble across a similar problem in the future. Thanks!
Example workflow (note that
is used as the type annotation for the argument to the
task - replacing it with
solves the error):
Copy code
from pathlib import Path
from typing import Annotated

from flytekit import HashMethod, current_context, task, workflow
from flytekit.types.file import FlyteFile

def hash_fn(ff: FlyteFile) -> str:
    return ff.path

HashedFile = Annotated[FlyteFile, HashMethod(hash_fn)]

def create_file() -> HashedFile:
    f = Path(current_context().working_directory) / "data.txt"
    f.write_text("Hello World")
    return HashedFile(str(f))

def do_work(ff: HashedFile) -> None:

def wf() -> None:
    data_file = create_file()

if __name__ == "__main__":
Copy code
Traceback (most recent call last):
  File "/work/mlops/splat-ml/.sandbox/", line 34, in <module>
  File "/work/mlops/splat-ml/.venv/lib/python3.9/site-packages/flytekit/core/", line 263, in __call__
    return flyte_entity_call_handler(self, *args, **input_kwargs)
  File "/work/mlops/splat-ml/.venv/lib/python3.9/site-packages/flytekit/core/", line 1093, in flyte_entity_call_handler
    result = cast(LocallyExecutable, entity).local_execute(child_ctx, **kwargs)
  File "/work/mlops/splat-ml/.venv/lib/python3.9/site-packages/flytekit/core/", line 282, in local_execute
    function_outputs = self.execute(**kwargs)
  File "/work/mlops/splat-ml/.venv/lib/python3.9/site-packages/flytekit/core/", line 722, in execute
    return exception_scopes.user_entry_point(self._workflow_function)(**kwargs)
  File "/work/mlops/splat-ml/.venv/lib/python3.9/site-packages/flytekit/exceptions/", line 198, in user_entry_point
    return wrapped(*args, **kwargs)
  File "/work/mlops/splat-ml/.sandbox/", line 30, in wf
  File "/work/mlops/splat-ml/.venv/lib/python3.9/site-packages/flytekit/core/", line 299, in __call__
    return flyte_entity_call_handler(self, *args, **kwargs)  # type: ignore
  File "/work/mlops/splat-ml/.venv/lib/python3.9/site-packages/flytekit/core/", line 1085, in flyte_entity_call_handler
    return cast(LocallyExecutable, entity).local_execute(ctx, **kwargs)
  File "/work/mlops/splat-ml/.venv/lib/python3.9/site-packages/flytekit/core/", line 280, in local_execute
    outputs_literal_map = self.sandbox_execute(ctx, input_literal_map)
  File "/work/mlops/splat-ml/.venv/lib/python3.9/site-packages/flytekit/core/", line 346, in sandbox_execute
    return self.dispatch_execute(ctx, input_literal_map)
  File "/work/mlops/splat-ml/.venv/lib/python3.9/site-packages/flytekit/core/", line 518, in dispatch_execute
    native_inputs = TypeEngine.literal_map_to_kwargs(exec_ctx, input_literal_map, self.python_interface.inputs)
  File "/work/mlops/splat-ml/.venv/lib/python3.9/site-packages/flytekit/core/", line 867, in literal_map_to_kwargs
    return {k: TypeEngine.to_python_value(ctx, lm.literals[k], python_types[k]) for k, v in lm.literals.items()}
  File "/work/mlops/splat-ml/.venv/lib/python3.9/site-packages/flytekit/core/", line 867, in <dictcomp>
    return {k: TypeEngine.to_python_value(ctx, lm.literals[k], python_types[k]) for k, v in lm.literals.items()}
  File "/work/mlops/splat-ml/.venv/lib/python3.9/site-packages/flytekit/core/", line 831, in to_python_value
    return transformer.to_python_value(ctx, lv, expected_python_type)
  File "/work/mlops/splat-ml/.venv/lib/python3.9/site-packages/flytekit/types/file/", line 417, in to_python_value
    if not issubclass(expected_python_type, FlyteFile):  # type: ignore
  File "/home/adriano/.pyenv/versions/3.9.16/lib/python3.9/", line 123, in __subclasscheck__
    return _abc_subclasscheck(cls, subclass)
TypeError: issubclass() arg 1 must be a class
The offending line in ``:
Copy code
if not issubclass(expected_python_type, FlyteFile):  # type: ignore
    raise TypeError(f"Neither os.PathLike nor FlyteFile specified {expected_python_type}")
You may need to add the annotated check to the
method for this to work. cc @Eduardo Apolinario (eapolinario)
@Adrian Rumpold, this seems like a reasonable extension. Feel free to open a PR (should be as simple as adding this check to
). You can link to the same gh issue (and this time we can close it for good 🙂 )
Sounds good, I'll prepare another MR! Does this warrant any documentation notes or extra test cases regarding the semantics (as mentioned in the OP)?