python / python/cpython

Instances of generic classes defined with PEP695 syntax are unpickleable

未关闭
#129,250 6 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

interpreter-core topic-typing type-bug
主要语言
Python
星标
77.2k
派生
36k
PR 合并指标
PR 指标待抓取

描述

Bug report

Bug description:

Generic classes that are instantiated with the Class[Type](...) syntax have an undocumented(?) __orig_class__ attribute defined on them that contains a reference to the type passed in the brackets. This attribute is pickled along with the class as usual, and in the cases when that type is well-behaved this works fine. However, PEP695-defined TypeVars have their __module__ set to typing, and so pickling fails as it is not a true member of the typing module. This prevents the usage of either Class[Type](...) syntax or PEP695 syntax in code near anything that must be pickled.

import pickle
from typing import Generic, TypeVar

T = TypeVar('T')

class Foo(Generic[T]): # equivalently class Foo[Anything]:
    pass

def bar[Baz]():
    return Foo[Baz]()

pickle.dumps(bar())
#    pickle.dumps(bar())
#    ~~~~~~~~~~~~^^^^^^^
# _pickle.PicklingError: Can't pickle Baz: attribute lookup Baz on typing failed

print(bar().__dict__)
# {'__orig_class__': __main__.Foo[Baz]}
print(bar().__orig_class__.__parameters__[0])
# Baz
print(bar().__orig_class__.__parameters__[0].__module__)
# typing
CPython versions tested on:

3.13

Operating systems tested on:

Linux

Linked PRs
  • gh-129446

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

从 issue 中的 reproducer 开始,重点关注 PEP 695 泛型类、orig_class 和 pickle.dumps()。将行为与关联的 PR gh-129446 进行比较;当使用所示语法创建的实例能够在不出现所报告的 PicklingError 的情况下进行 pickle 时,这项工作就完成了。

由索引模型根据 Issue 内容生成。

评估

技术栈
python
领域
compilers
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
停滞
描述清晰度
基本清楚
新手友好度
25/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。