From edd95099586f82507b05630ccc7c8fbec4cbc584 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 22 Jul 2026 22:21:49 +0300 Subject: [PATCH] gh-82535: Ignore address resolution failure in SysLogHandler constructor The address may be temporarily unresolvable when the handler is created. It is resolved again when a record is emitted. Co-Authored-By: Claude Opus 4.8 (1M context) --- Lib/logging/handlers.py | 6 +++++- Lib/test/test_logging.py | 18 ++++++++++++++++++ ...26-07-22-19-21-20.gh-issue-82535.METFqd.rst | 3 +++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-07-22-19-21-20.gh-issue-82535.METFqd.rst diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index a5394d2dbea6494..c273733ad7dda77 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -901,7 +901,11 @@ def __init__(self, address=('localhost', SYSLOG_UDP_PORT), self.socktype = socktype self.timeout = timeout self.socket = None - self.createSocket() + # The address is resolved again when emitting an event. + try: + self.createSocket() + except socket.gaierror: + pass def _connect_unixsocket(self, address): use_socktype = self.socktype diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 06b3aa66fc47a31..de65e48f1676fef 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -2155,6 +2155,24 @@ def tearDown(self): self.server_class.address_family = socket.AF_INET super(IPv6SysLogHandlerTest, self).tearDown() +@support.requires_working_socket() +class UnresolvableSysLogAddressTest(BaseTest): + + """Test for SysLogHandler with a temporarily unresolvable address.""" + + @patch('socket.getaddrinfo') + def test_unresolvable_address(self, mock_getaddrinfo): + # The address can be unresolvable when the handler is created. + mock_getaddrinfo.side_effect = socket.gaierror + hdlr = logging.handlers.SysLogHandler(('localhost', 514)) + self.addCleanup(hdlr.close) + self.assertIsNone(hdlr.socket) + # It is resolved again when a record is emitted. + calls = mock_getaddrinfo.call_count + with support.captured_stderr(): + hdlr.emit(logging.makeLogRecord({'msg': 'sp\xe4m'})) + self.assertGreater(mock_getaddrinfo.call_count, calls) + @support.requires_working_socket() @threading_helper.requires_working_threading() class HTTPHandlerTest(BaseTest): diff --git a/Misc/NEWS.d/next/Library/2026-07-22-19-21-20.gh-issue-82535.METFqd.rst b/Misc/NEWS.d/next/Library/2026-07-22-19-21-20.gh-issue-82535.METFqd.rst new file mode 100644 index 000000000000000..e027f81256b703e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-22-19-21-20.gh-issue-82535.METFqd.rst @@ -0,0 +1,3 @@ +:class:`logging.handlers.SysLogHandler` no longer fails +if the address cannot be resolved when the handler is created. +The address is resolved again when a record is emitted.