Update from Peter Moody.
This commit is contained in:
parent
77fb82981e
commit
989165fe9e
131
pep-3144.txt
131
pep-3144.txt
|
@ -31,40 +31,63 @@ Motivation:
|
||||||
|
|
||||||
|
|
||||||
Rationale:
|
Rationale:
|
||||||
|
|
||||||
ipaddr was designed with the goal of abstracting out as much of the common
|
|
||||||
functionality as possible. As mentioned earlier, the similarities between
|
|
||||||
addresses and networks, IPV6 and IPV4 allows much code to be reused since
|
|
||||||
python allows for easy (and clean) multiple inheritance. Methods which are
|
|
||||||
specific to IPV4 or IPV6, addresses or networks are inherited from
|
|
||||||
appropriately named classes (Basev4, Basev6, BaseNet, BaseIP, etc) to
|
|
||||||
provide the full functionality of IPv4Address, IPv4Network, IPv6Address and
|
|
||||||
IPv6Network.
|
|
||||||
|
|
||||||
|
ipaddr was designed with a few basic principals in mind:
|
||||||
|
|
||||||
|
- IPv4 and IPv6 objects are distinct.
|
||||||
|
- IP addresses and IP networks are distinct.
|
||||||
|
- the library should be useful and the assumptions obvious to the network
|
||||||
|
programmer.
|
||||||
|
- IP networks should be treated as lists (as opposed to some other
|
||||||
|
python intrinsic) in so far as it makes sense.
|
||||||
|
- the library should be lightweight and fast without sacrificing
|
||||||
|
expected functionality.
|
||||||
|
|
||||||
- Distinct IPV4 and IPV6 objects.
|
- Distinct IPV4 and IPV6 objects.
|
||||||
|
|
||||||
While there are many similarities, IPV4 and IPV6 objects are fundamentally
|
While there are many similarities, IPV4 and IPV6 objects are fundamentally
|
||||||
different. The similarities allow for easy abstraction of certain
|
different. The similarities allow for easy abstraction of certain
|
||||||
operations which affect the bits from both in the same manner, but their
|
operations which affect the bits from both in the same manner, but their
|
||||||
differences mean attempts to combine them into one object would be like
|
differences mean attempts to combine them into one object yield unexpected
|
||||||
trying to force a round peg into a square hole (or visa versa).
|
results. According to Vint Cerf, "I have seen a substantial amount of
|
||||||
|
traffic about IPv4 and IPv6 comparisons and the general consensus is that
|
||||||
|
these are not comparable." (Vint Cerf [2]). For python versions >= 3.0,
|
||||||
|
this means that (<, >, <=, >=) comparison operations between IPv4 and IPv6
|
||||||
|
objects raise a TypeError per the Ordering Comparisons [3].
|
||||||
|
|
||||||
- Distinct network and address objects.
|
- Distinct network and address objects.
|
||||||
|
|
||||||
Many people think of IP addresses and IP networks as synonymous, while they
|
An IPV4 address is a single 32 bit number while the IPV4 address assigned
|
||||||
are however, distinct. An IPV4 address is a single 32 bit number while the
|
to a networked computer is a 32 bit address and associated network.
|
||||||
IPV4 address assigned to a networked computer is a 32 bit address and
|
Similarly, an IPV6 address is a 128 bit number while an IPV6 address
|
||||||
associated network. Similarly, an IPV6 address is a 128 bit number while
|
assigned to a networked computer is a 128 bit number and associated network
|
||||||
an IPV6 address assigned to a networked computer is a 128 bit number and
|
information. The similarities leads to easy abstraction of some methods
|
||||||
associated network information. The similarities leads to easy abstraction
|
and properties, but there are obviously a number of address/network
|
||||||
of some methods and properties, but there are obviously a number of
|
specific properties which require they be distinct. For instance, IP
|
||||||
address/network specific properties which require they be distinct. For
|
networks contain a network address (the base address of the network),
|
||||||
instance, IP networks contain network address (the base address of the
|
broadcast address (the upper end of the network, also the address to
|
||||||
network), broadcast addresses (the upper end of the network, also the
|
which every machine on a given network is supposed listen, hence the name
|
||||||
address to which every machine on a given network is supposed listen, hence
|
broadcast), supernetworks and subnetworks, etc. The individual property
|
||||||
the name broadcast), supernetworks and subnetworks, etc. The individual
|
addresses in an IP network obviously don't have the same properties,
|
||||||
property addresses in an IP network obviously don't have the same
|
they're simply 32 or 128 bit numbers.
|
||||||
properties, they're simply 32 or 128 bit numbers.
|
|
||||||
|
- Principal of least confusion for network programmers.
|
||||||
|
|
||||||
|
It should be understood that, above all, this module is designed with the
|
||||||
|
network administrator in mind. In practice, this means that a number of
|
||||||
|
assumptions are made with regards to common usage and the library prefers
|
||||||
|
the usefulness of accepted practice over strict adherence to RFCs. For
|
||||||
|
example, ipaddr accepts '192.168.1.1/24' as a network definition because
|
||||||
|
this is a very common way of describing an address + netmask despite the
|
||||||
|
fact that 192.168.1.1 is actually an IP address on the network
|
||||||
|
192.168.1.0/24. Strict adherence would require that networks have all of
|
||||||
|
the host bits masked to zero, which would require two objects to describe
|
||||||
|
that IP + network. In practice, a looser interpretation of a network is
|
||||||
|
a very useful if common abstraction, so ipaddr prefers to make this
|
||||||
|
available. For the developer who is concerned with strict adherence,
|
||||||
|
ipaddr provides an optional 'strict' boolean argument to the
|
||||||
|
IPv(4|6)Network constructors which guarantees that all host bits are masked
|
||||||
|
down.
|
||||||
|
|
||||||
- Treat network elements as lists (in so far as it's possible).
|
- Treat network elements as lists (in so far as it's possible).
|
||||||
|
|
||||||
|
@ -84,7 +107,7 @@ Rationale:
|
||||||
While some network programmers will undoubtedly want more than this library
|
While some network programmers will undoubtedly want more than this library
|
||||||
provides, keeping the functionality to strictly what's required from a IP
|
provides, keeping the functionality to strictly what's required from a IP
|
||||||
address manipulation module is critical to keeping the code fast, easily
|
address manipulation module is critical to keeping the code fast, easily
|
||||||
comprehensible and extensible. I've tried to provide enough options in
|
comprehensible and extensible. It is a goal to provide enough options in
|
||||||
terms of functionality to allow the developer to easily do their work
|
terms of functionality to allow the developer to easily do their work
|
||||||
without needlessly cluttering the library. Finally, It's important to note
|
without needlessly cluttering the library. Finally, It's important to note
|
||||||
that this design doesn't prevent subclassing or otherwise extending to meet
|
that this design doesn't prevent subclassing or otherwise extending to meet
|
||||||
|
@ -114,15 +137,15 @@ Specification:
|
||||||
addresses and networks, both IPv4 and IPv6. In short, there is common
|
addresses and networks, both IPv4 and IPv6. In short, there is common
|
||||||
functionality shared between (ipaddr class names in parentheses):
|
functionality shared between (ipaddr class names in parentheses):
|
||||||
|
|
||||||
1. all IP addresses and networks, both IPv4 and IPv6. (IPAddrBase)
|
1. all IP addresses and networks, both IPv4 and IPv6. (_IPAddrBase)
|
||||||
|
|
||||||
2. all IP addresses of both versions. (BaseIP)
|
2. all IP addresses of both versions. (_BaseIP)
|
||||||
|
|
||||||
3. all IP networks of both version. (BaseNet)
|
3. all IP networks of both version. (_BaseNet)
|
||||||
|
|
||||||
4. all IPv4 objects, both addresses and networks. (BaseV4)
|
4. all IPv4 objects, both addresses and networks. (_BaseV4)
|
||||||
|
|
||||||
5. all IPv6 objects, both addresses and networks. (BaseV6)
|
5. all IPv6 objects, both addresses and networks. (_BaseV6)
|
||||||
|
|
||||||
Seeing this as a clear hierarchy is important for recognizing how much
|
Seeing this as a clear hierarchy is important for recognizing how much
|
||||||
code is common between the four main classes. For this reason, ipaddr uses
|
code is common between the four main classes. For this reason, ipaddr uses
|
||||||
|
@ -137,9 +160,9 @@ Specification:
|
||||||
might guess, return the appropriately typed address or network objects for
|
might guess, return the appropriately typed address or network objects for
|
||||||
the given argument.
|
the given argument.
|
||||||
|
|
||||||
Finally, there is no meaningful natural ordering between IPv4 and IPv6
|
Finally, as mentioned earlier, there is no meaningful natural ordering
|
||||||
addresses ("these protocols are ships-in-the-night"), so rather than invent
|
between IPv4 and IPv6 addresses and networks [2]. Rather than invent a
|
||||||
a standard, ipaddr follows Ordering Comparisons [2] and returns a TypeError
|
standard, ipaddr follows Ordering Comparisons and returns a TypeError
|
||||||
when asked to compare objects of differing IP versions. In practice, there
|
when asked to compare objects of differing IP versions. In practice, there
|
||||||
are many ways a programmer may wish to order the addresses, so this this
|
are many ways a programmer may wish to order the addresses, so this this
|
||||||
shouldn't pose a problem for the developer who can easily write:
|
shouldn't pose a problem for the developer who can easily write:
|
||||||
|
@ -167,7 +190,9 @@ Specification:
|
||||||
In [1]: IPNetwork('1.1.1.1').with_hostmask
|
In [1]: IPNetwork('1.1.1.1').with_hostmask
|
||||||
Out[1]: '1.1.1.1/0.0.0.0'
|
Out[1]: '1.1.1.1/0.0.0.0'
|
||||||
|
|
||||||
the same applies to IPv6
|
the same applies to IPv6. It should be noted that netmasks and hostmasks
|
||||||
|
are not commonly used in IPv6, the methods exist for compatibility with
|
||||||
|
IPv4.
|
||||||
|
|
||||||
- Lazy evaluation combined with aggressive caching of network elements.
|
- Lazy evaluation combined with aggressive caching of network elements.
|
||||||
|
|
||||||
|
@ -308,17 +333,49 @@ Specification:
|
||||||
(the same methods exist for IPv4 networks and addresses, but they're
|
(the same methods exist for IPv4 networks and addresses, but they're
|
||||||
just stubs for returning the normal __str__ representation).
|
just stubs for returning the normal __str__ representation).
|
||||||
|
|
||||||
|
- Most other common operations.
|
||||||
|
|
||||||
|
It is a design goal to support all of the common operation expected from
|
||||||
|
an IP address manipulation module. As such, finding supernets, subnets,
|
||||||
|
address and network containment etc are all supported.
|
||||||
|
|
||||||
Reference Implementation:
|
Reference Implementation:
|
||||||
|
|
||||||
A reference implementation is available at:
|
A reference implementation is available at:
|
||||||
http://ipaddr-py.googlecode.com/svn/branches/2.0.x
|
http://ipaddr-py.googlecode.com/svn/trunk
|
||||||
|
|
||||||
|
|
||||||
References:
|
References:
|
||||||
|
|
||||||
[1] http://bugs.python.org/issue3959
|
[1] http://bugs.python.org/issue3959
|
||||||
[2] http://docs.python.org/dev/3.0/whatsnew/3.0.html#ordering-comparisons
|
[2] Appealing to authority is a logical fallacy, but Vint Cerf is an
|
||||||
|
an authority who can't be ignored. Full text of the email follows:
|
||||||
|
|
||||||
|
"""
|
||||||
|
I have seen a substantial amount of traffic about IPv4 and IPv6
|
||||||
|
comparisons and the general consensus is that these are not comparable.
|
||||||
|
|
||||||
|
If we were to take a very simple minded view, we might treat these as
|
||||||
|
pure integers in which case there is an ordering but not a useful one.
|
||||||
|
|
||||||
|
In the IPv4 world, "length" is important because we take longest (most
|
||||||
|
specific) address first for routing. Length is determine by the mask,
|
||||||
|
as you know.
|
||||||
|
|
||||||
|
Assuming that the same style of argument works in IPv6, we would have
|
||||||
|
to conclude that treating an IPv6 value purely as an integer for
|
||||||
|
comparison with IPv4 would lead to some really strange results.
|
||||||
|
|
||||||
|
All of IPv4 space would lie in the host space of 0::0/96 prefix of
|
||||||
|
IPv6. For any useful interpretation of IPv4, this is a non-starter.
|
||||||
|
|
||||||
|
I think the only sensible conclusion is that IPv4 values and IPv6 values
|
||||||
|
should be treated as non-comparable.
|
||||||
|
|
||||||
|
Vint
|
||||||
|
"""
|
||||||
|
|
||||||
|
[3] http://docs.python.org/dev/3.0/whatsnew/3.0.html#ordering-comparisons
|
||||||
|
|
||||||
|
|
||||||
Copyright:
|
Copyright:
|
||||||
|
|
Loading…
Reference in New Issue