[issue32820] Add bits method to ipaddress

2018-02-20 Thread Serhiy Storchaka

Serhiy Storchaka  added the comment:

And Eric, please avoid including the quote of previous message in your 
messages. This makes hard to read your messages and the whole discussion.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32820] Add bits method to ipaddress

2018-02-20 Thread Eric Osborne

Eric Osborne  added the comment:

Yeah, bits() is dead.  The thread has the same title, but I changed the PR
a while ago.  The diffs in the PR are for format().

I'll go over the code and clean it up.  The docstring in particular is
probably lousy.
Thanks!

eric

On Tue, Feb 20, 2018 at 3:35 AM Serhiy Storchaka 
wrote:

>
> Serhiy Storchaka  added the comment:
>
> I the bits() method is a dead end. The conclusion was to add __format__().
>
> --
>
> ___
> Python tracker 
> 
> ___
>

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32820] Add bits method to ipaddress

2018-02-20 Thread Serhiy Storchaka

Serhiy Storchaka  added the comment:

I the bits() method is a dead end. The conclusion was to add __format__().

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32820] Add bits method to ipaddress

2018-02-19 Thread Nick Coghlan

Nick Coghlan  added the comment:

The python-ideas discussion didn't turn up any major concerns we hadn't already 
considered, so you're in "wait for PR review" mode now. If you wanted to do a 
self-review in the meantime, then 
https://devguide.python.org/committing/#accepting-pull-requests covers the 
kinds of additional things a reviewer will be looking for.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32820] Add bits method to ipaddress

2018-02-19 Thread Eric Osborne

Eric Osborne  added the comment:

I brought it up on python-ideas.  Since I've not been through this process
before - what happens now?  Do I wait for code review on github, or is
there more I need to do?

eric

On Tue, Feb 13, 2018 at 11:56 PM Nick Coghlan 
wrote:

>
> Nick Coghlan  added the comment:
>
> Aye, definitely worth a thread on python-ideas. My rationale for
> suggesting something based on the built-in numeric codes is that it makes
> it straightforward for *users* to transfer knowledge from that
> mini-language.
>
> As far as parsing goes, I was thinking of something along the lines of the
> following naive approach:
>
> typechar = fmt[-1:]
> if not typechar or typechar not in ("b", "n", "x"):
> return super().__format__(fmt)
> prefix, group_sep, suffix = fmt[:-1].rpartition("_")
> if prefix and prefix != "#" or suffix:
> return super().__format__(fmt)
> field_width = self._calculate_field_width(typechar)
> return format(int(self),
> f"{prefix}0{field_width}{group_sep}{type_char}")
>
> --
>
> ___
> Python tracker 
> 
> ___
>

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32820] Add bits method to ipaddress

2018-02-14 Thread Eric Osborne

Eric Osborne  added the comment:

Cool, I will kick it over to python-ideas.  I checked in some code to
handle the format string and it's a lot like what you're suggesting, so
I'll leave that in there and see what happens.
Thanks!

eric

On Tue, Feb 13, 2018 at 11:56 PM Nick Coghlan 
wrote:

>
> Nick Coghlan  added the comment:
>
> Aye, definitely worth a thread on python-ideas. My rationale for
> suggesting something based on the built-in numeric codes is that it makes
> it straightforward for *users* to transfer knowledge from that
> mini-language.
>
> As far as parsing goes, I was thinking of something along the lines of the
> following naive approach:
>
> typechar = fmt[-1:]
> if not typechar or typechar not in ("b", "n", "x"):
> return super().__format__(fmt)
> prefix, group_sep, suffix = fmt[:-1].rpartition("_")
> if prefix and prefix != "#" or suffix:
> return super().__format__(fmt)
> field_width = self._calculate_field_width(typechar)
> return format(int(self),
> f"{prefix}0{field_width}{group_sep}{type_char}")
>
> --
>
> ___
> Python tracker 
> 
> ___
>

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32820] Add bits method to ipaddress

2018-02-13 Thread Nick Coghlan

Nick Coghlan  added the comment:

Aye, definitely worth a thread on python-ideas. My rationale for suggesting 
something based on the built-in numeric codes is that it makes it 
straightforward for *users* to transfer knowledge from that mini-language.

As far as parsing goes, I was thinking of something along the lines of the 
following naive approach:

typechar = fmt[-1:]
if not typechar or typechar not in ("b", "n", "x"):
return super().__format__(fmt)
prefix, group_sep, suffix = fmt[:-1].rpartition("_")
if prefix and prefix != "#" or suffix:
return super().__format__(fmt)
field_width = self._calculate_field_width(typechar)
return format(int(self), f"{prefix}0{field_width}{group_sep}{type_char}")

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32820] Add bits method to ipaddress

2018-02-13 Thread Eric V. Smith

Eric V. Smith  added the comment:

If you don't recognize the format string, you want to fall back to:

return super().__format__(fmt)

Since that will call object.__format__, it will generate an error if fmt is not 
the empty string, which is what it does currently for IP addresses.

As far as parsing the format specifier, you're on your own. _pydecimal.py has a 
version that parses something very similar (or maybe identical) to the 
mini-language used by float, int, str, etc. But I'm not sure you need to go 
that far. Since you can define any format spec you'd like, you're not 
constrained to the mini-language used by the built-in types (see datetime for 
an example, which just calls strftime). I think the _pydecimal.py approach of 
using a regex isn't bad, but you might want to delay loading re until 
__format__ is called.

Before you go too far down this path, I think this should probably be taken to 
python-ideas to hash out what the format spec for IP addresses would look like, 
or even if this is a good idea at all. I'm generally supportive of handling it 
through __format__().

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32820] Add bits method to ipaddress

2018-02-13 Thread Berker Peksag

Change by Berker Peksag :


--
nosy:  -berker.peksag

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32820] Add bits method to ipaddress

2018-02-13 Thread Berker Peksag

Berker Peksag  added the comment:

Eric, please delete the previous message when you reply by email. Keeping the 
previous message makes your comment harder to read. See 
https://bugs.python.org/issue32820#msg312050 on browser for example.

--
nosy: +berker.peksag

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32820] Add bits method to ipaddress

2018-02-13 Thread Eric Osborne

Eric Osborne  added the comment:

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
0001001000110100

format: n
0001001000110100

format: x
01020304

format: _b
_0001__0010__0011__0100

format: _n
_0001__0010__0011__0100

format: _x
0102_0304

format: #b
0b0001001000110100

format: #n
0b0001001000110100

format: #x
0x01020304

format: #_b
0b_0001__0010__0011__0100

format: #_n
0b_0001__0010__0011__0100

format: #_x
0x0102_0304

Thanks!

eric

On Mon, Feb 12, 2018 at 9:15 PM Nick Coghlan  wrote:

>
> Nick Coghlan  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")
> '0b_0001__0010__0011__0100'
> >>> format(int(ip6), "#041_x")
> '0x____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")
> '0b_0001__0010__0011__0100'
> >>> format(ip6, "#_n")
> '0x____0001_0002_0003_0004'
> ```
>
> --
>
> ___
> Python tracker 
> 
> ___
>

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32820] Add bits method to ipaddress

2018-02-12 Thread Nick Coghlan

Nick Coghlan  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")
'0b_0001__0010__0011__0100'
>>> format(int(ip6), "#041_x")
'0x____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")
'0b_0001__0010__0011__0100'
>>> format(ip6, "#_n")
'0x____0001_0002_0003_0004'
```

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32820] Add bits method to ipaddress

2018-02-12 Thread Eric Osborne

Eric Osborne  added the comment:

IPv6 is nasty no matter how you do it (cf.
https://tools.ietf.org/html/rfc1924).  And the ipaddr library already has
hex (packed()).

Binary's not about direct readabilty, but about ease of comparison.  It's
much easier to show the reader

'0b0001001000110100'
'0b0001001000110011'
'0b1100'

and have them figure out whether the mask contains both hosts than to show
them

'1.2.3.4'
'1.2.3.3'
'255.255.255.252'
and ask them to convert to binary in their heads.  Without the zero padding
on the left, this is very easy to get wrong.

But I certainly agree that this is somewhat niche and a convenience
function, and if the consensus is that this is too narrow for stdlib, so be
it.

eric

On Mon, Feb 12, 2018 at 8:46 AM Serhiy Storchaka 
wrote:

>
> Serhiy Storchaka  added the comment:
>
> I wouldn't say that
> "0b00011101101110001101101000111000101000101110001101110111001100110100"
> is a very human readable. For more readability it is better to group digits
> by 4 or 8, and why not use hexadecimal then?
>
> In any case the application of this feature looks pretty narrow to me. And
> since it can be implemented as a one-line function, I think it shouldn't be
> added in the stdlib. The ipaddress classes are already complex.
>
> --
>
> ___
> Python tracker 
> 
> ___
>

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32820] Add bits method to ipaddress

2018-02-12 Thread Serhiy Storchaka

Serhiy Storchaka  added the comment:

I wouldn't say that 
"0b00011101101110001101101000111000101000101110001101110111001100110100"
 is a very human readable. For more readability it is better to group digits by 
4 or 8, and why not use hexadecimal then?

In any case the application of this feature looks pretty narrow to me. And 
since it can be implemented as a one-line function, I think it shouldn't be 
added in the stdlib. The ipaddress classes are already complex.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32820] Add bits method to ipaddress

2018-02-12 Thread Eric Osborne via Python-bugs-list

Eric Osborne  added the comment:

It is often useful to have non-decimal representations of IP addresses.
Hex shows up a lot in sniffer traces, which is why I wanted to provide
__index__, but that's not going to happen.  I use binary a lot when
teaching subnet masking and address summarization - if you line up bit
patterns it's much easier to show how things lay out.  It's easy enough to
use bin(int(addr)) but that doesn't zero-pad the string it returns.  I find
myself doing something like

In [23]: a
Out[23]: IPv4Address('1.2.3.4')

In [24]: x = bin(int(a))[2:]

In [25]: full_x = '0b' + ('0' * (32-len(x)) + x)

In [26]: full_x
Out[26]: '0b0001001000110100'

Although, as Eric Smith has pointed out, there's a one liner way to do
this. But if an IP address can represent itself as an integer (IMO the
least useful form) it should have at least a binary representation, and
lack of a seperate __bin__ means this is as close as I could get.

eric

On Mon, Feb 12, 2018 at 7:39 AM Christian Heimes 
wrote:

>
> Christian Heimes  added the comment:
>
> I agree with Serhiy and Eric. It's a needless complication of the module.
> What's the actual use case of printing a human readable bit representation
> of an IP address?
>
> --
> nosy: +christian.heimes
>
> ___
> Python tracker 
> 
> ___
>

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32820] Add bits method to ipaddress

2018-02-12 Thread Christian Heimes

Christian Heimes  added the comment:

I agree with Serhiy and Eric. It's a needless complication of the module. 
What's the actual use case of printing a human readable bit representation of 
an IP address?

--
nosy: +christian.heimes

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32820] Add bits method to ipaddress

2018-02-12 Thread Serhiy Storchaka

Change by Serhiy Storchaka :


--
nosy: +ncoghlan -nick

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32820] Add bits method to ipaddress

2018-02-12 Thread Serhiy Storchaka

Serhiy Storchaka  added the comment:

The usefulness of this feature looks questionable to me.

--
nosy: +nick, serhiy.storchaka

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32820] Add bits method to ipaddress

2018-02-11 Thread Eric Osborne

Eric Osborne  added the comment:

Faster, too.
My way:
In [7]: %timeit bits(a)
1.67 µs ± 7.31 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)

Your way:
In [11]: %timeit b2(a)
1.2 µs ± 5.93 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)

I was a little worried about doing it all as a clever one-liner but this
seems worthwhile.  I'll change the code I submitted.
thanks!

eric

On Sun, Feb 11, 2018 at 6:21 PM Eric V. Smith 
wrote:

>
> Eric V. Smith  added the comment:
>
> Without commenting on how useful or desirable this would be, I'll point
> out the string can be computed as:
>
> return f'{int(self):#0{IPV4LENGTH+2}b}'
>
> --
> nosy: +eric.smith
>
> ___
> Python tracker 
> 
> ___
>

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32820] Add bits method to ipaddress

2018-02-11 Thread Eric V. Smith

Eric V. Smith  added the comment:

Without commenting on how useful or desirable this would be, I'll point out the 
string can be computed as:

return f'{int(self):#0{IPV4LENGTH+2}b}'

--
nosy: +eric.smith

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32820] Add bits method to ipaddress

2018-02-11 Thread Eric Osborne

Change by Eric Osborne :


--
keywords: +patch
pull_requests: +5434
stage:  -> patch review

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32820] Add bits method to ipaddress

2018-02-11 Thread Eric Osborne

Eric Osborne  added the comment:

redoing with a bits() property method to return a string, a la:

def bits(self):
fstr = '0' + str(IPV4LENGTH) + 'b'
return '0b' + format(int(self), fstr)


Works thusly:

import ipaddress as ip
a = ip.IPv4Address('0.0.0.42')
a.bits == '0b00101010'

--
resolution: rejected -> 
title: Add binary methods to ipaddress -> Add bits method to ipaddress

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com