Skip to content
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
4 changes: 3 additions & 1 deletion Doc/c-api/buffer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,9 @@ readonly, format

.. c:macro:: PyBUF_WRITEABLE
This is a :term:`soft deprecated` alias to :c:macro:`PyBUF_WRITABLE`.
This is an alias to :c:macro:`PyBUF_WRITABLE`.

.. soft-deprecated:: 3.13

.. c:macro:: PyBUF_FORMAT
Expand Down
4 changes: 3 additions & 1 deletion Doc/c-api/code.rst
Original file line number Diff line number Diff line change
Expand Up @@ -212,14 +212,16 @@ bound into a function.
.. c:function:: PyObject *PyCode_Optimize(PyObject *code, PyObject *consts, PyObject *names, PyObject *lnotab_obj)
This is a :term:`soft deprecated` function that does nothing.
This is a function that does nothing.
Prior to Python 3.10, this function would perform basic optimizations to a
code object.
.. versionchanged:: 3.10
This function now does nothing.
.. soft-deprecated:: 3.13
.. _c_codeobject_flags:
Expand Down
4 changes: 3 additions & 1 deletion Doc/c-api/descriptor.rst
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,16 @@ found in the dictionary of type objects.

.. c:macro:: PyDescr_COMMON

This is a :term:`soft deprecated` macro including the common fields for a
This is a macro including the common fields for a
descriptor object.

This was included in Python's C API by mistake; do not use it in extensions.
For creating custom descriptor objects, create a class implementing the
descriptor protocol (:c:member:`~PyTypeObject.tp_descr_get` and
:c:member:`~PyTypeObject.tp_descr_set`).

.. soft-deprecated:: 3.15


Built-in descriptors
^^^^^^^^^^^^^^^^^^^^
Expand Down
4 changes: 3 additions & 1 deletion Doc/c-api/exceptions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -818,14 +818,16 @@ Exception Classes

.. c:macro:: PyException_HEAD

This is a :term:`soft deprecated` macro including the base fields for an
This is a macro including the base fields for an
exception object.

This was included in Python's C API by mistake and is not designed for use
in extensions. For creating custom exception objects, use
:c:func:`PyErr_NewException` or otherwise create a class inheriting from
:c:data:`PyExc_BaseException`.

.. soft-deprecated:: 3.15


Exception Objects
=================
Expand Down
4 changes: 3 additions & 1 deletion Doc/c-api/gen.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ Deprecated API

.. c:macro:: PyAsyncGenASend_CheckExact(op)

This is a :term:`soft deprecated` API that was included in Python's C API
This is an API that was included in Python's C API
by mistake.

It is solely here for completeness; do not use this API.

.. soft-deprecated:: 3.14
7 changes: 3 additions & 4 deletions Doc/c-api/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -587,10 +587,10 @@ have been standardized in C11 (or previous standards).

.. c:macro:: Py_MEMCPY(dest, src, n)

This is a :term:`soft deprecated` alias to :c:func:`!memcpy`.
Use :c:func:`!memcpy` directly instead.
This is an alias to :c:func:`!memcpy`.

.. soft-deprecated:: 3.14
Use :c:func:`!memcpy` directly instead.

.. c:macro:: Py_UNICODE_SIZE

Expand All @@ -611,8 +611,7 @@ have been standardized in C11 (or previous standards).

.. c:macro:: Py_VA_COPY

This is a :term:`soft deprecated` alias to the C99-standard ``va_copy``
function.
This is an alias to the C99-standard ``va_copy`` function.

Historically, this would use a compiler-specific method to copy a ``va_list``.

Expand Down
4 changes: 3 additions & 1 deletion Doc/c-api/set.rst
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ Deprecated API
.. c:macro:: PySet_MINSIZE
A :term:`soft deprecated` constant representing the size of an internal
A constant representing the size of an internal
preallocated table inside :c:type:`PySetObject` instances.
This is documented solely for completeness, as there are no guarantees
Expand All @@ -211,3 +211,5 @@ Deprecated API
:c:macro:`!PySet_MINSIZE` can be replaced with a small constant like ``8``.
If looking for the size of a set, use :c:func:`PySet_Size` instead.
.. soft-deprecated:: 3.14
8 changes: 5 additions & 3 deletions Doc/c-api/typeobj.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1391,8 +1391,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)

.. versionchanged:: 3.9

Renamed to the current name, without the leading underscore.
The old provisional name is :term:`soft deprecated`.
Renamed to the current name, without the leading underscore.
The old provisional name is :term:`soft deprecated`.

.. versionchanged:: 3.12

Expand Down Expand Up @@ -1501,11 +1501,13 @@ and :c:data:`PyType_Type` effectively act as defaults.)

.. c:macro:: Py_TPFLAGS_HAVE_VERSION_TAG

This is a :term:`soft deprecated` macro that does nothing.
This macro does nothing.
Historically, this would indicate that the
:c:member:`~PyTypeObject.tp_version_tag` field was available and
initialized.

.. soft-deprecated:: 3.13


.. c:macro:: Py_TPFLAGS_INLINE_VALUES

Expand Down
10 changes: 5 additions & 5 deletions Doc/library/calendar.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ interpreted as prescribed by the ISO 8601 standard. Year 0 is 1 BC, year -1 is

.. method:: setfirstweekday(firstweekday)

Set the first weekday to *firstweekday*, passed as an :class:`int` (0--6)
Set the first weekday to *firstweekday*, passed as an :class:`int` (0--6).

Identical to setting the :attr:`~Calendar.firstweekday` property.

.. method:: iterweekdays()

Return an iterator for the week day numbers that will be used for one
Return an iterator for the weekday numbers that will be used for one
week. The first value from the iterator will be the same as the value of
the :attr:`~Calendar.firstweekday` property.

Expand All @@ -86,7 +86,7 @@ interpreted as prescribed by the ISO 8601 standard. Year 0 is 1 BC, year -1 is
Return an iterator for the month *month* in the year *year* similar to
:meth:`itermonthdates`, but not restricted by the :class:`datetime.date`
range. Days returned will be tuples consisting of a day of the month
number and a week day number.
number and a weekday number.


.. method:: itermonthdays3(year, month)
Expand Down Expand Up @@ -408,7 +408,7 @@ For simple text calendars this module provides the following functions.

.. function:: monthrange(year, month)

Returns weekday of first day of the month and number of days in month, for the
Returns weekday of first day of the month and number of days in month, for the
specified *year* and *month*.


Expand Down Expand Up @@ -446,7 +446,7 @@ For simple text calendars this module provides the following functions.
An unrelated but handy function that takes a time tuple such as returned by
the :func:`~time.gmtime` function in the :mod:`time` module, and returns the
corresponding Unix timestamp value, assuming an epoch of 1970, and the POSIX
encoding. In fact, :func:`time.gmtime` and :func:`timegm` are each others'
encoding. In fact, :func:`time.gmtime` and :func:`timegm` are each other's
inverse.


Expand Down
4 changes: 2 additions & 2 deletions Doc/library/ctypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3190,8 +3190,8 @@ Arrays and pointers
Equivalent to ``type * length``, where *type* is a
:mod:`!ctypes` data type and *length* an integer.

This function is :term:`soft deprecated` in favor of multiplication.
There are no plans to remove it.
.. soft-deprecated:: 3.14
In favor of multiplication.


.. class:: _Pointer
Expand Down
2 changes: 1 addition & 1 deletion Doc/library/mimetypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ the information :func:`init` sets up.
Added support for *url* being a :term:`path-like object`.

.. soft-deprecated:: 3.13
Passing a file path instead of URL is :term:`soft deprecated`.
Passing a file path instead of URL.
Use :func:`guess_file_type` for this.


Expand Down
6 changes: 4 additions & 2 deletions Include/internal/pycore_stackref.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,10 @@ static const _PyStackRef PyStackRef_NULL = { .index = 0 };
static const _PyStackRef PyStackRef_ERROR = { .index = (1 << Py_TAGGED_SHIFT) };

#define PyStackRef_None ((_PyStackRef){ .index = (2 << Py_TAGGED_SHIFT) } )
#define PyStackRef_False ((_PyStackRef){ .index = (3 << Py_TAGGED_SHIFT) })
#define PyStackRef_True ((_PyStackRef){ .index = (4 << Py_TAGGED_SHIFT) })
#define _Py_STACKREF_FALSE_INDEX (3 << Py_TAGGED_SHIFT)
#define _Py_STACKREF_TRUE_INDEX (4 << Py_TAGGED_SHIFT)
#define PyStackRef_False ((_PyStackRef){ .index = _Py_STACKREF_FALSE_INDEX })
#define PyStackRef_True ((_PyStackRef){ .index = _Py_STACKREF_TRUE_INDEX })

#define INITIAL_STACKREF_INDEX (5 << Py_TAGGED_SHIFT)

Expand Down
2 changes: 1 addition & 1 deletion Lib/test/support/strace_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def sections(self):
def _filter_memory_call(call):
# mmap can operate on a fd or "MAP_ANONYMOUS" which gives a block of memory.
# Ignore "MAP_ANONYMOUS + the "MAP_ANON" alias.
if call.syscall == "mmap" and "MAP_ANON" in call.args[3]:
if call.syscall in ("mmap", "mmap2") and "MAP_ANON" in call.args[3]:
return True

if call.syscall in ("munmap", "mprotect"):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Allow for custom LLVM path using ``LLVM_TOOLS_INSTALL_DIR`` during JIT build.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Errors during the PGO training job on Windows are no longer ignored, and a non-zero return code will cause the build to fail.
18 changes: 11 additions & 7 deletions PCbuild/build.bat
Original file line number Diff line number Diff line change
Expand Up @@ -170,16 +170,20 @@ if "%do_pgo%"=="true" (
del /s "%dir%\*.pgc"
del /s "%dir%\..\Lib\*.pyc"
set conf=PGUpdate
if "%clean%"=="false" (
echo on
call "%dir%\..\python.bat" %pgo_job%
@echo off
call :Kill
set target=Build
)
if "%clean%"=="false" goto :RunPgoJob
)
goto :Build

:RunPgoJob
echo on
call "%dir%\..\python.bat" %pgo_job%
@echo off
set pgo_errorlevel=%ERRORLEVEL%
call :Kill
if %pgo_errorlevel% NEQ 0 exit /B %pgo_errorlevel%
set target=Build
goto :Build

:Kill
echo on
%MSBUILD% "%dir%\pythoncore.vcxproj" /t:KillPython %verbose%^
Expand Down
2 changes: 1 addition & 1 deletion PCbuild/regen.targets
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@
<JITArgs Condition="$(Platform) == 'x64'">x86_64-pc-windows-msvc</JITArgs>
<JITArgs Condition="$(Configuration) == 'Debug'">$(JITArgs) --debug</JITArgs>
</PropertyGroup>
<Exec Command='$(PythonForBuild) "$(PySourcePath)Tools\jit\build.py" $(JITArgs) --output-dir "$(GeneratedJitStencilsDir)" --pyconfig-dir "$(PySourcePath)PC"'/>
<Exec Command='$(PythonForBuild) "$(PySourcePath)Tools\jit\build.py" $(JITArgs) --output-dir "$(GeneratedJitStencilsDir)" --pyconfig-dir "$(PySourcePath)PC" --llvm-version="$(LLVM_VERSION)" --llvm-tools-install-dir="$(LLVM_TOOLS_INSTALL_DIR)"'/>
</Target>
<Target Name="_CleanJIT" AfterTargets="Clean">
<Delete Files="@(_JITOutputs)"/>
Expand Down
8 changes: 1 addition & 7 deletions Python/pylifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -1641,18 +1641,12 @@ Py_InitializeFromConfig(const PyConfig *config)
void
Py_InitializeEx(int install_sigs)
{
PyStatus status;

status = _PyRuntime_Initialize();
if (_PyStatus_EXCEPTION(status)) {
Py_ExitStatusException(status);
}

if (Py_IsInitialized()) {
/* bpo-33932: Calling Py_Initialize() twice does nothing. */
return;
}

PyStatus status;
PyConfig config;
_PyConfig_InitCompatConfig(&config);

Expand Down
9 changes: 7 additions & 2 deletions Tools/jit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ Python 3.11 or newer is required to build the JIT.

The JIT compiler does not require end users to install any third-party dependencies, but part of it must be *built* using LLVM[^why-llvm]. You are *not* required to build the rest of CPython using LLVM, or even the same version of LLVM (in fact, this is uncommon).

LLVM version 21 is the officially supported version. You can modify if needed using the `LLVM_VERSION` env var during configure. Both `clang` and `llvm-readobj` need to be installed and discoverable (version suffixes, like `clang-19`, are okay). It's highly recommended that you also have `llvm-objdump` available, since this allows the build script to dump human-readable assembly for the generated code.
LLVM version 21 is the officially supported version. Both `clang` and `llvm-readobj` need to be installed and discoverable (version suffixes, like `clang-21`, are okay). It's highly recommended that you also have `llvm-objdump` available, since this allows the build script to dump human-readable assembly for the generated code.

You can customize the LLVM configuration using environment variables before running configure:

- LLVM_VERSION: Specify a different LLVM version (default: 21)
- LLVM_TOOLS_INSTALL_DIR: Point to a specific LLVM installation prefix when multiple installations exist (the tools are expected in `<dir>/bin`)

It's easy to install all of the required tools:

Expand Down Expand Up @@ -62,7 +67,7 @@ choco install llvm --version=21.1.0

### Dev Containers

If you are working on CPython in a [Codespaces instance](https://devguide.python.org/getting-started/setup-building/#using-codespaces), there's no
If you are working on CPython in a [Codespaces instance](https://devguide.python.org/getting-started/setup-building/#using-codespaces), there's no
need to install LLVM as the Fedora 43 base image includes LLVM 21 out of the box.

## Building
Expand Down
25 changes: 22 additions & 3 deletions Tools/jit/_llvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,18 @@ async def _get_brew_llvm_prefix(llvm_version: str, *, echo: bool = False) -> str


@_async_cache
async def _find_tool(tool: str, llvm_version: str, *, echo: bool = False) -> str | None:
async def _find_tool(
tool: str,
llvm_version: str,
llvm_tools_install_dir: str | None,
*,
echo: bool = False,
) -> str | None:
# Explicitly defined LLVM installation location
if llvm_tools_install_dir:
path = os.path.join(llvm_tools_install_dir, "bin", tool)
if await _check_tool_version(path, llvm_version, echo=echo):
return path
# Unversioned executables:
path = tool
if await _check_tool_version(path, llvm_version, echo=echo):
Expand Down Expand Up @@ -114,10 +125,11 @@ async def maybe_run(
args: typing.Iterable[str],
echo: bool = False,
llvm_version: str = _LLVM_VERSION,
llvm_tools_install_dir: str | None = None,
) -> str | None:
"""Run an LLVM tool if it can be found. Otherwise, return None."""

path = await _find_tool(tool, llvm_version, echo=echo)
path = await _find_tool(tool, llvm_version, llvm_tools_install_dir, echo=echo)
return path and await _run(path, args, echo=echo)


Expand All @@ -126,10 +138,17 @@ async def run(
args: typing.Iterable[str],
echo: bool = False,
llvm_version: str = _LLVM_VERSION,
llvm_tools_install_dir: str | None = None,
) -> str:
"""Run an LLVM tool if it can be found. Otherwise, raise RuntimeError."""

output = await maybe_run(tool, args, echo=echo, llvm_version=llvm_version)
output = await maybe_run(
tool,
args,
echo=echo,
llvm_version=llvm_version,
llvm_tools_install_dir=llvm_tools_install_dir,
)
if output is None:
raise RuntimeError(f"Can't find {tool}-{llvm_version}!")
return output
Loading
Loading