Skip to content
Closed
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
2 changes: 1 addition & 1 deletion .azure-pipelines/macos-steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ steps:
- script: ./configure --with-pydebug --with-openssl=/usr/local/opt/openssl --prefix=/opt/python-azdev
displayName: 'Configure CPython (debug)'

- script: make -s -j4
- script: make -j4
displayName: 'Build CPython'

- script: make pythoninfo
Expand Down
2 changes: 1 addition & 1 deletion .azure-pipelines/posix-steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ steps:
- script: ./configure --with-pydebug
displayName: 'Configure CPython (debug)'

- script: make -s -j4
- script: make -j4
displayName: 'Build CPython'

- ${{ if eq(parameters.coverage, 'true') }}:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
- name: Configure CPython
run: ./configure --with-pydebug --with-openssl=/usr/local/opt/openssl --prefix=/opt/python-dev
- name: Build CPython
run: make -s -j4
run: make -j4
- name: Display build info
run: make pythoninfo
- name: Tests
Expand All @@ -82,7 +82,7 @@ jobs:
- name: Configure CPython
run: ./configure --with-pydebug --with-openssl=$PWD/multissl/openssl/$OPENSSL_VER
- name: Build CPython
run: make -s -j4
run: make -j4
- name: Display build info
run: make pythoninfo
- name: Tests
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
- name: Configure CPython
run: ./configure --with-openssl=$PWD/multissl/openssl/$OPENSSL_VER
- name: Build CPython
run: make -s -j4
run: make -j4
- name: Display build info
run: make pythoninfo
- name: 'Coverage Preparation'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/doc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
- name: 'Configure CPython'
run: ./configure --with-pydebug
- name: 'Build CPython'
run: make -s -j4
run: make -j4
- name: 'Install build dependencies'
run: make -C Doc/ PYTHON=../python venv
- name: 'Build documentation'
Expand Down
22 changes: 11 additions & 11 deletions Doc/c-api/arg.rst
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ which disallows mutable objects such as :class:`bytearray`.
Like ``s*``, but the Python object may also be ``None``, in which case the
``buf`` member of the :c:type:`Py_buffer` structure is set to ``NULL``.

``z#`` (:class:`str`, read-only :term:`bytes-like object` or ``None``) [const char \*, int]
``z#`` (:class:`str`, read-only :term:`bytes-like object` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`]
Like ``s#``, but the Python object may also be ``None``, in which case the C
pointer is set to ``NULL``.

Expand All @@ -124,7 +124,7 @@ which disallows mutable objects such as :class:`bytearray`.
bytes-like objects. **This is the recommended way to accept
binary data.**

``y#`` (read-only :term:`bytes-like object`) [const char \*, int]
``y#`` (read-only :term:`bytes-like object`) [const char \*, int or :c:type:`Py_ssize_t`]
This variant on ``s#`` doesn't accept Unicode objects, only bytes-like
objects.

Expand Down Expand Up @@ -155,7 +155,7 @@ which disallows mutable objects such as :class:`bytearray`.
Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using
:c:func:`PyUnicode_AsWideCharString`.

``u#`` (:class:`str`) [const Py_UNICODE \*, int]
``u#`` (:class:`str`) [const Py_UNICODE \*, int or :c:type:`Py_ssize_t`]
This variant on ``u`` stores into two C variables, the first one a pointer to a
Unicode data buffer, the second one its length. This variant allows
null code points.
Expand All @@ -172,7 +172,7 @@ which disallows mutable objects such as :class:`bytearray`.
Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using
:c:func:`PyUnicode_AsWideCharString`.

``Z#`` (:class:`str` or ``None``) [const Py_UNICODE \*, int]
``Z#`` (:class:`str` or ``None``) [const Py_UNICODE \*, int or :c:type:`Py_ssize_t`]
Like ``u#``, but the Python object may also be ``None``, in which case the
:c:type:`Py_UNICODE` pointer is set to ``NULL``.

Expand Down Expand Up @@ -213,7 +213,7 @@ which disallows mutable objects such as :class:`bytearray`.
recoding them. Instead, the implementation assumes that the byte string object uses
the encoding passed in as parameter.

``es#`` (:class:`str`) [const char \*encoding, char \*\*buffer, int \*buffer_length]
``es#`` (:class:`str`) [const char \*encoding, char \*\*buffer, int or :c:type:`Py_ssize_t` \*buffer_length]
This variant on ``s#`` is used for encoding Unicode into a character buffer.
Unlike the ``es`` format, this variant allows input data which contains NUL
characters.
Expand Down Expand Up @@ -244,7 +244,7 @@ which disallows mutable objects such as :class:`bytearray`.
In both cases, *\*buffer_length* is set to the length of the encoded data
without the trailing NUL byte.

``et#`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer, int \*buffer_length]
``et#`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer, int or :c:type:`Py_ssize_t` \*buffer_length]
Same as ``es#`` except that byte string objects are passed through without recoding
them. Instead, the implementation assumes that the byte string object uses the
encoding passed in as parameter.
Expand Down Expand Up @@ -549,7 +549,7 @@ Building values
Convert a null-terminated C string to a Python :class:`str` object using ``'utf-8'``
encoding. If the C string pointer is ``NULL``, ``None`` is used.

``s#`` (:class:`str` or ``None``) [const char \*, int]
``s#`` (:class:`str` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`]
Convert a C string and its length to a Python :class:`str` object using ``'utf-8'``
encoding. If the C string pointer is ``NULL``, the length is ignored and
``None`` is returned.
Expand All @@ -558,30 +558,30 @@ Building values
This converts a C string to a Python :class:`bytes` object. If the C
string pointer is ``NULL``, ``None`` is returned.

``y#`` (:class:`bytes`) [const char \*, int]
``y#`` (:class:`bytes`) [const char \*, int or :c:type:`Py_ssize_t`]
This converts a C string and its lengths to a Python object. If the C
string pointer is ``NULL``, ``None`` is returned.

``z`` (:class:`str` or ``None``) [const char \*]
Same as ``s``.

``z#`` (:class:`str` or ``None``) [const char \*, int]
``z#`` (:class:`str` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`]
Same as ``s#``.

``u`` (:class:`str`) [const wchar_t \*]
Convert a null-terminated :c:type:`wchar_t` buffer of Unicode (UTF-16 or UCS-4)
data to a Python Unicode object. If the Unicode buffer pointer is ``NULL``,
``None`` is returned.

``u#`` (:class:`str`) [const wchar_t \*, int]
``u#`` (:class:`str`) [const wchar_t \*, int or :c:type:`Py_ssize_t`]
Convert a Unicode (UTF-16 or UCS-4) data buffer and its length to a Python
Unicode object. If the Unicode buffer pointer is ``NULL``, the length is ignored
and ``None`` is returned.

``U`` (:class:`str` or ``None``) [const char \*]
Same as ``s``.

``U#`` (:class:`str` or ``None``) [const char \*, int]
``U#`` (:class:`str` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`]
Same as ``s#``.

``i`` (:class:`int`) [int]
Expand Down
26 changes: 24 additions & 2 deletions Doc/library/ipaddress.rst
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,20 @@ write code that handles both IP versions correctly. Address objects are
:RFC:`4291` for details. For example,
``"0000:0000:0000:0000:0000:0abc:0007:0def"`` can be compressed to
``"::abc:7:def"``.

Optionally, the string may also have a scope zone ID, expressed
with a suffix ``%scope_id``. If present, the scope ID must be non-empty,
and may not contain ``%``.
See :RFC:`4007` for details.
For example, ``fe80::1234%1`` might identify address ``fe80::1234`` on the first link of the node.
2. An integer that fits into 128 bits.
3. An integer packed into a :class:`bytes` object of length 16, big-endian.


>>> ipaddress.IPv6Address('2001:db8::1000')
IPv6Address('2001:db8::1000')
>>> ipaddress.IPv6Address('ff02::5678%1')
IPv6Address('ff02::5678%1')

.. attribute:: compressed

Expand Down Expand Up @@ -268,6 +277,12 @@ write code that handles both IP versions correctly. Address objects are
``::FFFF/96``), this property will report the embedded IPv4 address.
For any other address, this property will be ``None``.

.. attribute:: scope_id

For scoped addresses as defined by :RFC:`4007`, this property identifies
the particular zone of the address's scope that the address belongs to,
as a string. When no scope zone is specified, this property will be ``None``.

.. attribute:: sixtofour

For addresses that appear to be 6to4 addresses (starting with
Expand Down Expand Up @@ -299,6 +314,8 @@ the :func:`str` and :func:`int` builtin functions::
>>> int(ipaddress.IPv6Address('::1'))
1

Note that IPv6 scoped addresses are converted to integers without scope zone ID.


Operators
^^^^^^^^^
Expand All @@ -311,15 +328,20 @@ IPv6).
Comparison operators
""""""""""""""""""""

Address objects can be compared with the usual set of comparison operators. Some
examples::
Address objects can be compared with the usual set of comparison operators.
Same IPv6 addresses with different scope zone IDs are not equal.
Some examples::

>>> IPv4Address('127.0.0.2') > IPv4Address('127.0.0.1')
True
>>> IPv4Address('127.0.0.2') == IPv4Address('127.0.0.1')
False
>>> IPv4Address('127.0.0.2') != IPv4Address('127.0.0.1')
True
>>> IPv6Address('fe80::1234') == IPv6Address('fe80::1234%1')
False
>>> IPv6Address('fe80::1234%1') != IPv6Address('fe80::1234%2')
True


Arithmetic operators
Expand Down
20 changes: 10 additions & 10 deletions Doc/library/socket.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,15 @@ created. Socket addresses are represented as follows:
Python programs.

- For :const:`AF_INET6` address family, a four-tuple ``(host, port, flowinfo,
scopeid)`` is used, where *flowinfo* and *scopeid* represent the ``sin6_flowinfo``
scope_id)`` is used, where *flowinfo* and *scope_id* represent the ``sin6_flowinfo``
and ``sin6_scope_id`` members in :const:`struct sockaddr_in6` in C. For
:mod:`socket` module methods, *flowinfo* and *scopeid* can be omitted just for
backward compatibility. Note, however, omission of *scopeid* can cause problems
:mod:`socket` module methods, *flowinfo* and *scope_id* can be omitted just for
backward compatibility. Note, however, omission of *scope_id* can cause problems
in manipulating scoped IPv6 addresses.

.. versionchanged:: 3.7
For multicast addresses (with *scopeid* meaningful) *address* may not contain
``%scope`` (or ``zone id``) part. This information is superfluous and may
For multicast addresses (with *scope_id* meaningful) *address* may not contain
``%scope_id`` (or ``zone id``) part. This information is superfluous and may
be safely omitted (recommended).

- :const:`AF_NETLINK` sockets are represented as pairs ``(pid, groups)``.
Expand Down Expand Up @@ -738,7 +738,7 @@ The :mod:`socket` module also offers various network-related services:
:const:`AI_CANONNAME` is part of the *flags* argument; else *canonname*
will be empty. *sockaddr* is a tuple describing a socket address, whose
format depends on the returned *family* (a ``(address, port)`` 2-tuple for
:const:`AF_INET`, a ``(address, port, flow info, scope id)`` 4-tuple for
:const:`AF_INET`, a ``(address, port, flowinfo, scope_id)`` 4-tuple for
:const:`AF_INET6`), and is meant to be passed to the :meth:`socket.connect`
method.

Expand All @@ -759,7 +759,7 @@ The :mod:`socket` module also offers various network-related services:

.. versionchanged:: 3.7
for IPv6 multicast addresses, string representing an address will not
contain ``%scope`` part.
contain ``%scope_id`` part.

.. function:: getfqdn([name])

Expand Down Expand Up @@ -827,8 +827,8 @@ The :mod:`socket` module also offers various network-related services:
or numeric address representation in *host*. Similarly, *port* can contain a
string port name or a numeric port number.

For IPv6 addresses, ``%scope`` is appended to the host part if *sockaddr*
contains meaningful *scopeid*. Usually this happens for multicast addresses.
For IPv6 addresses, ``%scope_id`` is appended to the host part if *sockaddr*
contains meaningful *scope_id*. Usually this happens for multicast addresses.

For more information about *flags* you can consult :manpage:`getnameinfo(3)`.

Expand Down Expand Up @@ -1354,7 +1354,7 @@ to sockets.

.. versionchanged:: 3.7
For multicast IPv6 address, first item of *address* does not contain
``%scope`` part anymore. In order to get full IPv6 address use
``%scope_id`` part anymore. In order to get full IPv6 address use
:func:`getnameinfo`.

.. method:: socket.recvmsg(bufsize[, ancbufsize[, flags]])
Expand Down
16 changes: 16 additions & 0 deletions Doc/library/stdtypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4392,6 +4392,22 @@ pairs within braces, for example: ``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098:
>>> d.values() == d.values()
False

.. describe:: d | other

Create a new dictionary with the merged keys and values of *d* and
*other*, which must both be dictionaries. The values of *other* take
priority when *d* and *other* share keys.

.. versionadded:: 3.9

.. describe:: d |= other

Update the dictionary *d* with keys and values from *other*, which may be
either a :term:`mapping` or an :term:`iterable` of key/value pairs. The
values of *other* take priority when *d* and *other* share keys.

.. versionadded:: 3.9

Dictionaries compare equal if and only if they have the same ``(key,
value)`` pairs (regardless of ordering). Order comparisons ('<', '<=', '>=', '>') raise
:exc:`TypeError`.
Expand Down
2 changes: 2 additions & 0 deletions Doc/tools/susp-ignored.csv
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ library/ipaddress,,:db8,>>> ipaddress.IPv6Address('2001:db8::1000')
library/ipaddress,,::,>>> ipaddress.IPv6Address('2001:db8::1000')
library/ipaddress,,:db8,IPv6Address('2001:db8::1000')
library/ipaddress,,::,IPv6Address('2001:db8::1000')
library/ipaddress,,::,IPv6Address('ff02::5678%1')
library/ipaddress,,::,fe80::1234
library/ipaddress,,:db8,">>> ipaddress.ip_address(""2001:db8::1"").reverse_pointer"
library/ipaddress,,::,">>> ipaddress.ip_address(""2001:db8::1"").reverse_pointer"
library/ipaddress,,::,"""::abc:7:def"""
Expand Down
15 changes: 15 additions & 0 deletions Doc/whatsnew/3.9.rst
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ Summary -- Release highlights
New Features
============

Dictionary Merge & Update Operators
-----------------------------------

Merge (``|``) and update (``|=``) operators have been added to the built-in
:class:`dict` class. See :pep:`584` for a full description.
(Contributed by Brandt Bucher in :issue:`36144`.)


Other Language Changes
Expand Down Expand Up @@ -213,6 +219,15 @@ now raises :exc:`ImportError` instead of :exc:`ValueError` for invalid relative
import attempts.
(Contributed by Ngalim Siregar in :issue:`37444`.)

ipaddress
---------

:mod:`ipaddress` now supports IPv6 Scoped Addresses (IPv6 address with suffix ``%<scope_id>``).

Scoped IPv6 addresses can be parsed using :class:`ipaddress.IPv6Address`.
If present, scope zone ID is available through the :attr:`~ipaddress.IPv6Address.scope_id` attribute.
(Contributed by Oleksandr Pavliuk in :issue:`34788`.)

math
----

Expand Down
4 changes: 2 additions & 2 deletions Include/patchlevel.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
#define PY_MINOR_VERSION 9
#define PY_MICRO_VERSION 0
#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA
#define PY_RELEASE_SERIAL 3
#define PY_RELEASE_SERIAL 4

/* Version as a string */
#define PY_VERSION "3.9.0a3+"
#define PY_VERSION "3.9.0a4+"
/*--end constants--*/

/* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2.
Expand Down
Loading