Skip to content

Bug: from __future__ import annotations breaks cog.Path type recognition #2389

Open
@zsxkib

Description

@zsxkib

Cog Bug Report: from __future__ import annotations Breaks Type Recognition

Summary

Cog fails to recognize cog.Path type annotations when from __future__ import annotations is present, leading to confusing error messages and broken functionality.

Environment

  • Cog version: 0.14.9 (from docker build logs)
  • Python version: 3.11
  • Base image: r8.im/cog-base:cuda11.8-python3.11

Problem Description

When using from __future__ import annotations (PEP 563), cog's type validation system fails to recognize Path as cog.Path, even when imported correctly from the cog module.

Error Message

TypeError: Unsupported input type Path for parameter `image1`. 
Supported input types are: str, int, float, bool, cog.File, cog.Path, cog.Secret, or a Union or List of those types.

Minimal Reproduction Case

❌ Broken Code (with future annotations)

from __future__ import annotations
from cog import BasePredictor, Input, Path

class Predictor(BasePredictor):
    def predict(self, image: Path = Input(description="An image")) -> Path:
        return image

✅ Working Code (without future annotations)

from cog import BasePredictor, Input, Path

class Predictor(BasePredictor):
    def predict(self, image: Path = Input(description="An image")) -> Path:
        return image

Complete Reproduction Example

Save this as predict.py to reproduce the bug:

# predict.py - This will FAIL with the TypeError
from __future__ import annotations

from cog import BasePredictor, Input, Path
from PIL import Image

class Predictor(BasePredictor):
    def predict(
        self,
        image: Path = Input(description="Input image"),
    ) -> Path:
        """Simple pass-through prediction that exhibits the bug."""
        # This would normally just return the input image
        img = Image.open(image)
        output_path = Path("/tmp/output.png")
        img.save(output_path)
        return output_path

Corresponding cog.yaml:

build:
  python_version: "3.11"
  python_packages:
    - pillow==10.0.0

predict: "predict.py:Predictor"

Run with: cog predict -i image=@some_image.jpg

Expected Error:

TypeError: Unsupported input type Path for parameter `image`. 
Supported input types are: str, int, float, bool, cog.File, cog.Path, cog.Secret, or a Union or List of those types.

Fix: Remove the from __future__ import annotations line and it works perfectly.

Real-World Reproduction

This bug can be reproduced with an existing repository that demonstrates the exact issue:

# Clone the specific commit that exhibits the bug
git clone https://github.com/zsxkib/cog-handy-image-tools.git
cd cog-handy-image-tools
git checkout 9736f755a881ec6fcc44c8e283814f8b4b907d6b

# Try to run a prediction - this will fail with the TypeError
sudo cog predict -i image1="https://upload.wikimedia.org/wikipedia/commons/thumb/5/54/MrBeast_2023.jpg/1200px-MrBeast_2023.jpg" -i image2="https://images.uesp.net/b/be/SR-creature-Shadowmere.jpg"

What you'll see: The exact TypeError: Unsupported input type Path for parameter 'image1' error.

To fix it: Remove line 13 (from __future__ import annotations) from predict.py and it works perfectly.

Commit reference: zsxkib/cog-handy-image-tools@9736f75

Investigation Steps Tried

1. Import Variations

  • from cog import BasePredictor, Input, Path as CogPath + using CogPath
  • import cog + using cog.Path and cog.Input
  • ❌ Adding explicit from pathlib import Path as StdPath to avoid conflicts
  • ❌ Removing Optional[Path] wrappers

2. Type Annotation Approaches

  • ❌ Using Optional[Path] for optional parameters
  • ❌ Using fully qualified cog.Path in type annotations
  • ❌ Various import alias strategies

3. The Fix

  • Removing from __future__ import annotations completely resolved the issue

Root Cause Analysis

The from __future__ import annotations import enables PEP 563 (postponed evaluation of annotations), which converts all type annotations to strings at runtime instead of actual type objects. Cog's type introspection system appears to rely on runtime type objects and cannot properly resolve string annotations back to their actual types.

Impact

  • High: Affects any modern Python codebase using future annotations
  • Confusing DX: Error message suggests Path vs cog.Path issue, not future annotations
  • Breaking Change: Will become more problematic as future annotations become default in Python 3.12+

Expected Behavior

Cog should support from __future__ import annotations since:

  1. It's becoming standard practice in modern Python
  2. It will be the default behavior in future Python versions
  3. Many type checkers and tools already handle string annotations properly

Suggested Fix

Cog's type validation should use typing.get_type_hints() or similar utilities that can resolve string annotations back to their actual types, rather than inspecting annotations directly.

Workaround

Remove from __future__ import annotations from cog predict.py files, but this forces users to avoid modern Python typing practices.

Test Case for Cog

The cog test suite should include tests with from __future__ import annotations to prevent regressions and ensure compatibility with modern Python typing practices.

Metadata

Metadata

Assignees

Labels

papercutSmall issues that build uptype/bugSomething isn't working

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions