https://github.com/python/cpython/commit/46acb79cd47211192bd52cd994715162d2b6dcf8
commit: 46acb79cd47211192bd52cd994715162d2b6dcf8
branch: main
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-07-24T19:54:01+03:00
summary:

gh-70990: Support bytes addresses of Unix sockets in SysLogHandler (GH-154500)

Only a str address was recognized as a Unix domain socket.  A bytes
address, which socket.bind() accepts, fell through to the (host, port)
branch and raised ValueError.

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>

files:
A Misc/NEWS.d/next/Library/2026-07-22-17-35-24.gh-issue-70990.xVHKwt.rst
M Doc/library/logging.handlers.rst
M Lib/logging/handlers.py
M Lib/test/test_logging.py

diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst
index 5152c7561fa1f2..7230224b4fc532 100644
--- a/Doc/library/logging.handlers.rst
+++ b/Doc/library/logging.handlers.rst
@@ -631,7 +631,8 @@ supports sending logging messages to a remote or local Unix 
syslog.
    the form of a ``(host, port)`` tuple.  If *address* is not specified,
    ``('localhost', 514)`` is used.  The address is used to open a socket.  An
    alternative to providing a ``(host, port)`` tuple is providing an address 
as a
-   string, for example '/dev/log'. In this case, a Unix domain socket is used 
to
+   string or a :class:`bytes` object, for example '/dev/log'.
+   In this case, a Unix domain socket is used to
    send the message to the syslog. If *facility* is not specified,
    :const:`LOG_USER` is used. The type of socket opened depends on the
    *socktype* argument, which defaults to :const:`socket.SOCK_DGRAM` and thus
@@ -664,6 +665,9 @@ supports sending logging messages to a remote or local Unix 
syslog.
    .. versionchanged:: 3.14
       *timeout* was added.
 
+   .. versionchanged:: next
+      *address* can now be a :class:`bytes` object.
+
    .. method:: close()
 
       Closes the socket to the remote host.
diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py
index a5394d2dbea649..c78a30763d9fa0 100644
--- a/Lib/logging/handlers.py
+++ b/Lib/logging/handlers.py
@@ -886,8 +886,9 @@ def __init__(self, address=('localhost', SYSLOG_UDP_PORT),
         """
         Initialize a handler.
 
-        If address is specified as a string, a UNIX socket is used. To log to a
-        local syslogd, "SysLogHandler(address="/dev/log")" can be used.
+        If address is specified as a string or bytes, a UNIX socket is used.
+        To log to a local syslogd, "SysLogHandler(address="/dev/log")" can be
+        used.
         If facility is not specified, LOG_USER is used. If socktype is
         specified as socket.SOCK_DGRAM or socket.SOCK_STREAM, that specific
         socket type will be used. For Unix sockets, you can also specify a
@@ -938,7 +939,7 @@ def createSocket(self):
         address = self.address
         socktype = self.socktype
 
-        if isinstance(address, str):
+        if not isinstance(address, (list, tuple)):
             self.unixsocket = True
             # Syslog server may be unavailable during handler initialisation.
             # C's openlog() function also ignores connection errors.
diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py
index 3a26454d0b7ed8..ccc7cce86883c8 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -2138,6 +2138,45 @@ def setUp(self):
         self.addCleanup(os_helper.unlink, self.address)
         SysLogHandlerTest.setUp(self)
 
+    def test_bytes_address(self):
+        # The Unix socket address can also be specified as bytes.
+        if self.server_exception:
+            self.skipTest(self.server_exception)
+        hdlr = logging.handlers.SysLogHandler(os.fsencode(self.address))
+        self.addCleanup(hdlr.close)
+        self.assertTrue(hdlr.unixsocket)
+        logger = logging.getLogger("slh-bytes")
+        logger.addHandler(hdlr)
+        self.addCleanup(logger.removeHandler, hdlr)
+        logger.error("sp\xe4m")
+        self.handled.wait(support.LONG_TIMEOUT)
+        self.assertEqual(self.log_output, b'<11>sp\xc3\xa4m\x00')
+
[email protected](sys.platform in ('linux', 'android'),
+                     'Linux specific test')
+class AbstractNamespaceSysLogHandlerTest(BaseTest):
+
+    """Test for SysLogHandler with a socket in the abstract namespace."""
+
+    def check(self, address):
+        sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
+        self.addCleanup(sock.close)
+        sock.bind(address)
+        sock.settimeout(support.LONG_TIMEOUT)
+        hdlr = logging.handlers.SysLogHandler(address)
+        self.addCleanup(hdlr.close)
+        self.assertTrue(hdlr.unixsocket)
+        hdlr.emit(logging.makeLogRecord({'msg': 'sp\xe4m'}))
+        self.assertEqual(sock.recv(1024), b'<12>sp\xc3\xa4m\x00')
+
+    def test_str_address(self):
+        # A str address is encoded with the filesystem encoding.
+        self.check('\0' + os_helper.TESTFN)
+
+    def test_bytes_address(self):
+        # The name is an arbitrary byte sequence, it need not be decodable.
+        self.check(b'\0test_logging_%d_\xff\xfe' % os.getpid())
+
 @unittest.skipUnless(socket_helper.IPV6_ENABLED,
                      'IPv6 support required for this test.')
 class IPv6SysLogHandlerTest(SysLogHandlerTest):
diff --git 
a/Misc/NEWS.d/next/Library/2026-07-22-17-35-24.gh-issue-70990.xVHKwt.rst 
b/Misc/NEWS.d/next/Library/2026-07-22-17-35-24.gh-issue-70990.xVHKwt.rst
new file mode 100644
index 00000000000000..4af22f88ddc413
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-07-22-17-35-24.gh-issue-70990.xVHKwt.rst
@@ -0,0 +1,4 @@
+:class:`logging.handlers.SysLogHandler` now accepts a :class:`bytes` address
+of a Unix domain socket, including an address in the abstract namespace.
+Previously only :class:`str` was recognized,
+and a :class:`bytes` address raised :exc:`ValueError`.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to