diff -r 04c916a1e82f Lib/socket.py --- a/Lib/socket.py Sat Jul 26 14:52:55 2014 +0200 +++ b/Lib/socket.py Sat Jul 26 15:02:17 2014 +0200 @@ -189,6 +189,39 @@ class _socketobject(object): for method in _delegate_methods: setattr(self, method, getattr(_sock, method)) + def __repr__(self): + """Wrap __repr__() to reveal the real class name and socket + address(es). + """ + closed = isinstance(self._sock, _closedsocket) + if not closed: + s = "<%s.%s fd=%i, family=%s, type=%s, proto=%i" \ + % (self.__class__.__module__, + self.__class__.__name__, + self.fileno(), + self.family, + self.type, + self.proto) + try: + laddr = self.getsockname() + if laddr: + s += ", laddr=%s" % str(laddr) + except error: + pass + try: + raddr = self.getpeername() + if raddr: + s += ", raddr=%s" % str(raddr) + except error: + pass + s += '>' + else: + fd = -1 + s = "<%s.%s[closed]>" \ + % (self.__class__.__module__, + self.__class__.__name__) + return s + def close(self, _closedsocket=_closedsocket, _delegate_methods=_delegate_methods, setattr=setattr): # This function should not reference any globals. See issue #808164. diff -r 04c916a1e82f Lib/test/test_socket.py --- a/Lib/test/test_socket.py Sat Jul 26 14:52:55 2014 +0200 +++ b/Lib/test/test_socket.py Sat Jul 26 15:02:17 2014 +0200 @@ -249,6 +249,21 @@ class SocketPairTest(unittest.TestCase, class GeneralModuleTests(unittest.TestCase): + def test_repr(self): + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + try: + self.assertIn('fd=%i' % s.fileno(), repr(s)) + self.assertIn('family=%s' % socket.AF_INET, repr(s)) + self.assertIn('type=%s' % socket.SOCK_STREAM, repr(s)) + self.assertIn('proto=0', repr(s)) + self.assertNotIn('raddr', repr(s)) + s.bind(('127.0.0.1', 0)) + self.assertIn('laddr', repr(s)) + self.assertIn(str(s.getsockname()), repr(s)) + finally: + s.close() + self.assertEqual(repr(s), '') + @unittest.skipUnless(_socket is not None, 'need _socket module') def test_csocket_repr(self): s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM)