diff -r fae92299eb68 Doc/library/socket.rst --- a/Doc/library/socket.rst Sat Jan 25 13:27:53 2014 -0500 +++ b/Doc/library/socket.rst Sun Jan 26 13:45:42 2014 -0800 @@ -186,20 +186,25 @@ Exceptions :func:`~socket.setdefaulttimeout`). The accompanying value is a string whose value is currently always "timed out". .. versionchanged:: 3.3 This class was made a subclass of :exc:`OSError`. Constants ^^^^^^^^^ + The AF_* and SOCK_* constants are now integer enumerations (:class:`IntEnum`) + of :class:`AddressFamily` and :class:`SocketKind`. + + .. versionadded:: 3.4 + .. data:: AF_UNIX AF_INET AF_INET6 These constants represent the address (and protocol) families, used for the first argument to :func:`.socket`. If the :const:`AF_UNIX` constant is not defined then this protocol is unsupported. More constants may be available depending on the system. diff -r fae92299eb68 Lib/socket.py --- a/Lib/socket.py Sat Jan 25 13:27:53 2014 -0500 +++ b/Lib/socket.py Sun Jan 26 13:45:42 2014 -0800 @@ -64,24 +64,24 @@ EWOULDBLOCK = getattr(errno, 'EWOULDBLOC # Set up the socket.AF_* socket.SOCK_* constants as members of IntEnums for # nicer string representations. # Note that _socket only knows about the integer values. The public interface # in this module understands the enums and translates them back from integers # where needed (e.g. .family property of a socket object). AddressFamily = IntEnum('AddressFamily', {name: value for name, value in globals().items() if name.isupper() and name.startswith('AF_')}) globals().update(AddressFamily.__members__) -SocketType = IntEnum('SocketType', +SocketKind = IntEnum('SocketKind', {name: value for name, value in globals().items() if name.isupper() and name.startswith('SOCK_')}) -globals().update(SocketType.__members__) +globals().update(SocketKind.__members__) def _intenum_converter(value, enum_klass): """Convert a numeric family value to an IntEnum member. If it's not a known member, return the numeric value itself. """ try: return enum_klass(value) except ValueError: return value @@ -262,21 +262,21 @@ class socket(_socket.socket): @property def family(self): """Read-only access to the address family for this socket. """ return _intenum_converter(super().family, AddressFamily) @property def type(self): """Read-only access to the socket type. """ - return _intenum_converter(super().type, SocketType) + return _intenum_converter(super().type, SocketKind) if os.name == 'nt': def get_inheritable(self): return os.get_handle_inheritable(self.fileno()) def set_inheritable(self, inheritable): os.set_handle_inheritable(self.fileno(), inheritable) else: def get_inheritable(self): return os.get_inheritable(self.fileno()) def set_inheritable(self, inheritable): @@ -523,13 +523,13 @@ def getaddrinfo(host, port, family=0, ty The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] for res in _socket.getaddrinfo(host, port, family, type, proto, flags): af, socktype, proto, canonname, sa = res addrlist.append((_intenum_converter(af, AddressFamily), - _intenum_converter(socktype, SocketType), + _intenum_converter(socktype, SocketKind), proto, canonname, sa)) return addrlist diff -r fae92299eb68 Lib/test/test_socket.py --- a/Lib/test/test_socket.py Sat Jan 25 13:27:53 2014 -0500 +++ b/Lib/test/test_socket.py Sun Jan 26 13:45:42 2014 -0800 @@ -637,20 +637,27 @@ def requireSocket(*args): err is not None, "can't create socket({0}): {1}".format( ", ".join(str(o) for o in args), err)) ####################################################################### ## Begin Tests class GeneralModuleTests(unittest.TestCase): + def test_SocketType_is_socketobject(self): + import _socket + self.assertTrue(socket.SocketType is _socket.socket) + s = socket.socket() + self.assertIsInstance(s, socket.SocketType) + s.close() + def test_repr(self): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) with s: 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)) @@ -1192,21 +1199,21 @@ class GeneralModuleTests(unittest.TestCa # port number or None socket.getaddrinfo(HOST, "http") socket.getaddrinfo(HOST, 80) socket.getaddrinfo(HOST, None) # test family and socktype filters infos = socket.getaddrinfo(HOST, 80, socket.AF_INET, socket.SOCK_STREAM) for family, type, _, _, _ in infos: self.assertEqual(family, socket.AF_INET) self.assertEqual(str(family), 'AddressFamily.AF_INET') self.assertEqual(type, socket.SOCK_STREAM) - self.assertEqual(str(type), 'SocketType.SOCK_STREAM') + self.assertEqual(str(type), 'SocketKind.SOCK_STREAM') infos = socket.getaddrinfo(HOST, None, 0, socket.SOCK_STREAM) for _, socktype, _, _, _ in infos: self.assertEqual(socktype, socket.SOCK_STREAM) # test proto and flags arguments socket.getaddrinfo(HOST, None, 0, 0, socket.SOL_TCP) socket.getaddrinfo(HOST, None, 0, 0, 0, socket.AI_PASSIVE) # a server willing to support both IPv4 and IPv6 will # usually do this socket.getaddrinfo(None, 0, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE) @@ -1355,21 +1362,21 @@ class GeneralModuleTests(unittest.TestCa self.assertRaises(OverflowError, socket.getnameinfo, (support.HOSTv6, 0, 0xffffffff), 0) with socket.socket(socket.AF_INET6, socket.SOCK_STREAM) as s: self.assertRaises(OverflowError, s.bind, (support.HOSTv6, 0, -10)) def test_str_for_enums(self): # Make sure that the AF_* and SOCK_* constants have enum-like string # reprs. with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: self.assertEqual(str(s.family), 'AddressFamily.AF_INET') - self.assertEqual(str(s.type), 'SocketType.SOCK_STREAM') + self.assertEqual(str(s.type), 'SocketKind.SOCK_STREAM') @unittest.skipIf(os.name == 'nt', 'Will not work on Windows') def test_uknown_socket_family_repr(self): # Test that when created with a family that's not one of the known # AF_*/SOCK_* constants, socket.family just returns the number. # # To do this we fool socket.socket into believing it already has an # open fd because on this path it doesn't actually verify the family and # type and populates the socket object. #