Pipe inheritance broken on Windows since 3.13
Ninguém assumiu esta issue ainda.
- Linguagem predominante
- Python
- Estrelas
- 77.2k
- Forks
- 36k
- Métricas de merge de PRs
- Métricas de PR pendentes
Descrição
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
Guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Direção de pesquisa
Comece executando os arquivos main.py e sub.py fornecidos no Windows com Python 3.12 e 3.13, concentrando-se em os.pipe, os.set_inheritable, os.spawnl e os.fdopen. Rastreie o caminho do processo do Windows e da herança de pipe para identificar por que o processo filho recebe um handle inválido e, em seguida, verifique a correção com um teste de regressão que cubra o exemplo mínimo.
Escrita pelo modelo de indexação a partir do texto da issue.
Avaliação
- Stack de tecnologia
- python
- Domínio
- operating-systems
- Tipo de issue
- Bug
- Dificuldade
- 4/5
- Tempo estimado
- 3-5 dias
- Status de atividade
- Estagnada
- Clareza
- Razoavelmente clara
- Facilidade para iniciantes
- 35/100