]> granicus.if.org Git - python/commitdiff
Fix issue #17675: make socket repr() provide local and remote addresses (if any).
authorGiampaolo Rodola' <g.rodola@gmail.com>
Wed, 10 Apr 2013 13:49:47 +0000 (15:49 +0200)
committerGiampaolo Rodola' <g.rodola@gmail.com>
Wed, 10 Apr 2013 13:49:47 +0000 (15:49 +0200)
Lib/socket.py
Lib/test/test_socket.py
Misc/NEWS

index da0c39a8aef3f956206170ac24ff585335090677..96f8ed0c7f7a4d4457881ea0df2407b1c29b24f0 100644 (file)
@@ -103,13 +103,32 @@ class socket(_socket.socket):
             self.close()
 
     def __repr__(self):
-        """Wrap __repr__() to reveal the real class name."""
-        s = _socket.socket.__repr__(self)
-        if s.startswith("<socket object"):
-            s = "<%s.%s%s%s" % (self.__class__.__module__,
-                                self.__class__.__name__,
-                                getattr(self, '_closed', False) and " [closed] " or "",
-                                s[7:])
+        """Wrap __repr__() to reveal the real class name and socket
+        address(es).
+        """
+        closed = getattr(self, '_closed', False)
+        s = "<%s.%s%s fd=%i, family=%i, type=%i, proto=%i" \
+            % (self.__class__.__module__,
+               self.__class__.__name__,
+               " [closed]" if closed else "",
+               self.fileno(),
+               self.family,
+               self.type,
+               self.proto)
+        if not closed:
+            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 += '>'
         return s
 
     def __getstate__(self):
index ec76671025281f76b8823c4cc86b9a430fc8e0de..9b6d18448a1ea679634a2ea99c6774ca6fad6a6b 100644 (file)
@@ -652,8 +652,17 @@ class GeneralModuleTests(unittest.TestCase):
 
     def test_repr(self):
         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        self.addCleanup(s.close)
-        self.assertTrue(repr(s).startswith("<socket.socket object"))
+        with s:
+            self.assertIn('fd=%i' % s.fileno(), repr(s))
+            self.assertIn('family=%i' % socket.AF_INET, repr(s))
+            self.assertIn('type=%i' % socket.SOCK_STREAM, repr(s))
+            self.assertIn('proto=0', repr(s))
+            self.assertIn('laddr', repr(s))
+            self.assertNotIn('raddr', repr(s))
+            s.bind(('127.0.0.1', 0))
+            self.assertIn(str(s.getsockname()), repr(s))
+        self.assertIn('[closed]', repr(s))
+        self.assertNotIn('laddr', repr(s))
 
     def test_weakref(self):
         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
index 38f6cde61987c34572a6fe7c37ee0ea7c9a19873..ff0226a84478bf22bc10fdf8f573784bfa0b870a 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -32,6 +32,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #17675: socket repr() provides local and remote addresses (if any).
+  Patch by Giampaolo Rodola'
+
 - Issue #17093: Make the ABCs in importlib.abc provide default values or raise
   reasonable exceptions for their methods to make them more amenable to super()
   calls.