python / python/cpython

Class creation doesn't call __set_name__ when creating class members in another __set_name__

未關閉
#122,381 4 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

type-bug
主要語言
Python
星號
77.2k
分支
36k
PR 合併指標
PR 指標待擷取

描述

Bug report

Bug description:

When inserting a class member during some other class member's __set_name__ call, the __set_name__ method of the newly-inserted member doesn't get called as expected.

As an example, take this snippet:

class I_Am_Altering_The_Deal:
    def __set_name__(self, owner, name):
        print(f"__set_name__({self.__class__.__name__}, {owner.__name__}, {name!r}")
        owner.han_solo = Pray_I_Dont_Alter_It_Any_Further()
        
class Pray_I_Dont_Alter_It_Any_Further:
    def __set_name__(self, owner, name):
        print(f"__set_name__({self.__class__.__name__}, {owner.__name__}, {name!r}")

class Cloud_City:
    luke_skywalker = I_Am_Altering_The_Deal()

I would expect both __set_name__ functions to be called, resulting in the output:

__set_name__(I_Am_Altering_The_Deal, Cloud_City, 'luke_skywalker')
__set_name__(Pray_I_Dont_Alter_It_Any_Further, Cloud_City, 'han_solo')

But what is actually output, is:

__set_name__(I_Am_Altering_The_Deal, Cloud_City, 'luke_skywalker')

Discovered while testing a PEP-487 implementation for Micropython: micropython/micropython#15503.

Maybe be related to #72983.

CPython versions tested on:

3.8, 3.10, 3.12

Operating systems tested on:

Linux

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

研究方向

首先執行 issue 中的類別建立程式碼片段,並將其輸出與預期的兩次 set_name 呼叫進行比較。閱讀 PEP-487 的實作和相關 issue #72983;當在另一個成員的 set_name 呼叫期間插入的成員收到其自身預期的回呼,並具備回歸測試涵蓋時,修正才算完成。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
python
領域
compilers
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
停滯
描述清晰度
描述清楚
新手友好度
35/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。