mirror of https://github.com/python/cpython
merge heads
This commit is contained in:
commit
21603c96e8
|
@ -9,17 +9,26 @@
|
|||
|
||||
--------------
|
||||
|
||||
The :mod:`ipaddress` module provides the capabilities to create, manipulate and
|
||||
operate on IPv4 and IPv6 addresses and networks.
|
||||
.. note::
|
||||
|
||||
This is the full module API reference - for an overview and introduction,
|
||||
see :ref:`ipaddress-howto`.
|
||||
The ``ipaddress`` module has been included in the standard library on a
|
||||
:term:`provisional basis <provisional package>`. Backwards incompatible
|
||||
changes (up to and including removal of the package) may occur if deemed
|
||||
necessary by the core developers.
|
||||
|
||||
:mod:`ipaddress` provides the capabilities to create, manipulate and
|
||||
operate on IPv4 and IPv6 addresses and networks.
|
||||
|
||||
The functions and classes in this module make it straightforward to handle
|
||||
various tasks related to IP addresses, including checking whether or not two
|
||||
hosts are on the same subnet, iterating over all hosts in a particular
|
||||
subnet, as well as checking whether or not a string represents a valid
|
||||
IP address or network definition.
|
||||
subnet, checking whether or not a string represents a valid IP address or
|
||||
network definition, and so on.
|
||||
|
||||
This is the full module API reference - for an overview and introduction,
|
||||
see :ref:`ipaddress-howto`.
|
||||
|
||||
.. versionadded:: 3.3
|
||||
|
||||
|
||||
Convenience factory functions
|
||||
|
@ -65,15 +74,24 @@ IP addresses, networks and interfaces:
|
|||
:exc:`ValueError` is raised if *address* does not represent a valid IPv4 or
|
||||
IPv6 address.
|
||||
|
||||
One downside of these convenience functions is that the need to handle both
|
||||
IPv4 and IPv6 formats means that error messages provide minimal
|
||||
information on the precise error, as the functions don't know whether the
|
||||
IPv4 or IPv6 format was intended. More detailed error reporting can be
|
||||
obtained by calling the appropriate version specific class constructors
|
||||
directly.
|
||||
|
||||
|
||||
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. To avoid duplication, all
|
||||
common attributes will only be documented for :class:`IPv4Address`.
|
||||
write code that handles both IP versions correctly.
|
||||
|
||||
.. class:: IPv4Address(address)
|
||||
|
||||
|
@ -84,66 +102,79 @@ common attributes will only be documented for :class:`IPv4Address`.
|
|||
|
||||
1. A string in decimal-dot notation, consisting of four decimal integers in
|
||||
the inclusive range 0-255, separated by dots (e.g. ``192.168.0.1``). Each
|
||||
integer represents an octet (byte) in the address, big-endian.
|
||||
integer represents an octet (byte) in the address. Leading zeroes are
|
||||
tolerated only for values less then 8 (as there is no ambiguity
|
||||
between the decimal and octal interpretations of such strings).
|
||||
2. An integer that fits into 32 bits.
|
||||
3. An integer packed into a :class:`bytes` object of length 4, big-endian.
|
||||
3. An integer packed into a :class:`bytes` object of length 4 (most
|
||||
significant octet first).
|
||||
|
||||
>>> ipaddress.IPv4Address('192.168.0.1')
|
||||
IPv4Address('192.168.0.1')
|
||||
>>> ipaddress.IPv4Address('192.0.2.1') == ipaddress.IPv4Address(3221225985)
|
||||
True
|
||||
|
||||
.. attribute:: exploded
|
||||
|
||||
The longhand version of the address as a string. Note: the
|
||||
exploded/compressed distinction is meaningful only for IPv6 addresses.
|
||||
For IPv4 addresses it is the same.
|
||||
|
||||
.. attribute:: compressed
|
||||
|
||||
The shorthand version of the address as a string.
|
||||
|
||||
.. attribute:: packed
|
||||
|
||||
The binary representation of this address - a :class:`bytes` object.
|
||||
>>> ipaddress.IPv4Address(3221225985)
|
||||
IPv4Address('192.168.0.1')
|
||||
>>> ipaddress.IPv4Address(b'\xC0\xA8\x00\x01')
|
||||
IPv4Address('192.168.0.1')
|
||||
|
||||
.. attribute:: version
|
||||
|
||||
A numeric version number.
|
||||
The appropriate version number: ``4`` for IPv4, ``6`` for IPv6.
|
||||
|
||||
.. attribute:: max_prefixlen
|
||||
|
||||
Maximal length of the prefix (in bits). The prefix defines the number of
|
||||
leading bits in an address that are compared to determine whether or not an
|
||||
address is part of a network.
|
||||
The total number of bits in the address representation for this
|
||||
version: ``32`` for IPv4, ``128`` for IPv6.
|
||||
|
||||
The prefix defines the number of leading bits in an address that
|
||||
are compared to determine whether or not an address is part of a
|
||||
network.
|
||||
|
||||
.. attribute:: compressed
|
||||
.. attribute:: exploded
|
||||
|
||||
The string representation in dotted decimal notation. Leading zeroes
|
||||
are never included in the representation.
|
||||
|
||||
As IPv4 does not define a shorthand notation for addresses with octets
|
||||
set to zero, these two attributes are always the same as ``str(addr)``
|
||||
for IPv4 addresses. Exposing these attributes makes it easier to
|
||||
write display code that can handle both IPv4 and IPv6 addresses.
|
||||
|
||||
.. attribute:: packed
|
||||
|
||||
The binary representation of this address - a :class:`bytes` object of
|
||||
the appropriate length (most significant octet first). This is 4 bytes
|
||||
for IPv4 and 16 bytes for IPv6.
|
||||
|
||||
.. attribute:: is_multicast
|
||||
|
||||
``True`` if the address is reserved for multicast use. See :RFC:`3171` (for
|
||||
IPv4) or :RFC:`2373` (for IPv6).
|
||||
``True`` if the address is reserved for multicast use. See
|
||||
:RFC:`3171` (for IPv4) or :RFC:`2373` (for IPv6).
|
||||
|
||||
.. attribute:: is_private
|
||||
|
||||
``True`` if the address is allocated for private networks. See :RFC:`1918`
|
||||
(for IPv4) or :RFC:`4193` (for IPv6).
|
||||
``True`` if the address is allocated for private networks. See
|
||||
:RFC:`1918` (for IPv4) or :RFC:`4193` (for IPv6).
|
||||
|
||||
.. attribute:: is_unspecified
|
||||
|
||||
``True`` if the address is unspecified. See :RFC:`5375` (for IPv4) or
|
||||
:RFC:`2373` (for IPv6).
|
||||
``True`` if the address is unspecified. See :RFC:`5375` (for IPv4)
|
||||
or :RFC:`2373` (for IPv6).
|
||||
|
||||
.. attribute:: is_reserved
|
||||
|
||||
``True`` if the address is otherwise IETF reserved.
|
||||
``True`` if the address is otherwise IETF reserved.
|
||||
|
||||
.. attribute:: is_loopback
|
||||
|
||||
``True`` if this is a loopback address. See :RFC:`3330` (for IPv4) or
|
||||
:RFC:`2373` (for IPv6).
|
||||
``True`` if this is a loopback address. See :RFC:`3330` (for IPv4)
|
||||
or :RFC:`2373` (for IPv6).
|
||||
|
||||
.. attribute:: is_link_local
|
||||
|
||||
``True`` if the address is reserved for link-local. See :RFC:`3927`.
|
||||
``True`` if the address is reserved for link-local usage. See
|
||||
:RFC:`3927`.
|
||||
|
||||
|
||||
.. class:: IPv6Address(address)
|
||||
|
||||
|
@ -165,31 +196,75 @@ common attributes will only be documented for :class:`IPv4Address`.
|
|||
>>> ipaddress.IPv6Address('2001:db8::1000')
|
||||
IPv6Address('2001:db8::1000')
|
||||
|
||||
All the attributes exposed by :class:`IPv4Address` are supported. In
|
||||
addition, the following attributs are exposed only by :class:`IPv6Address`.
|
||||
.. attribute:: compressed
|
||||
|
||||
The short form of the address representation, with leading zeroes in
|
||||
groups omitted and the longest sequence of groups consisting entirely of
|
||||
zeroes collapsed to a single empty group.
|
||||
|
||||
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.
|
||||
|
||||
.. attribute:: packed
|
||||
.. attribute:: version
|
||||
.. attribute:: max_prefixlen
|
||||
.. attribute:: is_multicast
|
||||
.. attribute:: is_private
|
||||
.. attribute:: is_unspecified
|
||||
.. attribute:: is_reserved
|
||||
.. attribute:: is_loopback
|
||||
.. attribute:: is_link_local
|
||||
|
||||
Refer to the corresponding attribute documentation in
|
||||
:class:`IPv4Address`
|
||||
|
||||
.. attribute:: is_site_local
|
||||
|
||||
``True`` if the address is reserved for site-local. Note that the site-local
|
||||
address space has been deprecated by :RFC:`3879`. Use
|
||||
:attr:`~IPv4Address.is_private` to test if this address is in the space of
|
||||
unique local addresses as defined by :RFC:`4193`.
|
||||
``True`` if the address is reserved for site-local usage. Note that
|
||||
the site-local address space has been deprecated by :RFC:`3879`. Use
|
||||
:attr:`~IPv4Address.is_private` to test if this address is in the
|
||||
space of unique local addresses as defined by :RFC:`4193`.
|
||||
|
||||
.. attribute:: ipv4_mapped
|
||||
|
||||
If this address represents a IPv4 mapped address, return the IPv4 mapped
|
||||
address. Otherwise return ``None``.
|
||||
|
||||
.. attribute:: teredo
|
||||
|
||||
If this address appears to be a teredo address (starts with ``2001::/32``),
|
||||
return a tuple of embedded teredo IPs ``(server, client)`` pairs. Otherwise
|
||||
return ``None``.
|
||||
For addresses that appear to be IPv4 mapped addresses (starting with
|
||||
``::FFFF/96``), this property will report the embedded IPv4 address.
|
||||
For any other address, this property will be ``None``.
|
||||
|
||||
.. attribute:: sixtofour
|
||||
|
||||
If this address appears to contain a 6to4 embedded address, return the
|
||||
embedded IPv4 address. Otherwise return ``None``.
|
||||
For addresses that appear to be 6to4 addresses (starting with
|
||||
``2002::/16``) as defined by :RFC:`3056`, this property will report
|
||||
the embedded IPv4 address. For any other address, this property will
|
||||
be ``None``.
|
||||
|
||||
.. attribute:: teredo
|
||||
|
||||
For addresses that appear to be Teredo addresses (starting with
|
||||
``2001::/32``) as defined by :RFC:`4380`, this property will report
|
||||
the embedded ``(server, client)`` IP address pair. For any other
|
||||
address, this property will be ``None``.
|
||||
|
||||
|
||||
Conversion to Strings and Integers
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To interoperate with networking interfaces such as the socket module,
|
||||
addresses must be converted to strings or integers. This is handled using
|
||||
the :func:`str` and :func:`int` builtin functions::
|
||||
|
||||
>>> str(ipaddress.IPv4Address('192.168.0.1'))
|
||||
'192.168.0.1'
|
||||
>>> int(ipaddress.IPv4Address('192.168.0.1'))
|
||||
3232235521
|
||||
>>> str(ipaddress.IPv6Address('::1'))
|
||||
'::1'
|
||||
>>> int(ipaddress.IPv6Address('::1'))
|
||||
1
|
||||
|
||||
|
||||
Operators
|
||||
|
@ -199,6 +274,7 @@ Address 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
|
||||
"""""""""""""""""
|
||||
|
||||
|
@ -212,6 +288,7 @@ examples::
|
|||
>>> IPv4Address('127.0.0.2') != IPv4Address('127.0.0.1')
|
||||
True
|
||||
|
||||
|
||||
Arithmetic operators
|
||||
""""""""""""""""""""
|
||||
|
||||
|
@ -227,45 +304,337 @@ Integers can be added to or subtracted from address objects. Some examples::
|
|||
ipaddress.AddressValueError: 4294967296 (>= 2**32) is not permitted as an IPv4 address
|
||||
|
||||
|
||||
IP Network definitions
|
||||
----------------------
|
||||
|
||||
The :class:`IPv4Network` and :class:`IPv6Network` objects provide a mechanism
|
||||
for defining and inspecting IP network definitions. A network definition
|
||||
consists of a *mask* and a *network address*, and as such defines a range of
|
||||
IP addresses that equal the network address when masked (binary AND) with the
|
||||
mask. For example, a network definition with the mask ``255.255.255.0`` and
|
||||
the network address ``192.168.1.0`` consists of IP addresses in the inclusive
|
||||
range ``192.168.1.0`` to ``192.168.1.255``.
|
||||
|
||||
|
||||
Prefix, net mask and host mask
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
There are several equivalent ways to specify IP network masks. A *prefix*
|
||||
``/<nbits>`` is a notation that denotes how many high-order bits are set in
|
||||
the network mask. A *net mask* is an IP address with some number of
|
||||
high-order bits set. Thus the prefix ``/24`` is equivalent to the net mask
|
||||
``255.255.255.0`` in IPv4, or ``ffff:ff00::`` in IPv6. In addition, a
|
||||
*host mask* is the logical inverse of a *net mask*, and is sometimes used
|
||||
(for example in Cisco access control lists) to denote a network mask. The
|
||||
host mask equivalent to ``/24`` in IPv4 is ``0.0.0.255``.
|
||||
|
||||
|
||||
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`.
|
||||
|
||||
.. class:: IPv4Network(address, strict=True)
|
||||
|
||||
Construct an IPv4 network. *address* is a string or integer representing the
|
||||
IP address (and optionally the network). An :exc:`AddressValueError` is
|
||||
raised if *address* is not a valid IPv4 address. A :exc:`NetmaskValueError`
|
||||
is raised if the netmask is not valid for an IPv4 address.
|
||||
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``.
|
||||
|
||||
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``.
|
||||
|
||||
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*.
|
||||
|
||||
An :exc:`AddressValueError` is raised if *address* is not a valid IPv4
|
||||
address. A :exc:`NetmaskValueError` is raised if the mask is not valid for
|
||||
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
|
||||
then :exc:`ValueError` is raised. Otherwise, the host bits are masked out
|
||||
to determine the appropriate network address.
|
||||
|
||||
>>> ipaddress.IPv4Network('192.0.2.0/27')
|
||||
IPv4Network('192.0.2.0/27')
|
||||
>>> ipaddress.IPv4Network('192.0.2.0/27').netmask
|
||||
IPv4Address('255.255.255.224')
|
||||
>>> ipaddress.IPv4Network('192.0.2.5/27', strict=False)
|
||||
IPv4Network('192.0.2.0/27')
|
||||
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``
|
||||
|
||||
.. attribute:: version
|
||||
.. attribute:: max_prefixlen
|
||||
|
||||
Refer to the corresponding attribute documentation in
|
||||
: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
|
||||
true 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:: host mask
|
||||
|
||||
The host mask, as a string.
|
||||
|
||||
.. attribute:: with_prefixlen
|
||||
.. attribute:: compressed
|
||||
.. attribute:: exploded
|
||||
|
||||
A string representation of the network, with the mask in prefix
|
||||
notation.
|
||||
|
||||
``with_prefixlen`` and ``compressed`` are always the same as
|
||||
``str(network)``.
|
||||
``exploded`` uses the exploded form the network address.
|
||||
|
||||
.. attribute:: with_netmask
|
||||
|
||||
A string representation of the network, with the mask in net mask
|
||||
notation.
|
||||
|
||||
.. attribute:: with_hostmask
|
||||
|
||||
A string representation of the network, with the mask in host mask
|
||||
notation.
|
||||
|
||||
.. attribute:: num_addresses
|
||||
|
||||
The total number of addresses in the network.
|
||||
|
||||
.. attribute:: prefixlen
|
||||
|
||||
Length of the network prefix, in bits.
|
||||
|
||||
.. method:: hosts()
|
||||
|
||||
Returns an iterator over the usable hosts in the network. The usable
|
||||
hosts are all the IP addresses that belong to the network, except the
|
||||
network address itself and the network broadcast address.
|
||||
|
||||
>>> list(ip_network('192.0.2.0/29').hosts())
|
||||
[IPv4Address('192.0.2.1'), IPv4Address('192.0.2.2'),
|
||||
IPv4Address('192.0.2.3'), IPv4Address('192.0.2.4'),
|
||||
IPv4Address('192.0.2.5'), IPv4Address('192.0.2.6')]
|
||||
|
||||
.. method:: overlaps(other)
|
||||
|
||||
``True`` if this network is partly or wholly contained in *other* or
|
||||
or *other* is wholly contained in this network.
|
||||
|
||||
.. method:: address_exclude(network)
|
||||
|
||||
Computes the network definitions resulting from removing the given
|
||||
*network* from this one. Returns an iterator of network objects.
|
||||
Raises :exc:`ValueError` if *network* is not completely contained in
|
||||
this network.
|
||||
|
||||
>>> n1 = ip_network('192.0.2.0/28')
|
||||
>>> n2 = ip_network('192.0.2.1/32')
|
||||
>>> list(n1.address_exclude(n2))
|
||||
[IPv4Network('192.0.2.8/29'), IPv4Network('192.0.2.4/30'),
|
||||
IPv4Network('192.0.2.2/31'), IPv4Network('192.0.2.0/32')]
|
||||
|
||||
.. method:: subnets(prefixlen_diff=1, new_prefix=None)
|
||||
|
||||
The subnets that join to make the current network definition, depending
|
||||
on the argument values. *prefixlen_diff* is the amount our prefix
|
||||
length should be increased by. *new_prefix* is the desired new
|
||||
prefix of the subnets; it must be larger than our prefix. One and
|
||||
only one of *prefixlen_diff* and *new_prefix* must be set. Returns an
|
||||
iterator of network objects.
|
||||
|
||||
>>> list(ip_network('192.0.2.0/24').subnets())
|
||||
[IPv4Network('192.0.2.0/25'), IPv4Network('192.0.2.128/25')]
|
||||
>>> list(ip_network('192.0.2.0/24').subnets(prefixlen_diff=2))
|
||||
[IPv4Network('192.0.2.0/26'), IPv4Network('192.0.2.64/26'),
|
||||
IPv4Network('192.0.2.128/26'), IPv4Network('192.0.2.192/26')]
|
||||
>>> list(ip_network('192.0.2.0/24').subnets(new_prefix=26))
|
||||
[IPv4Network('192.0.2.0/26'), IPv4Network('192.0.2.64/26'),
|
||||
IPv4Network('192.0.2.128/26'), IPv4Network('192.0.2.192/26')]
|
||||
>>> list(ip_network('192.0.2.0/24').subnets(new_prefix=23))
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
raise ValueError('new prefix must be longer')
|
||||
ValueError: new prefix must be longer
|
||||
>>> list(ip_network('192.0.2.0/24').subnets(new_prefix=25))
|
||||
[IPv4Network('192.0.2.0/25'), IPv4Network('192.0.2.128/25')]
|
||||
|
||||
.. method:: supernet(prefixlen_diff=1, new_prefix=None)
|
||||
|
||||
The supernet containing this network definition, depending on the
|
||||
argument values. *prefixlen_diff* is the amount our prefix length
|
||||
should be decreased by. *new_prefix* is the desired new prefix of
|
||||
the supernet; it must be smaller than our prefix. One and only one
|
||||
of *prefixlen_diff* and *new_prefix* must be set. Returns a single
|
||||
network object.
|
||||
|
||||
>>> ip_network('192.0.2.0/24').supernet()
|
||||
IPv4Network('192.0.2.0/23')
|
||||
>>> ip_network('192.0.2.0/24').supernet(prefixlen_diff=2)
|
||||
IPv4Network('192.0.0.0/22')
|
||||
>>> ip_network('192.0.2.0/24').supernet(new_prefix=20)
|
||||
IPv4Network('192.0.0.0/20')
|
||||
|
||||
.. method:: compare_networks(other)
|
||||
|
||||
Compare this network to *other*. In this comparison only the network
|
||||
addresses are considered; host bits aren't. Returns either ``-1``,
|
||||
``0`` or ``1``.
|
||||
|
||||
>>> ip_network('192.0.2.1/32').compare_networks(ip_network('192.0.2.2/32'))
|
||||
-1
|
||||
>>> ip_network('192.0.2.1/32').compare_networks(ip_network('192.0.2.0/32'))
|
||||
1
|
||||
>>> 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. *address* is a string or integer representing the
|
||||
IP address (and optionally the network). An :exc:`AddressValueError` is
|
||||
raised if *address* is not a valid IPv6 address. A :exc:`NetmaskValueError`
|
||||
is raised if the netmask is not valid for an IPv6 address.
|
||||
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``.
|
||||
|
||||
For example, the following *address* specifications are equivalent:
|
||||
``2001:db00::0/24`` and ``2001:db00::0/ffff:ff00::``.
|
||||
|
||||
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, bit-endian.
|
||||
The interpretation is similar to an integer *address*.
|
||||
|
||||
An :exc:`AddressValueError` is raised if *address* is not a valid IPv6
|
||||
address. A :exc:`NetmaskValueError` is raised if the mask is not valid for
|
||||
an IPv6 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
|
||||
then :exc:`ValueError` is raised. Otherwise, the host bits are masked out
|
||||
to determine the appropriate network address.
|
||||
|
||||
>>> ipaddress.IPv6Network('2001:db8::/96')
|
||||
IPv6Network('2001:db8::/96')
|
||||
>>> ipaddress.IPv6Network('2001:db8::/96').netmask
|
||||
IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff::')
|
||||
>>> ipaddress.IPv6Network('2001:db8::1000/96', strict=False)
|
||||
IPv6Network('2001:db8::/96')
|
||||
.. attribute:: version
|
||||
.. attribute:: max_prefixlen
|
||||
.. attribute:: is_multicast
|
||||
.. attribute:: is_private
|
||||
.. attribute:: is_unspecified
|
||||
.. attribute:: is_reserved
|
||||
.. attribute:: is_loopback
|
||||
.. attribute:: is_link_local
|
||||
.. attribute:: network_address
|
||||
.. attribute:: broadcast_address
|
||||
.. attribute:: host mask
|
||||
.. 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`
|
||||
|
||||
.. attribute:: is_site_local
|
||||
|
||||
These attribute is true for the network as a whole if it is true
|
||||
true 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.
|
||||
|
||||
|
||||
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
|
||||
example::
|
||||
|
||||
>>> for addr in IPv4Network('192.0.2.0/28'):
|
||||
... addr
|
||||
...
|
||||
IPv4Address('192.0.2.0')
|
||||
IPv4Address('192.0.2.1')
|
||||
IPv4Address('192.0.2.2')
|
||||
IPv4Address('192.0.2.3')
|
||||
IPv4Address('192.0.2.4')
|
||||
IPv4Address('192.0.2.5')
|
||||
IPv4Address('192.0.2.6')
|
||||
IPv4Address('192.0.2.7')
|
||||
IPv4Address('192.0.2.8')
|
||||
IPv4Address('192.0.2.9')
|
||||
IPv4Address('192.0.2.10')
|
||||
IPv4Address('192.0.2.11')
|
||||
IPv4Address('192.0.2.12')
|
||||
IPv4Address('192.0.2.13')
|
||||
IPv4Address('192.0.2.14')
|
||||
IPv4Address('192.0.2.15')
|
||||
|
||||
|
||||
Networks as containers of addresses
|
||||
"""""""""""""""""""""""""""""""""""
|
||||
|
||||
Network objects can act as containers of addresses. Some examples::
|
||||
|
||||
>>> IPv4Network('192.0.2.0/28')[0]
|
||||
IPv4Address('192.0.2.0')
|
||||
>>> IPv4Network('192.0.2.0/28')[15]
|
||||
IPv4Address('192.0.2.15')
|
||||
>>> IPv4Address('192.0.2.6') in IPv4Network('192.0.2.0/28')
|
||||
True
|
||||
>>> IPv4Address('192.0.3.6') in IPv4Network('192.0.2.0/28')
|
||||
False
|
||||
|
||||
|
||||
Interface objects
|
||||
|
|
|
@ -2248,7 +2248,7 @@ features:
|
|||
dirs.remove('CVS') # don't visit CVS directories
|
||||
|
||||
In the next example, walking the tree bottom-up is essential:
|
||||
:func:`unlinkat` doesn't allow deleting a directory before the directory is
|
||||
:func:`rmdir` doesn't allow deleting a directory before the directory is
|
||||
empty::
|
||||
|
||||
# Delete everything reachable from the directory named in "top",
|
||||
|
@ -2258,9 +2258,9 @@ features:
|
|||
import os
|
||||
for root, dirs, files, rootfd in os.fwalk(top, topdown=False):
|
||||
for name in files:
|
||||
os.unlinkat(rootfd, name)
|
||||
os.unlink(name, dir_fd=rootfd)
|
||||
for name in dirs:
|
||||
os.unlinkat(rootfd, name, os.AT_REMOVEDIR)
|
||||
os.rmdir(name, dir_fd=rootfd)
|
||||
|
||||
Availability: Unix.
|
||||
|
||||
|
|
|
@ -53,6 +53,18 @@ This article explains the new features in Python 3.3, compared to 3.2.
|
|||
release, so it's worth checking back even after reading earlier versions.
|
||||
|
||||
|
||||
Summary
|
||||
=======
|
||||
|
||||
Major changes since Python 3.2:
|
||||
|
||||
* 4 new modules: :mod:`faulthandler`, :mod:`ipaddress`, :mod:`lzma` and :mod:`venv`.
|
||||
* Syntax changes:
|
||||
|
||||
- ``u'unicode'`` syntax is accepted again
|
||||
- Add ``yield from`` syntax
|
||||
|
||||
|
||||
PEP 405: Virtual Environments
|
||||
=============================
|
||||
|
||||
|
@ -786,8 +798,71 @@ aforementioned annoyances.
|
|||
(contributed by Antoine Pitrou in :issue:`9260`.)
|
||||
|
||||
|
||||
New and Improved Modules
|
||||
========================
|
||||
Builtin functions and types
|
||||
===========================
|
||||
|
||||
* :func:`open` gets a new *opener* parameter: the underlying file descriptor
|
||||
for the file object is then obtained by calling *opener* with (*file*,
|
||||
*flags*). It can be used to use custom flags like :data:`os.O_CLOEXEC` for
|
||||
example. The ``'x'`` mode was added: open for exclusive creation, failing if
|
||||
the file already exists.
|
||||
* :func:`print`: added the *flush* keyword argument. If the *flush* keyword
|
||||
argument is true, the stream is forcibly flushed.
|
||||
* :func:`hash`: hash randomization is enabled by default, see
|
||||
:meth:`object.__hash__` and :envvar:`PYTHONHASHSEED`.
|
||||
* The :class:`str` type gets a new :meth:`~str.casefold` method: return a
|
||||
casefolded copy of the string, casefolded strings may be used for caseless
|
||||
matching. For example, ``'ß'.casefold()`` returns ``'ss'``.
|
||||
|
||||
|
||||
New Modules
|
||||
===========
|
||||
|
||||
faulthandler
|
||||
------------
|
||||
|
||||
This new debug module contains functions to dump Python tracebacks explicitly,
|
||||
on a fault (a crash like a segmentation fault), after a timeout, or on a user
|
||||
signal. Call :func:`faulthandler.enable` to install fault handlers for the
|
||||
:const:`SIGSEGV`, :const:`SIGFPE`, :const:`SIGABRT`, :const:`SIGBUS`, and
|
||||
:const:`SIGILL` signals. You can also enable them at startup by setting the
|
||||
:envvar:`PYTHONFAULTHANDLER` environment variable or by using :option:`-X`
|
||||
``faulthandler`` command line option.
|
||||
|
||||
Example of a segmentation fault on Linux: ::
|
||||
|
||||
$ python -q -X faulthandler
|
||||
>>> import ctypes
|
||||
>>> ctypes.string_at(0)
|
||||
Fatal Python error: Segmentation fault
|
||||
|
||||
Current thread 0x00007fb899f39700:
|
||||
File "/home/python/cpython/Lib/ctypes/__init__.py", line 486 in string_at
|
||||
File "<stdin>", line 1 in <module>
|
||||
Segmentation fault
|
||||
|
||||
|
||||
ipaddress
|
||||
---------
|
||||
|
||||
The new :mod:`ipaddress` module provides tools for creating and manipulating
|
||||
objects representing IPv4 and IPv6 addresses, networks and interfaces (i.e.
|
||||
an IP address associated with a specific IP subnet).
|
||||
|
||||
(Contributed by Google and Peter Moody in :pep:`3144`)
|
||||
|
||||
lzma
|
||||
----
|
||||
|
||||
The newly-added :mod:`lzma` module provides data compression and decompression
|
||||
using the LZMA algorithm, including support for the ``.xz`` and ``.lzma``
|
||||
file formats.
|
||||
|
||||
(Contributed by Nadeem Vawda and Per Øyvind Karlsen in :issue:`6715`)
|
||||
|
||||
|
||||
Improved Modules
|
||||
================
|
||||
|
||||
abc
|
||||
---
|
||||
|
@ -815,12 +890,22 @@ The :mod:`array` module supports the :c:type:`long long` type using ``q`` and
|
|||
(Contributed by Oren Tirosh and Hirokazu Yamamoto in :issue:`1172711`)
|
||||
|
||||
|
||||
base64, binascii
|
||||
----------------
|
||||
|
||||
ASCII-only Unicode strings are now accepted by the decoding functions of the
|
||||
modern interface. For example, ``base64.b64decode('YWJj')`` returns ``b'abc'``.
|
||||
|
||||
|
||||
bz2
|
||||
---
|
||||
|
||||
The :mod:`bz2` module has been rewritten from scratch. In the process, several
|
||||
new features have been added:
|
||||
|
||||
* New :func:`bz2.open` function: open a bzip2-compressed file in binary or
|
||||
text mode.
|
||||
|
||||
* :class:`bz2.BZ2File` can now read from and write to arbitrary file-like
|
||||
objects, by means of its constructor's *fileobj* argument.
|
||||
|
||||
|
@ -910,7 +995,7 @@ their ``__init__`` method (for example, file objects) or in their
|
|||
crypt
|
||||
-----
|
||||
|
||||
Addition of salt and modular crypt format and the :func:`~crypt.mksalt`
|
||||
Addition of salt and modular crypt format (hashing method) and the :func:`~crypt.mksalt`
|
||||
function to the :mod:`crypt` module.
|
||||
|
||||
(:issue:`10924`)
|
||||
|
@ -931,6 +1016,17 @@ curses
|
|||
|
||||
(Contributed by Iñigo Serna in :issue:`6755`)
|
||||
|
||||
datetime
|
||||
--------
|
||||
|
||||
* Equality comparisons between naive and aware :class:`~datetime.datetime`
|
||||
instances don't raise :exc:`TypeError`.
|
||||
* New :meth:`datetime.datetime.timestamp` method: Return POSIX timestamp
|
||||
corresponding to the :class:`~datetime.datetime` instance.
|
||||
* The :meth:`datetime.datetime.strftime` method supports formatting years
|
||||
older than 1000.
|
||||
|
||||
|
||||
decimal
|
||||
-------
|
||||
|
||||
|
@ -1024,14 +1120,6 @@ API changes
|
|||
changed to match the order displayed by :func:`repr`.
|
||||
|
||||
|
||||
faulthandler
|
||||
------------
|
||||
|
||||
New module: :mod:`faulthandler`.
|
||||
|
||||
* :envvar:`PYTHONFAULTHANDLER`
|
||||
* :option:`-X` ``faulthandler``
|
||||
|
||||
ftplib
|
||||
------
|
||||
|
||||
|
@ -1043,6 +1131,13 @@ handle NAT with non-secure FTP without opening fixed ports.
|
|||
(Contributed by Giampaolo Rodolà in :issue:`12139`)
|
||||
|
||||
|
||||
gc
|
||||
--
|
||||
|
||||
It is now possible to register callbacks invoked by the garbage collector
|
||||
before and after collection using the new :`data:`~gc.callbacks` list.
|
||||
|
||||
|
||||
hmac
|
||||
----
|
||||
|
||||
|
@ -1087,24 +1182,11 @@ already exists. It is based on the C11 'x' mode to fopen().
|
|||
|
||||
(Contributed by David Townshend in :issue:`12760`)
|
||||
|
||||
|
||||
ipaddress
|
||||
---------
|
||||
|
||||
The new :mod:`ipaddress` module provides tools for creating and manipulating
|
||||
objects representing IPv4 and IPv6 addresses, networks and interfaces (i.e.
|
||||
an IP address associated with a specific IP subnet).
|
||||
|
||||
(Contributed by Google and Peter Moody in :pep:`3144`)
|
||||
|
||||
lzma
|
||||
----
|
||||
|
||||
The newly-added :mod:`lzma` module provides data compression and decompression
|
||||
using the LZMA algorithm, including support for the ``.xz`` and ``.lzma``
|
||||
file formats.
|
||||
|
||||
(Contributed by Nadeem Vawda and Per Øyvind Karlsen in :issue:`6715`)
|
||||
The constructor of the :class:`~io.TextIOWrapper` class has a new
|
||||
*write_through* optional argument. If *write_through* is ``True``, calls to
|
||||
:meth:`~io.TextIOWrapper.write` are guaranteed not to be buffered: any data
|
||||
written on the :class:`~io.TextIOWrapper` object is immediately handled to its
|
||||
underlying binary buffer.
|
||||
|
||||
|
||||
math
|
||||
|
@ -1163,6 +1245,30 @@ os
|
|||
|
||||
(Patch submitted by Ross Lagerwall and Giampaolo Rodolà in :issue:`10882`.)
|
||||
|
||||
* To avoid race conditions like symlink attacks and issues with temporary
|
||||
files and directories, it is more reliable (and also faster) to manipulate
|
||||
file descriptors instead of file names. Python 3.3 enhances existing functions
|
||||
and introduces new functions to work on file descriptors (:issue:`4761`,
|
||||
:issue:`10755`).
|
||||
|
||||
- The :mod:`os` module has a new :func:`~os.fwalk` function similar to
|
||||
:func:`~os.walk` except that it also yields file descriptors referring to the
|
||||
directories visited. This is especially useful to avoid symlink races.
|
||||
|
||||
- The following functions get new optional *dir_fd* (:ref:`paths relative to
|
||||
directory descriptors <dir_fd>`) and/or *follow_symlinks* (:ref:`not
|
||||
following symlinks <follow_symlinks>`):
|
||||
:func:`~os.access`, :func:`~os.chflags`, :func:`~os.chmod`, :func:`~os.chown`,
|
||||
:func:`~os.link`, :func:`~os.lstat`, :func:`~os.mkdir`, :func:`~os.mkfifo`,
|
||||
:func:`~os.mknod`, :func:`~os.open`, :func:`~os.readlink`, :func:`~os.remove`,
|
||||
:func:`~os.rename`, :func:`~os.replace`, :func:`~os.rmdir`, :func:`~os.stat`,
|
||||
:func:`~os.symlink`, :func:`~os.unlink`, :func:`~os.utime`.
|
||||
|
||||
- The following functions now support a file descriptor for their path argument:
|
||||
:func:`~os.chdir`, :func:`~os.chmod`, :func:`~os.chown`,
|
||||
:func:`~os.execve`, :func:`~os.listdir`, :func:`~os.pathconf`, :func:`~os.path.exists`,
|
||||
:func:`~os.stat`, :func:`~os.statvfs`, :func:`~os.utime`.
|
||||
|
||||
* The :mod:`os` module has two new functions: :func:`~os.getpriority` and
|
||||
:func:`~os.setpriority`. They can be used to get or set process
|
||||
niceness/priority in a fashion similar to :func:`os.nice` but extended to all
|
||||
|
@ -1170,10 +1276,6 @@ os
|
|||
|
||||
(Patch submitted by Giampaolo Rodolà in :issue:`10784`.)
|
||||
|
||||
* The :mod:`os` module has a new :func:`~os.fwalk` function similar to
|
||||
:func:`~os.walk` except that it also yields file descriptors referring to the
|
||||
directories visited. This is especially useful to avoid symlink races.
|
||||
|
||||
* The new :func:`os.replace` function allows cross-platform renaming of a
|
||||
file with overwriting the destination. With :func:`os.rename`, an existing
|
||||
destination file is overwritten under POSIX, but raises an error under
|
||||
|
@ -1181,78 +1283,51 @@ os
|
|||
(Contributed by Antoine Pitrou in :issue:`8828`.)
|
||||
|
||||
* The new :func:`os.get_terminal_size` function queries the size of the
|
||||
terminal attached to a file descriptor.
|
||||
terminal attached to a file descriptor. See also
|
||||
:func:`shutil.get_terminal_size`.
|
||||
(Contributed by Zbigniew Jędrzejewski-Szmek in :issue:`13609`.)
|
||||
|
||||
.. XXX sort out this mess after beta1
|
||||
|
||||
* "at" functions (:issue:`4761`):
|
||||
* New functions to support Linux extended attributes (:issue:`12720`):
|
||||
:func:`~os.getxattr`, :func:`~os.listxattr`, :func:`~os.removexattr`,
|
||||
:func:`~os.setxattr`.
|
||||
|
||||
* :func:`~os.faccessat`
|
||||
* :func:`~os.fchmodat`
|
||||
* :func:`~os.fchownat`
|
||||
* :func:`~os.fstatat`
|
||||
* :func:`~os.futimesat`
|
||||
* :func:`~os.linkat`
|
||||
* :func:`~os.mkdirat`
|
||||
* :func:`~os.mkfifoat`
|
||||
* :func:`~os.mknodat`
|
||||
* :func:`~os.openat`
|
||||
* :func:`~os.readlinkat`
|
||||
* :func:`~os.renameat`
|
||||
* :func:`~os.symlinkat`
|
||||
* :func:`~os.unlinkat`
|
||||
* :func:`~os.utimensat`
|
||||
* New interface to the scheduler. These functions
|
||||
control how a process is allocated CPU time by the operating system. New
|
||||
functions:
|
||||
:func:`~os.sched_get_priority_max`, :func:`~os.sched_get_priority_min`,
|
||||
:func:`~os.sched_getaffinity`, :func:`~os.sched_getparam`,
|
||||
:func:`~os.sched_getscheduler`, :func:`~os.sched_rr_get_interval`,
|
||||
:func:`~os.sched_setaffinity`, :func:`~os.sched_setparam`,
|
||||
:func:`~os.sched_setscheduler`, :func:`~os.sched_yield`,
|
||||
|
||||
* extended attributes (:issue:`12720`):
|
||||
* New functions to control the file system:
|
||||
|
||||
* :func:`~os.fgetxattr`
|
||||
* :func:`~os.flistxattr`
|
||||
* :func:`~os.fremovexattr`
|
||||
* :func:`~os.fsetxattr`
|
||||
* :func:`~os.getxattr`
|
||||
* :func:`~os.lgetxattr`
|
||||
* :func:`~os.listxattr`
|
||||
* :func:`~os.llistxattr`
|
||||
* :func:`~os.lremovexattr`
|
||||
* :func:`~os.lsetxattr`
|
||||
* :func:`~os.removexattr`
|
||||
* :func:`~os.setxattr`
|
||||
* :func:`~os.posix_fadvise`: Announces an intention to access data in a
|
||||
specific pattern thus allowing the kernel to make optimizations.
|
||||
* :func:`~os.posix_fallocate`: Ensures that enough disk space is allocated
|
||||
for a file.
|
||||
* :func:`~os.sync`: Force write of everything to disk.
|
||||
|
||||
* Scheduler functions (:issue:`12655`):
|
||||
* Add some extra posix functions to the os module:
|
||||
|
||||
* :func:`~os.sched_get_priority_max`
|
||||
* :func:`~os.sched_get_priority_min`
|
||||
* :func:`~os.sched_getaffinity`
|
||||
* :func:`~os.sched_getparam`
|
||||
* :func:`~os.sched_getscheduler`
|
||||
* :func:`~os.sched_rr_get_interval`
|
||||
* :func:`~os.sched_setaffinity`
|
||||
* :func:`~os.sched_setparam`
|
||||
* :func:`~os.sched_setscheduler`
|
||||
* :func:`~os.sched_yield`
|
||||
* :func:`~os.lockf`: Apply, test or remove a POSIX lock on an open file descriptor.
|
||||
* :func:`~os.pread`: Read from a file descriptor at an offset, the file
|
||||
offset remains unchanged.
|
||||
* :func:`~os.pwrite`: Write to a file descriptor from an offset, leaving
|
||||
the file offset unchanged.
|
||||
* :func:`~os.readv`: Read from a file descriptor into a number of writable buffers.
|
||||
* :func:`~os.truncate`: Truncate the file corresponding to *path*, so that
|
||||
it is at most *length* bytes in size.
|
||||
* :func:`~os.waitid`: Wait for the completion of one or more child processes.
|
||||
* :func:`~os.writev`: Write the contents of *buffers* to a file descriptor,
|
||||
where *buffers* is an arbitrary sequence of buffers.
|
||||
* :func:`~os.getgrouplist` (:issue:`9344`): Return list of group ids that
|
||||
specified user belongs to.
|
||||
|
||||
* Add some extra posix functions to the os module (:issue:`10812`):
|
||||
|
||||
* :func:`~os.fexecve`
|
||||
* :func:`~os.futimens`
|
||||
* :func:`~os.futimes`
|
||||
* :func:`~os.lockf`
|
||||
* :func:`~os.lutimes`
|
||||
* :func:`~os.posix_fadvise`
|
||||
* :func:`~os.posix_fallocate`
|
||||
* :func:`~os.pread`
|
||||
* :func:`~os.pwrite`
|
||||
* :func:`~os.readv`
|
||||
* :func:`~os.sync`
|
||||
* :func:`~os.truncate`
|
||||
* :func:`~os.waitid`
|
||||
* :func:`~os.writev`
|
||||
|
||||
* Other new functions:
|
||||
|
||||
* :func:`~os.flistdir` (:issue:`10755`)
|
||||
* :func:`~os.getgrouplist` (:issue:`9344`)
|
||||
* :func:`~os.times` and :func:`~os.uname`: Return type changed from a tuple to
|
||||
a tuple-like object with named attributes.
|
||||
|
||||
|
||||
pdb
|
||||
|
@ -1614,6 +1689,16 @@ Deprecated Python modules, functions and methods
|
|||
* The behaviour of :func:`time.clock` depends on the platform: use the new
|
||||
:func:`time.perf_counter` or :func:`time.process_time` function instead,
|
||||
depending on your requirements, to have a well defined behaviour.
|
||||
* The :func:`os.stat_float_times` function is deprecated.
|
||||
* :mod:`abc` module:
|
||||
|
||||
* :class:`abc.abstractproperty` has been deprecated, use :class:`property`
|
||||
with :func:`abc.abstractmethod` instead.
|
||||
* :class:`abc.abstractclassmethod` has been deprecated, use
|
||||
:class:`classmethod` with :func:`abc.abstractmethod` instead.
|
||||
* :class:`abc.abstractstaticmethod` has been deprecated, use
|
||||
:class:`staticmethod` with :func:`abc.abstractmethod` instead.
|
||||
|
||||
|
||||
|
||||
Deprecated functions and types of the C API
|
||||
|
@ -1690,7 +1775,9 @@ that may require changes to your code.
|
|||
Porting Python code
|
||||
-------------------
|
||||
|
||||
.. XXX add a point about hash randomization and that it's always on in 3.3
|
||||
* Hash randomization is enabled by default. Set the :envvar:`PYTHONHASHSEED`
|
||||
environment variable to ``0`` to disable hash randomization. See also the
|
||||
:meth:`object.__hash__` method.
|
||||
|
||||
* :issue:`12326`: On Linux, sys.platform doesn't contain the major version
|
||||
anymore. It is now always 'linux', instead of 'linux2' or 'linux3' depending
|
||||
|
|
|
@ -413,8 +413,10 @@ class GzipFile(io.BufferedIOBase):
|
|||
if self.fileobj is None:
|
||||
return b''
|
||||
try:
|
||||
# 1024 is the same buffering heuristic used in read()
|
||||
self._read(max(n, 1024))
|
||||
# Ensure that we don't return b"" if we haven't reached EOF.
|
||||
while self.extrasize == 0:
|
||||
# 1024 is the same buffering heuristic used in read()
|
||||
self._read(max(n, 1024))
|
||||
except EOFError:
|
||||
pass
|
||||
offset = self.offset - self.extrastart
|
||||
|
|
570
Lib/ipaddress.py
570
Lib/ipaddress.py
|
@ -497,6 +497,7 @@ class _IPAddressBase(_TotalOrderingMixin):
|
|||
prefixlen = self._prefixlen
|
||||
return self._string_from_ip_int(self._ip_int_from_prefix(prefixlen))
|
||||
|
||||
|
||||
class _BaseAddress(_IPAddressBase):
|
||||
|
||||
"""A generic IP object.
|
||||
|
@ -511,9 +512,6 @@ class _BaseAddress(_IPAddressBase):
|
|||
and '/' in str(address)):
|
||||
raise AddressValueError("Unexpected '/' in %r" % address)
|
||||
|
||||
def __index__(self):
|
||||
return self._ip
|
||||
|
||||
def __int__(self):
|
||||
return self._ip
|
||||
|
||||
|
@ -571,12 +569,6 @@ class _BaseNetwork(_IPAddressBase):
|
|||
def __init__(self, address):
|
||||
self._cache = {}
|
||||
|
||||
def __index__(self):
|
||||
return int(self.network_address) ^ self.prefixlen
|
||||
|
||||
def __int__(self):
|
||||
return int(self.network_address)
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(%r)' % (self.__class__.__name__, str(self))
|
||||
|
||||
|
@ -943,6 +935,76 @@ class _BaseNetwork(_IPAddressBase):
|
|||
strict=False)
|
||||
return t.__class__('%s/%d' % (t.network_address, t.prefixlen))
|
||||
|
||||
@property
|
||||
def is_multicast(self):
|
||||
"""Test if the address is reserved for multicast use.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is a multicast address.
|
||||
See RFC 2373 2.7 for details.
|
||||
|
||||
"""
|
||||
return (self.network_address.is_multicast and
|
||||
self.broadcast_address.is_multicast)
|
||||
|
||||
@property
|
||||
def is_reserved(self):
|
||||
"""Test if the address is otherwise IETF reserved.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is within one of the
|
||||
reserved IPv6 Network ranges.
|
||||
|
||||
"""
|
||||
return (self.network_address.is_reserved and
|
||||
self.broadcast_address.is_reserved)
|
||||
|
||||
@property
|
||||
def is_link_local(self):
|
||||
"""Test if the address is reserved for link-local.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is reserved per RFC 4291.
|
||||
|
||||
"""
|
||||
return (self.network_address.is_link_local and
|
||||
self.broadcast_address.is_link_local)
|
||||
|
||||
@property
|
||||
def is_private(self):
|
||||
"""Test if this address is allocated for private networks.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is reserved per RFC 4193.
|
||||
|
||||
"""
|
||||
return (self.network_address.is_private and
|
||||
self.broadcast_address.is_private)
|
||||
|
||||
@property
|
||||
def is_unspecified(self):
|
||||
"""Test if the address is unspecified.
|
||||
|
||||
Returns:
|
||||
A boolean, True if this is the unspecified address as defined in
|
||||
RFC 2373 2.5.2.
|
||||
|
||||
"""
|
||||
return (self.network_address.is_unspecified and
|
||||
self.broadcast_address.is_unspecified)
|
||||
|
||||
@property
|
||||
def is_loopback(self):
|
||||
"""Test if the address is a loopback address.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is a loopback address as defined in
|
||||
RFC 2373 2.5.3.
|
||||
|
||||
"""
|
||||
return (self.network_address.is_loopback and
|
||||
self.broadcast_address.is_loopback)
|
||||
|
||||
|
||||
class _BaseV4:
|
||||
|
||||
|
@ -1100,102 +1162,6 @@ class _BaseV4:
|
|||
def version(self):
|
||||
return self._version
|
||||
|
||||
@property
|
||||
def is_reserved(self):
|
||||
"""Test if the address is otherwise IETF reserved.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is within the
|
||||
reserved IPv4 Network range.
|
||||
|
||||
"""
|
||||
reserved_network = IPv4Network('240.0.0.0/4')
|
||||
if isinstance(self, _BaseAddress):
|
||||
return self in reserved_network
|
||||
return (self.network_address in reserved_network and
|
||||
self.broadcast_address in reserved_network)
|
||||
|
||||
@property
|
||||
def is_private(self):
|
||||
"""Test if this address is allocated for private networks.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is reserved per RFC 1918.
|
||||
|
||||
"""
|
||||
private_10 = IPv4Network('10.0.0.0/8')
|
||||
private_172 = IPv4Network('172.16.0.0/12')
|
||||
private_192 = IPv4Network('192.168.0.0/16')
|
||||
if isinstance(self, _BaseAddress):
|
||||
return (self in private_10 or self in private_172 or
|
||||
self in private_192)
|
||||
else:
|
||||
return ((self.network_address in private_10 and
|
||||
self.broadcast_address in private_10) or
|
||||
(self.network_address in private_172 and
|
||||
self.broadcast_address in private_172) or
|
||||
(self.network_address in private_192 and
|
||||
self.broadcast_address in private_192))
|
||||
|
||||
@property
|
||||
def is_multicast(self):
|
||||
"""Test if the address is reserved for multicast use.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is multicast.
|
||||
See RFC 3171 for details.
|
||||
|
||||
"""
|
||||
multicast_network = IPv4Network('224.0.0.0/4')
|
||||
if isinstance(self, _BaseAddress):
|
||||
return self in IPv4Network('224.0.0.0/4')
|
||||
return (self.network_address in multicast_network and
|
||||
self.broadcast_address in multicast_network)
|
||||
|
||||
@property
|
||||
def is_unspecified(self):
|
||||
"""Test if the address is unspecified.
|
||||
|
||||
Returns:
|
||||
A boolean, True if this is the unspecified address as defined in
|
||||
RFC 5735 3.
|
||||
|
||||
"""
|
||||
unspecified_address = IPv4Address('0.0.0.0')
|
||||
if isinstance(self, _BaseAddress):
|
||||
return self == unspecified_address
|
||||
return (self.network_address == self.broadcast_address ==
|
||||
unspecified_address)
|
||||
|
||||
@property
|
||||
def is_loopback(self):
|
||||
"""Test if the address is a loopback address.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is a loopback per RFC 3330.
|
||||
|
||||
"""
|
||||
loopback_address = IPv4Network('127.0.0.0/8')
|
||||
if isinstance(self, _BaseAddress):
|
||||
return self in loopback_address
|
||||
|
||||
return (self.network_address in loopback_address and
|
||||
self.broadcast_address in loopback_address)
|
||||
|
||||
@property
|
||||
def is_link_local(self):
|
||||
"""Test if the address is reserved for link-local.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is link-local per RFC 3927.
|
||||
|
||||
"""
|
||||
linklocal_network = IPv4Network('169.254.0.0/16')
|
||||
if isinstance(self, _BaseAddress):
|
||||
return self in linklocal_network
|
||||
return (self.network_address in linklocal_network and
|
||||
self.broadcast_address in linklocal_network)
|
||||
|
||||
|
||||
class IPv4Address(_BaseV4, _BaseAddress):
|
||||
|
||||
|
@ -1242,6 +1208,79 @@ class IPv4Address(_BaseV4, _BaseAddress):
|
|||
"""The binary representation of this address."""
|
||||
return v4_int_to_packed(self._ip)
|
||||
|
||||
@property
|
||||
def is_reserved(self):
|
||||
"""Test if the address is otherwise IETF reserved.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is within the
|
||||
reserved IPv4 Network range.
|
||||
|
||||
"""
|
||||
reserved_network = IPv4Network('240.0.0.0/4')
|
||||
return self in reserved_network
|
||||
|
||||
@property
|
||||
def is_private(self):
|
||||
"""Test if this address is allocated for private networks.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is reserved per RFC 1918.
|
||||
|
||||
"""
|
||||
private_10 = IPv4Network('10.0.0.0/8')
|
||||
private_172 = IPv4Network('172.16.0.0/12')
|
||||
private_192 = IPv4Network('192.168.0.0/16')
|
||||
return (self in private_10 or
|
||||
self in private_172 or
|
||||
self in private_192)
|
||||
|
||||
@property
|
||||
def is_multicast(self):
|
||||
"""Test if the address is reserved for multicast use.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is multicast.
|
||||
See RFC 3171 for details.
|
||||
|
||||
"""
|
||||
multicast_network = IPv4Network('224.0.0.0/4')
|
||||
return self in multicast_network
|
||||
|
||||
@property
|
||||
def is_unspecified(self):
|
||||
"""Test if the address is unspecified.
|
||||
|
||||
Returns:
|
||||
A boolean, True if this is the unspecified address as defined in
|
||||
RFC 5735 3.
|
||||
|
||||
"""
|
||||
unspecified_address = IPv4Address('0.0.0.0')
|
||||
return self == unspecified_address
|
||||
|
||||
@property
|
||||
def is_loopback(self):
|
||||
"""Test if the address is a loopback address.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is a loopback per RFC 3330.
|
||||
|
||||
"""
|
||||
loopback_network = IPv4Network('127.0.0.0/8')
|
||||
return self in loopback_network
|
||||
|
||||
@property
|
||||
def is_link_local(self):
|
||||
"""Test if the address is reserved for link-local.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is link-local per RFC 3927.
|
||||
|
||||
"""
|
||||
linklocal_network = IPv4Network('169.254.0.0/16')
|
||||
return self in linklocal_network
|
||||
|
||||
|
||||
class IPv4Interface(IPv4Address):
|
||||
|
||||
|
@ -1291,10 +1330,6 @@ class IPv4Interface(IPv4Address):
|
|||
def __hash__(self):
|
||||
return self._ip ^ self._prefixlen ^ int(self.network.network_address)
|
||||
|
||||
@property
|
||||
def prefixlen(self):
|
||||
return self._prefixlen
|
||||
|
||||
@property
|
||||
def ip(self):
|
||||
return IPv4Address(self._ip)
|
||||
|
@ -1669,7 +1704,7 @@ class _BaseV6:
|
|||
hex_str = '%032x' % ip_int
|
||||
parts = [hex_str[x:x+4] for x in range(0, 32, 4)]
|
||||
if isinstance(self, (_BaseNetwork, IPv6Interface)):
|
||||
return '%s/%d' % (':'.join(parts), self.prefixlen)
|
||||
return '%s/%d' % (':'.join(parts), self._prefixlen)
|
||||
return ':'.join(parts)
|
||||
|
||||
@property
|
||||
|
@ -1680,162 +1715,6 @@ class _BaseV6:
|
|||
def version(self):
|
||||
return self._version
|
||||
|
||||
@property
|
||||
def is_multicast(self):
|
||||
"""Test if the address is reserved for multicast use.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is a multicast address.
|
||||
See RFC 2373 2.7 for details.
|
||||
|
||||
"""
|
||||
multicast_network = IPv6Network('ff00::/8')
|
||||
if isinstance(self, _BaseAddress):
|
||||
return self in multicast_network
|
||||
return (self.network_address in multicast_network and
|
||||
self.broadcast_address in multicast_network)
|
||||
|
||||
@property
|
||||
def is_reserved(self):
|
||||
"""Test if the address is otherwise IETF reserved.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is within one of the
|
||||
reserved IPv6 Network ranges.
|
||||
|
||||
"""
|
||||
reserved_networks = [IPv6Network('::/8'), IPv6Network('100::/8'),
|
||||
IPv6Network('200::/7'), IPv6Network('400::/6'),
|
||||
IPv6Network('800::/5'), IPv6Network('1000::/4'),
|
||||
IPv6Network('4000::/3'), IPv6Network('6000::/3'),
|
||||
IPv6Network('8000::/3'), IPv6Network('A000::/3'),
|
||||
IPv6Network('C000::/3'), IPv6Network('E000::/4'),
|
||||
IPv6Network('F000::/5'), IPv6Network('F800::/6'),
|
||||
IPv6Network('FE00::/9')]
|
||||
|
||||
if isinstance(self, _BaseAddress):
|
||||
return any(self in x for x in reserved_networks)
|
||||
return any(self.network_address in x and self.broadcast_address in x
|
||||
for x in reserved_networks)
|
||||
|
||||
@property
|
||||
def is_link_local(self):
|
||||
"""Test if the address is reserved for link-local.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is reserved per RFC 4291.
|
||||
|
||||
"""
|
||||
linklocal_network = IPv6Network('fe80::/10')
|
||||
if isinstance(self, _BaseAddress):
|
||||
return self in linklocal_network
|
||||
return (self.network_address in linklocal_network and
|
||||
self.broadcast_address in linklocal_network)
|
||||
|
||||
@property
|
||||
def is_site_local(self):
|
||||
"""Test if the address is reserved for site-local.
|
||||
|
||||
Note that the site-local address space has been deprecated by RFC 3879.
|
||||
Use is_private to test if this address is in the space of unique local
|
||||
addresses as defined by RFC 4193.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is reserved per RFC 3513 2.5.6.
|
||||
|
||||
"""
|
||||
sitelocal_network = IPv6Network('fec0::/10')
|
||||
if isinstance(self, _BaseAddress):
|
||||
return self in sitelocal_network
|
||||
return (self.network_address in sitelocal_network and
|
||||
self.broadcast_address in sitelocal_network)
|
||||
|
||||
@property
|
||||
def is_private(self):
|
||||
"""Test if this address is allocated for private networks.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is reserved per RFC 4193.
|
||||
|
||||
"""
|
||||
private_network = IPv6Network('fc00::/7')
|
||||
if isinstance(self, _BaseAddress):
|
||||
return self in private_network
|
||||
return (self.network_address in private_network and
|
||||
self.broadcast_address in private_network)
|
||||
|
||||
@property
|
||||
def ipv4_mapped(self):
|
||||
"""Return the IPv4 mapped address.
|
||||
|
||||
Returns:
|
||||
If the IPv6 address is a v4 mapped address, return the
|
||||
IPv4 mapped address. Return None otherwise.
|
||||
|
||||
"""
|
||||
if (self._ip >> 32) != 0xFFFF:
|
||||
return None
|
||||
return IPv4Address(self._ip & 0xFFFFFFFF)
|
||||
|
||||
@property
|
||||
def teredo(self):
|
||||
"""Tuple of embedded teredo IPs.
|
||||
|
||||
Returns:
|
||||
Tuple of the (server, client) IPs or None if the address
|
||||
doesn't appear to be a teredo address (doesn't start with
|
||||
2001::/32)
|
||||
|
||||
"""
|
||||
if (self._ip >> 96) != 0x20010000:
|
||||
return None
|
||||
return (IPv4Address((self._ip >> 64) & 0xFFFFFFFF),
|
||||
IPv4Address(~self._ip & 0xFFFFFFFF))
|
||||
|
||||
@property
|
||||
def sixtofour(self):
|
||||
"""Return the IPv4 6to4 embedded address.
|
||||
|
||||
Returns:
|
||||
The IPv4 6to4-embedded address if present or None if the
|
||||
address doesn't appear to contain a 6to4 embedded address.
|
||||
|
||||
"""
|
||||
if (self._ip >> 112) != 0x2002:
|
||||
return None
|
||||
return IPv4Address((self._ip >> 80) & 0xFFFFFFFF)
|
||||
|
||||
@property
|
||||
def is_unspecified(self):
|
||||
"""Test if the address is unspecified.
|
||||
|
||||
Returns:
|
||||
A boolean, True if this is the unspecified address as defined in
|
||||
RFC 2373 2.5.2.
|
||||
|
||||
"""
|
||||
if isinstance(self, (IPv6Network, IPv6Interface)):
|
||||
return int(self.network_address) == 0 and getattr(
|
||||
self, '_prefixlen', 128) == 128
|
||||
return self._ip == 0
|
||||
|
||||
@property
|
||||
def is_loopback(self):
|
||||
"""Test if the address is a loopback address.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is a loopback address as defined in
|
||||
RFC 2373 2.5.3.
|
||||
|
||||
"""
|
||||
if isinstance(self, IPv6Network):
|
||||
return int(self) == 1 and getattr(
|
||||
self, '_prefixlen', 128) == 128
|
||||
elif isinstance(self, IPv6Interface):
|
||||
return int(self.network.network_address) == 1 and getattr(
|
||||
self, '_prefixlen', 128) == 128
|
||||
return self._ip == 1
|
||||
|
||||
|
||||
class IPv6Address(_BaseV6, _BaseAddress):
|
||||
|
||||
|
@ -1884,6 +1763,138 @@ class IPv6Address(_BaseV6, _BaseAddress):
|
|||
"""The binary representation of this address."""
|
||||
return v6_int_to_packed(self._ip)
|
||||
|
||||
@property
|
||||
def is_multicast(self):
|
||||
"""Test if the address is reserved for multicast use.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is a multicast address.
|
||||
See RFC 2373 2.7 for details.
|
||||
|
||||
"""
|
||||
multicast_network = IPv6Network('ff00::/8')
|
||||
return self in multicast_network
|
||||
|
||||
@property
|
||||
def is_reserved(self):
|
||||
"""Test if the address is otherwise IETF reserved.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is within one of the
|
||||
reserved IPv6 Network ranges.
|
||||
|
||||
"""
|
||||
reserved_networks = [IPv6Network('::/8'), IPv6Network('100::/8'),
|
||||
IPv6Network('200::/7'), IPv6Network('400::/6'),
|
||||
IPv6Network('800::/5'), IPv6Network('1000::/4'),
|
||||
IPv6Network('4000::/3'), IPv6Network('6000::/3'),
|
||||
IPv6Network('8000::/3'), IPv6Network('A000::/3'),
|
||||
IPv6Network('C000::/3'), IPv6Network('E000::/4'),
|
||||
IPv6Network('F000::/5'), IPv6Network('F800::/6'),
|
||||
IPv6Network('FE00::/9')]
|
||||
|
||||
return any(self in x for x in reserved_networks)
|
||||
|
||||
@property
|
||||
def is_link_local(self):
|
||||
"""Test if the address is reserved for link-local.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is reserved per RFC 4291.
|
||||
|
||||
"""
|
||||
linklocal_network = IPv6Network('fe80::/10')
|
||||
return self in linklocal_network
|
||||
|
||||
@property
|
||||
def is_site_local(self):
|
||||
"""Test if the address is reserved for site-local.
|
||||
|
||||
Note that the site-local address space has been deprecated by RFC 3879.
|
||||
Use is_private to test if this address is in the space of unique local
|
||||
addresses as defined by RFC 4193.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is reserved per RFC 3513 2.5.6.
|
||||
|
||||
"""
|
||||
sitelocal_network = IPv6Network('fec0::/10')
|
||||
return self in sitelocal_network
|
||||
|
||||
@property
|
||||
def is_private(self):
|
||||
"""Test if this address is allocated for private networks.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is reserved per RFC 4193.
|
||||
|
||||
"""
|
||||
private_network = IPv6Network('fc00::/7')
|
||||
return self in private_network
|
||||
|
||||
@property
|
||||
def is_unspecified(self):
|
||||
"""Test if the address is unspecified.
|
||||
|
||||
Returns:
|
||||
A boolean, True if this is the unspecified address as defined in
|
||||
RFC 2373 2.5.2.
|
||||
|
||||
"""
|
||||
return self._ip == 0
|
||||
|
||||
@property
|
||||
def is_loopback(self):
|
||||
"""Test if the address is a loopback address.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is a loopback address as defined in
|
||||
RFC 2373 2.5.3.
|
||||
|
||||
"""
|
||||
return self._ip == 1
|
||||
|
||||
@property
|
||||
def ipv4_mapped(self):
|
||||
"""Return the IPv4 mapped address.
|
||||
|
||||
Returns:
|
||||
If the IPv6 address is a v4 mapped address, return the
|
||||
IPv4 mapped address. Return None otherwise.
|
||||
|
||||
"""
|
||||
if (self._ip >> 32) != 0xFFFF:
|
||||
return None
|
||||
return IPv4Address(self._ip & 0xFFFFFFFF)
|
||||
|
||||
@property
|
||||
def teredo(self):
|
||||
"""Tuple of embedded teredo IPs.
|
||||
|
||||
Returns:
|
||||
Tuple of the (server, client) IPs or None if the address
|
||||
doesn't appear to be a teredo address (doesn't start with
|
||||
2001::/32)
|
||||
|
||||
"""
|
||||
if (self._ip >> 96) != 0x20010000:
|
||||
return None
|
||||
return (IPv4Address((self._ip >> 64) & 0xFFFFFFFF),
|
||||
IPv4Address(~self._ip & 0xFFFFFFFF))
|
||||
|
||||
@property
|
||||
def sixtofour(self):
|
||||
"""Return the IPv4 6to4 embedded address.
|
||||
|
||||
Returns:
|
||||
The IPv4 6to4-embedded address if present or None if the
|
||||
address doesn't appear to contain a 6to4 embedded address.
|
||||
|
||||
"""
|
||||
if (self._ip >> 112) != 0x2002:
|
||||
return None
|
||||
return IPv4Address((self._ip >> 80) & 0xFFFFFFFF)
|
||||
|
||||
|
||||
class IPv6Interface(IPv6Address):
|
||||
|
||||
|
@ -1931,10 +1942,6 @@ class IPv6Interface(IPv6Address):
|
|||
def __hash__(self):
|
||||
return self._ip ^ self._prefixlen ^ int(self.network.network_address)
|
||||
|
||||
@property
|
||||
def prefixlen(self):
|
||||
return self._prefixlen
|
||||
|
||||
@property
|
||||
def ip(self):
|
||||
return IPv6Address(self._ip)
|
||||
|
@ -1952,6 +1959,14 @@ class IPv6Interface(IPv6Address):
|
|||
return '%s/%s' % (self._string_from_ip_int(self._ip),
|
||||
self.hostmask)
|
||||
|
||||
@property
|
||||
def is_unspecified(self):
|
||||
return self._ip == 0 and self.network.is_unspecified
|
||||
|
||||
@property
|
||||
def is_loopback(self):
|
||||
return self._ip == 1 and self.network.is_loopback
|
||||
|
||||
|
||||
class IPv6Network(_BaseV6, _BaseNetwork):
|
||||
|
||||
|
@ -2060,3 +2075,18 @@ class IPv6Network(_BaseV6, _BaseNetwork):
|
|||
except ValueError:
|
||||
return False
|
||||
return 0 <= prefixlen <= self._max_prefixlen
|
||||
|
||||
@property
|
||||
def is_site_local(self):
|
||||
"""Test if the address is reserved for site-local.
|
||||
|
||||
Note that the site-local address space has been deprecated by RFC 3879.
|
||||
Use is_private to test if this address is in the space of unique local
|
||||
addresses as defined by RFC 4193.
|
||||
|
||||
Returns:
|
||||
A boolean, True if the address is reserved per RFC 3513 2.5.6.
|
||||
|
||||
"""
|
||||
return (self.network_address.is_site_local and
|
||||
self.broadcast_address.is_site_local)
|
||||
|
|
|
@ -313,6 +313,8 @@ class CGIHTTPServerTestCase(BaseTestCase):
|
|||
class request_handler(NoLogRequestHandler, CGIHTTPRequestHandler):
|
||||
pass
|
||||
|
||||
linesep = os.linesep.encode('ascii')
|
||||
|
||||
def setUp(self):
|
||||
BaseTestCase.setUp(self)
|
||||
self.cwd = os.getcwd()
|
||||
|
@ -410,7 +412,7 @@ class CGIHTTPServerTestCase(BaseTestCase):
|
|||
|
||||
def test_headers_and_content(self):
|
||||
res = self.request('/cgi-bin/file1.py')
|
||||
self.assertEqual((b'Hello World\n', 'text/html', 200),
|
||||
self.assertEqual((b'Hello World' + self.linesep, 'text/html', 200),
|
||||
(res.read(), res.getheader('Content-type'), res.status))
|
||||
|
||||
def test_post(self):
|
||||
|
@ -419,7 +421,7 @@ class CGIHTTPServerTestCase(BaseTestCase):
|
|||
headers = {'Content-type' : 'application/x-www-form-urlencoded'}
|
||||
res = self.request('/cgi-bin/file2.py', 'POST', params, headers)
|
||||
|
||||
self.assertEqual(res.read(), b'1, python, 123456\n')
|
||||
self.assertEqual(res.read(), b'1, python, 123456' + self.linesep)
|
||||
|
||||
def test_invaliduri(self):
|
||||
res = self.request('/cgi-bin/invalid')
|
||||
|
@ -430,20 +432,20 @@ class CGIHTTPServerTestCase(BaseTestCase):
|
|||
headers = {b'Authorization' : b'Basic ' +
|
||||
base64.b64encode(b'username:pass')}
|
||||
res = self.request('/cgi-bin/file1.py', 'GET', headers=headers)
|
||||
self.assertEqual((b'Hello World\n', 'text/html', 200),
|
||||
self.assertEqual((b'Hello World' + self.linesep, 'text/html', 200),
|
||||
(res.read(), res.getheader('Content-type'), res.status))
|
||||
|
||||
def test_no_leading_slash(self):
|
||||
# http://bugs.python.org/issue2254
|
||||
res = self.request('cgi-bin/file1.py')
|
||||
self.assertEqual((b'Hello World\n', 'text/html', 200),
|
||||
self.assertEqual((b'Hello World' + self.linesep, 'text/html', 200),
|
||||
(res.read(), res.getheader('Content-type'), res.status))
|
||||
|
||||
def test_os_environ_is_not_altered(self):
|
||||
signature = "Test CGI Server"
|
||||
os.environ['SERVER_SOFTWARE'] = signature
|
||||
res = self.request('/cgi-bin/file1.py')
|
||||
self.assertEqual((b'Hello World\n', 'text/html', 200),
|
||||
self.assertEqual((b'Hello World' + self.linesep, 'text/html', 200),
|
||||
(res.read(), res.getheader('Content-type'), res.status))
|
||||
self.assertEqual(os.environ['SERVER_SOFTWARE'], signature)
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
import unittest
|
||||
import re
|
||||
import contextlib
|
||||
import operator
|
||||
import ipaddress
|
||||
|
||||
class BaseTestCase(unittest.TestCase):
|
||||
|
@ -72,6 +73,14 @@ class CommonTestMixin:
|
|||
with self.assertAddressError(re.escape(repr("1.0"))):
|
||||
self.factory(1.0)
|
||||
|
||||
def test_not_an_index_issue15559(self):
|
||||
# Implementing __index__ makes for a very nasty interaction with the
|
||||
# bytes constructor. Thus, we disallow implicit use as an integer
|
||||
self.assertRaises(TypeError, operator.index, self.factory(1))
|
||||
self.assertRaises(TypeError, hex, self.factory(1))
|
||||
self.assertRaises(TypeError, bytes, self.factory(1))
|
||||
|
||||
|
||||
class CommonTestMixin_v4(CommonTestMixin):
|
||||
|
||||
def test_leading_zeros(self):
|
||||
|
@ -599,7 +608,6 @@ class IpaddrUnitTest(unittest.TestCase):
|
|||
self.assertEqual(first, last)
|
||||
self.assertEqual(128, ipaddress._count_righthand_zero_bits(0, 128))
|
||||
self.assertEqual("IPv4Network('1.2.3.0/24')", repr(self.ipv4_network))
|
||||
self.assertEqual('0x1020318', hex(self.ipv4_network))
|
||||
|
||||
def testMissingAddressVersion(self):
|
||||
class Broken(ipaddress._BaseAddress):
|
||||
|
@ -639,8 +647,8 @@ class IpaddrUnitTest(unittest.TestCase):
|
|||
|
||||
ipv4 = ipaddress.ip_network('1.2.3.4')
|
||||
ipv6 = ipaddress.ip_network('2001:658:22a:cafe:200:0:0:1')
|
||||
self.assertEqual(ipv4, ipaddress.ip_network(int(ipv4)))
|
||||
self.assertEqual(ipv6, ipaddress.ip_network(int(ipv6)))
|
||||
self.assertEqual(ipv4, ipaddress.ip_network(int(ipv4.network_address)))
|
||||
self.assertEqual(ipv6, ipaddress.ip_network(int(ipv6.network_address)))
|
||||
|
||||
v6_int = 42540616829182469433547762482097946625
|
||||
self.assertEqual(self.ipv6_interface._ip,
|
||||
|
@ -723,8 +731,8 @@ class IpaddrUnitTest(unittest.TestCase):
|
|||
'2001:658:22a:cafe:ffff:ffff:ffff:ffff')
|
||||
|
||||
def testGetPrefixlen(self):
|
||||
self.assertEqual(self.ipv4_interface.prefixlen, 24)
|
||||
self.assertEqual(self.ipv6_interface.prefixlen, 64)
|
||||
self.assertEqual(self.ipv4_interface.network.prefixlen, 24)
|
||||
self.assertEqual(self.ipv6_interface.network.prefixlen, 64)
|
||||
|
||||
def testGetSupernet(self):
|
||||
self.assertEqual(self.ipv4_network.supernet().prefixlen, 23)
|
||||
|
@ -1545,13 +1553,6 @@ class IpaddrUnitTest(unittest.TestCase):
|
|||
self.assertEqual(42540616829182469433547762482097946625,
|
||||
int(self.ipv6_address))
|
||||
|
||||
def testHexRepresentation(self):
|
||||
self.assertEqual(hex(0x1020304),
|
||||
hex(self.ipv4_address))
|
||||
|
||||
self.assertEqual(hex(0x20010658022ACAFE0200000000000001),
|
||||
hex(self.ipv6_address))
|
||||
|
||||
def testForceVersion(self):
|
||||
self.assertEqual(ipaddress.ip_network(1).version, 4)
|
||||
self.assertEqual(ipaddress.IPv6Network(1).version, 6)
|
||||
|
|
|
@ -77,8 +77,12 @@ Core and Builtins
|
|||
Library
|
||||
-------
|
||||
|
||||
- Issue #15546: Fix handling of pathological input data in the read1() method of
|
||||
the BZ2File, GzipFile and LZMAFile classes.
|
||||
- Issue #15559: To avoid a problematic failure mode when passed to the bytes
|
||||
constructor, objects in the ipaddress module no longer implement __index__
|
||||
(they still implement __int__ as appropriate)
|
||||
|
||||
- Issue #15546: Fix handling of pathological input data in the peek() and
|
||||
read1() methods of the BZ2File, GzipFile and LZMAFile classes.
|
||||
|
||||
- Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog
|
||||
ended with '\'. Patch by Roger Serwy.
|
||||
|
|
Loading…
Reference in New Issue