Pipe inheritance broken on Windows since 3.13
未關閉
還沒有人認領這個 Issue。
3.13
3.14
OS-windows
type-bug
- 主要語言
- Python
- 星號
- 77.2k
- 分支
- 36k
- PR 合併指標
- PR 指標待擷取
描述
Bug report
Bug description:
Passing an inheritable pipe file descriptor to a child process is somehow broken on Windows since Python 3.13. Opening the file descriptor in the child process crashes with [WinError 6] the handle is invalid.
> py -3.12-64 .\main.py
INFO:root:S: Starting
INFO:root:Duration for 10000 requests: 0.37447249999968335 s
INFO:root:S: EOF Quitting
> py -3.13-64 .\main.py
INFO:root:S: Starting
Traceback (most recent call last):
File "D:\temp\test-pipe-main\sub.py", line 31, in <module>
main()
~~~~^^
File "D:\temp\test-pipe-main\sub.py", line 14, in main
reply_write_fobj = os.fdopen(reply_write_fd, "wb", buffering=0)
File "<frozen os>", line 1068, in fdopen
OSError: [WinError 6] Das Handle ist ungültig
Minimal example
import logging
import os
import pickle
import sys
import time
def main():
logging.basicConfig(level=logging.INFO)
reply_read_fd, reply_write_fd = os.pipe()
request_read_fd, request_write_fd = os.pipe()
child_fds = [reply_write_fd, request_read_fd]
for fd in child_fds:
os.set_inheritable(fd, True)
reply_read_fobj = os.fdopen(reply_read_fd, "rb", buffering=0)
request_write_fobj = os.fdopen(request_write_fd, "wb", buffering=0)
child_pid = os.spawnl(
os.P_NOWAIT,
sys.executable,
os.path.basename(sys.executable),
"sub.py",
*(str(fd) for fd in child_fds),
)
for fd in child_fds:
os.close(fd)
number_requests = 10000
start = time.perf_counter()
for i in range(number_requests):
request = f"test{i}"
pickle.dump(request, request_write_fobj)
logging.debug(f"C: Sent {request}")
reply = pickle.load(reply_read_fobj)
logging.debug(f"C: Got {reply}")
duration = time.perf_counter() - start
logging.info(f"Duration for {number_requests} requests: {duration} s")
request_write_fobj.close()
os.waitpid(child_pid, 0)
time.sleep(1)
if __name__ == "__main__":
main()
import logging
import os
import pickle
import sys
def main():
logging.basicConfig(level=logging.INFO)
reply_write_fd = int(sys.argv[1])
request_read_fd = int(sys.argv[2])
logging.info("S: Starting")
reply_write_fobj = os.fdopen(reply_write_fd, "wb", buffering=0)
request_read_fobj = os.fdopen(request_read_fd, "rb", buffering=0)
logging.debug("S: Sent event")
while True:
try:
request: str = pickle.load(request_read_fobj)
except EOFError:
logging.info("S: EOF Quitting")
return
logging.debug(f"S: Handle {request}")
reply = "test"
pickle.dump(reply, reply_write_fobj)
logging.debug("S: Sent event")
if __name__ == "__main__":
main()
CPython versions tested on:
3.12, 3.13
Operating systems tested on:
Windows
貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
研究方向
先在 Windows 上使用 Python 3.12 和 3.13 執行提供的 main.py 和 sub.py,重點關注 os.pipe、os.set_inheritable、os.spawnl 和 os.fdopen。追蹤 Windows 處理程序與管道繼承路徑,以找出子處理程序收到無效控制代碼的原因,然後透過涵蓋最小範例的回歸測試驗證修正。
由索引模型根據 Issue 內容生成。
評估
- 技術堆疊
- python
- 領域
- operating-systems
- Issue 類型
- 缺陷
- 難度
- 4/5
- 預估耗時
- 3-5 天
- 活躍度
- 停滯
- 描述清晰度
- 基本清楚
- 新手友好度
- 35/100