Skip to content

[BUG] when using from __future__ import annotations the pydantic type transformer doesn't properly recognize types  #6694

@gverkes

Description

@gverkes

Flyte & Flytekit version

flytekit 1.16.1

Describe the bug

When using from __future__ import annotations in Python, Pydantic BaseModel fields fail to be properly typed in Flyte tasks. The PydanticTransformer.get_literal_type() method directly accesses __annotations__ which contains string literals instead of actual type objects when
future annotations are enabled. This causes Flyte to treat all fields as unsupported types and fall back to PickleFile serialization.

Root cause: In flytekit/extras/pydantic_transformer/transformer.py:28, the code uses:

fields = t.__annotations__.items()

With from __future__ import annotations, __annotations__ contains strings like 'str' and 'int' instead of the actual str and int type objects. This breaks TypeEngine.to_literal_type() on line 32, causing it to fail to recognize standard Python types.

Expected behavior: Flyte should properly handle Pydantic models regardless of whether future annotations are used, since this is a standard Python feature (PEP 563) and will become the default behavior in Python 3.14.

Actual behavior: Field types are misidentified as unsupported, triggering warnings like:

  WARNING - Unsupported Type str found, Flyte will default to use PickleFile as the transport.
  WARNING - Unsupported Type int found, Flyte will default to use PickleFile as the transport.

Solution: Use Pydantic's built-in field APIs (model_fields for v2, __fields__ for v1) which properly resolve string annotations to actual type objects.

Expected behavior

Flyte should properly recognize and handle all field types in Pydantic BaseModel classes, regardless of whether from __future__ import annotations is used. Standard Python types like str, int, float, list, etc. should be correctly identified and serialized using their
appropriate Flyte literal types, not fall back to PickleFile.

When a task with a Pydantic BaseModel parameter is defined, the type system should:

  1. Correctly extract the actual Python types from the model's fields
  2. Convert them to appropriate Flyte literal types
  3. Generate proper type metadata for the workflow

This should work consistently whether future annotations are enabled or not, since PEP 563 is a standard Python feature and will become the default in Python 3.14.

Additional context to reproduce

  1. Create a Python file with from __future__ import annotations:
from __future__ import annotations

from pydantic import BaseModel
from flytekit import task, workflow


class MyModel(BaseModel):
    name: str
    age: int


@task
def process_model(model: MyModel) -> str:
    return f"{model.name} is {model.age} years old"


@workflow
def my_workflow(model: MyModel) -> str:
    return process_model(model=model)


if __name__ == "__main__":
    test_model = MyModel(name="Alice", age=30)
    result = my_workflow(model=test_model)
    print(result)
  1. Run the script:
python test_script.py
  1. Observe the warnings in the output:
WARNING - Unsupported Type str found, Flyte will default to use PickleFile as the transport.
WARNING - Unsupported Type int found, Flyte will default to use PickleFile as the transport.
  1. Without from __future__ import annotations, the same code works correctly without warnings.

Environment:

  • Python: 3.8+ (future annotations available from 3.7+)
  • Pydantic: Both v1 and v2 affected
  • Flytekit: Current version (issue exists in the transformer code)

Screenshots

No response

Are you sure this issue hasn't been raised already?

  • Yes

Have you read the Code of Conduct?

  • Yes

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinguntriagedThis issues has not yet been looked at by the Maintainers

    Type

    No type

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions