diff -r e281a57d5b29 Doc/library/socket.rst --- a/Doc/library/socket.rst Tue Apr 19 08:53:14 2016 +0200 +++ b/Doc/library/socket.rst Wed Apr 20 20:55:20 2016 +0200 @@ -46,7 +46,7 @@ - The address of an :const:`AF_UNIX` socket bound to a file system node is represented as a string, using the file system encoding and the ``'surrogateescape'`` error handler (see :pep:`383`). An address in - Linux's abstract namespace is returned as a :term:`bytes-like object` with + Linux's abstract namespace is also represented as a string with an initial null byte; note that sockets in this namespace can communicate with normal file system sockets, so programs intended to run on Linux may need to deal with both types of address. A string or diff -r e281a57d5b29 Lib/test/test_logging.py --- a/Lib/test/test_logging.py Tue Apr 19 08:53:14 2016 +0200 +++ b/Lib/test/test_logging.py Wed Apr 20 20:55:20 2016 +0200 @@ -1619,6 +1619,24 @@ SysLogHandlerTest.tearDown(self) os.remove(self.address) +@unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required") +@unittest.skipUnless(threading, 'Threading required for this test.') +@unittest.skipUnless(sys.platform == 'linux', 'Linux specific test') +class UnixSysLogAbstractNamespaceHandlerTest(SysLogHandlerTest): + + """Test for SysLogHandler with Unix sockets in the abstract namespace.""" + + if threading and hasattr(socket, "AF_UNIX"): + server_class = TestUnixDatagramServer + + def setUp(self): + # override the definition in the base class + self.address = '\x00python_logging_test' + SysLogHandlerTest.setUp(self) + + def tearDown(self): + SysLogHandlerTest.tearDown(self) + @unittest.skipUnless(threading, 'Threading required for this test.') class HTTPHandlerTest(BaseTest): """Test for HTTPHandler.""" @@ -4187,7 +4205,7 @@ ExceptionTest, SysLogHandlerTest, HTTPHandlerTest, NTEventLogHandlerTest, TimedRotatingFileHandlerTest, UnixSocketHandlerTest, UnixDatagramHandlerTest, UnixSysLogHandlerTest, - MiscTestCase) + UnixSysLogAbstractNamespaceHandlerTest, MiscTestCase) if __name__ == "__main__": test_main() diff -r e281a57d5b29 Lib/test/test_socket.py --- a/Lib/test/test_socket.py Tue Apr 19 08:53:14 2016 +0200 +++ b/Lib/test/test_socket.py Wed Apr 20 20:55:20 2016 +0200 @@ -4512,7 +4512,7 @@ UNIX_PATH_MAX = 108 def testLinuxAbstractNamespace(self): - address = b"\x00python-test-hello\x00\xff" + address = "\x00python-test-hello\x00\xff" with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s1: s1.bind(address) s1.listen() @@ -4523,7 +4523,7 @@ self.assertEqual(s2.getpeername(), address) def testMaxName(self): - address = b"\x00" + b"h" * (self.UNIX_PATH_MAX - 1) + address = "\x00" + "h" * (self.UNIX_PATH_MAX - 1) with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s: s.bind(address) self.assertEqual(s.getsockname(), address) @@ -4538,7 +4538,16 @@ s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) try: s.bind("\x00python\x00test\x00") - self.assertEqual(s.getsockname(), b"\x00python\x00test\x00") + self.assertEqual(s.getsockname(), "\x00python\x00test\x00") + finally: + s.close() + + def testBytesName(self): + # Check that an abstract name can be passed as a bytes instance. + s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + try: + s.bind(b"\x00python\x00test\x00") + self.assertEqual(s.getsockname(), "\x00python\x00test\x00") finally: s.close() @@ -4546,7 +4555,7 @@ # Check that an abstract name can be passed as a bytearray. with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s: s.bind(bytearray(b"\x00python\x00test\x00")) - self.assertEqual(s.getsockname(), b"\x00python\x00test\x00") + self.assertEqual(s.getsockname(), "\x00python\x00test\x00") @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'test needs socket.AF_UNIX') class TestUnixDomain(unittest.TestCase): diff -r e281a57d5b29 Misc/NEWS --- a/Misc/NEWS Tue Apr 19 08:53:14 2016 +0200 +++ b/Misc/NEWS Wed Apr 20 20:55:20 2016 +0200 @@ -245,6 +245,11 @@ Library ------- +- Issue #26803: An AF_UNIX socket address in Linux’s abstract namespace is no + longer returned as a bytes object but as a string using the file system + encoding and the 'surrogateescape' error handler, same as a plain AF_UNIX + address. + - Issue #24838: tarfile's ustar and gnu formats now correctly calculate name and link field limits for multibyte character encodings like utf-8. diff -r e281a57d5b29 Modules/socketmodule.c --- a/Modules/socketmodule.c Tue Apr 19 08:53:14 2016 +0200 +++ b/Modules/socketmodule.c Wed Apr 20 20:55:20 2016 +0200 @@ -1183,7 +1183,7 @@ #ifdef linux if (a->sun_path[0] == 0) { /* Linux abstract namespace */ addrlen -= offsetof(struct sockaddr_un, sun_path); - return PyBytes_FromStringAndSize(a->sun_path, addrlen); + return PyUnicode_DecodeFSDefaultAndSize(a->sun_path, addrlen); } else #endif /* linux */