classification
Title: Constructor of ipaddress.IPv*Interface does not follow documentation
Type: behavior Stage: needs patch
Components: Versions: Python 3.6, Python 3.5
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Ilya.Kulakov, eric.smith, louielu, pmoody
Priority: normal Keywords: easy

Created on 2017-03-23 21:59 by Ilya.Kulakov, last changed 2017-03-25 11:37 by louielu.

Pull Requests
URL Status Linked Edit
PR 816 open louielu, 2017-03-25 10:20
Messages (7)
msg290062 - (view) Author: Ilya Kulakov (Ilya.Kulakov) Date: 2017-03-23 21:59
As per documentation, it should understand the same arguments as IPv*Network.

Unfortunately it does not recognize netmask in string form. Hence the following code will fail:

    ipaddress.ip_interface(('192.168.1.10', '255.255.255.0'))

while the following will work:

    ipaddress.ip_network(('192.168.1.10', '255.255.255.0'), strict=False)
msg290069 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2017-03-23 23:43
This should be easy enough to fix, at least in IPv4Interface.__init__. It needs to copy some of IPv4Network.__init__, dealing with address[1] and calling _make_netmask(). Currently, it just calls int(address[1]).

I haven't looked at IPv6Interface.

Tests are also needed, of course.
msg290462 - (view) Author: Louie Lu (louielu) * Date: 2017-03-25 03:58
The document here says: https://docs.python.org/3/library/ipaddress.html#interface-objects

""IPv4Interface is a subclass of IPv4Address""

trying with:

>>> ipaddress.IPv4Address(('192.168.128.0', '255.255.255.0'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.6/ipaddress.py", line 1284, in __init__
    self._ip = self._ip_int_from_string(addr_str)
  File "/usr/lib/python3.6/ipaddress.py", line 1118, in _ip_int_from_string
    raise AddressValueError("Expected 4 octets in %r" % ip_str)
ipaddress.AddressValueError: Expected 4 octets in "('192.168.128.0', '255.255.255.0')"

So the behavior of IPv4Interface seem to be correct?
msg290469 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2017-03-25 09:03
While an IPv4Interface may be a subclass of an IPv4Address, it definitely has more information attached to it: the netmask of the network it's on. So an interface (like a network) needs to allow additional parameters to specify the netmask.

It should be true that IPv4Interface is like IPv4Network, but it will allow arbitrary host bits. A IPv4Network in strict mode will have all zeros for the host bits, while a IPv4Network in non-strict mode will allow ones in the host bits (see Ilya's original example).

If you look at IPv4Interface.__init__, it actually does just that: creates an IPv4Network with strict=False, then extracts the network parts. I'm not exactly sure why it also has the int(address[1]) code there, too, since IPvv4Network deals with the address[1] part. I would think extracting _prefixlen from the network (as it does later in __init__ for the non-tuple case) would be good enough.
msg290472 - (view) Author: Louie Lu (louielu) * Date: 2017-03-25 10:21
Eric: I made the patch, reference to which IPv*Network dealing with tuple. Should I also add the unittest for it?

Also, can you help me code review this, thanks.
msg290473 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2017-03-25 10:31
Thanks! Yes, we'll need tests.

I'm out of town most of the weekend, but I'll look at this as soon as I can.
msg290479 - (view) Author: Louie Lu (louielu) * Date: 2017-03-25 11:37
Add unittest. Since IPv6 do not support prefix netmask ('ffff:ff00::'), it have only test like this:

>>> a = ipaddress.ip_interface(('dead:beaf::', '32'))
>>> b = ipaddress.ip_interface('dead:beaf::/32')
>>> str(a) == str(b)
History
Date User Action Args
2017-03-25 11:37:43louielusetmessages: + msg290479
2017-03-25 10:31:01eric.smithsetmessages: + msg290473
2017-03-25 10:21:53louielusetmessages: + msg290472
2017-03-25 10:20:22louielusetpull_requests: + pull_request722
2017-03-25 09:03:48eric.smithsetmessages: + msg290469
2017-03-25 03:58:04louielusetnosy: + louielu
messages: + msg290462
2017-03-24 22:21:27terry.reedysetnosy: + pmoody
2017-03-23 23:43:13eric.smithsetnosy: + eric.smith
messages: + msg290069

keywords: + easy
stage: needs patch
2017-03-23 21:59:48Ilya.Kulakovcreate