diff --git a/Doc/library/ipaddress.rst b/Doc/library/ipaddress.rst --- a/Doc/library/ipaddress.rst +++ b/Doc/library/ipaddress.rst @@ -86,17 +86,18 @@ IP Addresses ------------ Address objects ^^^^^^^^^^^^^^^ The :class:`IPv4Address` and :class:`IPv6Address` objects share a lot of common attributes. Some attributes that are only meaningful for IPv6 addresses are also implemented by :class:`IPv4Address` objects, in order to make it easier to -write code that handles both IP versions correctly. +write code that handles both IP versions correctly. Address objects are +hashable, so they can be used as keys in dictionaries. .. class:: IPv4Address(address) Construct an IPv4 address. An :exc:`AddressValueError` is raised if *address* is not a valid IPv4 address. The following constitutes a valid IPv4 address: @@ -231,17 +232,17 @@ write code that handles both IP versions This is also the value returned by ``str(addr)`` for IPv6 addresses. .. attribute:: exploded The long form of the address representation, with all leading zeroes and groups consisting entirely of zeroes included. - For the following attributes, see the corresponding documention of the + For the following attributes, see the corresponding documentation of the :class:`IPv4Address` class: .. attribute:: packed .. attribute:: reverse_pointer .. attribute:: version .. attribute:: max_prefixlen .. attribute:: is_multicast .. attribute:: is_private @@ -363,33 +364,37 @@ host mask equivalent to ``/24`` in IPv4 Network objects ^^^^^^^^^^^^^^^ All attributes implemented by address objects are implemented by network objects as well. In addition, network objects implement additional attributes. All of these are common between :class:`IPv4Network` and :class:`IPv6Network`, so to avoid duplication they are only documented for :class:`IPv4Network`. +Network objects are hashable, so they can be used as keys in dictionaries. .. class:: IPv4Network(address, strict=True) Construct an IPv4 network definition. *address* can be one of the following: 1. A string consisting of an IP address and an optional mask, separated by a slash (``/``). The IP address is the network address, and the mask can be either a single number, which means it's a *prefix*, or a string representation of an IPv4 address. If it's the latter, the mask is - interpreted as a *net mask* if it starts with a non-zero field, or as - a *host mask* if it starts with a zero field. If no mask is provided, - it's considered to be ``/32``. + interpreted as a *net mask* if possible, or as a *host mask* otherwise. + If no mask is provided, it's considered to be ``/32``. For example, the following *address* specifications are equivalent: ``192.168.1.0/24``, ``192.168.1.0/255.255.255.0`` and ``192.168.1.0/0.0.0.255``. + Note that the two ambiguous cases are both treated as net masks: + ``0.0.0.0/0.0.0.0`` is ``0.0.0.0/0``, and + ``1.2.3.4/255.255.255.255`` is ``1.2.3.4/32``. + 2. An integer that fits into 32 bits. This is equivalent to a single-address network, with the network address being *address* and the mask being ``/32``. 3. An integer packed into a :class:`bytes` object of length 4, big-endian. The interpretation is similar to an integer *address*. 4. A two-tuple of an address description and a netmask, where the address @@ -403,51 +408,55 @@ so to avoid duplication they are only do an IPv4 address. If *strict* is ``True`` and host bits are set in the supplied address, then :exc:`ValueError` is raised. Otherwise, the host bits are masked out to determine the appropriate network address. Unless stated otherwise, all network methods accepting other network/address objects will raise :exc:`TypeError` if the argument's IP version is - incompatible to ``self`` + incompatible to ``self``. .. versionchanged:: 3.5 Added the two-tuple form for the *address* constructor parameter. .. attribute:: version .. attribute:: max_prefixlen Refer to the corresponding attribute documentation in - :class:`IPv4Address` + :class:`IPv4Address`. .. attribute:: is_multicast .. attribute:: is_private .. attribute:: is_unspecified .. attribute:: is_reserved .. attribute:: is_loopback .. attribute:: is_link_local These attributes are true for the network as a whole if they are true - for both the network address and the broadcast address + for both the network address and the broadcast address. .. attribute:: network_address The network address for the network. The network address and the prefix length together uniquely define a network. .. attribute:: broadcast_address The broadcast address for the network. Packets sent to the broadcast address should be received by every host on the network. .. attribute:: hostmask - The host mask, as a string. + The host mask, as an :class:`IPv4Address` object. + + .. attribute:: netmask + + The net mask, as an :class:`IPv4Address` object. .. attribute:: with_prefixlen .. attribute:: compressed .. attribute:: exploded A string representation of the network, with the mask in prefix notation. @@ -556,25 +565,25 @@ so to avoid duplication they are only do >>> ip_network('192.0.2.1/32').compare_networks(ip_network('192.0.2.1/32')) 0 .. class:: IPv6Network(address, strict=True) Construct an IPv6 network definition. *address* can be one of the following: - 1. A string consisting of an IP address and an optional mask, separated by - a slash (``/``). The IP address is the network address, and the mask - can be either a single number, which means it's a *prefix*, or a string - representation of an IPv6 address. If it's the latter, the mask is - interpreted as a *net mask*. If no mask is provided, it's considered to - be ``/128``. + 1. A string consisting of an IP address and an optional prefix length, + separated by a slash (``/``). The IP address is the network address, + and the prefix length must be a single number, the *prefix*. If no + prefix length is provided, it's considered to be ``/128``. - For example, the following *address* specifications are equivalent: - ``2001:db00::0/24`` and ``2001:db00::0/ffff:ff00::``. + For example, the *address* specification might be ``2001:db00::0/24``. + + Note that IPv6 networks can't be specified using a net mask or a host + mask - those features are only in :class:`IPv4Network`. 2. An integer that fits into 128 bits. This is equivalent to a single-address network, with the network address being *address* and the mask being ``/128``. 3. An integer packed into a :class:`bytes` object of length 16, big-endian. The interpretation is similar to an integer *address*. @@ -601,52 +610,53 @@ so to avoid duplication they are only do .. attribute:: is_private .. attribute:: is_unspecified .. attribute:: is_reserved .. attribute:: is_loopback .. attribute:: is_link_local .. attribute:: network_address .. attribute:: broadcast_address .. attribute:: hostmask + .. attribute:: netmask .. attribute:: with_prefixlen .. attribute:: compressed .. attribute:: exploded .. attribute:: with_netmask .. attribute:: with_hostmask .. attribute:: num_addresses .. attribute:: prefixlen .. method:: hosts() .. method:: overlaps(other) .. method:: address_exclude(network) .. method:: subnets(prefixlen_diff=1, new_prefix=None) .. method:: supernet(prefixlen_diff=1, new_prefix=None) .. method:: compare_networks(other) Refer to the corresponding attribute documentation in - :class:`IPv4Network` + :class:`IPv4Network`. .. attribute:: is_site_local These attribute is true for the network as a whole if it is true - for both the network address and the broadcast address + for both the network address and the broadcast address. Operators ^^^^^^^^^ Network objects support some operators. Unless stated otherwise, operators can only be applied between compatible objects (i.e. IPv4 with IPv4, IPv6 with IPv6). Logical operators """"""""""""""""" -Network objects can be compared with the usual set of logical operators, -similarly to address objects. +Network objects can be compared with the usual set of logical operators. +Network objects are ordered first by network address, then by net mask. Iteration """"""""" Network objects can be iterated to list all the addresses belonging to the network. For iteration, *all* hosts are returned, including unusable hosts (for usable hosts, use the :meth:`~IPv4Network.hosts` method). An @@ -686,16 +696,18 @@ Network objects can act as containers of True >>> IPv4Address('192.0.3.6') in IPv4Network('192.0.2.0/28') False Interface objects ----------------- +Interface objects are hashable, so they can be used as keys in dictionaries. + .. class:: IPv4Interface(address) Construct an IPv4 interface. The meaning of *address* is as in the constructor of :class:`IPv4Network`, except that arbitrary host addresses are always accepted. :class:`IPv4Interface` is a subclass of :class:`IPv4Address`, so it inherits all the attributes from that class. In addition, the following attributes @@ -757,16 +769,53 @@ Interface objects .. attribute:: with_prefixlen .. attribute:: with_netmask .. attribute:: with_hostmask Refer to the corresponding attribute documentation in :class:`IPv4Interface`. +Operators +^^^^^^^^^ + +Interface objects support some operators. Unless stated otherwise, operators +can only be applied between compatible objects (i.e. IPv4 with IPv4, IPv6 with +IPv6). + + +Logical operators +""""""""""""""""" + +Interface objects can be compared with the usual set of logical operators. + +For equality comparison (``==`` and ``!=``), both the IP address and network +must be the same for the objects to be equal. An interface will not compare +equal to any address or network object. + +For ordering (``<``, ``>``, etc) the rules are different. Interface and +address objects with the same IP version can be compared, and the address +objects will always sort before the interface objects. Two interface objects +are compared by comparing their networks, using the same rules as +:class:`IPv4Network` or :class:`IPv6Network`. The IP address plays no part in +the comparison. Note that you will get strange results when comparing two +interface objects with the same network but different IP addresses:: + + >>> a = ipaddress.IPv4Interface('128.0.0.3/8') + >>> b = ipaddress.IPv4Interface('128.0.0.5/8') + >>> a < b + False + >>> b < a + False + >>> a > b + True + >>> b > a + True + + Other Module Level Functions ---------------------------- The module also provides the following module level functions: .. function:: v4_int_to_packed(address) Represent an address as 4 packed bytes in network (big-endian) order. @@ -822,17 +871,17 @@ The module also provides the following m Return a key suitable for sorting between networks and addresses. Address and Network objects are not sortable by default; they're fundamentally different, so the expression:: IPv4Address('192.0.2.0') <= IPv4Network('192.0.2.0/24') doesn't make sense. There are some times however, where you may wish to have :mod:`ipaddress` sort these anyway. If you need to do this, you can use - this function as the ``key`` argument to :func:`sorted()`. + this function as the *key* argument to :func:`sorted()`. *obj* is either a network or address object. Custom Exceptions ----------------- To support more specific error reporting from class constructors, the @@ -840,9 +889,9 @@ module defines the following exceptions: .. exception:: AddressValueError(ValueError) Any value error related to the address. .. exception:: NetmaskValueError(ValueError) - Any value error related to the netmask. + Any value error related to the net mask. diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py --- a/Lib/test/test_ipaddress.py +++ b/Lib/test/test_ipaddress.py @@ -472,16 +472,22 @@ class NetmaskTestMixin_v4(CommonTestMixi class InterfaceTestCase_v4(BaseTestCase, NetmaskTestMixin_v4): factory = ipaddress.IPv4Interface class NetworkTestCase_v4(BaseTestCase, NetmaskTestMixin_v4): factory = ipaddress.IPv4Network + def test_no_mask(self): + self.assertEqual( + ipaddress.ip_network('1.2.3.4'), + ipaddress.IPv4Network('1.2.3.4/32') + ) + class NetmaskTestMixin_v6(CommonTestMixin_v6): """Input validation on interfaces and networks is very similar""" def test_split_netmask(self): addr = "cafe:cafe::/128/190" with self.assertAddressError("Only one '/' permitted in %r" % addr): self.factory(addr)