logging: `SMTPHandler.emit()` leaks the SMTP connection when sending fails
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:
SMTPHandler.emit() only closes its SMTP connection on the success path: smtp.quit() is the last statement of the try block (Lib/logging/handlers.py#L1109-L1154).
If starttls(), login() or send_message() raises, control jumps to except Exception: self.handleError(record) and the connection is never closed — cleanup is left to the garbage collector.
Reproducer
import gc, logging, logging.handlers, socket, threading, time
logging.raiseExceptions = False
open_conns = []
def handle(conn):
conn.sendall(b"220 fake ESMTP\r\n")
for line in conn.makefile("rb"):
cmd = line.strip().upper()
if cmd.startswith(b"EHLO"):
conn.sendall(b"250-fake\r\n250 AUTH PLAIN LOGIN\r\n")
elif cmd.startswith(b"AUTH"):
conn.sendall(b"535 authentication failed\r\n")
else:
conn.sendall(b"250 ok\r\n")
open_conns.remove(conn) # reached when the client closes the connection
conn.close()
def serve(listener):
while True:
conn, _ = listener.accept()
open_conns.append(conn)
threading.Thread(target=handle, args=(conn,), daemon=True).start()
listener = socket.create_server(("127.0.0.1", 0))
threading.Thread(target=serve, args=(listener,), daemon=True).start()
h = logging.handlers.SMTPHandler(("127.0.0.1", listener.getsockname()[1]),
"me@example.com", "you@example.com", "subject",
credentials=("user", "wrong-password"))
for i in range(5):
h.emit(logging.makeLogRecord({"msg": "hello"})) # SMTPAuthenticationError
time.sleep(0.5)
print("open connections after 5 failed emits:", len(open_conns))
gc.collect(); time.sleep(0.5)
print("after gc.collect():", len(open_conns))
Output on main:
open connections after 5 failed emits: 5
after gc.collect(): 0
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Linked PRs
- gh-155950
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 em Lib/logging/handlers.py, em SMTPHandler.emit(), e execute o reprodutor fornecido da falha de autenticação. O trabalho estará concluído quando os caminhos em que starttls(), login() ou send_message() falham não deixarem mais conexões SMTP abertas; verifique o comportamento com o reprodutor. A PR vinculada gh-155950 indica que o trabalho já está em andamento.
Escrita pelo modelo de indexação a partir do texto da issue.
Avaliação
- Stack de tecnologia
- python
- Domínio
- backend
- Tipo de issue
- Bug
- Dificuldade
- 2/5
- Tempo estimado
- 1-3 horas
- Status de atividade
- Estagnada
- Clareza
- Claramente especificada
- Facilidade para iniciantes
- 25/100