Skip to content

gh-73458: Fix logging.config.listen() on a host without an IPv4 address#154491

Open
serhiy-storchaka wants to merge 2 commits into
python:mainfrom
serhiy-storchaka:fix-logging-listen-family
Open

gh-73458: Fix logging.config.listen() on a host without an IPv4 address#154491
serhiy-storchaka wants to merge 2 commits into
python:mainfrom
serhiy-storchaka:fix-logging-listen-family

Conversation

@serhiy-storchaka

@serhiy-storchaka serhiy-storchaka commented Jul 22, 2026

Copy link
Copy Markdown
Member

logging.config.listen() cannot be used on a host without an IPv4 address, and any failure to start the server leaves the caller waiting forever.

The server is created in a thread which set the ready event only after a successful start, so if the receiver could not be constructed, the thread died and t.ready.wait() blocked forever. This is the hang reported in gh-73458 and gh-82076. It happens for any failure to start, not only on IPv6 hosts: an invalid or already used port hangs the caller too.

ConfigSocketReceiver also inherited address_family = AF_INET from ThreadingTCPServer while binding the name localhost, so the bind fails if localhost has no IPv4 address. The family is now taken from the resolved address, but only when there is no IPv4 address, so dual-stack hosts keep binding IPv4 as before. Resolution errors are left to the server, so an invalid port still reports the same exception as before.

Verified by patching socket.getaddrinfo() so that localhost resolves only to ::1: before the change the client gets ConnectionRefusedError, after it the connection is made over AF_INET6 and the configuration is delivered. With ports -1, 65536, 99999, 'http', 'nosuchservice', None and 1.5 the raised exception types are unchanged; only the hang is gone.

The test no longer forces AF_INET when connecting, and the waits for ready now have a timeout, so a regression fails instead of hanging.

🤖 Generated with Claude Code

… address

The server is created in a thread which set the "ready" event only after a
successful start, so a failure to start left the caller waiting for that
event forever.  Set it also on failure.

The receiver always used AF_INET, which fails if the host has no IPv4
address, for example if "localhost" is only aliased to ::1.  Use the family
of the first resolved address in such case.

Also fixes pythongh-82076.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Like the other logging.config.listen() tests.  It failed on WASI and
Emscripten, which cannot start a thread.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@serhiy-storchaka
serhiy-storchaka requested a review from gpshead July 22, 2026 16:20
@serhiy-storchaka serhiy-storchaka added needs backport to 3.13 bugs and security fixes needs backport to 3.14 bugs and security fixes needs backport to 3.15 pre-release feature fixes, bugs and security fixes labels Jul 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting core review needs backport to 3.13 bugs and security fixes needs backport to 3.14 bugs and security fixes needs backport to 3.15 pre-release feature fixes, bugs and security fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant