-
Notifications
You must be signed in to change notification settings - Fork 14
Description
We have a Python 3.14 codebase and trying to migrate to Dataframely v2. In many scenarios we encounter exceptions during module import, which appear to be related to the introduction in 3.14 of deferred evaluation of annotations (https://docs.python.org/3/reference/compound_stmts.html#annotations). Notably, things work fine with Dataframely v1.
The stack trace is as follows:
Traceback (most recent call last):
File "xxxx.py", line 8, in <module>
import dataframely as dy
File "/xx/.venv/lib/python3.14/site-packages/dataframely/__init__.py", line 17, in <module>
from .collection import (
...<4 lines>...
)
File "/xx/.venv/lib/python3.14/site-packages/dataframely/collection/__init__.py", line 5, in <module>
from .collection import (
...<4 lines>...
)
File "/xx/.venv/lib/python3.14/site-packages/dataframely/collection/collection.py", line 52, in <module>
class Collection(BaseCollection, ABC):
...<1159 lines>...
)
File "/xx/.venv/lib/python3.14/site-packages/dataframely/collection/_base.py", line 115, in __new__
result.update(mcs._get_metadata_recursively(base))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "/xx/.venv/lib/python3.14/site-packages/dataframely/collection/_base.py", line 187, in _get_metadata_recursively
result.update(CollectionMeta._get_metadata(kls.__dict__)) # type: ignore
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
File "/xx/.venv/lib/python3.14/site-packages/dataframely/collection/_base.py", line 200, in _get_metadata
annotations = source["__annotate_func__"](Format.VALUE)
TypeError: 'NoneType' object is not callable
Some thoughts from Claude:
The core issue is that
dataframelyassumes__annotate_func__is always callable when it exists, but in Python 3.14 with PEP 649, it can beNonewhen:
- A class has no annotations
- Annotations are being processed during certain import contexts
- The annotation evaluation is deferred and not yet available
The fix is simple: check if
__annotate_func__is not None (and ideally also callable) before calling it, and fall back to using__annotations__directly when it's not available.This is a common compatibility issue that many metaclass-based libraries are encountering with Python 3.14's new annotation system.
Thanks in advance for taking a look!