Skip to content

Commit f6c99ee

Browse files
committed
Added .shorthand property to IPv4Network and IPv6Network in the ipaddress module
1 parent b70a567 commit f6c99ee

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

Lib/ipaddress.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,6 +1547,30 @@ def __init__(self, address, strict=True):
15471547
elif self._prefixlen == (self.max_prefixlen):
15481548
self.hosts = lambda: [IPv4Address(addr)]
15491549

1550+
@property
1551+
def shorthand(self):
1552+
"""
1553+
Returns the shorthand representation of the IPv4 network.
1554+
1555+
This method abbreviates the IPv4 network by removing trailing
1556+
zero octets from the network address.
1557+
1558+
Returns:
1559+
str: The shorthand IPv4 network in the format 'X.X/X'.
1560+
1561+
Example:
1562+
>>> network = IPv4Network('192.168.0.0/24')
1563+
>>> network.shorthand
1564+
'192.168/24'
1565+
"""
1566+
# Split the network address into octets
1567+
octets = str(self.network_address).split('.')
1568+
# Remove trailing zero octets
1569+
while octets and octets[-1] == '0':
1570+
octets.pop()
1571+
# Rejoin the remaining octets and append the prefix length
1572+
return '.'.join(octets) + f"/{self.prefixlen}"
1573+
15501574
@property
15511575
@functools.lru_cache()
15521576
def is_global(self):
@@ -2341,6 +2365,24 @@ def hosts(self):
23412365
for x in range(network + 1, broadcast + 1):
23422366
yield self._address_class(x)
23432367

2368+
@property
2369+
def shorthand(self):
2370+
"""
2371+
Returns the shorthand representation of the IPv6 network.
2372+
2373+
This method compresses the IPv6 address to its shortest form
2374+
and appends the prefix length.
2375+
2376+
Returns:
2377+
str: The shorthand IPv6 network in the format 'X::/Y'.
2378+
2379+
Example:
2380+
>>> network = IPv6Network('2001:db8:0:0:0:0:0:0/32')
2381+
>>> network.shorthand
2382+
'2001:db8::/32'
2383+
"""
2384+
return f"{self.network_address.compressed}/{self.prefixlen}"
2385+
23442386
@property
23452387
def is_site_local(self):
23462388
"""Test if the address is reserved for site-local.

Lib/test/test_ipaddress.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,12 @@ def test_subnet_of_mixed_types(self):
709709
ipaddress.IPv6Network('::1/128').subnet_of(
710710
ipaddress.IPv4Network('10.0.0.0/30'))
711711

712+
def test_shorthand_ipv4(self):
713+
self.assertEqual(ipaddress.IPv4Network("1.2.0.0/16").shorthand, "1.2/16")
714+
self.assertEqual(ipaddress.IPv4Network("10.0.0.0/8").shorthand, "10/8")
715+
self.assertEqual(ipaddress.IPv4Network("192.168.0.0/24").shorthand, "192.168/24")
716+
self.assertEqual(ipaddress.IPv4Network("0.0.0.0/0").shorthand, "/0")
717+
712718

713719
class NetmaskTestMixin_v6(CommonTestMixin_v6):
714720
"""Input validation on interfaces and networks is very similar"""
@@ -865,6 +871,13 @@ def test_supernet_of(self):
865871
self.factory('2000:aaa::/48').supernet_of(
866872
self.factory('2000:aaa::/56')))
867873

874+
def test_shorthand_ipv6(self):
875+
self.assertEqual(ipaddress.IPv6Network("2001:db8:0:0:0:0:0:0/32").shorthand, "2001:db8::/32")
876+
self.assertEqual(ipaddress.IPv6Network("::/0").shorthand, "::/0")
877+
self.assertEqual(ipaddress.IPv6Network("0:0:0:0:0:0:0:0/0").shorthand, "::/0")
878+
self.assertEqual(ipaddress.IPv6Network("2001:db8:0:0:0:0:0:1/128").shorthand, "2001:db8::1/128")
879+
self.assertEqual(ipaddress.IPv6Network("::1/128").shorthand, "::1/128")
880+
868881

869882
class FactoryFunctionErrors(BaseTestCase):
870883

0 commit comments

Comments
 (0)