Description
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
+ usingCogPath
- ❌
import cog
+ usingcog.Path
andcog.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
vscog.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:
- It's becoming standard practice in modern Python
- It will be the default behavior in future Python versions
- 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.