This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author ewosborne
Recipients christian.heimes, eric.smith, ewosborne, ncoghlan, serhiy.storchaka
Date 2018-02-13.13:38:37
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <CA+97oKOUZ56H+5swEmbEpGcuf0=Mc4EO9ZadAo9O51pEDeAGOQ@mail.gmail.com>
In-reply-to <1518488105.02.0.467229070634.issue32820@psf.upfronthosting.co.za>
Content
This is an interesting idea.  I hacked together something to handle IPv4
and pushed it to the repository.  It works, but I'm afraid it may be kinda
ugly.  Do you have any examples of good, pythonic ways to parse the format
string or otherwise extend __format__?  I didn't see many examples in
stdlib, and the ones I did got pretty deep into it pretty quick.

Test output:

IPv4 address 1.2.3.4
format: b
00000001000000100000001100000100

format: n
00000001000000100000001100000100

format: x
01020304

format: _b
0000_0001_0000_0010_0000_0011_0000_0100

format: _n
0000_0001_0000_0010_0000_0011_0000_0100

format: _x
0102_0304

format: #b
0b00000001000000100000001100000100

format: #n
0b00000001000000100000001100000100

format: #x
0x01020304

format: #_b
0b0000_0001_0000_0010_0000_0011_0000_0100

format: #_n
0b0000_0001_0000_0010_0000_0011_0000_0100

format: #_x
0x0102_0304

Thanks!

eric

On Mon, Feb 12, 2018 at 9:15 PM Nick Coghlan <report@bugs.python.org> wrote:

>
> Nick Coghlan <ncoghlan@gmail.com> added the comment:
>
> I think the aspect that makes this potentially worthy of a helper function
> is the need to dynamically adjust the field width based on whether you're
> printing an IPv4 address or an IPv6 one, whether you're printing it in
> binary or hexadecimal, whether you're printing separator characters, and
> whether you're printing the base indicator prefix.
>
> For example, consider the following:
>
> ```
> >>> ip4 = ipaddress.ip_address("1.2.3.4")
> >>> ip4
> IPv4Address('1.2.3.4')
> >>> ip6 = ipaddress.ip_address("::1:2:3:4")
> >>> ip6
> IPv6Address('::1:2:3:4')
> >>> format(int(ip4), "#041_b")
> '0b0000_0001_0000_0010_0000_0011_0000_0100'
> >>> format(int(ip6), "#041_x")
> '0x0000_0000_0000_0000_0001_0002_0003_0004'
> ```
>
> The "41" in those examples comes from "prefix_len + (num_bits /
> bits_per_char) + (num_bits / bits_per_char / chars_per_separator) - 1":
>
> IPv4 in binary: 2 + (32 / 1) + (32 / 1 / 4) - 1 = 2 + 32 + 8 - 1 = 41
> IPv6 in hex: 2 + (128 / 4) + (128 / 1 / 4) - 1 = 2 + 32 + 8 - 1 = 41
>
> So I think the potentially interesting method to implement here would be
> *__format__*, such that the field width calculation could be made implicit
> based on the other options selected.
>
> While backwards compatibility means that IP address formatting would still
> need to be equivalent to "str(ip)" by default, it would be reasonably
> straightforward to make "format(ip, 'b')" output the number in binary,
> "format(ip, 'x')" do it in hex, and "format(ip, 'n')" be equivalent to "b"
> for IPv4 addresses, and "x" for IPv6 ones.
>
> Unlike ordinary numbers, the IP addresses would always be zero-padded to a
> fixed width (32-bits for IPv4, 128 bits for IPv6), but "#" and "_" would be
> accepted to indicate whether or to add the base indicator prefix and/or
> group separators.
>
> Given those enhancements, the display examples above would become:
>
> ```
> >>> format(ip4, "#_n")
> '0b0000_0001_0000_0010_0000_0011_0000_0100'
> >>> format(ip6, "#_n")
> '0x0000_0000_0000_0000_0001_0002_0003_0004'
> ```
>
> ----------
>
> _______________________________________
> Python tracker <report@bugs.python.org>
> <https://bugs.python.org/issue32820>
> _______________________________________
>
History
Date User Action Args
2018-02-13 13:38:37ewosbornesetrecipients: + ewosborne, ncoghlan, eric.smith, christian.heimes, serhiy.storchaka
2018-02-13 13:38:37ewosbornelinkissue32820 messages
2018-02-13 13:38:37ewosbornecreate