Skip to content

Commit 7b33127

Browse files
authored
[3.13] gh-141497: Make ipaddress.IP{v4,v6}Network.hosts() always returning an iterator (GH-141547) (GH-141695)
(cherry picked from commit 6b1bdf6) Co-authored-by: Krishna Chaitanya <141550576+XChaitanyaX@users.noreply.github.com>
1 parent d4e4924 commit 7b33127

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

Lib/ipaddress.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1559,7 +1559,7 @@ def __init__(self, address, strict=True):
15591559
if self._prefixlen == (self._max_prefixlen - 1):
15601560
self.hosts = self.__iter__
15611561
elif self._prefixlen == (self._max_prefixlen):
1562-
self.hosts = lambda: [IPv4Address(addr)]
1562+
self.hosts = lambda: iter((IPv4Address(addr),))
15631563

15641564
@property
15651565
@functools.lru_cache()
@@ -2359,7 +2359,7 @@ def __init__(self, address, strict=True):
23592359
if self._prefixlen == (self._max_prefixlen - 1):
23602360
self.hosts = self.__iter__
23612361
elif self._prefixlen == self._max_prefixlen:
2362-
self.hosts = lambda: [IPv6Address(addr)]
2362+
self.hosts = lambda: iter((IPv6Address(addr),))
23632363

23642364
def hosts(self):
23652365
"""Generate Iterator over usable hosts in a network.

Lib/test/test_ipaddress.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import pickle
1313
import ipaddress
1414
import weakref
15+
from collections.abc import Iterator
1516
from test.support import LARGEST, SMALLEST
1617

1718

@@ -1472,18 +1473,27 @@ def testGetSupernet4(self):
14721473
self.ipv6_scoped_network.supernet(new_prefix=62))
14731474

14741475
def testHosts(self):
1476+
hosts = self.ipv4_network.hosts()
1477+
self.assertIsInstance(hosts, Iterator)
1478+
self.assertEqual(ipaddress.IPv4Address('1.2.3.1'), next(hosts))
14751479
hosts = list(self.ipv4_network.hosts())
14761480
self.assertEqual(254, len(hosts))
14771481
self.assertEqual(ipaddress.IPv4Address('1.2.3.1'), hosts[0])
14781482
self.assertEqual(ipaddress.IPv4Address('1.2.3.254'), hosts[-1])
14791483

14801484
ipv6_network = ipaddress.IPv6Network('2001:658:22a:cafe::/120')
1485+
hosts = ipv6_network.hosts()
1486+
self.assertIsInstance(hosts, Iterator)
1487+
self.assertEqual(ipaddress.IPv6Address('2001:658:22a:cafe::1'), next(hosts))
14811488
hosts = list(ipv6_network.hosts())
14821489
self.assertEqual(255, len(hosts))
14831490
self.assertEqual(ipaddress.IPv6Address('2001:658:22a:cafe::1'), hosts[0])
14841491
self.assertEqual(ipaddress.IPv6Address('2001:658:22a:cafe::ff'), hosts[-1])
14851492

14861493
ipv6_scoped_network = ipaddress.IPv6Network('2001:658:22a:cafe::%scope/120')
1494+
hosts = ipv6_scoped_network.hosts()
1495+
self.assertIsInstance(hosts, Iterator)
1496+
self.assertEqual((ipaddress.IPv6Address('2001:658:22a:cafe::1')), next(hosts))
14871497
hosts = list(ipv6_scoped_network.hosts())
14881498
self.assertEqual(255, len(hosts))
14891499
self.assertEqual(ipaddress.IPv6Address('2001:658:22a:cafe::1'), hosts[0])
@@ -1494,6 +1504,12 @@ def testHosts(self):
14941504
ipaddress.IPv4Address('2.0.0.1')]
14951505
str_args = '2.0.0.0/31'
14961506
tpl_args = ('2.0.0.0', 31)
1507+
hosts = ipaddress.ip_network(str_args).hosts()
1508+
self.assertIsInstance(hosts, Iterator)
1509+
self.assertEqual(next(hosts), addrs[0])
1510+
hosts = ipaddress.ip_network(tpl_args).hosts()
1511+
self.assertIsInstance(hosts, Iterator)
1512+
self.assertEqual(next(hosts), addrs[0])
14971513
self.assertEqual(addrs, list(ipaddress.ip_network(str_args).hosts()))
14981514
self.assertEqual(addrs, list(ipaddress.ip_network(tpl_args).hosts()))
14991515
self.assertEqual(list(ipaddress.ip_network(str_args).hosts()),
@@ -1503,6 +1519,12 @@ def testHosts(self):
15031519
addrs = [ipaddress.IPv4Address('1.2.3.4')]
15041520
str_args = '1.2.3.4/32'
15051521
tpl_args = ('1.2.3.4', 32)
1522+
hosts = ipaddress.ip_network(str_args).hosts()
1523+
self.assertIsInstance(hosts, Iterator)
1524+
self.assertEqual(next(hosts), addrs[0])
1525+
hosts = ipaddress.ip_network(tpl_args).hosts()
1526+
self.assertIsInstance(hosts, Iterator)
1527+
self.assertEqual(next(hosts), addrs[0])
15061528
self.assertEqual(addrs, list(ipaddress.ip_network(str_args).hosts()))
15071529
self.assertEqual(addrs, list(ipaddress.ip_network(tpl_args).hosts()))
15081530
self.assertEqual(list(ipaddress.ip_network(str_args).hosts()),
@@ -1512,6 +1534,12 @@ def testHosts(self):
15121534
ipaddress.IPv6Address('2001:658:22a:cafe::1')]
15131535
str_args = '2001:658:22a:cafe::/127'
15141536
tpl_args = ('2001:658:22a:cafe::', 127)
1537+
hosts = ipaddress.ip_network(str_args).hosts()
1538+
self.assertIsInstance(hosts, Iterator)
1539+
self.assertEqual(next(hosts), addrs[0])
1540+
hosts = ipaddress.ip_network(tpl_args).hosts()
1541+
self.assertIsInstance(hosts, Iterator)
1542+
self.assertEqual(next(hosts), addrs[0])
15151543
self.assertEqual(addrs, list(ipaddress.ip_network(str_args).hosts()))
15161544
self.assertEqual(addrs, list(ipaddress.ip_network(tpl_args).hosts()))
15171545
self.assertEqual(list(ipaddress.ip_network(str_args).hosts()),
@@ -1520,6 +1548,12 @@ def testHosts(self):
15201548
addrs = [ipaddress.IPv6Address('2001:658:22a:cafe::1'), ]
15211549
str_args = '2001:658:22a:cafe::1/128'
15221550
tpl_args = ('2001:658:22a:cafe::1', 128)
1551+
hosts = ipaddress.ip_network(str_args).hosts()
1552+
self.assertIsInstance(hosts, Iterator)
1553+
self.assertEqual(next(hosts), addrs[0])
1554+
hosts = ipaddress.ip_network(tpl_args).hosts()
1555+
self.assertIsInstance(hosts, Iterator)
1556+
self.assertEqual(next(hosts), addrs[0])
15231557
self.assertEqual(addrs, list(ipaddress.ip_network(str_args).hosts()))
15241558
self.assertEqual(addrs, list(ipaddress.ip_network(tpl_args).hosts()))
15251559
self.assertEqual(list(ipaddress.ip_network(str_args).hosts()),
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
:mod:`ipaddress`: ensure that the methods
2+
:meth:`IPv4Network.hosts() <ipaddress.IPv4Network.hosts>` and
3+
:meth:`IPv6Network.hosts() <ipaddress.IPv6Network.hosts>` always return an
4+
iterator.

0 commit comments

Comments
 (0)