Skip to content

Python 3.14 and Dataframely v2 incompatibility in certain scenarios #226

@svet-b

Description

@svet-b

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 dataframely assumes __annotate_func__ is always callable when it exists, but in Python 3.14 with PEP 649, it can be None when:

  • 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!

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions