1212
1313
1414import functools
15+ import warnings
1516
1617IPV4LENGTH = 32
1718IPV6LENGTH = 128
@@ -295,7 +296,7 @@ def _collapse_addresses_internal(addresses):
295296 if last is not None :
296297 # Since they are sorted, last.network_address <= net.network_address
297298 # is a given.
298- if last .broadcast_address >= net .broadcast_address :
299+ if last .last_address >= net .last_address :
299300 continue
300301 yield net
301302 last = net
@@ -685,28 +686,28 @@ def hosts(self):
685686
686687 """
687688 network = int (self .network_address )
688- broadcast = int (self .broadcast_address )
689- for x in range (network + 1 , broadcast ):
689+ last = int (self .last_address )
690+ for x in range (network + 1 , last ):
690691 yield self ._address_class (x )
691692
692693 def __iter__ (self ):
693694 network = int (self .network_address )
694- broadcast = int (self .broadcast_address )
695- for x in range (network , broadcast + 1 ):
695+ last = int (self .last_address )
696+ for x in range (network , last + 1 ):
696697 yield self ._address_class (x )
697698
698699 def __getitem__ (self , n ):
699700 network = int (self .network_address )
700- broadcast = int (self .broadcast_address )
701+ last = int (self .last_address )
701702 if n >= 0 :
702- if network + n > broadcast :
703+ if network + n > last :
703704 raise IndexError ('address out of range' )
704705 return self ._address_class (network + n )
705706 else :
706707 n += 1
707- if broadcast + n < network :
708+ if last + n < network :
708709 raise IndexError ('address out of range' )
709- return self ._address_class (broadcast + n )
710+ return self ._address_class (last + n )
710711
711712 def __lt__ (self , other ):
712713 if not isinstance (other , _BaseNetwork ):
@@ -746,14 +747,9 @@ def __contains__(self, other):
746747 def overlaps (self , other ):
747748 """Tell if self is partly contained in other."""
748749 return self .network_address in other or (
749- self .broadcast_address in other or (
750+ self .last_address in other or (
750751 other .network_address in self or (
751- other .broadcast_address in self )))
752-
753- @functools .cached_property
754- def broadcast_address (self ):
755- return self ._address_class (int (self .network_address ) |
756- int (self .hostmask ))
752+ other .last_address in self )))
757753
758754 @functools .cached_property
759755 def hostmask (self ):
@@ -774,7 +770,7 @@ def with_hostmask(self):
774770 @property
775771 def num_addresses (self ):
776772 """Number of hosts in the current subnet."""
777- return int (self .broadcast_address ) - int (self .network_address ) + 1
773+ return int (self .last_address ) - int (self .network_address ) + 1
778774
779775 @property
780776 def _address_class (self ):
@@ -968,7 +964,7 @@ def subnets(self, prefixlen_diff=1, new_prefix=None):
968964 new_prefixlen , self ))
969965
970966 start = int (self .network_address )
971- end = int (self .broadcast_address ) + 1
967+ end = int (self .last_address ) + 1
972968 step = (int (self .hostmask ) + 1 ) >> prefixlen_diff
973969 for new_addr in range (start , end , step ):
974970 current = self .__class__ ((new_addr , new_prefixlen ))
@@ -1025,7 +1021,7 @@ def is_multicast(self):
10251021
10261022 """
10271023 return (self .network_address .is_multicast and
1028- self .broadcast_address .is_multicast )
1024+ self .last_address .is_multicast )
10291025
10301026 @staticmethod
10311027 def _is_subnet_of (a , b ):
@@ -1034,7 +1030,7 @@ def _is_subnet_of(a, b):
10341030 if a .version != b .version :
10351031 raise TypeError (f"{ a } and { b } are not of the same version" )
10361032 return (b .network_address <= a .network_address and
1037- b .broadcast_address >= a .broadcast_address )
1033+ b .last_address >= a .last_address )
10381034 except AttributeError :
10391035 raise TypeError (f"Unable to test subnet containment "
10401036 f"between { a } and { b } " )
@@ -1057,7 +1053,7 @@ def is_reserved(self):
10571053
10581054 """
10591055 return (self .network_address .is_reserved and
1060- self .broadcast_address .is_reserved )
1056+ self .last_address .is_reserved )
10611057
10621058 @property
10631059 def is_link_local (self ):
@@ -1068,7 +1064,7 @@ def is_link_local(self):
10681064
10691065 """
10701066 return (self .network_address .is_link_local and
1071- self .broadcast_address .is_link_local )
1067+ self .last_address .is_link_local )
10721068
10731069 @property
10741070 def is_private (self ):
@@ -1080,10 +1076,10 @@ def is_private(self):
10801076
10811077 """
10821078 return any (self .network_address in priv_network and
1083- self .broadcast_address in priv_network
1079+ self .last_address in priv_network
10841080 for priv_network in self ._constants ._private_networks ) and all (
10851081 self .network_address not in network and
1086- self .broadcast_address not in network
1082+ self .last_address not in network
10871083 for network in self ._constants ._private_networks_exceptions
10881084 )
10891085
@@ -1108,7 +1104,7 @@ def is_unspecified(self):
11081104
11091105 """
11101106 return (self .network_address .is_unspecified and
1111- self .broadcast_address .is_unspecified )
1107+ self .last_address .is_unspecified )
11121108
11131109 @property
11141110 def is_loopback (self ):
@@ -1120,7 +1116,7 @@ def is_loopback(self):
11201116
11211117 """
11221118 return (self .network_address .is_loopback and
1123- self .broadcast_address .is_loopback )
1119+ self .last_address .is_loopback )
11241120
11251121
11261122class _BaseConstants :
@@ -1561,6 +1557,15 @@ def is_global(self):
15611557 self .broadcast_address in IPv4Network ('100.64.0.0/10' )) and
15621558 not self .is_private )
15631559
1560+ @functools .cached_property
1561+ def last_address (self ):
1562+ return self ._address_class (int (self .network_address ) |
1563+ int (self .hostmask ))
1564+
1565+ @functools .cached_property
1566+ def broadcast_address (self ):
1567+ return self .last_address
1568+
15641569
15651570class _IPv4Constants :
15661571 _linklocal_network = IPv4Network ('169.254.0.0/16' )
@@ -2272,7 +2277,7 @@ class IPv6Network(_BaseV6, _BaseNetwork):
22722277 Attributes: [examples for IPv6('2001:db8::1000/124')]
22732278 .network_address: IPv6Address('2001:db8::1000')
22742279 .hostmask: IPv6Address('::f')
2275- .broadcast_address : IPv6Address('2001:db8::100f')
2280+ .last_address : IPv6Address('2001:db8::100f')
22762281 .netmask: IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0')
22772282 .prefixlen: 124
22782283
@@ -2337,8 +2342,8 @@ def hosts(self):
23372342
23382343 """
23392344 network = int (self .network_address )
2340- broadcast = int (self .broadcast_address )
2341- for x in range (network + 1 , broadcast + 1 ):
2345+ last = int (self .last_address )
2346+ for x in range (network + 1 , last + 1 ):
23422347 yield self ._address_class (x )
23432348
23442349 @property
@@ -2354,7 +2359,18 @@ def is_site_local(self):
23542359
23552360 """
23562361 return (self .network_address .is_site_local and
2357- self .broadcast_address .is_site_local )
2362+ self .last_address .is_site_local )
2363+
2364+ @property
2365+ def last_address (self ):
2366+ """The last address in the network, the address with all the host bits set."""
2367+ return self ._address_class (int (self .network_address ) |
2368+ int (self .hostmask ))
2369+
2370+ @property
2371+ @warnings .deprecated ("IPv6 has no broadcast addresses, use last_address instead for the address with all the host bits set." )
2372+ def broadcast_address (self ):
2373+ return self .last_address
23582374
23592375
23602376class _IPv6Constants :
0 commit comments