[Python-Dev] PEP 3144 review.

Scott Dial scott+python-dev at scottdial.com
Tue Sep 15 19:16:06 CEST 2009


R. David Murray wrote:
> On Tue, 15 Sep 2009 at 14:28, Antoine Pitrou wrote:
>> Andrew McNamara <andrewm <at> object-craft.com.au> writes:
>>>
>>>    >>> ipaddr.IPv4Network('192.168.1.1/16').network
>>>     IPv4Address('192.168.0.0')
>>
>> Er, does this mean that taking the `network` attribute from a network
>> object
>> actually gives an address object (not a network)?
>> It looks horribly misleading to me.
> 
> That was my opinion, too.  I've always called that number the 'zero'
> of the network, but other people said that it is usually called the
> 'network'.
> 
> I also find it odd to see a 'network' with an IP address of 192.168.1.1.
> That looks like a host-address-plus-netmask to me, not a network
> address.
> 

It just happened that I needed a tool today to calculate the gateway IP
for an interface, and I took it as an opportunity to try out this ipaddr
module. I'll attempt to relate my experience below...

I have to concur with the opinions above. I was very confused by the
following error:

>>> addr = ipaddr.IPAddress("10.1.2.3/255.255.240.0")
...
ipaddr.IPAddressIPValidationError: '98.223.189.24/255.255.240.0' is not
a valid address (hint, it's probably a network)

Because, it *is* a address of a host on a network. I gave in and said:

>>> net = ipaddr.IPNetwork("10.1.2.3/255.255.240.0")

But then, I was dumbfounded as to how I could get the gateway IP from
this IPNetwork object. It took me a while to figure out that you can
iterate over IPNetwork instances:

>>> gateway = net[1]

I was then confused, because:

>>> print(type(gateway))
<class 'ipaddr.IPv4Address'>

Which sorta blew my mind.. I fully expected to receive an IPNetwork back
from that operation. It is unclear to me why the network information
gets chucked by that operation. I foresee having to work around that in
real applications by doing something obnoxious like:

>>> actual_gateway = ipaddr.IPNetwork("%s/%s" % (gateway, addr.netmask))

But since I only actually needed the IP address for the gateway, it
fulfilled my needs.

In the end, I found the names IPNetwork/IPAddress and their
instantiations confusing. ISTM that IPNetwork is overloaded and plays
two roles of being an IPNetwork and being an IPAddressWithNetwork. And
finally, it's unclear to me why iterating over a IPNetwork would not
produce a sequence of IPNetwork(/IPAddressWithNetwork) objects.

ISTM that if I started with an IPNetwork object, the API should always
return IPNetwork objects. If I want just an IPAddress object, then I can
always fetch the "ip" attribute to get that. Perhaps there is some
compelling conceptual argument as to why this is not correct, but it
seems like the API destroys information needlessly.

Just my opinion..

-- 
Scott Dial
scott at scottdial.com
scodial at cs.indiana.edu


More information about the Python-Dev mailing list