Skip to content

Preserve unread lazy class annotations on Python 3.14 - #610

Draft
pralav-25 wants to merge 1 commit into
cloudpipe:masterfrom
pralav-25:fix/unread-class-annotations
Draft

pralav-25 wants to merge 1 commit into
cloudpipe:masterfrom
pralav-25:fix/unread-class-annotations

Conversation

@pralav-25

Copy link
Copy Markdown

Unread annotations on a Python 3.14 dynamic class are lost when the class is pickled by value. A fresh-process round trip of class C: x: int returns an empty annotation dictionary unless its annotations were accessed first.

Materialize the native annotation cache before sorted class-state extraction, only for an owned lazy annotation function whose cache has not been populated. The snapshot retains the existing cache representation while excluding the annotation closure. Fresh-process regressions cover unread/read annotations, class-local/self/resolved references, derived classes, cached metaclass getters/setters and deterministic chained pickling.

Annotations are evaluated when dumping, consistent with dynamic function annotations. Unresolved bare names therefore raise NameError during dumping; quoted references and future-import annotations retain their string values. This behavior is recorded in the changelog.

Fixes #608.

Validation:

  • Exact upstream source with the final regressions: 10 expected failures and 12 passes (eight annotation-loss failures and two checks of the documented NameError change).
  • Python 3.14.8: 285 passed, 13 skipped and two expected xfails.
  • Tox Python 3.12.14: 270 passed, 28 skipped and two expected xfails.
  • Pinned pre-commit hooks, wheel/sdist build, Twine and git diff --check pass.
  • Separate review passed 72 semantic scenarios and 64 native-cache chained cases across Python 3.14.8 and 3.15.0rc2 free-threaded. The full supported Python/OS matrix was not run locally.
  • Four exploratory future-import byte-determinism cases reproduce on unchanged upstream; their annotation values are preserved. These baseline cases are separate from the native-cache path changed here.

AI assistance: OpenAI Codex prepared the implementation, regression tests and changelog, ran the checks, and performed a separate agent review of the final patch.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A class pickled by value before its annotations are read loses them.

1 participant