<div dir="ltr"><div><div><div>Folks-<br><br></div>  The ipaddress library returns an IP address object which can represent itself in a number of ways:<br><br><span style="font-family:monospace"><br>In [1]: import ipaddress<br><br>In [2]: v4 = ipaddress.IPv4Address('1.2.3.4')<br><br>In [3]: print(v4)<br>1.2.3.4<br><br>In [4]: v4<br>Out[4]: IPv4Address('1.2.3.4')<br><br>In [6]: v4.packed<br>Out[6]: b'\x01\x02\x03\x04'<br><br>In [9]: str(v4)<br>Out[9]: '1.2.3.4'<br><br>In [10]: int(v4)<br>Out[10]: 16909060<br><br>In [13]: bin(int(v4))<br>Out[13]: '0b1000000100000001100000100'<br><br>In [14]: hex(int(v4))<br>Out[14]: '0x1020304'<br><br>In [15]: oct(int(v4))<br>Out[15]: '0o100401404'<br></span><br></div>There are IPv6 objects as well:<br><br><span style="font-family:monospace">In [6]: v6 = ipaddress.IPv6Address('2001:0db8:85a3:0000:0000:8a2e:0370:7334')<br><br>In [7]: int(v6)<br>Out[7]: 42540766452641154071740215577757643572</span><br><br></div>and what I'm proposing will work for both address families.<br><div><div><div>In either case, bin/hex/oct don't work on them directly, but on the integer representation.  This is a little annoying but not such a big deal.  What is a big deal (at least to me) is that the binary representation isn't zero-padded.  This makes it harder to compare two IP addresses by eye to see what the differences are, i.e.:<br><br><span style="font-family:monospace">In [16]: a = ipaddress.IPv4Address('0.2.3.4')<br>In [30]: bin(int(a))<br>Out[30]: '0b100000001100000100'<br><br>In [31]: bin(int(v4))<br>Out[31]: '0b1000000100000001100000100'</span><br><br>  It would be nice if there was a way to have an IP address always present itself in fully zero-padded binary (32 bits for IPv4, 128 bits for IPv6).  I find this particularly convenient when putting together  training material, as it's easier to show subnetting and aggregation if you point at the binary than if you give people dotted-quad addresses and ask them to do the binary conversion in their head.  Hex is also handy when you're comparing a dotted-quad IP address to a hex sniffer trace.  It's possible to do this in a one-liner (thanks to Eric Smith): <span style="font-family:monospace">f'{int(v4):#0{34}b}'.  <font face="sans-serif">But this is a little cryptic.</font></span><span style="font-family:monospace"></span><br><div class="inbox-inbox-fX"><br></div></div><div>  I opened bpo-32820 (<a href="https://github.com/python/cpython/pull/5627">https://github.com/python/cpython/pull/5627</a>) to contribute a way to do this.  I started with an __index__ method but Issue 15559 (<a href="https://github.com/python/cpython/commit/e0c3f5edc0f20cc28363258df501758c1bdb1ca7">https://github.com/python/cpython/commit/e0c3f5edc0f20cc28363258df501758c1bdb1ca7</a>) rules this out.  I instead added a bits() class method so that v4.bits would return the fully padded string.  This was not terribly pretty, but it mirrored packed(), at least.<br><br>  Nick Coghlan suggested I instead extend __format__, which is what the diffs in the current pull request do.  This allows a great deal more flexibility: the current code takes 'b', 'n', or 'x' types, as well as the '#' option and support for the '_' separator.  I realize now I didn't add 'o' but I certainly can for completeness.  I debated adding rfc1924 encoding for IPv6 addresses but decided it was entirely too silly.<br><br></div><div>  This is just a convenience function, but IMO fills a need.  Is this worth pursuing? <br><br><br><br><br><br></div><div>eric<br><br></div><div><h1 class="inbox-inbox-gh-header-title"><span class="inbox-inbox-js-issue-title"><br></span></h1>

</div></div></div></div>