Skip to content

Commit

Permalink
Merge branch 'main' into fix/codecs/xmlcharrefreplace-errors-126004
Browse files Browse the repository at this point in the history
  • Loading branch information
picnixz authored Jan 14, 2025
2 parents e3cec4f + 1153e66 commit 5261772
Show file tree
Hide file tree
Showing 264 changed files with 7,865 additions and 2,922 deletions.
11 changes: 6 additions & 5 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,14 @@ Doc/library/site.rst @FFY00
Lib/test/test_except*.py @iritkatriel
Objects/exceptions.c @iritkatriel

# Hashing
**/*hashlib* @gpshead @tiran
# Hashing & cryptographic primitives
**/*hashlib* @gpshead @tiran @picnixz
**/*pyhash* @gpshead @tiran
**/sha* @gpshead @tiran
Modules/md5* @gpshead @tiran
**/*blake* @gpshead @tiran
**/sha* @gpshead @tiran @picnixz
Modules/md5* @gpshead @tiran @picnixz
**/*blake* @gpshead @tiran @picnixz
Modules/_hacl/** @gpshead
**/*hmac* @gpshead @picnixz

# logging
**/*logging* @vsajip
Expand Down
17 changes: 16 additions & 1 deletion .github/workflows/reusable-change-detection.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,22 @@ jobs:
# into the PR branch anyway.
#
# https://github.com/python/core-workflow/issues/373
git diff --name-only "origin/$GITHUB_BASE_REF.." | grep -qvE '(\.rst$|^Doc|^Misc|^\.pre-commit-config\.yaml$|\.ruff\.toml$|\.md$|mypy\.ini$)' && echo "run-tests=true" >> "$GITHUB_OUTPUT" || true
grep_ignore_args=(
# file extensions
-e '\.md$'
-e '\.rst$'
# top-level folders
-e '^Doc/'
-e '^Misc/'
# configuration files
-e '^\.github/CODEOWNERS$'
-e '^\.pre-commit-config\.yaml$'
-e '\.ruff\.toml$'
-e 'mypy\.ini$'
)
git diff --name-only "origin/$GITHUB_BASE_REF.." \
| grep -qvE "${grep_ignore_args[@]}" \
&& echo "run-tests=true" >> "$GITHUB_OUTPUT" || true
fi
# Check if we should run hypothesis tests
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/reusable-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ jobs:
# Run "doctest" on HEAD as new syntax doesn't exist in the latest stable release
doctest:
name: 'Doctest'
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
Expand Down
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ repos:
hooks:
- id: check-dependabot
- id: check-github-workflows
- id: check-readthedocs

- repo: https://github.com/rhysd/actionlint
rev: v1.7.4
Expand Down
102 changes: 76 additions & 26 deletions Doc/c-api/apiabiversion.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@
API and ABI Versioning
***********************


Build-time version constants
----------------------------

CPython exposes its version number in the following macros.
Note that these correspond to the version code is **built** with,
not necessarily the version used at **run time**.
Note that these correspond to the version code is **built** with.
See :c:var:`Py_Version` for the version used at **run time**.

See :ref:`stable` for a discussion of API and ABI stability across versions.

Expand Down Expand Up @@ -37,37 +41,83 @@ See :ref:`stable` for a discussion of API and ABI stability across versions.
.. c:macro:: PY_VERSION_HEX
The Python version number encoded in a single integer.
See :c:func:`Py_PACK_FULL_VERSION` for the encoding details.

The underlying version information can be found by treating it as a 32 bit
number in the following manner:

+-------+-------------------------+-------------------------+--------------------------+
| Bytes | Bits (big endian order) | Meaning | Value for ``3.4.1a2`` |
+=======+=========================+=========================+==========================+
| 1 | 1-8 | ``PY_MAJOR_VERSION`` | ``0x03`` |
+-------+-------------------------+-------------------------+--------------------------+
| 2 | 9-16 | ``PY_MINOR_VERSION`` | ``0x04`` |
+-------+-------------------------+-------------------------+--------------------------+
| 3 | 17-24 | ``PY_MICRO_VERSION`` | ``0x01`` |
+-------+-------------------------+-------------------------+--------------------------+
| 4 | 25-28 | ``PY_RELEASE_LEVEL`` | ``0xA`` |
+ +-------------------------+-------------------------+--------------------------+
| | 29-32 | ``PY_RELEASE_SERIAL`` | ``0x2`` |
+-------+-------------------------+-------------------------+--------------------------+
Use this for numeric comparisons, for example,
``#if PY_VERSION_HEX >= ...``.

Thus ``3.4.1a2`` is hexversion ``0x030401a2`` and ``3.10.0`` is
hexversion ``0x030a00f0``.

Use this for numeric comparisons, e.g. ``#if PY_VERSION_HEX >= ...``.

This version is also available via the symbol :c:var:`Py_Version`.
Run-time version
----------------

.. c:var:: const unsigned long Py_Version
The Python runtime version number encoded in a single constant integer, with
the same format as the :c:macro:`PY_VERSION_HEX` macro.
The Python runtime version number encoded in a single constant integer.
See :c:func:`Py_PACK_FULL_VERSION` for the encoding details.
This contains the Python version used at run time.

Use this for numeric comparisons, for example, ``if (Py_Version >= ...)``.

.. versionadded:: 3.11

All the given macros are defined in :source:`Include/patchlevel.h`.

Bit-packing macros
------------------

.. c:function:: uint32_t Py_PACK_FULL_VERSION(int major, int minor, int micro, int release_level, int release_serial)
Return the given version, encoded as a single 32-bit integer with
the following structure:
+------------------+-------+----------------+-----------+--------------------------+
| | No. | | | Example values |
| | of | | +-------------+------------+
| Argument | bits | Bit mask | Bit shift | ``3.4.1a2`` | ``3.10.0`` |
+==================+=======+================+===========+=============+============+
| *major* | 8 | ``0xFF000000`` | 24 | ``0x03`` | ``0x03`` |
+------------------+-------+----------------+-----------+-------------+------------+
| *minor* | 8 | ``0x00FF0000`` | 16 | ``0x04`` | ``0x0A`` |
+------------------+-------+----------------+-----------+-------------+------------+
| *micro* | 8 | ``0x0000FF00`` | 8 | ``0x01`` | ``0x00`` |
+------------------+-------+----------------+-----------+-------------+------------+
| *release_level* | 4 | ``0x000000F0`` | 4 | ``0xA`` | ``0xF`` |
+------------------+-------+----------------+-----------+-------------+------------+
| *release_serial* | 4 | ``0x0000000F`` | 0 | ``0x2`` | ``0x0`` |
+------------------+-------+----------------+-----------+-------------+------------+
For example:
+-------------+------------------------------------+-----------------+
| Version | ``Py_PACK_FULL_VERSION`` arguments | Encoded version |
+=============+====================================+=================+
| ``3.4.1a2`` | ``(3, 4, 1, 0xA, 2)`` | ``0x030401a2`` |
+-------------+------------------------------------+-----------------+
| ``3.10.0`` | ``(3, 10, 0, 0xF, 0)`` | ``0x030a00f0`` |
+-------------+------------------------------------+-----------------+
Out-of range bits in the arguments are ignored.
That is, the macro can be defined as:
.. code-block:: c
#ifndef Py_PACK_FULL_VERSION
#define Py_PACK_FULL_VERSION(X, Y, Z, LEVEL, SERIAL) ( \
(((X) & 0xff) << 24) | \
(((Y) & 0xff) << 16) | \
(((Z) & 0xff) << 8) | \
(((LEVEL) & 0xf) << 4) | \
(((SERIAL) & 0xf) << 0))
#endif
``Py_PACK_FULL_VERSION`` is primarily a macro, intended for use in
``#if`` directives, but it is also available as an exported function.

.. versionadded:: 3.14

.. c:function:: uint32_t Py_PACK_VERSION(int major, int minor)
Equivalent to ``Py_PACK_FULL_VERSION(major, minor, 0, 0, 0)``.
The result does not correspond to any Python release, but is useful
in numeric comparisons.
.. versionadded:: 3.14
34 changes: 23 additions & 11 deletions Doc/c-api/arg.rst
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,24 @@ There are three ways strings and buffers can be converted to C:
Numbers
-------

These formats allow representing Python numbers or single characters as C numbers.
Formats that require :class:`int`, :class:`float` or :class:`complex` can
also use the corresponding special methods :meth:`~object.__index__`,
:meth:`~object.__float__` or :meth:`~object.__complex__` to convert
the Python object to the required type.

For signed integer formats, :exc:`OverflowError` is raised if the value
is out of range for the C type.
For unsigned integer formats, no range checking is done --- the
most significant bits are silently truncated when the receiving field is too
small to receive the value.

``b`` (:class:`int`) [unsigned char]
Convert a nonnegative Python integer to an unsigned tiny int, stored in a C
Convert a nonnegative Python integer to an unsigned tiny integer, stored in a C
:c:expr:`unsigned char`.

``B`` (:class:`int`) [unsigned char]
Convert a Python integer to a tiny int without overflow checking, stored in a C
Convert a Python integer to a tiny integer without overflow checking, stored in a C
:c:expr:`unsigned char`.

``h`` (:class:`int`) [short int]
Expand Down Expand Up @@ -307,7 +319,7 @@ Other objects

.. _o_ampersand:

``O&`` (object) [*converter*, *anything*]
``O&`` (object) [*converter*, *address*]
Convert a Python object to a C variable through a *converter* function. This
takes two arguments: the first is a function, the second is the address of a C
variable (of arbitrary type), converted to :c:expr:`void *`. The *converter*
Expand All @@ -321,14 +333,20 @@ Other objects
the conversion has failed. When the conversion fails, the *converter* function
should raise an exception and leave the content of *address* unmodified.

If the *converter* returns ``Py_CLEANUP_SUPPORTED``, it may get called a
.. c:macro:: Py_CLEANUP_SUPPORTED
:no-typesetting:

If the *converter* returns :c:macro:`!Py_CLEANUP_SUPPORTED`, it may get called a
second time if the argument parsing eventually fails, giving the converter a
chance to release any memory that it had already allocated. In this second
call, the *object* parameter will be ``NULL``; *address* will have the same value
as in the original call.

Examples of converters: :c:func:`PyUnicode_FSConverter` and
:c:func:`PyUnicode_FSDecoder`.

.. versionchanged:: 3.1
``Py_CLEANUP_SUPPORTED`` was added.
:c:macro:`!Py_CLEANUP_SUPPORTED` was added.

``p`` (:class:`bool`) [int]
Tests the value passed in for truth (a boolean **p**\ redicate) and converts
Expand All @@ -344,12 +362,6 @@ Other objects
in *items*. The C arguments must correspond to the individual format units in
*items*. Format units for sequences may be nested.

It is possible to pass "long" integers (integers whose value exceeds the
platform's :c:macro:`LONG_MAX`) however no proper range checking is done --- the
most significant bits are silently truncated when the receiving field is too
small to receive the value (actually, the semantics are inherited from downcasts
in C --- your mileage may vary).

A few other characters have a meaning in a format string. These may not occur
inside nested parentheses. They are:

Expand Down
11 changes: 11 additions & 0 deletions Doc/c-api/init.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1492,6 +1492,17 @@ All of the following functions must be called after :c:func:`Py_Initialize`.
.. versionadded:: 3.8
.. c:function:: PyObject* PyUnstable_InterpreterState_GetMainModule(PyInterpreterState *interp)
Return a :term:`strong reference` to the ``__main__`` `module object <moduleobjects>`_
for the given interpreter.
The caller must hold the GIL.
.. versionadded:: 3.13
.. c:type:: PyObject* (*_PyFrameEvalFunction)(PyThreadState *tstate, _PyInterpreterFrame *frame, int throwflag)
Type of a frame evaluation function.
Expand Down
7 changes: 7 additions & 0 deletions Doc/c-api/object.rst
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,13 @@ Object Protocol
on failure. This is equivalent to the Python statement ``del o[key]``.
.. c:function:: int PyObject_DelItemString(PyObject *o, const char *key)
This is the same as :c:func:`PyObject_DelItem`, but *key* is
specified as a :c:expr:`const char*` UTF-8 encoded bytes string,
rather than a :c:expr:`PyObject*`.
.. c:function:: PyObject* PyObject_Dir(PyObject *o)
This is equivalent to the Python expression ``dir(o)``, returning a (possibly
Expand Down
32 changes: 32 additions & 0 deletions Doc/c-api/sys.rst
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,38 @@ Operating System Utilities
The function now uses the UTF-8 encoding on Windows if
:c:member:`PyPreConfig.legacy_windows_fs_encoding` is zero.
.. c:function:: FILE* Py_fopen(PyObject *path, const char *mode)
Similar to :c:func:`!fopen`, but *path* is a Python object and
an exception is set on error.
*path* must be a :class:`str` object, a :class:`bytes` object,
or a :term:`path-like object`.
On success, return the new file pointer.
On error, set an exception and return ``NULL``.
The file must be closed by :c:func:`Py_fclose` rather than calling directly
:c:func:`!fclose`.
The file descriptor is created non-inheritable (:pep:`446`).
The caller must hold the GIL.
.. versionadded:: next
.. c:function:: int Py_fclose(FILE *file)
Close a file that was opened by :c:func:`Py_fopen`.
On success, return ``0``.
On error, return ``EOF`` and ``errno`` is set to indicate the error.
In either case, any further access (including another call to
:c:func:`Py_fclose`) to the stream results in undefined behavior.
.. versionadded:: next
.. _systemfunctions:
Expand Down
35 changes: 27 additions & 8 deletions Doc/c-api/unicode.rst
Original file line number Diff line number Diff line change
Expand Up @@ -786,33 +786,52 @@ Functions encoding to and decoding from the :term:`filesystem encoding and
error handler` (:pep:`383` and :pep:`529`).
To encode file names to :class:`bytes` during argument parsing, the ``"O&"``
converter should be used, passing :c:func:`PyUnicode_FSConverter` as the
converter should be used, passing :c:func:`!PyUnicode_FSConverter` as the
conversion function:
.. c:function:: int PyUnicode_FSConverter(PyObject* obj, void* result)
ParseTuple converter: encode :class:`str` objects -- obtained directly or
:ref:`PyArg_Parse\* converter <arg-parsing>`: encode :class:`str` objects -- obtained directly or
through the :class:`os.PathLike` interface -- to :class:`bytes` using
:c:func:`PyUnicode_EncodeFSDefault`; :class:`bytes` objects are output as-is.
*result* must be a :c:expr:`PyBytesObject*` which must be released when it is
no longer used.
*result* must be an address of a C variable of type :c:expr:`PyObject*`
(or :c:expr:`PyBytesObject*`).
On success, set the variable to a new :term:`strong reference` to
a :ref:`bytes object <bytesobjects>` which must be released
when it is no longer used and return a non-zero value
(:c:macro:`Py_CLEANUP_SUPPORTED`).
Embedded null bytes are not allowed in the result.
On failure, return ``0`` with an exception set.
If *obj* is ``NULL``, the function releases a strong reference
stored in the variable referred by *result* and returns ``1``.
.. versionadded:: 3.1
.. versionchanged:: 3.6
Accepts a :term:`path-like object`.
To decode file names to :class:`str` during argument parsing, the ``"O&"``
converter should be used, passing :c:func:`PyUnicode_FSDecoder` as the
converter should be used, passing :c:func:`!PyUnicode_FSDecoder` as the
conversion function:
.. c:function:: int PyUnicode_FSDecoder(PyObject* obj, void* result)
ParseTuple converter: decode :class:`bytes` objects -- obtained either
:ref:`PyArg_Parse\* converter <arg-parsing>`: decode :class:`bytes` objects -- obtained either
directly or indirectly through the :class:`os.PathLike` interface -- to
:class:`str` using :c:func:`PyUnicode_DecodeFSDefaultAndSize`; :class:`str`
objects are output as-is. *result* must be a :c:expr:`PyUnicodeObject*` which
must be released when it is no longer used.
objects are output as-is.
*result* must be an address of a C variable of type :c:expr:`PyObject*`
(or :c:expr:`PyUnicodeObject*`).
On success, set the variable to a new :term:`strong reference` to
a :ref:`Unicode object <unicodeobjects>` which must be released
when it is no longer used and return a non-zero value
(:c:macro:`Py_CLEANUP_SUPPORTED`).
Embedded null characters are not allowed in the result.
On failure, return ``0`` with an exception set.
If *obj* is ``NULL``, release the strong reference
to the object referred to by *result* and return ``1``.
.. versionadded:: 3.2
Expand Down
2 changes: 2 additions & 0 deletions Doc/data/stable_abi.dat

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 5261772

Please sign in to comment.