Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge alt-built Python 3.7 to Main Python 3.7 #59

Merged
merged 11 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 39 additions & 4 deletions Doc/library/ipaddress.rst
Original file line number Diff line number Diff line change
Expand Up @@ -168,18 +168,53 @@ 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``.

.. versionchanged:: 3.8.20

Fixed some false positives and false negatives.

* ``192.0.0.0/24`` is considered private with the exception of ``192.0.0.9/32`` and
``192.0.0.10/32`` (previously: only the ``192.0.0.0/29`` sub-range was considered private).
* ``64:ff9b:1::/48`` is considered private.
* ``2002::/16`` is considered private.
* There are exceptions within ``2001::/23`` (otherwise considered private): ``2001:1::1/128``,
``2001:1::2/128``, ``2001:3::/32``, ``2001:4:112::/48``, ``2001:20::/28``, ``2001:30::/28``.
The exceptions are not considered private.

.. 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

.. versionchanged:: 3.8.20

Fixed some false positives and false negatives, see :attr:`is_private` for details.

.. attribute:: is_unspecified

``True`` if the address is unspecified. See :RFC:`5735` (for IPv4)
Expand Down
15 changes: 14 additions & 1 deletion Doc/library/pathlib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ Methods and properties

.. testsetup::

from pathlib import PurePosixPath, PureWindowsPath
from pathlib import PurePath, PurePosixPath, PureWindowsPath

Pure paths provide the following methods and properties:

Expand Down Expand Up @@ -462,6 +462,19 @@ Pure paths provide the following methods and properties:
True


.. method:: PurePath.is_relative_to(*other)

Return whether or not this path is relative to the *other* path.

>>> p = PurePath('/etc/passwd')
>>> p.is_relative_to('/etc')
True
>>> p.is_relative_to('/usr')
False

.. versionadded:: 3.9


.. method:: PurePath.is_reserved()

With :class:`PureWindowsPath`, return ``True`` if the path is considered
Expand Down
15 changes: 12 additions & 3 deletions Doc/library/tempfile.rst
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,12 @@ The module defines the following user-callable items:
the truncate method now accepts a ``size`` argument.


.. function:: TemporaryDirectory(suffix=None, prefix=None, dir=None)
.. function:: TemporaryDirectory(suffix=None, prefix=None, dir=None, ignore_cleanup_errors=False)

This function securely creates a temporary directory using the same rules as :func:`mkdtemp`.
The resulting object can be used as a context manager (see
:ref:`tempfile-examples`). On completion of the context or destruction
of the temporary directory object the newly created temporary directory
of the temporary directory object, the newly created temporary directory
and all its contents are removed from the filesystem.

The directory name can be retrieved from the :attr:`name` attribute of the
Expand All @@ -119,10 +119,19 @@ The module defines the following user-callable items:
the :keyword:`with` statement, if there is one.

The directory can be explicitly cleaned up by calling the
:func:`cleanup` method.
:func:`cleanup` method. If *ignore_cleanup_errors* is true, any unhandled
exceptions during explicit or implicit cleanup (such as a
:exc:`PermissionError` removing open files on Windows) will be ignored,
and the remaining removable items deleted on a "best-effort" basis.
Otherwise, errors will be raised in whatever context cleanup occurs
(the :func:`cleanup` call, exiting the context manager, when the object
is garbage-collected or during interpreter shutdown).

.. versionadded:: 3.2

.. versionchanged:: 3.10
Added *ignore_cleanup_errors* parameter.


.. function:: mkstemp(suffix=None, prefix=None, dir=None, text=False)

Expand Down
8 changes: 8 additions & 0 deletions Doc/tools/susp-ignored.csv
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,14 @@ library/ipaddress,,:db00,2001:db00::0/24
library/ipaddress,,::,2001:db00::0/24
library/ipaddress,,:db00,2001:db00::0/ffff:ff00::
library/ipaddress,,::,2001:db00::0/ffff:ff00::
library/ipaddress,,:ff9b,64:ff9b:1::/48
library/ipaddress,,::,64:ff9b:1::/48
library/ipaddress,,::,2001::
library/ipaddress,,::,2001:1::
library/ipaddress,,::,2001:3::
library/ipaddress,,::,2001:4:112::
library/ipaddress,,::,2001:20::
library/ipaddress,,::,2001:30::
library/itertools,,:step,elements from seq[start:stop:step]
library/itertools,,:stop,elements from seq[start:stop:step]
library/logging.handlers,,:port,host:port
Expand Down
8 changes: 8 additions & 0 deletions Doc/whatsnew/3.7.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2650,3 +2650,11 @@ post-handshake TLS encrypted data. Security issue reported as
<https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-40217>`_ by Aapo
Oksman. Patch by Gregory P. Smith.

Notable changes in 3.7.17.4
=========================

ipaddress
---------

* Fixed ``is_global`` and ``is_private`` behavior in ``IPv4Address``,
``IPv6Address``, ``IPv4Network`` and ``IPv6Network``.
95 changes: 78 additions & 17 deletions Lib/ipaddress.py
Original file line number Diff line number Diff line change
Expand Up @@ -1345,18 +1345,41 @@ 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)
return (
any(self in net for net in self._constants._private_networks)
and all(self not in net for net in self._constants._private_networks_exceptions)
)

@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 @@ -1557,13 +1580,15 @@ class _IPv4Constants:

_public_network = IPv4Network('100.64.0.0/10')

# Not globally reachable address blocks listed on
# https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
_private_networks = [
IPv4Network('0.0.0.0/8'),
IPv4Network('10.0.0.0/8'),
IPv4Network('127.0.0.0/8'),
IPv4Network('169.254.0.0/16'),
IPv4Network('172.16.0.0/12'),
IPv4Network('192.0.0.0/29'),
IPv4Network('192.0.0.0/24'),
IPv4Network('192.0.0.170/31'),
IPv4Network('192.0.2.0/24'),
IPv4Network('192.168.0.0/16'),
Expand All @@ -1574,6 +1599,11 @@ class _IPv4Constants:
IPv4Network('255.255.255.255/32'),
]

_private_networks_exceptions = [
IPv4Network('192.0.0.9/32'),
IPv4Network('192.0.0.10/32'),
]

_reserved_network = IPv4Network('240.0.0.0/4')

_unspecified_address = IPv4Address('0.0.0.0')
Expand Down Expand Up @@ -1964,23 +1994,42 @@ 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.
* ``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)
ipv4_mapped = self.ipv4_mapped
if ipv4_mapped is not None:
return ipv4_mapped.is_private
return (
any(self in net for net in self._constants._private_networks)
and all(self not in net for net in self._constants._private_networks_exceptions)
)

@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 Expand Up @@ -2217,19 +2266,31 @@ class _IPv6Constants:

_multicast_network = IPv6Network('ff00::/8')

# Not globally reachable address blocks listed on
# https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
_private_networks = [
IPv6Network('::1/128'),
IPv6Network('::/128'),
IPv6Network('::ffff:0:0/96'),
IPv6Network('64:ff9b:1::/48'),
IPv6Network('100::/64'),
IPv6Network('2001::/23'),
IPv6Network('2001:2::/48'),
IPv6Network('2001:db8::/32'),
IPv6Network('2001:10::/28'),
# IANA says N/A, let's consider it not globally reachable to be safe
IPv6Network('2002::/16'),
IPv6Network('fc00::/7'),
IPv6Network('fe80::/10'),
]

_private_networks_exceptions = [
IPv6Network('2001:1::1/128'),
IPv6Network('2001:1::2/128'),
IPv6Network('2001:3::/32'),
IPv6Network('2001:4:112::/48'),
IPv6Network('2001:20::/28'),
IPv6Network('2001:30::/28'),
]

_reserved_networks = [
IPv6Network('::/8'), IPv6Network('100::/8'),
IPv6Network('200::/7'), IPv6Network('400::/6'),
Expand Down
9 changes: 9 additions & 0 deletions Lib/pathlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,15 @@ def relative_to(self, *other):
return self._from_parsed_parts('', root if n == 1 else '',
abs_parts[n:])

def is_relative_to(self, *other):
"""Return True if the path is relative to another path or False.
"""
try:
self.relative_to(*other)
return True
except ValueError:
return False

@property
def parts(self):
"""An object providing sequence-like access to the
Expand Down
2 changes: 1 addition & 1 deletion Lib/platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -1282,7 +1282,7 @@ def python_version_tuple():
will always include the patchlevel (it defaults to 0).

"""
return tuple(_sys_version()[1].split('.'))
return tuple(_sys_version()[1].split('.', 2))

def python_branch():

Expand Down
15 changes: 12 additions & 3 deletions Lib/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,18 +375,27 @@ def setcopyright():
"Jython is maintained by the Jython developers (www.jython.org).")
else:
builtins.credits = _sitebuiltins._Printer("credits", """\
ActivePython is a Python distribution by ActiveState Software Inc.
Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
for supporting Python development. See www.python.org for more information.""")
files, dirs = [], []
# Not all modules are required to have a __file__ attribute. See
# PEP 420 for more details.
if hasattr(os, '__file__'):
here = os.path.dirname(os.__file__)
files.extend(["LICENSE.txt", "LICENSE"])
dirs.extend([os.path.join(here, os.pardir), here, os.curdir])
files.extend(["LICENSE.txt", "LICENSE", "License.txt"])
dirs.extend(
[os.path.join(here, os.pardir, "Doc"), # dev build and installation on Windows
os.path.join(here, os.pardir, os.pardir, "doc", # APy install on Linux
"python%s.%s" % sys.version_info[:2]),
# APy install on Mac OS X
os.path.join(here, os.pardir, os.pardir, "Resources",
"Python.app", "Contents", "Resources", "English.lproj",
"Help"),
here]) # dev build on Linux
builtins.license = _sitebuiltins._Printer(
"license",
"See https://www.python.org/psf/license/",
"See https://www.activestate.com/activepython/license-agreement",
files, dirs)


Expand Down
Loading