Skip to content

Commit

Permalink
pythonGH-65056: Improve the IP address' is_global/is_private document…
Browse files Browse the repository at this point in the history
…ation (pythonGH-113186)

* pythonGH-65056: Improve the IP address' is_global/is_private documentation

It wasn't clear what the semantics of is_global/is_private are and, when
one gets to the bottom of it, it's not quite so simple (hence the
exceptions listed).

Co-authored-by: Petr Viktorin <encukou@gmail.com>
  • Loading branch information
2 people authored and vstinner committed Mar 20, 2024
1 parent 194671b commit 61c1e8f
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 17 deletions.
27 changes: 23 additions & 4 deletions Doc/library/ipaddress.rst
Expand Up @@ -178,15 +178,34 @@ write code that handles both IP versions correctly. Address objects are

.. attribute:: is_private

``True`` if the address is allocated for private networks. See
``True`` if the address is defined as not globally reachable by
iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_
(for IPv6).
(for IPv6) with the following exceptions:

* ``is_private`` is ``False`` for the shared address space (``100.64.0.0/10``)
* For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the
semantics of the underlying IPv4 addresses and the following condition holds
(see :attr:`IPv6Address.ipv4_mapped`)::

address.is_private == address.ipv4_mapped.is_private

``is_private`` has value opposite to :attr:`is_global`, except for the shared address space
(``100.64.0.0/10`` range) where they are both ``False``.

.. attribute:: is_global

``True`` if the address is allocated for public networks. See
``True`` if the address is defined as globally reachable by
iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_
(for IPv6).
(for IPv6) with the following exception:

For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the
semantics of the underlying IPv4 addresses and the following condition holds
(see :attr:`IPv6Address.ipv4_mapped`)::

address.is_global == address.ipv4_mapped.is_global

``is_global`` has value opposite to :attr:`is_private`, except for the shared address space
(``100.64.0.0/10`` range) where they are both ``False``.

.. versionadded:: 3.4

Expand Down
58 changes: 45 additions & 13 deletions Lib/ipaddress.py
Expand Up @@ -1333,18 +1333,38 @@ def is_reserved(self):
@property
@functools.lru_cache()
def is_private(self):
"""Test if this address is allocated for private networks.
"""``True`` if the address is defined as not globally reachable by
iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_
(for IPv6) with the following exceptions:
Returns:
A boolean, True if the address is reserved per
iana-ipv4-special-registry.
* ``is_private`` is ``False`` for ``100.64.0.0/10``
* For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the
semantics of the underlying IPv4 addresses and the following condition holds
(see :attr:`IPv6Address.ipv4_mapped`)::
address.is_private == address.ipv4_mapped.is_private
``is_private`` has value opposite to :attr:`is_global`, except for the ``100.64.0.0/10``
IPv4 range where they are both ``False``.
"""
return any(self in net for net in self._constants._private_networks)

@property
@functools.lru_cache()
def is_global(self):
"""``True`` if the address is defined as globally reachable by
iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_
(for IPv6) with the following exception:
For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the
semantics of the underlying IPv4 addresses and the following condition holds
(see :attr:`IPv6Address.ipv4_mapped`)::
address.is_global == address.ipv4_mapped.is_global
``is_global`` has value opposite to :attr:`is_private`, except for the ``100.64.0.0/10``
IPv4 range where they are both ``False``.
"""
return self not in self._constants._public_network and not self.is_private

@property
Expand Down Expand Up @@ -2049,13 +2069,19 @@ def is_site_local(self):
@property
@functools.lru_cache()
def is_private(self):
"""Test if this address is allocated for private networks.
"""``True`` if the address is defined as not globally reachable by
iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_
(for IPv6) with the following exceptions:
Returns:
A boolean, True if the address is reserved per
iana-ipv6-special-registry, or is ipv4_mapped and is
reserved in the iana-ipv4-special-registry.
* ``is_private`` is ``False`` for ``100.64.0.0/10``
* For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the
semantics of the underlying IPv4 addresses and the following condition holds
(see :attr:`IPv6Address.ipv4_mapped`)::
address.is_private == address.ipv4_mapped.is_private
``is_private`` has value opposite to :attr:`is_global`, except for the ``100.64.0.0/10``
IPv4 range where they are both ``False``.
"""
ipv4_mapped = self.ipv4_mapped
if ipv4_mapped is not None:
Expand All @@ -2064,12 +2090,18 @@ def is_private(self):

@property
def is_global(self):
"""Test if this address is allocated for public networks.
"""``True`` if the address is defined as globally reachable by
iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_
(for IPv6) with the following exception:
Returns:
A boolean, true if the address is not reserved per
iana-ipv6-special-registry.
For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the
semantics of the underlying IPv4 addresses and the following condition holds
(see :attr:`IPv6Address.ipv4_mapped`)::
address.is_global == address.ipv4_mapped.is_global
``is_global`` has value opposite to :attr:`is_private`, except for the ``100.64.0.0/10``
IPv4 range where they are both ``False``.
"""
return not self.is_private

Expand Down

0 comments on commit 61c1e8f

Please sign in to comment.