[Python-Dev] PEP 3144 review.

Andrew McNamara andrewm at object-craft.com.au
Thu Sep 17 09:15:16 CEST 2009


> > As the module stands, we have a pair of address-without-mask classes
> > called *Address, and a pair of address-with-mask classes called
> > *Network. So, sometimes when you want to record an *address* you use
> > a class called Network, and that class comes with a behaviours that
> > make no sense in the context of a singleton network end-point (it can't
> > "contain" other addresses, although it's .network can).
>
>I'm going to consistently use "address" to mean a singleton and
>"network" to mean a container in the following.

Ta. I think it's useful to have a common terminology.

>I still don't see why an address-with-mask is useful, except that the
>network is deducible as {'network': address & mask, 'mask': mask}.  Is
>there *any* other way you would *ever* use that?
>
>It seems to me that for some purposes (implementing dig(1), for
>example), an IPv4Address can contain only the address (ie, a 32-bit
>integer) as a data attribute, and (with methods for using that
>attribute) that is the minimal implementation of IPv4Address.
>
>However, there are other cases (eg, routing) where it's useful to
>associate an address with its network, and I don't see much harm in
>doing so by adding a 'network' attribute to the base class
>IPv4Address, since addresses are hardly useful except in the context
>of networks.  Of course that attribute is often going to be None (eg,
>in implementing dig(1) the remote nameserver is unlikely to tell you
>the netmask).  However, when iterating over an IPv4Network, the
>iterator can automatically fill in the 'network' attribute, and that's
>fairly cheap.

Conceptually, you sometimes need a bare address, and other times,
you need an address with an associated network (host interface
configs, router configs, etc). By AddressWithMask, I really mean
AddressWithEnoughInformationToDeriveNetworkWhenNeeded. Conveniently,
IPv4 and IPv6 addressing allows us to derive the network from the host
address combined with the netmask - in other words, we don't have to attach
a real Network object to Address objects until the user tries to access
it, and then we derive it from the address and mask.

>While to me neither the 'network' attribute nor the iterator behavior
>just described seems amazing useful in the base classes, it seems to
>me that precisely those behaviors will be reinvented over and over
>again for derived classes.  Furthermore they are natural enough that
>they won't bother people who don't need them.  (That's despite at
>least one person (IIRC it was Antoine) firmly saying "an IPv4Address
>should contain exactly one 32-bit int, no more, no less", so I could
>be wrong.)  

If you have a .network attribute on an address object, checking if an
address is in the same network as another address becomes:

    addr_a in addr_b.network

As the module stands, you write that as:

    addr_a in addr_b

I don't think the intent is as clear with the later.

>It seems to me that the only good reason for not having a
>'network' attribute that contains an IPv4Network instance or None is
>efficiency: the space for the attribute and the overhead of filling it
>in the iterator.  I personally can't think of an application that
>would care (from what I hear, Cisco has no interest in writing its
>routers' IP stacks in Python, amazingly enough), but in theory ...

The implementation already lazily creates most things like this.

>Finally, I agree that using IPv4Network as address-with-mask is a
>confusing, undiscoverable abuse.  In particular, I think that every
>time I went a week without using that idiom, I'd get nervous when I
>saw it again: "Are you *sure* that won't raise an error or silently
>get the lower bits masked off?!  If not now, in the next version?"

Yes.

-- 
Andrew McNamara, Senior Developer, Object Craft
http://www.object-craft.com.au/


More information about the Python-Dev mailing list