Pipe inheritance broken on Windows since 3.13
Chưa có ai nhận issue này.
- Ngôn ngữ chính
- Python
- Star
- 77.2k
- Fork
- 35.9k
- Chỉ số merge pull request
- Chỉ số pull request đang chờ
Mô tả
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
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Hướng nghiên cứu
Bắt đầu bằng cách chạy main.py và sub.py được cung cấp trên Windows với Python 3.12 và 3.13, tập trung vào os.pipe, os.set_inheritable, os.spawnl và os.fdopen. Theo dõi đường đi của tiến trình Windows và quá trình kế thừa pipe để xác định lý do tiến trình con nhận được một handle không hợp lệ, sau đó xác minh bản sửa bằng một bài kiểm thử hồi quy bao quát ví dụ tối thiểu.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- python
- Lĩnh vực
- operating-systems
- Loại issue
- Lỗi
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức độ hoạt động
- Đình trệ
- Độ rõ ràng
- Khá rõ ràng
- Mức phù hợp với người mới
- 35/100