Expanding on the default unpickling behavior of objects that do not implement __setstate__

未关闭
#96,224 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
3/5
预计耗时
1-2 天
新手友好度
38/100
Issue 类型
文档
描述清晰度
基本清楚
活跃度
停滞
技术栈
python
领域
documentation

调研方向

从解释 getstatesetstate 以及反序列化行为的文档部分开始。明确说明接受元组状态,区分针对动态状态的直接 dict 更新与针对插槽状态的 setattr 调用,并在不依赖现有模糊注释的情况下解释相关行为。

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

描述

docs

Documentation

I'm about to open a PR for it myself but I wanted to also open a related issue (just in case there are any objections)
Ever since Python 3.11, __getstate__'s default implementation has been added to object. With that change, the section explaining __getstate__ was expanded to also explain the default implementation in regards to slotted objects and the fact that their default state is a tuple of dicts (1 for the slotted dict and 1 optional dynamic dict) .

With this change, the user is now aware of the new concept of the "slotted state" and therefore should be aware of how it is handled when __setstate__ was not implemented. The current documentation states that the user may choose to implement __getstate__ and not __setstate__ so long as the returned state was a dict.

This needs to be updated to explain it also accepts tuples of the former format. Moreover, it should be updated to explain how do these 2 dicts differ in their setting behavior:

  1. The dynamic dict MUST be set using direct edit of the instance's __dict__ (in order to not activate __setattr__ which is very important, especially on immutable instances that will throw an exception on such calls). This is behavior is similar to pure dict states (and should probably be documented as well)
  2. The slotted dict MUST be set using calls to setattr (since they by definition do not exist on the instance __dict__ and therefore cannot be directly edited. Also we want to avoid accidentally a duplicate value on that dict)

Explaining this behavior will be more detailed and helpful than the current note that vaguely states:

At unpickling time, some methods like __getattr__(), __getattribute__(), or __setattr__() may be called upon the instance. 
In case those methods rely on some internal invariant being true, the type should implement __new__() to establish such an invariant, 
as __init__() is not called when unpickling an instance.

Explaining it will also prevent users from mistakenly relying on __setattr__ when they shouldn't. This will also prevents libraries like jsonpickle from incorrectly implementing their unpickling behavior to always use setattr (which causes bugs that arise from discrepancies with the default pickle library.

主要语言
Python
星标
77.2k
派生
36k
平均合并
1 天 9 小时
30 天内合并 PR
558

贡献指南

打开贡献指南

从这里开始

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

python/cpython 的其他 Issue

查看 python/cpython 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

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