Merge remote-tracking branch 'origin/main' into HEAD

This commit is contained in:
Dino Viehland 2025-11-03 10:10:28 -08:00
commit 8d57aca95a
1284 changed files with 27792 additions and 11927 deletions

View file

@ -0,0 +1,73 @@
{
"image": "ghcr.io/python/wasicontainer:latest",
"onCreateCommand": [
// Install common tooling.
"dnf",
"install",
"-y",
// For umask fix below.
"/usr/bin/setfacl"
],
"updateContentCommand": {
// Using the shell for `nproc` usage.
"python": "python3 Tools/wasm/wasi build --quiet -- --with-pydebug -C"
},
"postCreateCommand": {
// https://github.com/orgs/community/discussions/26026
"umask fix: workspace": ["sudo", "setfacl", "-bnR", "."],
"umask fix: /tmp": ["sudo", "setfacl", "-bnR", "/tmp"]
},
"customizations": {
"vscode": {
"extensions": [
// Highlighting for Parser/Python.asdl.
"brettcannon.zephyr-asdl",
// Highlighting for configure.ac.
"maelvalais.autoconf",
// C auto-complete.
"ms-vscode.cpptools",
// Python auto-complete.
"ms-python.python"
],
"settings": {
"C_Cpp.default.compilerPath": "/usr/bin/clang",
"C_Cpp.default.cStandard": "c11",
"C_Cpp.default.defines": [
"CONFIG_64",
"Py_BUILD_CORE"
],
"C_Cpp.default.includePath": [
"${workspaceFolder}/*",
"${workspaceFolder}/Include/**"
],
// https://github.com/microsoft/vscode-cpptools/issues/10732
"C_Cpp.errorSquiggles": "disabled",
"editor.insertSpaces": true,
"editor.rulers": [
80
],
"editor.tabSize": 4,
"editor.trimAutoWhitespace": true,
"files.associations": {
"*.h": "c"
},
"files.encoding": "utf8",
"files.eol": "\n",
"files.insertFinalNewline": true,
"files.trimTrailingWhitespace": true,
"python.analysis.diagnosticSeverityOverrides": {
// Complains about shadowing the stdlib w/ the stdlib.
"reportShadowedImports": "none",
// Doesn't like _frozen_importlib.
"reportMissingImports": "none"
},
"python.analysis.extraPaths": [
"Lib"
],
"[restructuredtext]": {
"editor.tabSize": 3
}
}
}
}
}

4
.github/CODEOWNERS vendored
View file

@ -86,6 +86,10 @@ Modules/makesetup @erlend-aasland @AA-Turner @emmatyping
Modules/Setup* @erlend-aasland @AA-Turner @emmatyping
Tools/build/regen-configure.sh @AA-Turner
# generate-build-details
Tools/build/generate-build-details.py @FFY00
Lib/test/test_build_details.py @FFY00
# ----------------------------------------------------------------------------
# Documentation

View file

@ -1,6 +1,7 @@
self-hosted-runner:
# Pending https://github.com/rhysd/actionlint/issues/533
labels: ["windows-11-arm"]
# and https://github.com/rhysd/actionlint/issues/571
labels: ["windows-11-arm", "macos-15-intel"]
config-variables: null

View file

@ -202,24 +202,16 @@ jobs:
strategy:
fail-fast: false
matrix:
# Cirrus and macos-14 are M1, macos-13 is default GHA Intel.
# macOS 13 only runs tests against the GIL-enabled CPython.
# Cirrus used for upstream, macos-14 for forks.
# macos-14 is M1, macos-15-intel is Intel.
# macos-15-intel only runs tests against the GIL-enabled CPython.
os:
- ghcr.io/cirruslabs/macos-runner:sonoma
- macos-14
- macos-13
is-fork: # only used for the exclusion trick
- ${{ github.repository_owner != 'python' }}
- macos-15-intel
free-threading:
- false
- true
exclude:
- os: ghcr.io/cirruslabs/macos-runner:sonoma
is-fork: true
- os: macos-14
is-fork: false
- os: macos-13
- os: macos-15-intel
free-threading: true
uses: ./.github/workflows/reusable-macos.yml
with:
@ -273,7 +265,7 @@ jobs:
# Keep 1.1.1w in our list despite it being upstream EOL and otherwise
# unsupported as it most resembles other 1.1.1-work-a-like ssl APIs
# supported by important vendors such as AWS-LC.
openssl_ver: [1.1.1w, 3.0.17, 3.2.5, 3.3.4, 3.4.2, 3.5.2]
openssl_ver: [1.1.1w, 3.0.18, 3.2.6, 3.3.5, 3.4.3, 3.5.4]
# See Tools/ssl/make_ssl_data.py for notes on adding a new version
env:
OPENSSL_VER: ${{ matrix.openssl_ver }}
@ -409,9 +401,8 @@ jobs:
fail-fast: false
matrix:
include:
# Use the same runs-on configuration as build-macos and build-ubuntu.
- arch: aarch64
runs-on: ${{ github.repository_owner == 'python' && 'ghcr.io/cirruslabs/macos-runner:sonoma' || 'macos-14' }}
runs-on: macos-14
- arch: x86_64
runs-on: ubuntu-24.04
@ -421,7 +412,30 @@ jobs:
with:
persist-credentials: false
- name: Build and test
run: ./Android/android.py ci ${{ matrix.arch }}-linux-android
run: ./Android/android.py ci --fast-ci ${{ matrix.arch }}-linux-android
build-ios:
name: iOS
needs: build-context
if: needs.build-context.outputs.run-tests == 'true'
timeout-minutes: 60
runs-on: macos-15
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
# GitHub recommends explicitly selecting the desired Xcode version:
# https://github.com/actions/runner-images/issues/12541#issuecomment-3083850140
# This became a necessity as a result of
# https://github.com/actions/runner-images/issues/12541 and
# https://github.com/actions/runner-images/issues/12751.
- name: Select Xcode version
run: |
sudo xcode-select --switch /Applications/Xcode_16.4.app
- name: Build and test
run: python3 Apple ci iOS --fast-ci --simulator 'iPhone 16e,OS=18.5'
build-wasi:
name: 'WASI'
@ -438,7 +452,7 @@ jobs:
needs: build-context
if: needs.build-context.outputs.run-tests == 'true'
env:
OPENSSL_VER: 3.0.16
OPENSSL_VER: 3.0.18
PYTHONSTRICTEXTENSIONBUILD: 1
steps:
- uses: actions/checkout@v4
@ -558,7 +572,7 @@ jobs:
matrix:
os: [ubuntu-24.04]
env:
OPENSSL_VER: 3.0.16
OPENSSL_VER: 3.0.18
PYTHONSTRICTEXTENSIONBUILD: 1
ASAN_OPTIONS: detect_leaks=0:allocator_may_return_null=1:handle_segv=0
steps:
@ -732,6 +746,7 @@ jobs:
- build-ubuntu-ssltests-awslc
- build-ubuntu-ssltests-openssl
- build-android
- build-ios
- build-wasi
- test-hypothesis
- build-asan
@ -768,6 +783,7 @@ jobs:
build-ubuntu-ssltests-awslc,
build-ubuntu-ssltests-openssl,
build-android,
build-ios,
build-wasi,
test-hypothesis,
build-asan,

View file

@ -68,7 +68,7 @@ jobs:
- true
- false
llvm:
- 19
- 20
include:
- target: i686-pc-windows-msvc/msvc
architecture: Win32
@ -81,7 +81,7 @@ jobs:
runner: windows-11-arm
- target: x86_64-apple-darwin/clang
architecture: x86_64
runner: macos-13
runner: macos-15-intel
- target: aarch64-apple-darwin/clang
architecture: aarch64
runner: macos-14
@ -106,15 +106,10 @@ jobs:
./PCbuild/build.bat --experimental-jit ${{ matrix.debug && '-d' || '' }} -p ${{ matrix.architecture }}
./PCbuild/rt.bat ${{ matrix.debug && '-d' || '' }} -p ${{ matrix.architecture }} -q --multiprocess 0 --timeout 4500 --verbose2 --verbose3
# The `find` line is required as a result of https://github.com/actions/runner-images/issues/9966.
# This is a bug in the macOS runner image where the pre-installed Python is installed in the same
# directory as the Homebrew Python, which causes the build to fail for macos-13. This line removes
# the symlink to the pre-installed Python so that the Homebrew Python is used instead.
- name: macOS
if: runner.os == 'macOS'
run: |
brew update
find /usr/local/bin -lname '*/Library/Frameworks/Python.framework/*' -delete
brew install llvm@${{ matrix.llvm }}
export SDKROOT="$(xcrun --show-sdk-path)"
# Set MACOSX_DEPLOYMENT_TARGET and -Werror=unguarded-availability to
@ -143,7 +138,7 @@ jobs:
fail-fast: false
matrix:
llvm:
- 19
- 20
steps:
- uses: actions/checkout@v4
with:
@ -171,7 +166,7 @@ jobs:
fail-fast: false
matrix:
llvm:
- 19
- 20
steps:
- uses: actions/checkout@v4
with:

View file

@ -16,6 +16,7 @@ on:
- "Tools/build/check_extension_modules.py"
- "Tools/build/check_warnings.py"
- "Tools/build/compute-changes.py"
- "Tools/build/consts_getter.py"
- "Tools/build/deepfreeze.py"
- "Tools/build/generate-build-details.py"
- "Tools/build/generate_sbom.py"

View file

@ -1,31 +0,0 @@
name: Update GH projects
on:
issues:
types:
- opened
- labeled
permissions:
contents: read
jobs:
add-to-project:
name: Add issues to projects
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
include:
# if an issue has any of these labels, it will be added
# to the corresponding project
- { project: 2, label: "release-blocker, deferred-blocker" }
- { project: 32, label: sprint }
steps:
- uses: actions/add-to-project@v1.0.0
with:
project-url: https://github.com/orgs/python/projects/${{ matrix.project }}
github-token: ${{ secrets.ADD_TO_PROJECT_PAT }}
labeled: ${{ matrix.label }}

View file

@ -43,9 +43,9 @@ jobs:
key: ${{ github.job }}-${{ env.IMAGE_OS_VERSION }}-${{ inputs.config_hash }}
- name: Install Homebrew dependencies
run: |
brew install pkg-config openssl@3.0 xz gdbm tcl-tk@8 make
brew install pkg-config openssl@3.0 xz gdbm tcl-tk@9 make
# Because alternate versions are not symlinked into place by default:
brew link --overwrite tcl-tk@8
brew link --overwrite tcl-tk@9
- name: Configure CPython
run: |
MACOSX_DEPLOYMENT_TARGET=10.15 \
@ -60,15 +60,15 @@ jobs:
--prefix=/opt/python-dev \
--with-openssl="$(brew --prefix openssl@3.0)"
- name: Build CPython
if : ${{ inputs.free-threading || inputs.os != 'macos-13' }}
if : ${{ inputs.free-threading || inputs.os != 'macos-15-intel' }}
run: gmake -j8
- name: Build CPython for compiler warning check
if : ${{ !inputs.free-threading && inputs.os == 'macos-13' }}
if : ${{ !inputs.free-threading && inputs.os == 'macos-15-intel' }}
run: set -o pipefail; gmake -j8 --output-sync 2>&1 | tee compiler_output_macos.txt
- name: Display build info
run: make pythoninfo
- name: Check compiler warnings
if : ${{ !inputs.free-threading && inputs.os == 'macos-13' }}
if : ${{ !inputs.free-threading && inputs.os == 'macos-15-intel' }}
run: >-
python3 Tools/build/check_warnings.py
--compiler-output-file-path=compiler_output_macos.txt

View file

@ -30,7 +30,7 @@ jobs:
runs-on: ${{ inputs.os }}
timeout-minutes: 60
env:
OPENSSL_VER: 3.0.15
OPENSSL_VER: 3.0.18
PYTHONSTRICTEXTENSIONBUILD: 1
TERM: linux
steps:

View file

@ -13,11 +13,11 @@ env:
jobs:
build-wasi-reusable:
name: 'build and test'
runs-on: ubuntu-24.04
runs-on: ubuntu-24.04-arm
timeout-minutes: 60
env:
WASMTIME_VERSION: 22.0.0
WASI_SDK_VERSION: 24
WASMTIME_VERSION: 38.0.3
WASI_SDK_VERSION: 25
WASI_SDK_PATH: /opt/wasi-sdk
CROSS_BUILD_PYTHON: cross-build/build
CROSS_BUILD_WASI: cross-build/wasm32-wasip1
@ -40,7 +40,7 @@ jobs:
if: steps.cache-wasi-sdk.outputs.cache-hit != 'true'
run: |
mkdir "${WASI_SDK_PATH}" && \
curl -s -S --location "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION}/wasi-sdk-${WASI_SDK_VERSION}.0-x86_64-linux.tar.gz" | \
curl -s -S --location "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION}/wasi-sdk-${WASI_SDK_VERSION}.0-arm64-linux.tar.gz" | \
tar --strip-components 1 --directory "${WASI_SDK_PATH}" --extract --gunzip
- name: "Configure ccache action"
uses: hendrikmuhs/ccache-action@v1.2

View file

@ -58,7 +58,7 @@ jobs:
# runner: windows-2022
- target: x86_64-apple-darwin/clang
architecture: x86_64
runner: macos-13
runner: macos-15-intel
- target: aarch64-apple-darwin/clang
architecture: aarch64
runner: macos-14
@ -101,17 +101,10 @@ jobs:
set LLVMInstallDir=C:\Program Files\LLVM
./PCbuild/build.bat --tail-call-interp -p ${{ matrix.architecture }}
# The `find` line is required as a result of https://github.com/actions/runner-images/issues/9966.
# This is a bug in the macOS runner image where the pre-installed Python is installed in the same
# directory as the Homebrew Python, which causes the build to fail for macos-13. This line removes
# the symlink to the pre-installed Python so that the Homebrew Python is used instead.
# Note: when a new LLVM is released, the homebrew installation directory changes, so the builds will fail.
# We either need to upgrade LLVM or change the directory being pointed to.
- name: Native macOS (release)
if: runner.os == 'macOS'
run: |
brew update
find /usr/local/bin -lname '*/Library/Frameworks/Python.framework/*' -delete
brew install llvm@${{ matrix.llvm }}
export SDKROOT="$(xcrun --show-sdk-path)"
export PATH="/usr/local/opt/llvm@${{ matrix.llvm }}/bin:$PATH"

View file

@ -26,6 +26,10 @@ repos:
name: Run Ruff (lint) on Tools/peg_generator/
args: [--exit-non-zero-on-fix, --config=Tools/peg_generator/.ruff.toml]
files: ^Tools/peg_generator/
- id: ruff-check
name: Run Ruff (lint) on Tools/wasm/
args: [--exit-non-zero-on-fix, --config=Tools/wasm/.ruff.toml]
files: ^Tools/wasm/
- id: ruff-format
name: Run Ruff (format) on Doc/
args: [--check]
@ -34,6 +38,10 @@ repos:
name: Run Ruff (format) on Tools/build/check_warnings.py
args: [--check, --config=Tools/build/.ruff.toml]
files: ^Tools/build/check_warnings.py
- id: ruff-format
name: Run Ruff (format) on Tools/wasm/
args: [--check, --config=Tools/wasm/.ruff.toml]
files: ^Tools/wasm/
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 25.9.0

View file

@ -2,6 +2,7 @@
import asyncio
import argparse
import json
import os
import platform
import re
@ -184,10 +185,16 @@ def make_build_python(context):
run(["make", "-j", str(os.cpu_count())])
# To create new builds of these dependencies, usually all that's necessary is to
# push a tag to the cpython-android-source-deps repository, and GitHub Actions
# will do the rest.
#
# If you're a member of the Python core team, and you'd like to be able to push
# these tags yourself, please contact Malcolm Smith or Russell Keith-Magee.
def unpack_deps(host, prefix_dir):
os.chdir(prefix_dir)
deps_url = "https://github.com/beeware/cpython-android-source-deps/releases/download"
for name_ver in ["bzip2-1.0.8-3", "libffi-3.4.4-3", "openssl-3.0.15-4",
for name_ver in ["bzip2-1.0.8-3", "libffi-3.4.4-3", "openssl-3.0.18-0",
"sqlite-3.50.4-0", "xz-5.4.6-1", "zstd-1.5.7-1"]:
filename = f"{name_ver}-{host}.tar.gz"
download(f"{deps_url}/{name_ver}/{filename}")
@ -546,27 +553,33 @@ async def gradle_task(context):
task_prefix = "connected"
env["ANDROID_SERIAL"] = context.connected
if context.command:
mode = "-c"
module = context.command
else:
mode = "-m"
module = context.module or "test"
if context.ci_mode:
context.args[0:0] = [
# See _add_ci_python_opts in libregrtest/main.py.
"-W", "error", "-bb", "-E",
# Randomization is disabled because order-dependent failures are
# much less likely to pass on a rerun in single-process mode.
"-m", "test",
f"--{context.ci_mode}-ci", "--single-process", "--no-randomize"
]
if not any(arg in context.args for arg in ["-c", "-m"]):
context.args[0:0] = ["-m", "test"]
args = [
gradlew, "--console", "plain", f"{task_prefix}DebugAndroidTest",
] + [
# Build-time properties
f"-Ppython.{name}={value}"
f"-P{name}={value}"
for name, value in [
("sitePackages", context.site_packages), ("cwd", context.cwd)
] if value
] + [
# Runtime properties
f"-Pandroid.testInstrumentationRunnerArguments.python{name}={value}"
for name, value in [
("Mode", mode), ("Module", module), ("Args", join_command(context.args))
] if value
("python.sitePackages", context.site_packages),
("python.cwd", context.cwd),
(
"android.testInstrumentationRunnerArguments.pythonArgs",
json.dumps(context.args),
),
]
if value
]
if context.verbose >= 2:
args.append("--info")
@ -734,15 +747,14 @@ def ci(context):
else:
with TemporaryDirectory(prefix=SCRIPT_NAME) as temp_dir:
print("::group::Tests")
# Prove the package is self-contained by using it to run the tests.
shutil.unpack_archive(package_path, temp_dir)
# Randomization is disabled because order-dependent failures are
# much less likely to pass on a rerun in single-process mode.
launcher_args = ["--managed", "maxVersion", "-v"]
test_args = ["--fast-ci", "--single-process", "--no-randomize"]
launcher_args = [
"--managed", "maxVersion", "-v", f"--{context.ci_mode}-ci"
]
run(
["./android.py", "test", *launcher_args, "--", *test_args],
["./android.py", "test", *launcher_args],
cwd=temp_dir
)
print("::endgroup::")
@ -825,18 +837,11 @@ def add_parser(*args, **kwargs):
test.add_argument(
"--cwd", metavar="DIR", type=abspath,
help="Directory to copy as the app's working directory.")
mode_group = test.add_mutually_exclusive_group()
mode_group.add_argument(
"-c", dest="command", help="Execute the given Python code.")
mode_group.add_argument(
"-m", dest="module", help="Execute the module with the given name.")
test.epilog = (
"If neither -c nor -m are passed, the default is '-m test', which will "
"run Python's own test suite.")
test.add_argument(
"args", nargs="*", help=f"Arguments to add to sys.argv. "
f"Separate them from {SCRIPT_NAME}'s own arguments with `--`.")
"args", nargs="*", help=f"Python command-line arguments. "
f"Separate them from {SCRIPT_NAME}'s own arguments with `--`. "
f"If neither -c nor -m are included, `-m test` will be prepended, "
f"which will run Python's own test suite.")
# Package arguments.
for subcommand in [package, ci]:
@ -844,6 +849,16 @@ def add_parser(*args, **kwargs):
"-g", action="store_true", default=False, dest="debug",
help="Include debug information in package")
# CI arguments
for subcommand in [test, ci]:
group = subcommand.add_mutually_exclusive_group(required=subcommand is ci)
group.add_argument(
"--fast-ci", action="store_const", dest="ci_mode", const="fast",
help="Add test arguments for GitHub Actions")
group.add_argument(
"--slow-ci", action="store_const", dest="ci_mode", const="slow",
help="Add test arguments for buildbots")
return parser.parse_args()

View file

@ -47,7 +47,7 @@ for ((i, prefix) in prefixes.withIndex()) {
val libDir = file("$prefix/lib")
val version = run {
for (filename in libDir.list()!!) {
"""python(\d+\.\d+)""".toRegex().matchEntire(filename)?.let {
"""python(\d+\.\d+[a-z]*)""".toRegex().matchEntire(filename)?.let {
return@run it.groupValues[1]
}
}
@ -64,7 +64,8 @@ for ((i, prefix) in prefixes.withIndex()) {
val libPythonDir = file("$libDir/python$pythonVersion")
val triplet = run {
for (filename in libPythonDir.list()!!) {
"""_sysconfigdata__android_(.+).py""".toRegex().matchEntire(filename)?.let {
"""_sysconfigdata_[a-z]*_android_(.+).py""".toRegex()
.matchEntire(filename)?.let {
return@run it.groupValues[1]
}
}

View file

@ -20,7 +20,7 @@ class PythonSuite {
val status = PythonTestRunner(
InstrumentationRegistry.getInstrumentation().targetContext
).run(
InstrumentationRegistry.getArguments()
InstrumentationRegistry.getArguments().getString("pythonArgs")!!,
)
assertEquals(0, status)
} finally {

View file

@ -3,6 +3,7 @@
#include <jni.h>
#include <pthread.h>
#include <Python.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
@ -15,6 +16,13 @@ static void throw_runtime_exception(JNIEnv *env, const char *message) {
message);
}
static void throw_errno(JNIEnv *env, const char *error_prefix) {
char error_message[1024];
snprintf(error_message, sizeof(error_message),
"%s: %s", error_prefix, strerror(errno));
throw_runtime_exception(env, error_message);
}
// --- Stdio redirection ------------------------------------------------------
@ -95,10 +103,7 @@ JNIEXPORT void JNICALL Java_org_python_testbed_PythonTestRunner_redirectStdioToL
for (StreamInfo *si = STREAMS; si->file; si++) {
char *error_prefix;
if ((error_prefix = redirect_stream(si))) {
char error_message[1024];
snprintf(error_message, sizeof(error_message),
"%s: %s", error_prefix, strerror(errno));
throw_runtime_exception(env, error_message);
throw_errno(env, error_prefix);
return;
}
}
@ -107,13 +112,38 @@ JNIEXPORT void JNICALL Java_org_python_testbed_PythonTestRunner_redirectStdioToL
// --- Python initialization ---------------------------------------------------
static PyStatus set_config_string(
JNIEnv *env, PyConfig *config, wchar_t **config_str, jstring value
) {
const char *value_utf8 = (*env)->GetStringUTFChars(env, value, NULL);
PyStatus status = PyConfig_SetBytesString(config, config_str, value_utf8);
(*env)->ReleaseStringUTFChars(env, value, value_utf8);
return status;
static char *init_signals() {
// Some tests use SIGUSR1, but that's blocked by default in an Android app in
// order to make it available to `sigwait` in the Signal Catcher thread.
// (https://cs.android.com/android/platform/superproject/+/android14-qpr3-release:art/runtime/signal_catcher.cc).
// That thread's functionality is only useful for debugging the JVM, so disabling
// it should not weaken the tests.
//
// There's no safe way of stopping the thread completely (#123982), but simply
// unblocking SIGUSR1 is enough to fix most tests.
//
// However, in tests that generate multiple different signals in quick
// succession, it's possible for SIGUSR1 to arrive while the main thread is busy
// running the C-level handler for a different signal. In that case, the SIGUSR1
// may be sent to the Signal Catcher thread instead, which will generate a log
// message containing the text "reacting to signal".
//
// Such tests may need to be changed in one of the following ways:
// * Use a signal other than SIGUSR1 (e.g. test_stress_delivery_simultaneous in
// test_signal.py).
// * Send the signal to a specific thread rather than the whole process (e.g.
// test_signals in test_threadsignals.py.
sigset_t set;
if (sigemptyset(&set)) {
return "sigemptyset";
}
if (sigaddset(&set, SIGUSR1)) {
return "sigaddset";
}
if ((errno = pthread_sigmask(SIG_UNBLOCK, &set, NULL))) {
return "pthread_sigmask";
}
return NULL;
}
static void throw_status(JNIEnv *env, PyStatus status) {
@ -121,27 +151,47 @@ static void throw_status(JNIEnv *env, PyStatus status) {
}
JNIEXPORT int JNICALL Java_org_python_testbed_PythonTestRunner_runPython(
JNIEnv *env, jobject obj, jstring home, jstring runModule
JNIEnv *env, jobject obj, jstring home, jarray args
) {
const char *home_utf8 = (*env)->GetStringUTFChars(env, home, NULL);
char cwd[PATH_MAX];
snprintf(cwd, sizeof(cwd), "%s/%s", home_utf8, "cwd");
if (chdir(cwd)) {
throw_errno(env, "chdir");
return 1;
}
char *error_prefix;
if ((error_prefix = init_signals())) {
throw_errno(env, error_prefix);
return 1;
}
PyConfig config;
PyStatus status;
PyConfig_InitIsolatedConfig(&config);
PyConfig_InitPythonConfig(&config);
status = set_config_string(env, &config, &config.home, home);
if (PyStatus_Exception(status)) {
jsize argc = (*env)->GetArrayLength(env, args);
const char *argv[argc + 1];
for (int i = 0; i < argc; i++) {
jobject arg = (*env)->GetObjectArrayElement(env, args, i);
argv[i] = (*env)->GetStringUTFChars(env, arg, NULL);
}
argv[argc] = NULL;
// PyConfig_SetBytesArgv "must be called before other methods, since the
// preinitialization configuration depends on command line arguments"
if (PyStatus_Exception(status = PyConfig_SetBytesArgv(&config, argc, (char**)argv))) {
throw_status(env, status);
return 1;
}
status = set_config_string(env, &config, &config.run_module, runModule);
status = PyConfig_SetBytesString(&config, &config.home, home_utf8);
if (PyStatus_Exception(status)) {
throw_status(env, status);
return 1;
}
// Some tests generate SIGPIPE and SIGXFSZ, which should be ignored.
config.install_signal_handlers = 1;
status = Py_InitializeFromConfig(&config);
if (PyStatus_Exception(status)) {
throw_status(env, status);

View file

@ -5,6 +5,7 @@ import android.os.*
import android.system.Os
import android.widget.TextView
import androidx.appcompat.app.*
import org.json.JSONArray
import java.io.*
@ -15,30 +16,25 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val status = PythonTestRunner(this).run("-m", "test", "-W -uall")
val status = PythonTestRunner(this).run("""["-m", "test", "-W", "-uall"]""")
findViewById<TextView>(R.id.tvHello).text = "Exit status $status"
}
}
class PythonTestRunner(val context: Context) {
fun run(instrumentationArgs: Bundle) = run(
instrumentationArgs.getString("pythonMode")!!,
instrumentationArgs.getString("pythonModule")!!,
instrumentationArgs.getString("pythonArgs") ?: "",
)
/** Run Python.
*
* @param mode Either "-c" or "-m".
* @param module Python statements for "-c" mode, or a module name for
* "-m" mode.
* @param args Arguments to add to sys.argv. Will be parsed by `shlex.split`.
* @param args Python command-line, encoded as JSON.
* @return The Python exit status: zero on success, nonzero on failure. */
fun run(mode: String, module: String, args: String) : Int {
Os.setenv("PYTHON_MODE", mode, true)
Os.setenv("PYTHON_MODULE", module, true)
Os.setenv("PYTHON_ARGS", args, true)
fun run(args: String) : Int {
// We leave argument 0 as an empty string, which is a placeholder for the
// executable name in embedded mode.
val argsJsonArray = JSONArray(args)
val argsStringArray = Array<String>(argsJsonArray.length() + 1) { it -> ""}
for (i in 0..<argsJsonArray.length()) {
argsStringArray[i + 1] = argsJsonArray.getString(i)
}
// Python needs this variable to help it find the temporary directory,
// but Android only sets it on API level 33 and later.
@ -47,10 +43,7 @@ class PythonTestRunner(val context: Context) {
val pythonHome = extractAssets()
System.loadLibrary("main_activity")
redirectStdioToLogcat()
// The main module is in src/main/python. We don't simply call it
// "main", as that could clash with third-party test code.
return runPython(pythonHome.toString(), "android_testbed_main")
return runPython(pythonHome.toString(), argsStringArray)
}
private fun extractAssets() : File {
@ -59,6 +52,13 @@ class PythonTestRunner(val context: Context) {
throw RuntimeException("Failed to delete $pythonHome")
}
extractAssetDir("python", context.filesDir)
// Empty directories are lost in the asset packing/unpacking process.
val cwd = File(pythonHome, "cwd")
if (!cwd.exists()) {
cwd.mkdir()
}
return pythonHome
}
@ -88,5 +88,5 @@ class PythonTestRunner(val context: Context) {
}
private external fun redirectStdioToLogcat()
private external fun runPython(home: String, runModule: String) : Int
private external fun runPython(home: String, args: Array<String>) : Int
}

View file

@ -1,48 +0,0 @@
import os
import runpy
import shlex
import signal
import sys
# Some tests use SIGUSR1, but that's blocked by default in an Android app in
# order to make it available to `sigwait` in the Signal Catcher thread.
# (https://cs.android.com/android/platform/superproject/+/android14-qpr3-release:art/runtime/signal_catcher.cc).
# That thread's functionality is only useful for debugging the JVM, so disabling
# it should not weaken the tests.
#
# There's no safe way of stopping the thread completely (#123982), but simply
# unblocking SIGUSR1 is enough to fix most tests.
#
# However, in tests that generate multiple different signals in quick
# succession, it's possible for SIGUSR1 to arrive while the main thread is busy
# running the C-level handler for a different signal. In that case, the SIGUSR1
# may be sent to the Signal Catcher thread instead, which will generate a log
# message containing the text "reacting to signal".
#
# Such tests may need to be changed in one of the following ways:
# * Use a signal other than SIGUSR1 (e.g. test_stress_delivery_simultaneous in
# test_signal.py).
# * Send the signal to a specific thread rather than the whole process (e.g.
# test_signals in test_threadsignals.py.
signal.pthread_sigmask(signal.SIG_UNBLOCK, [signal.SIGUSR1])
mode = os.environ["PYTHON_MODE"]
module = os.environ["PYTHON_MODULE"]
sys.argv[1:] = shlex.split(os.environ["PYTHON_ARGS"])
cwd = f"{sys.prefix}/cwd"
if not os.path.exists(cwd):
# Empty directories are lost in the asset packing/unpacking process.
os.mkdir(cwd)
os.chdir(cwd)
if mode == "-c":
# In -c mode, sys.path starts with an empty string, which means whatever the current
# working directory is at the moment of each import.
sys.path.insert(0, "")
exec(module, {})
elif mode == "-m":
sys.path.insert(0, os.getcwd())
runpy.run_module(module, run_name="__main__", alter_sys=True)
else:
raise ValueError(f"unknown mode: {mode}")

View file

@ -312,11 +312,18 @@ def unpack_deps(
On iOS, as a safety mechanism, any dynamic libraries will be purged from
the unpacked dependencies.
"""
# To create new builds of these dependencies, usually all that's necessary
# is to push a tag to the cpython-apple-source-deps repository, and GitHub
# Actions will do the rest.
#
# If you're a member of the Python core team, and you'd like to be able to
# push these tags yourself, please contact Malcolm Smith or Russell
# Keith-Magee.
deps_url = "https://github.com/beeware/cpython-apple-source-deps/releases/download"
for name_ver in [
"BZip2-1.0.8-2",
"libFFI-3.4.7-2",
"OpenSSL-3.0.17-1",
"OpenSSL-3.0.18-1",
"XZ-5.6.4-2",
"mpdecimal-4.0.0-2",
"zstd-1.5.7-1",
@ -816,7 +823,7 @@ def test(context: argparse.Namespace, host: str | None = None) -> None:
+ [
"--",
"test",
"--slow-ci" if context.slow else "--fast-ci",
f"--{context.ci_mode}-ci",
"--single-process",
"--no-randomize",
# Timeout handling requires subprocesses; explicitly setting
@ -829,11 +836,39 @@ def test(context: argparse.Namespace, host: str | None = None) -> None:
)
def apple_sim_host(platform_name: str) -> str:
"""Determine the native simulator target for this platform."""
for _, slice_parts in HOSTS[platform_name].items():
for host_triple in slice_parts:
parts = host_triple.split('-')
if parts[0] == platform.machine() and parts[-1] == "simulator":
return host_triple
raise KeyError(platform_name)
def ci(context: argparse.Namespace) -> None:
"""The implementation of the "ci" command."""
"""The implementation of the "ci" command.
In "Fast" mode, this compiles the build python, and the simulator for the
build machine's architecture; and runs the test suite with `--fast-ci`
configuration.
In "Slow" mode, it compiles the build python, plus all candidate
architectures (both device and simulator); then runs the test suite with
`--slow-ci` configuration.
"""
clean(context, "all")
if context.ci_mode == "slow":
# In slow mode, build and test the full XCframework
build(context, host="all")
test(context, host="all")
else:
# In fast mode, just build the simulator platform.
sim_host = apple_sim_host(context.platform)
build(context, host="build")
build(context, host=sim_host)
test(context, host=sim_host)
def parse_args() -> argparse.Namespace:
@ -940,11 +975,13 @@ def parse_args() -> argparse.Namespace:
"an ARM64 iPhone 16 Pro simulator running iOS 26.0."
),
)
cmd.add_argument(
"--slow",
action="store_true",
help="Run tests with --slow-ci options.",
)
group = cmd.add_mutually_exclusive_group()
group.add_argument(
"--fast-ci", action="store_const", dest="ci_mode", const="fast",
help="Add test arguments for GitHub Actions")
group.add_argument(
"--slow-ci", action="store_const", dest="ci_mode", const="slow",
help="Add test arguments for buildbots")
for subcommand in [configure_build, configure_host, build, ci]:
subcommand.add_argument(
@ -1005,4 +1042,10 @@ def signal_handler(*args):
if __name__ == "__main__":
# Under the buildbot, stdout is not a TTY, but we must still flush after
# every line to make sure our output appears in the correct order relative
# to the output of our subprocesses.
for stream in [sys.stdout, sys.stderr]:
stream.reconfigure(line_buffering=True)
main()

View file

@ -224,6 +224,17 @@ ### Testing a multi-architecture framework
$ python Apple test iOS
This test will attempt to find an "SE-class" simulator (i.e., an iPhone SE, or
iPhone 16e, or similar), and run the test suite on the most recent version of
iOS that is available. You can specify a simulator using the `--simulator`
command line argument, providing the name of the simulator (e.g., `--simulator
'iPhone 16 Pro'`). You can also use this argument to control the OS version used
for testing; `--simulator 'iPhone 16 Pro,OS=18.2'` would attempt to run the
tests on an iPhone 16 Pro running iOS 18.2.
If the test runner is executed on GitHub Actions, the `GITHUB_ACTIONS`
environment variable will be exposed to the iOS process at runtime.
### Testing a single-architecture framework
The `Apple/testbed` folder that contains an Xcode project that is able to run

View file

@ -35,6 +35,9 @@
setenv("NO_COLOR", "1", true);
setenv("PYTHON_COLORS", "0", true);
if (getenv("GITHUB_ACTIONS")) {
NSLog(@"Running in a GitHub Actions environment");
}
// Arguments to pass into the test suite runner.
// argv[0] must identify the process; any subsequent arg
// will be handled as if it were an argument to `python -m test`

View file

@ -1,5 +1,6 @@
import argparse
import json
import os
import re
import shutil
import subprocess
@ -78,6 +79,13 @@ def xcode_test(location: Path, platform: str, simulator: str, verbose: bool):
check=True,
)
# Any environment variable prefixed with TEST_RUNNER_ is exposed into the
# test runner environment. There are some variables (like those identifying
# CI platforms) that can be useful to have access to.
test_env = os.environ.copy()
if "GITHUB_ACTIONS" in os.environ:
test_env["TEST_RUNNER_GITHUB_ACTIONS"] = os.environ["GITHUB_ACTIONS"]
print("Running test project...")
# Test execution *can't* be run -quiet; verbose mode
# is how we see the output of the test output.
@ -85,6 +93,7 @@ def xcode_test(location: Path, platform: str, simulator: str, verbose: bool):
["xcodebuild", "test-without-building"] + args,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
env=test_env,
)
while line := (process.stdout.readline()).decode(*DECODE_ARGS):
# Strip the timestamp/process prefix from each log line
@ -412,4 +421,9 @@ def main():
if __name__ == "__main__":
# Under the buildbot, stdout is not a TTY, but we must still flush after
# every line to make sure our output appears in the correct order relative
# to the output of our subprocesses.
for stream in [sys.stdout, sys.stderr]:
stream.reconfigure(line_buffering=True)
main()

View file

@ -184,7 +184,7 @@ venv:
fi
.PHONY: dist-no-html
dist-no-html: dist-text dist-pdf dist-epub dist-texinfo
dist-no-html: dist-text dist-epub dist-texinfo
.PHONY: dist
dist:

View file

@ -19,6 +19,12 @@ If you find a bug in this documentation or would like to propose an improvement,
please submit a bug report on the :ref:`issue tracker <using-the-tracker>`. If you
have a suggestion on how to fix it, include that as well.
.. only:: translation
If the bug or suggested improvement concerns the translation of this
documentation, submit the report to the
`translations repository <TRANSLATION_REPO_>`_ instead.
You can also open a discussion item on our
`Documentation Discourse forum <https://discuss.python.org/c/documentation/26>`_.

View file

@ -160,7 +160,7 @@ There are three ways strings and buffers can be converted to C:
``w*`` (read-write :term:`bytes-like object`) [Py_buffer]
This format accepts any object which implements the read-write buffer
interface. It fills a :c:type:`Py_buffer` structure provided by the caller.
The buffer may contain embedded null bytes. The caller have to call
The buffer may contain embedded null bytes. The caller has to call
:c:func:`PyBuffer_Release` when it is done with the buffer.
``es`` (:class:`str`) [const char \*encoding, char \*\*buffer]
@ -305,7 +305,7 @@ the minimal value for the corresponding signed integer type of the same size.
``D`` (:class:`complex`) [Py_complex]
Convert a Python complex number to a C :c:type:`Py_complex` structure.
.. deprecated:: next
.. deprecated:: 3.15
For unsigned integer formats ``B``, ``H``, ``I``, ``k`` and ``K``,
:exc:`DeprecationWarning` is emitted when the value is larger than

View file

@ -236,7 +236,7 @@ PyBytesWriter
The :c:type:`PyBytesWriter` API can be used to create a Python :class:`bytes`
object.
.. versionadded:: next
.. versionadded:: 3.15
.. c:type:: PyBytesWriter
@ -259,8 +259,9 @@ Create, Finish, Discard
If *size* is greater than zero, allocate *size* bytes, and set the
writer size to *size*. The caller is responsible to write *size*
bytes using :c:func:`PyBytesWriter_GetData`.
This function does not overallocate.
On error, set an exception and return NULL.
On error, set an exception and return ``NULL``.
*size* must be positive or zero.
@ -349,6 +350,8 @@ Low-level API
Resize the writer to *size* bytes. It can be used to enlarge or to
shrink the writer.
This function typically overallocates to achieve amortized performance when
resizing multiple times.
Newly allocated bytes are left uninitialized.
@ -360,6 +363,8 @@ Low-level API
.. c:function:: int PyBytesWriter_Grow(PyBytesWriter *writer, Py_ssize_t grow)
Resize the writer by adding *grow* bytes to the current writer size.
This function typically overallocates to achieve amortized performance when
resizing multiple times.
Newly allocated bytes are left uninitialized.

View file

@ -15,7 +15,7 @@ Refer to :ref:`using-capsules` for more information on using these objects.
.. c:type:: PyCapsule
This subtype of :c:type:`PyObject` represents an opaque value, useful for C
extension modules who need to pass an opaque value (as a :c:expr:`void*`
extension modules which need to pass an opaque value (as a :c:expr:`void*`
pointer) through Python code to other C code. It is often used to make a C
function pointer defined in one module available to other modules, so the
regular import mechanism can be used to access C APIs defined in dynamically

View file

@ -289,7 +289,7 @@ may change without deprecation warnings.
.. c:function:: Py_ssize_t PyUnstable_Eval_RequestCodeExtraIndex(freefunc free)
Return a new an opaque index value used to adding data to code objects.
Return a new opaque index value used to adding data to code objects.
You generally call this function once (per interpreter) and use the result
with ``PyCode_GetExtra`` and ``PyCode_SetExtra`` to manipulate

View file

@ -7,7 +7,7 @@ Codec registry and support functions
Register a new codec search function.
As side effect, this tries to load the :mod:`!encodings` package, if not yet
As a side effect, this tries to load the :mod:`!encodings` package, if not yet
done, to make sure that it is always first in the list of search functions.
.. c:function:: int PyCodec_Unregister(PyObject *search_function)
@ -39,7 +39,7 @@ Codec registry and support functions
*object* is passed through the decoder function found for the given
*encoding* using the error handling method defined by *errors*. *errors* may
be ``NULL`` to use the default method defined for the codec. Raises a
:exc:`LookupError` if no encoder can be found.
:exc:`LookupError` if no decoder can be found.
Codec lookup API

View file

@ -16,7 +16,7 @@ Complex Number Objects
The complex number value, using the C :c:type:`Py_complex` representation.
.. deprecated-removed:: next 3.20
.. deprecated-removed:: 3.15 3.20
Use :c:func:`PyComplex_AsCComplex` and
:c:func:`PyComplex_FromCComplex` to convert a
Python complex number to/from the C :c:type:`Py_complex`

View file

@ -41,7 +41,7 @@ The return value (*rv*) for these functions should be interpreted as follows:
``rv + 1`` bytes would have been needed to succeed. ``str[size-1]`` is ``'\0'``
in this case.
* When ``rv < 0``, "something bad happened." ``str[size-1]`` is ``'\0'`` in
* When ``rv < 0``, the output conversion failed and ``str[size-1]`` is ``'\0'`` in
this case too, but the rest of *str* is undefined. The exact cause of the error
depends on the underlying platform.

View file

@ -50,7 +50,7 @@ Dictionary Objects
.. c:function:: int PyDict_Contains(PyObject *p, PyObject *key)
Determine if dictionary *p* contains *key*. If an item in *p* is matches
Determine if dictionary *p* contains *key*. If an item in *p* matches
*key*, return ``1``, otherwise return ``0``. On error, return ``-1``.
This is equivalent to the Python expression ``key in p``.
@ -198,7 +198,7 @@ Dictionary Objects
.. c:function:: int PyDict_Pop(PyObject *p, PyObject *key, PyObject **result)
Remove *key* from dictionary *p* and optionally return the removed value.
Do not raise :exc:`KeyError` if the key missing.
Do not raise :exc:`KeyError` if the key is missing.
- If the key is present, set *\*result* to a new reference to the removed
value if *result* is not ``NULL``, and return ``1``.
@ -207,7 +207,7 @@ Dictionary Objects
- On error, raise an exception and return ``-1``.
Similar to :meth:`dict.pop`, but without the default value and
not raising :exc:`KeyError` if the key missing.
not raising :exc:`KeyError` if the key is missing.
.. versionadded:: 3.13

View file

@ -175,6 +175,9 @@ There are a few functions specific to Python functions.
.. versionadded:: 3.12
- ``PyFunction_PYFUNC_EVENT_MODIFY_QUALNAME``
.. versionadded:: 3.15
.. c:type:: int (*PyFunction_WatchCallback)(PyFunction_WatchEvent event, PyFunctionObject *func, PyObject *new_value)

View file

@ -1113,7 +1113,7 @@ code, or when embedding the Python interpreter:
This function is safe to call without an :term:`attached thread state`; it
will simply return ``NULL`` indicating that there was no prior thread state.
.. seealso:
.. seealso::
:c:func:`PyEval_ReleaseThread`
.. note::
@ -1124,6 +1124,19 @@ code, or when embedding the Python interpreter:
The following functions use thread-local storage, and are not compatible
with sub-interpreters:
.. c:type:: PyGILState_STATE
The type of the value returned by :c:func:`PyGILState_Ensure` and passed to
:c:func:`PyGILState_Release`.
.. c:enumerator:: PyGILState_LOCKED
The GIL was already held when :c:func:`PyGILState_Ensure` was called.
.. c:enumerator:: PyGILState_UNLOCKED
The GIL was not held when :c:func:`PyGILState_Ensure` was called.
.. c:function:: PyGILState_STATE PyGILState_Ensure()
Ensure that the current thread is ready to call the Python C API regardless
@ -1174,12 +1187,12 @@ with sub-interpreters:
made on the main thread. This is mainly a helper/diagnostic function.
.. note::
This function does not account for :term:`thread states <thread state>` created
by something other than :c:func:`PyGILState_Ensure` (such as :c:func:`PyThreadState_New`).
This function may return non-``NULL`` even when the :term:`thread state`
is detached.
Prefer :c:func:`PyThreadState_Get` or :c:func:`PyThreadState_GetUnchecked`
for most cases.
.. seealso: :c:func:`PyThreadState_Get``
.. seealso:: :c:func:`PyThreadState_Get`
.. c:function:: int PyGILState_Check()
@ -1278,11 +1291,11 @@ All of the following functions must be called after :c:func:`Py_Initialize`.
must be :term:`attached <attached thread state>`
.. versionchanged:: 3.9
This function now calls the :c:member:`PyThreadState.on_delete` callback.
This function now calls the :c:member:`!PyThreadState.on_delete` callback.
Previously, that happened in :c:func:`PyThreadState_Delete`.
.. versionchanged:: 3.13
The :c:member:`PyThreadState.on_delete` callback was removed.
The :c:member:`!PyThreadState.on_delete` callback was removed.
.. c:function:: void PyThreadState_Delete(PyThreadState *tstate)
@ -2127,7 +2140,7 @@ use a thread key and functions to associate a :c:expr:`void*` value per
thread.
A :term:`thread state` does *not* need to be :term:`attached <attached thread state>`
when calling these functions; they suppl their own locking.
when calling these functions; they supply their own locking.
Note that :file:`Python.h` does not include the declaration of the TLS APIs,
you need to include :file:`pythread.h` to use thread-local storage.

View file

@ -54,6 +54,6 @@ There are two functions specifically for working with iterators.
- ``PYGEN_RETURN`` if iterator returns. Return value is returned via *presult*.
- ``PYGEN_NEXT`` if iterator yields. Yielded value is returned via *presult*.
- ``PYGEN_ERROR`` if iterator has raised and exception. *presult* is set to ``NULL``.
- ``PYGEN_ERROR`` if iterator has raised an exception. *presult* is set to ``NULL``.
.. versionadded:: 3.10

View file

@ -43,7 +43,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
.. impl-detail::
CPython keeps an array of integer objects for all integers
between ``-5`` and ``256``. When you create an int in that range
between ``-5`` and ``1024``. When you create an int in that range
you actually just get back a reference to the existing object.

View file

@ -102,6 +102,10 @@ Module Objects
Return a pointer to the :c:type:`PyModuleDef` struct from which the module was
created, or ``NULL`` if the module wasn't created from a definition.
On error, return ``NULL`` with an exception set.
Use :c:func:`PyErr_Occurred` to tell this case apart from a mising
:c:type:`!PyModuleDef`.
.. c:function:: PyObject* PyModule_GetFilenameObject(PyObject *module)

View file

@ -201,7 +201,7 @@ Object Protocol
This case can arise from forgetting ``NULL`` checks and would delete the
attribute.
.. versionchanged:: next
.. versionchanged:: 3.15
Must not be called with NULL value if an exception is set.
@ -226,7 +226,7 @@ Object Protocol
For more details, see :c:func:`PyUnicode_InternFromString`, which may be
used internally to create a key object.
.. versionchanged:: next
.. versionchanged:: 3.15
Must not be called with NULL value if an exception is set.
@ -600,7 +600,7 @@ Object Protocol
Clear the managed dictionary of *obj*.
This function must only be called in a traverse function of the type which
This function must only be called in a clear function of the type which
has the :c:macro:`Py_TPFLAGS_MANAGED_DICT` flag set.
.. versionadded:: 3.13

View file

@ -202,7 +202,7 @@ third-party distributors.
ABI Checking
============
.. versionadded:: next
.. versionadded:: 3.15
Python includes a rudimentary check for ABI compatibility.
@ -249,7 +249,7 @@ The full API is described below for advanced use cases.
may lead to crashes.
In particular, it is not safe to examine the raised exception.
.. versionadded:: next
.. versionadded:: 3.15
.. c:macro:: PyABIInfo_VAR(NAME)
@ -266,7 +266,7 @@ The full API is described below for advanced use cases.
PyABIInfo_DEFAULT_ABI_VERSION
}
.. versionadded:: next
.. versionadded:: 3.15
.. c:type:: PyABIInfo
@ -294,7 +294,7 @@ The full API is described below for advanced use cases.
Default flags, based on current values of macros such as
:c:macro:`Py_LIMITED_API` and :c:macro:`Py_GIL_DISABLED`.
Alternately, the field can be set to to the following flags, combined
Alternately, the field can be set to the following flags, combined
by bitwise OR.
Unused bits must be set to zero.
@ -352,7 +352,7 @@ The full API is described below for advanced use cases.
values of macros such as :c:macro:`Py_LIMITED_API`,
:c:macro:`PY_VERSION_HEX` and :c:macro:`Py_GIL_DISABLED`.
.. versionadded:: next
.. versionadded:: 3.15
.. _limited-api-list:

View file

@ -268,7 +268,7 @@ accessible to C code. They all work with the current interpreter thread's
If the non-existing object should not be treated as a failure, you can use
:c:func:`PySys_GetOptionalAttr` instead.
.. versionadded:: next
.. versionadded:: 3.15
.. c:function:: PyObject *PySys_GetAttrString(const char *name)
@ -279,7 +279,7 @@ accessible to C code. They all work with the current interpreter thread's
If the non-existing object should not be treated as a failure, you can use
:c:func:`PySys_GetOptionalAttrString` instead.
.. versionadded:: next
.. versionadded:: 3.15
.. c:function:: int PySys_GetOptionalAttr(PyObject *name, PyObject **result)
@ -293,7 +293,7 @@ accessible to C code. They all work with the current interpreter thread's
* Set an exception, set *\*result* to ``NULL``, and return ``-1``,
if an error occurred.
.. versionadded:: next
.. versionadded:: 3.15
.. c:function:: int PySys_GetOptionalAttrString(const char *name, PyObject **result)
@ -301,7 +301,7 @@ accessible to C code. They all work with the current interpreter thread's
specified as a :c:expr:`const char*` UTF-8 encoded bytes string,
rather than a :c:expr:`PyObject*`.
.. versionadded:: next
.. versionadded:: 3.15
.. c:function:: PyObject *PySys_GetObject(const char *name)

View file

@ -37,6 +37,19 @@ Tuple Objects
or ``NULL`` with an exception set on failure.
.. c:function:: PyObject* PyTuple_FromArray(PyObject *const *array, Py_ssize_t size)
Create a tuple of *size* items and copy references from *array* to the new
tuple.
*array* can be NULL if *size* is ``0``.
On success, return a new reference.
On error, set an exception and return ``NULL``.
.. versionadded:: 3.15
.. c:function:: PyObject* PyTuple_Pack(Py_ssize_t n, ...)
Return a new tuple object of size *n*,

View file

@ -1260,7 +1260,7 @@ and :c:data:`PyType_Type` effectively act as defaults.)
This bit indicates that instances of the class have a :attr:`~object.__dict__`
attribute, and that the space for the dictionary is managed by the VM.
If this flag is set, :c:macro:`Py_TPFLAGS_HAVE_GC` should also be set.
If this flag is set, :c:macro:`Py_TPFLAGS_HAVE_GC` must also be set.
The type traverse function must call :c:func:`PyObject_VisitManagedDict`
and its clear function must call :c:func:`PyObject_ClearManagedDict`.
@ -1278,6 +1278,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
This bit indicates that instances of the class should be weakly
referenceable.
If this flag is set, :c:macro:`Py_TPFLAGS_HAVE_GC` must also be set.
.. versionadded:: 3.12
**Inheritance:**
@ -1704,7 +1706,7 @@ and :c:data:`PyType_Type` effectively act as defaults.)
:c:func:`Py_CLEAR` macro performs the operations in a safe order.
If the :c:macro:`Py_TPFLAGS_MANAGED_DICT` bit is set in the
:c:member:`~PyTypeObject.tp_flags` field, the traverse function must call
:c:member:`~PyTypeObject.tp_flags` field, the clear function must call
:c:func:`PyObject_ClearManagedDict` like this::
PyObject_ClearManagedDict((PyObject*)self);

View file

@ -359,6 +359,7 @@
'papersize': 'a4paper',
# The font size ('10pt', '11pt' or '12pt').
'pointsize': '10pt',
'maxlistdepth': '8', # See https://github.com/python/cpython/issues/139588
}
# Grouping the document tree into LaTeX files. List of tuples
@ -444,6 +445,25 @@
# https://github.com/sphinx-doc/sphinx/issues/12359
epub_use_index = False
# translation tag
# ---------------
language_code = None
for arg in sys.argv:
if arg.startswith('language='):
language_code = arg.split('=', 1)[1]
if language_code:
tags.add('translation') # noqa: F821
rst_epilog += f"""\
.. _TRANSLATION_REPO: https://github.com/python/python-docs-{language_code.replace("_", "-").lower()}
""" # noqa: F821
else:
rst_epilog += """\
.. _TRANSLATION_REPO: https://github.com/python
"""
# Options for the coverage checker
# --------------------------------

View file

@ -92,7 +92,7 @@ Pending removal in Python 3.15
Use ``class TD(TypedDict): pass`` or ``TD = TypedDict("TD", {})``
to create a TypedDict with zero field.
* The :func:`typing.no_type_check_decorator` decorator function
* The :func:`!typing.no_type_check_decorator` decorator function
has been deprecated since Python 3.13.
After eight years in the :mod:`typing` module,
it has yet to be supported by any major type checker.

View file

@ -63,7 +63,7 @@ Pending removal in Python 3.16
* :mod:`logging`:
Support for custom logging handlers with the *strm* argument is deprecated
* Support for custom logging handlers with the *strm* argument is deprecated
and scheduled for removal in Python 3.16. Define handlers with the *stream*
argument instead. (Contributed by Mariusz Felisiak in :gh:`115032`.)

View file

@ -8,6 +8,8 @@ Pending removal in Python 3.20
- :mod:`argparse`
- :mod:`csv`
- :mod:`!ctypes.macholib`
- :mod:`decimal` (use :data:`decimal.SPEC_VERSION` instead)
- :mod:`imaplib`
- :mod:`ipaddress`
- :mod:`json`
- :mod:`logging` (``__date__`` also deprecated)
@ -19,5 +21,6 @@ Pending removal in Python 3.20
- :mod:`tabnanny`
- :mod:`tkinter.font`
- :mod:`tkinter.ttk`
- :mod:`zlib`
(Contributed by Hugo van Kemenade in :gh:`76007`.)
(Contributed by Hugo van Kemenade and Stan Ulbrych in :gh:`76007`.)

View file

@ -15,7 +15,6 @@ although there is currently no date scheduled for their removal.
* :mod:`builtins`:
* ``bool(NotImplemented)``.
* Generators: ``throw(type, exc, tb)`` and ``athrow(type, exc, tb)``
signature is deprecated: use ``throw(exc)`` and ``athrow(exc)`` instead,
the single argument signature.

View file

@ -560,6 +560,8 @@ For an object to be weakly referenceable, the extension type must set the
field. The legacy :c:member:`~PyTypeObject.tp_weaklistoffset` field should
be left as zero.
If this flag is set, :c:macro:`Py_TPFLAGS_HAVE_GC` should also be set.
Concretely, here is how the statically declared type object would look::
static PyTypeObject TrivialType = {

View file

@ -186,7 +186,7 @@ How do I get documentation on Python?
-------------------------------------
The standard documentation for the current stable version of Python is available
at https://docs.python.org/3/. PDF, plain text, and downloadable HTML versions are
at https://docs.python.org/3/. EPUB, plain text, and downloadable HTML versions are
also available at https://docs.python.org/3/download.html.
The documentation is written in reStructuredText and processed by `the Sphinx

View file

@ -9,12 +9,11 @@ model of how :mod:`asyncio` fundamentally works, helping you understand the
how and why behind the recommended patterns.
You might be curious about some key :mod:`!asyncio` concepts.
You'll be comfortably able to answer these questions by the end of this
article:
By the end of this article, you'll be able to comfortably answer these questions:
- What's happening behind the scenes when an object is awaited?
- How does :mod:`!asyncio` differentiate between a task which doesn't need
CPU-time (such as a network request or file read) as opposed to a task that
CPU time (such as a network request or file read) as opposed to a task that
does (such as computing n-factorial)?
- How to write an asynchronous variant of an operation, such as
an async sleep or database request.
@ -35,7 +34,7 @@ A conceptual overview part 1: the high-level
--------------------------------------------
In part 1, we'll cover the main, high-level building blocks of :mod:`!asyncio`:
the event loop, coroutine functions, coroutine objects, tasks and ``await``.
the event loop, coroutine functions, coroutine objects, tasks, and ``await``.
==========
Event Loop
@ -56,7 +55,7 @@ Once it pauses or completes, it returns control to the event loop.
The event loop will then select another job from its pool and invoke it.
You can *roughly* think of the collection of jobs as a queue: jobs are added and
then processed one at a time, generally (but not always) in order.
This process repeats indefinitely with the event loop cycling endlessly
This process repeats indefinitely, with the event loop cycling endlessly
onwards.
If there are no more jobs pending execution, the event loop is smart enough to
rest and avoid needlessly wasting CPU cycles, and will come back when there's
@ -276,7 +275,7 @@ in this case, a call to resume ``plant_a_tree()``.
Generally speaking, when the awaited task finishes (``dig_the_hole_task``),
the original task or coroutine (``plant_a_tree()``) is added back to the event
loops to-do list to be resumed.
loop's to-do list to be resumed.
This is a basic, yet reliable mental model.
In practice, the control handoffs are slightly more complex, but not by much.
@ -310,7 +309,7 @@ Consider this program::
The first statement in the coroutine ``main()`` creates ``task_b`` and schedules
it for execution via the event loop.
Then, ``coro_a()`` is repeatedly awaited. Control never cedes to the
event loop which is why we see the output of all three ``coro_a()``
event loop, which is why we see the output of all three ``coro_a()``
invocations before ``coro_b()``'s output:
.. code-block:: none
@ -338,8 +337,8 @@ This behavior of ``await coroutine`` can trip a lot of people up!
That example highlights how using only ``await coroutine`` could
unintentionally hog control from other tasks and effectively stall the event
loop.
:func:`asyncio.run` can help you detect such occurences via the
``debug=True`` flag which accordingly enables
:func:`asyncio.run` can help you detect such occurrences via the
``debug=True`` flag, which enables
:ref:`debug mode <asyncio-debug-mode>`.
Among other things, it will log any coroutines that monopolize execution for
100ms or longer.
@ -348,8 +347,8 @@ The design intentionally trades off some conceptual clarity around usage of
``await`` for improved performance.
Each time a task is awaited, control needs to be passed all the way up the
call stack to the event loop.
That might sound minor, but in a large program with many ``await``'s and a deep
callstack that overhead can add up to a meaningful performance drag.
That might sound minor, but in a large program with many ``await`` statements and a deep
call stack, that overhead can add up to a meaningful performance drag.
------------------------------------------------
A conceptual overview part 2: the nuts and bolts
@ -372,7 +371,7 @@ resume a coroutine.
If the coroutine was paused and is now being resumed, the argument ``arg``
will be sent in as the return value of the ``yield`` statement which originally
paused it.
If the coroutine is being used for the first time (as opposed to being resumed)
If the coroutine is being used for the first time (as opposed to being resumed),
``arg`` must be ``None``.
.. code-block::
@ -403,14 +402,14 @@ If the coroutine is being used for the first time (as opposed to being resumed)
returned_value = e.value
print(f"Coroutine main() finished and provided value: {returned_value}.")
:ref:`yield <yieldexpr>`, like usual, pauses execution and returns control
:ref:`yield <yieldexpr>`, as usual, pauses execution and returns control
to the caller.
In the example above, the ``yield``, on line 3, is called by
``... = await rock`` on line 11.
More broadly speaking, ``await`` calls the :meth:`~object.__await__` method of
the given object.
``await`` also does one more very special thing: it propagates (or "passes
along") any ``yield``\ s it receives up the call-chain.
along") any ``yield``\ s it receives up the call chain.
In this case, that's back to ``... = coroutine.send(None)`` on line 16.
The coroutine is resumed via the ``coroutine.send(42)`` call on line 21.
@ -462,12 +461,12 @@ computation's status and result.
The term is a nod to the idea of something still to come or not yet happened,
and the object is a way to keep an eye on that something.
A future has a few important attributes. One is its state which can be either
"pending", "cancelled" or "done".
A future has a few important attributes. One is its state, which can be either
"pending", "cancelled", or "done".
Another is its result, which is set when the state transitions to done.
Unlike a coroutine, a future does not represent the actual computation to be
done; instead, it represents the status and result of that computation, kind of
like a status light (red, yellow or green) or indicator.
like a status light (red, yellow, or green) or indicator.
:class:`asyncio.Task` subclasses :class:`asyncio.Future` in order to gain
these various capabilities.
@ -490,8 +489,8 @@ We'll go through an example of how you could leverage a future to create your
own variant of asynchronous sleep (``async_sleep``) which mimics
:func:`asyncio.sleep`.
This snippet registers a few tasks with the event loop and then awaits a
coroutine wrapped in a task: ``async_sleep(3)``.
This snippet registers a few tasks with the event loop and then awaits the task
created by ``asyncio.create_task``, which wraps the ``async_sleep(3)`` coroutine.
We want that task to finish only after three seconds have elapsed, but without
preventing other tasks from running.
@ -540,8 +539,8 @@ will monitor how much time has elapsed and, accordingly, call
# Block until the future is marked as done.
await future
Below, we'll use a rather bare object, ``YieldToEventLoop()``, to ``yield``
from ``__await__`` in order to cede control to the event loop.
Below, we use a rather bare ``YieldToEventLoop()`` object to ``yield``
from its ``__await__`` method, ceding control to the event loop.
This is effectively the same as calling ``asyncio.sleep(0)``, but this approach
offers more clarity, not to mention it's somewhat cheating to use
``asyncio.sleep`` when showcasing how to implement it!
@ -552,13 +551,13 @@ The ``watcher_task``, which runs the coroutine ``_sleep_watcher(...)``, will
be invoked once per full cycle of the event loop.
On each resumption, it'll check the time and if not enough has elapsed, then
it'll pause once again and hand control back to the event loop.
Eventually, enough time will have elapsed, and ``_sleep_watcher(...)`` will
mark the future as done, and then itself finish too by breaking out of the
Once enough time has elapsed, ``_sleep_watcher(...)``
marks the future as done and completes by exiting its
infinite ``while`` loop.
Given this helper task is only invoked once per cycle of the event loop,
you'd be correct to note that this asynchronous sleep will sleep *at least*
three seconds, rather than exactly three seconds.
Note this is also of true of ``asyncio.sleep``.
Note this is also true of ``asyncio.sleep``.
::
@ -601,6 +600,6 @@ For reference, you could implement it without futures, like so::
else:
await YieldToEventLoop()
But, that's all for now. Hopefully you're ready to more confidently dive into
But that's all for now. Hopefully you're ready to more confidently dive into
some async programming or check out advanced topics in the
:mod:`rest of the documentation <asyncio>`.

View file

@ -127,7 +127,7 @@ This module defines the following constants and functions:
.. versionchanged:: 3.13
Added support for GNU/kFreeBSD.
.. versionchanged:: next
.. versionchanged:: 3.15
Added support for Solaris.

View file

@ -340,14 +340,29 @@ Functions
* VALUE: :attr:`!object.__annotations__` is tried first; if that does not exist,
the :attr:`!object.__annotate__` function is called if it exists.
* FORWARDREF: If :attr:`!object.__annotations__` exists and can be evaluated successfully,
it is used; otherwise, the :attr:`!object.__annotate__` function is called. If it
does not exist either, :attr:`!object.__annotations__` is tried again and any error
from accessing it is re-raised.
* When calling :attr:`!object.__annotate__` it is first called with :attr:`~Format.FORWARDREF`.
If this is not implemented, it will then check if :attr:`~Format.VALUE_WITH_FAKE_GLOBALS`
is supported and use that in the fake globals environment.
If neither of these formats are supported, it will fall back to using :attr:`~Format.VALUE`.
If :attr:`~Format.VALUE` fails, the error from this call will be raised.
* STRING: If :attr:`!object.__annotate__` exists, it is called first;
otherwise, :attr:`!object.__annotations__` is used and stringified
using :func:`annotations_to_string`.
* When calling :attr:`!object.__annotate__` it is first called with :attr:`~Format.STRING`.
If this is not implemented, it will then check if :attr:`~Format.VALUE_WITH_FAKE_GLOBALS`
is supported and use that in the fake globals environment.
If neither of these formats are supported, it will fall back to using :attr:`~Format.VALUE`
with the result converted using :func:`annotations_to_string`.
If :attr:`~Format.VALUE` fails, the error from this call will be raised.
Returns a dict. :func:`!get_annotations` returns a new dict every time
it's called; calling it twice on the same object will return two
different but equivalent dicts.

View file

@ -74,7 +74,7 @@ ArgumentParser objects
prefix_chars='-', fromfile_prefix_chars=None, \
argument_default=None, conflict_handler='error', \
add_help=True, allow_abbrev=True, exit_on_error=True, \
*, suggest_on_error=False, color=True)
*, suggest_on_error=True, color=True)
Create a new :class:`ArgumentParser` object. All parameters should be passed
as keyword arguments. Each parameter has its own more detailed description
@ -117,7 +117,7 @@ ArgumentParser objects
error info when an error occurs. (default: ``True``)
* suggest_on_error_ - Enables suggestions for mistyped argument choices
and subparser names (default: ``False``)
and subparser names (default: ``True``)
* color_ - Allow color output (default: ``True``)
@ -134,6 +134,9 @@ ArgumentParser objects
.. versionchanged:: 3.14
*suggest_on_error* and *color* parameters were added.
.. versionchanged:: 3.15
*suggest_on_error* default changed to ``True``.
The following sections describe how each of these are used.
@ -596,13 +599,11 @@ suggest_on_error
^^^^^^^^^^^^^^^^
By default, when a user passes an invalid argument choice or subparser name,
:class:`ArgumentParser` will exit with error info and list the permissible
argument choices (if specified) or subparser names as part of the error message.
If the user would like to enable suggestions for mistyped argument choices and
subparser names, the feature can be enabled by setting ``suggest_on_error`` to
``True``. Note that this only applies for arguments when the choices specified
are strings::
:class:`ArgumentParser` will exit with error info and provide suggestions for
mistyped arguments. The error message will list the permissible argument
choices (if specified) or subparser names, along with a "maybe you meant"
suggestion if a close match is found. Note that this only applies for arguments
when the choices specified are strings::
>>> parser = argparse.ArgumentParser(description='Process some integers.',
suggest_on_error=True)
@ -612,16 +613,14 @@ are strings::
>>> parser.parse_args(['--action', 'sumn', 1, 2, 3])
tester.py: error: argument --action: invalid choice: 'sumn', maybe you meant 'sum'? (choose from 'sum', 'max')
If you're writing code that needs to be compatible with older Python versions
and want to opportunistically use ``suggest_on_error`` when it's available, you
can set it as an attribute after initializing the parser instead of using the
keyword argument::
You can disable suggestions by setting ``suggest_on_error`` to ``False``::
>>> parser = argparse.ArgumentParser(description='Process some integers.')
>>> parser.suggest_on_error = True
>>> parser = argparse.ArgumentParser(description='Process some integers.',
suggest_on_error=False)
.. versionadded:: 3.14
.. versionchanged:: 3.15
Changed default value of ``suggest_on_error`` from ``False`` to ``True``.
color
^^^^^
@ -639,6 +638,11 @@ by setting ``color`` to ``False``::
... help='an integer for the accumulator')
>>> parser.parse_args(['--help'])
Note that when ``color=True``, colored output depends on both environment
variables and terminal capabilities. However, if ``color=False``, colored
output is always disabled, even if environment variables like ``FORCE_COLOR``
are set.
.. versionadded:: 3.14

View file

@ -363,6 +363,11 @@ Literals
function call).
This has the same meaning as ``FormattedValue.value``.
* ``str`` is a constant containing the text of the interpolation expression.
If ``str`` is set to ``None``, then ``value`` is used to generate code
when calling :func:`ast.unparse`. This no longer guarantees that the
generated code is identical to the original and is intended for code
generation.
* ``conversion`` is an integer:
* -1: no conversion
@ -2507,7 +2512,7 @@ and classes for traversing abstract syntax trees:
.. versionchanged:: 3.13
Added the *show_empty* option.
.. versionchanged:: next
.. versionchanged:: 3.15
Omit optional ``Load()`` values by default.

View file

@ -316,13 +316,14 @@ StreamWriter
If that fails, the data is queued in an internal write buffer until it can be
sent.
The *data* buffer should be a bytes, bytearray, or C-contiguous one-dimensional
memoryview object.
The method should be used along with the ``drain()`` method::
stream.write(data)
await stream.drain()
.. note::
The *data* buffer should be a C contiguous one-dimensional :term:`bytes-like object <bytes-like object>`.
.. method:: writelines(data)

View file

@ -533,7 +533,7 @@ The :mod:`calendar` module exports the following data attributes:
in the standalone form if the locale provides one. Else it is equivalent
to :data:`month_name`.
.. versionadded:: next
.. versionadded:: 3.15
.. data:: standalone_month_abbr
@ -542,7 +542,7 @@ The :mod:`calendar` module exports the following data attributes:
locale in the standalone form if the locale provides one. Else it is
equivalent to :data:`month_abbr`.
.. versionadded:: next
.. versionadded:: 3.15
.. data:: JANUARY
@ -710,8 +710,7 @@ The following options are accepted:
.. option:: month
The month of the specified :option:`year` to print the calendar for.
Must be a number between 1 and 12,
and may only be used in text mode.
Must be a number between 1 and 12.
Defaults to printing a calendar for the full year.

View file

@ -338,7 +338,7 @@ Constants
.. data:: nan
A floating-point "not a number" (NaN) value. Equivalent to
``float('nan')``.
``float('nan')``. See also :data:`math.nan`.
.. versionadded:: 3.6

View file

@ -29,7 +29,7 @@ build applications which provide an interactive interpreter prompt.
module.
.. class:: InteractiveConsole(locals=None, filename="<console>", local_exit=False)
.. class:: InteractiveConsole(locals=None, filename="<console>", *, local_exit=False)
Closely emulate the behavior of the interactive Python interpreter. This class
builds on :class:`InteractiveInterpreter` and adds prompting using the familiar

View file

@ -78,7 +78,7 @@ The full details for each codec can also be looked up directly:
.. versionchanged:: 3.9
Any characters except ASCII letters and digits and a dot are converted to underscore.
.. versionchanged:: next
.. versionchanged:: 3.15
No characters are converted to underscore anymore.
Spaces are converted to hyphens.
@ -989,17 +989,22 @@ defined in Unicode. A simple and straightforward way that can store each Unicode
code point, is to store each code point as four consecutive bytes. There are two
possibilities: store the bytes in big endian or in little endian order. These
two encodings are called ``UTF-32-BE`` and ``UTF-32-LE`` respectively. Their
disadvantage is that if e.g. you use ``UTF-32-BE`` on a little endian machine you
will always have to swap bytes on encoding and decoding. ``UTF-32`` avoids this
problem: bytes will always be in natural endianness. When these bytes are read
by a CPU with a different endianness, then bytes have to be swapped though. To
be able to detect the endianness of a ``UTF-16`` or ``UTF-32`` byte sequence,
there's the so called BOM ("Byte Order Mark"). This is the Unicode character
``U+FEFF``. This character can be prepended to every ``UTF-16`` or ``UTF-32``
byte sequence. The byte swapped version of this character (``0xFFFE``) is an
illegal character that may not appear in a Unicode text. So when the
first character in a ``UTF-16`` or ``UTF-32`` byte sequence
appears to be a ``U+FFFE`` the bytes have to be swapped on decoding.
disadvantage is that if, for example, you use ``UTF-32-BE`` on a little endian
machine you will always have to swap bytes on encoding and decoding.
Python's ``UTF-16`` and ``UTF-32`` codecs avoid this problem by using the
platform's native byte order when no BOM is present.
Python follows prevailing platform
practice, so native-endian data round-trips without redundant byte swapping,
even though the Unicode Standard defaults to big-endian when the byte order is
unspecified. When these bytes are read by a CPU with a different endianness,
the bytes have to be swapped. To be able to detect the endianness of a
``UTF-16`` or ``UTF-32`` byte sequence, a BOM ("Byte Order Mark") is used.
This is the Unicode character ``U+FEFF``. This character can be prepended to every
``UTF-16`` or ``UTF-32`` byte sequence. The byte swapped version of this character
(``0xFFFE``) is an illegal character that may not appear in a Unicode text.
When the first character of a ``UTF-16`` or ``UTF-32`` byte sequence is
``U+FFFE``, the bytes have to be swapped on decoding.
Unfortunately the character ``U+FEFF`` had a second purpose as
a ``ZERO WIDTH NO-BREAK SPACE``: a character that has no width and doesn't allow
a word to be split. It can e.g. be used to give hints to a ligature algorithm.
@ -1083,7 +1088,7 @@ alias for the ``'utf_8'`` codec.
refer to the source :source:`aliases.py <Lib/encodings/aliases.py>` file.
On Windows, ``cpXXX`` codecs are available for all code pages.
But only codecs listed in the following table are guarantead to exist on
But only codecs listed in the following table are guaranteed to exist on
other platforms.
.. impl-detail::

View file

@ -336,7 +336,7 @@ Collections Abstract Base Classes -- Detailed Descriptions
.. note::
In CPython, generator-based coroutines (:term:`generators <generator>`
decorated with :func:`@types.coroutine <types.coroutine>`) are
decorated with :deco:`types.coroutine`) are
*awaitables*, even though they do not have an :meth:`~object.__await__` method.
Using ``isinstance(gencoro, Awaitable)`` for them will return ``False``.
Use :func:`inspect.isawaitable` to detect them.
@ -354,7 +354,7 @@ Collections Abstract Base Classes -- Detailed Descriptions
.. note::
In CPython, generator-based coroutines (:term:`generators <generator>`
decorated with :func:`@types.coroutine <types.coroutine>`) are
decorated with :deco:`types.coroutine`) are
*awaitables*, even though they do not have an :meth:`~object.__await__` method.
Using ``isinstance(gencoro, Coroutine)`` for them will return ``False``.
Use :func:`inspect.isawaitable` to detect them.

View file

@ -404,7 +404,7 @@ or subtracting from an empty counter.
.. versionadded:: 3.3
Added support for unary plus, unary minus, and in-place multiset operations.
.. versionadded:: next
.. versionadded:: 3.15
Added support for the symmetric difference multiset operation, ``c ^ d``.
.. note::

View file

@ -1,6 +1,8 @@
The :mod:`!compression` package
===============================
.. module:: compression
.. versionadded:: 3.14
The :mod:`!compression` package contains the canonical compression modules

View file

@ -239,6 +239,8 @@ ThreadPoolExecutor Example
InterpreterPoolExecutor
-----------------------
.. versionadded:: 3.14
The :class:`InterpreterPoolExecutor` class uses a pool of interpreters
to execute calls asynchronously. It is a :class:`ThreadPoolExecutor`
subclass, which means each worker is running in its own thread.

View file

@ -327,10 +327,10 @@ Functions and classes provided:
.. function:: redirect_stdout(new_target)
Context manager for temporarily redirecting :data:`sys.stdout` to
another file or file-like object.
another :term:`file object`.
This tool adds flexibility to existing functions or classes whose output
is hardwired to stdout.
is hardwired to :data:`sys.stdout`.
For example, the output of :func:`help` normally is sent to *sys.stdout*.
You can capture that output in a string by redirecting the output to an
@ -366,8 +366,8 @@ Functions and classes provided:
.. function:: redirect_stderr(new_target)
Similar to :func:`~contextlib.redirect_stdout` but redirecting
:data:`sys.stderr` to another file or file-like object.
Similar to :func:`~contextlib.redirect_stdout` but redirecting the global
:data:`sys.stderr` to another :term:`file object`.
This context manager is :ref:`reentrant <reentrant-cms>`.

View file

@ -13,7 +13,7 @@ being deprecated in Python 3.11. The removal was decided in :pep:`594`.
Applications can use the :mod:`hashlib` module from the standard library.
Other possible replacements are third-party libraries from PyPI:
:pypi:`legacycrypt`, :pypi:`bcrypt`, :pypi:`argon2-cffi`, or :pypi:`passlib`.
:pypi:`legacycrypt`, :pypi:`bcrypt`, or :pypi:`argon2-cffi`.
These are not supported or maintained by the Python core team.
The last version of Python that provided the :mod:`!crypt` module was

View file

@ -317,7 +317,7 @@ Module contents
:func:`!field`, then the class attribute for this field will be
replaced by the specified *default* value. If *default* is not
provided, then the class attribute will be deleted. The intent is
that after the :func:`@dataclass <dataclass>` decorator runs, the class
that after the :deco:`dataclass` decorator runs, the class
attributes will all contain the default values for the fields, just
as if the default value itself were specified. For example,
after::
@ -427,7 +427,7 @@ Module contents
:data:`typing.Any` is used for ``type``. The values of *init*,
*repr*, *eq*, *order*, *unsafe_hash*, *frozen*,
*match_args*, *kw_only*, *slots*, and *weakref_slot* have
the same meaning as they do in :func:`@dataclass <dataclass>`.
the same meaning as they do in :deco:`dataclass`.
If *module* is defined, the :attr:`!__module__` attribute
of the dataclass is set to that value.
@ -435,12 +435,12 @@ Module contents
The *decorator* parameter is a callable that will be used to create the dataclass.
It should take the class object as a first argument and the same keyword arguments
as :func:`@dataclass <dataclass>`. By default, the :func:`@dataclass <dataclass>`
as :deco:`dataclass`. By default, the :deco:`dataclass`
function is used.
This function is not strictly required, because any Python
mechanism for creating a new class with :attr:`~object.__annotations__` can
then apply the :func:`@dataclass <dataclass>` function to convert that class to
then apply the :deco:`dataclass` function to convert that class to
a dataclass. This function is provided as a convenience. For
example::
@ -569,7 +569,7 @@ Post-init processing
def __post_init__(self):
self.c = self.a + self.b
The :meth:`~object.__init__` method generated by :func:`@dataclass <dataclass>` does not call base
The :meth:`~object.__init__` method generated by :deco:`dataclass` does not call base
class :meth:`!__init__` methods. If the base class has an :meth:`!__init__` method
that has to be called, it is common to call this method in a
:meth:`__post_init__` method::
@ -599,7 +599,7 @@ parameters to :meth:`!__post_init__`. Also see the warning about how
Class variables
---------------
One of the few places where :func:`@dataclass <dataclass>` actually inspects the type
One of the few places where :deco:`dataclass` actually inspects the type
of a field is to determine if a field is a class variable as defined
in :pep:`526`. It does this by checking if the type of the field is
:data:`typing.ClassVar`. If a field is a ``ClassVar``, it is excluded
@ -612,7 +612,7 @@ module-level :func:`fields` function.
Init-only variables
-------------------
Another place where :func:`@dataclass <dataclass>` inspects a type annotation is to
Another place where :deco:`dataclass` inspects a type annotation is to
determine if a field is an init-only variable. It does this by seeing
if the type of a field is of type :class:`InitVar`. If a field
is an :class:`InitVar`, it is considered a pseudo-field called an init-only
@ -646,7 +646,7 @@ Frozen instances
----------------
It is not possible to create truly immutable Python objects. However,
by passing ``frozen=True`` to the :func:`@dataclass <dataclass>` decorator you can
by passing ``frozen=True`` to the :deco:`dataclass` decorator you can
emulate immutability. In that case, dataclasses will add
:meth:`~object.__setattr__` and :meth:`~object.__delattr__` methods to the class. These
methods will raise a :exc:`FrozenInstanceError` when invoked.
@ -662,7 +662,7 @@ must use :meth:`!object.__setattr__`.
Inheritance
-----------
When the dataclass is being created by the :func:`@dataclass <dataclass>` decorator,
When the dataclass is being created by the :deco:`dataclass` decorator,
it looks through all of the class's base classes in reverse MRO (that
is, starting at :class:`object`) and, for each dataclass that it finds,
adds the fields from that base class to an ordered mapping of fields.
@ -786,7 +786,7 @@ for :attr:`!x` when creating a class instance will share the same copy
of :attr:`!x`. Because dataclasses just use normal Python class
creation they also share this behavior. There is no general way
for Data Classes to detect this condition. Instead, the
:func:`@dataclass <dataclass>` decorator will raise a :exc:`ValueError` if it
:deco:`dataclass` decorator will raise a :exc:`ValueError` if it
detects an unhashable default parameter. The assumption is that if
a value is unhashable, it is mutable. This is a partial solution,
but it does protect against many common errors.
@ -820,7 +820,7 @@ default value have the following special behaviors:
:meth:`~object.__get__` or :meth:`!__set__` method is called rather than returning or
overwriting the descriptor object.
* To determine whether a field contains a default value, :func:`@dataclass <dataclass>`
* To determine whether a field contains a default value, :deco:`dataclass`
will call the descriptor's :meth:`!__get__` method using its class access
form: ``descriptor.__get__(obj=None, type=cls)``. If the
descriptor returns a value in this case, it will be used as the

View file

@ -535,7 +535,7 @@ Other constructors, all class methods:
:c:func:`localtime` function. Raise :exc:`OSError` instead of
:exc:`ValueError` on :c:func:`localtime` failure.
.. versionchanged:: next
.. versionchanged:: 3.15
Accepts any real number as *timestamp*, not only integer or float.
@ -1023,7 +1023,7 @@ Other constructors, all class methods:
.. versionchanged:: 3.6
:meth:`fromtimestamp` may return instances with :attr:`.fold` set to 1.
.. versionchanged:: next
.. versionchanged:: 3.15
Accepts any real number as *timestamp*, not only integer or float.
@ -1067,7 +1067,7 @@ Other constructors, all class methods:
Use :meth:`datetime.fromtimestamp` with :const:`UTC` instead.
.. versionchanged:: next
.. versionchanged:: 3.15
Accepts any real number as *timestamp*, not only integer or float.
@ -2641,7 +2641,7 @@ differences between platforms in handling of unsupported format specifiers.
.. versionadded:: 3.12
``%:z`` was added for :meth:`~.datetime.strftime`
.. versionadded:: next
.. versionadded:: 3.15
``%:z`` was added for :meth:`~.datetime.strptime`
Technical Detail

View file

@ -217,7 +217,7 @@ or any other SQLite browser, including the SQLite CLI.
While reorganizing, as much as two times the size of the original database is required
in free disk space. However, be aware that this factor changes for each :mod:`dbm` submodule.
.. versionadded:: next
.. versionadded:: 3.15
:mod:`dbm.gnu` --- GNU database manager
@ -519,7 +519,7 @@ The :mod:`!dbm.dumb` module defines the following:
While reorganizing, no additional free disk space is required. However, be aware
that this factor changes for each :mod:`dbm` submodule.
.. versionadded:: next
.. versionadded:: 3.15
.. method:: dumbdbm.sync()

View file

@ -1569,7 +1569,16 @@ In addition to the three supplied contexts, new contexts can be created with the
Constants
---------
The constants in this section are only relevant for the C module. They
.. data:: SPEC_VERSION
The highest version of the General Decimal Arithmetic
Specification that this implementation complies with.
See https://speleotrove.com/decimal/decarith.html for the specification.
.. versionadded:: next
The following constants are only relevant for the C module. They
are also included in the pure Python version for compatibility.
+---------------------------------+---------------------+-------------------------------+

View file

@ -231,7 +231,7 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
*linejunk*: A function that accepts a single string argument, and returns
true if the string is junk, or false if not. The default is ``None``. There
is also a module-level function :func:`IS_LINE_JUNK`, which filters out lines
without visible characters, except for at most one pound character (``'#'``)
without visible characters, except for at most one hash character (``'#'``)
-- however the underlying :class:`SequenceMatcher` class does a dynamic
analysis of which lines are so frequent as to constitute noise, and this
usually works better than using this function.
@ -323,7 +323,7 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
See :ref:`difflib-interface` for a more detailed example.
.. versionchanged:: next
.. versionchanged:: 3.15
Added the *color* parameter.

View file

@ -1123,7 +1123,7 @@ from text files and modules with doctests:
The global ``__file__`` is added to the globals provided to doctests loaded
from a text file using :func:`DocFileSuite`.
.. versionchanged:: next
.. versionchanged:: 3.15
Run each example as a :ref:`subtest <subtests>`.
@ -1164,7 +1164,7 @@ from text files and modules with doctests:
:func:`DocTestSuite` returns an empty :class:`unittest.TestSuite` if *module*
contains no docstrings instead of raising :exc:`ValueError`.
.. versionchanged:: next
.. versionchanged:: 3.15
Run each example as a :ref:`subtest <subtests>`.
Under the covers, :func:`DocTestSuite` creates a :class:`unittest.TestSuite` out
@ -1564,7 +1564,7 @@ DocTestRunner objects
containing *example*. *out* is the output function that was passed to
:meth:`DocTestRunner.run`.
.. versionadded:: next
.. versionadded:: 3.15
.. method:: report_start(out, test, example)

View file

@ -450,7 +450,7 @@ The following exceptions are the exceptions that are usually raised.
:meth:`threading.Thread.join` can now raise this exception.
.. versionchanged:: next
.. versionchanged:: 3.15
This exception may be raised when acquiring :meth:`threading.Lock`
or :meth:`threading.RLock`.

View file

@ -125,7 +125,7 @@ The module defines the following functions:
Add support of arbitrary :term:`bytes-like objects <bytes-like object>`,
not only :class:`bytes`.
.. versionchanged:: next
.. versionchanged:: 3.15
The size of bytes-like objects is no longer limited to 1024 bytes.
@ -187,7 +187,7 @@ The module defines the following functions:
The GIL is always released during a system call.
System calls failing with EINTR are automatically retried.
.. versionchanged:: next
.. versionchanged:: 3.15
The size of not mutated bytes-like objects is no longer
limited to 1024 bytes.

View file

@ -190,7 +190,7 @@ The :mod:`functools` module defines the following functions:
Note, type specificity applies only to the function's immediate arguments
rather than their contents. The scalar arguments, ``Decimal(42)`` and
``Fraction(42)`` are be treated as distinct calls with distinct results.
``Fraction(42)`` are treated as distinct calls with distinct results.
In contrast, the tuple arguments ``('answer', Decimal(42))`` and
``('answer', Fraction(42))`` are treated as equivalent.
@ -690,7 +690,7 @@ The :mod:`functools` module defines the following functions:
return not arg
``@singledispatchmethod`` supports nesting with other decorators such as
:func:`@classmethod<classmethod>`. Note that to allow for
:deco:`classmethod`. Note that to allow for
``dispatcher.register``, ``singledispatchmethod`` must be the *outer most*
decorator. Here is the ``Negator`` class with the ``neg`` methods bound to
the class, rather than an instance of the class::
@ -712,8 +712,7 @@ The :mod:`functools` module defines the following functions:
return not arg
The same pattern can be used for other similar decorators:
:func:`@staticmethod<staticmethod>`,
:func:`@abstractmethod<abc.abstractmethod>`, and others.
:deco:`staticmethod`, :deco:`~abc.abstractmethod`, and others.
.. versionadded:: 3.8

View file

@ -18,23 +18,27 @@
single: - (minus); in glob-style wildcards
single: . (dot); in glob-style wildcards
The :mod:`glob` module finds all the pathnames matching a specified pattern
according to the rules used by the Unix shell, although results are returned in
arbitrary order. No tilde expansion is done, but ``*``, ``?``, and character
The :mod:`!glob` module finds pathnames
using pattern matching rules similar to the Unix shell.
No tilde expansion is done, but ``*``, ``?``, and character
ranges expressed with ``[]`` will be correctly matched. This is done by using
the :func:`os.scandir` and :func:`fnmatch.fnmatch` functions in concert, and
not by actually invoking a subshell.
Note that files beginning with a dot (``.``) can only be matched by
.. note::
The pathnames are returned in no particular order. If you need a specific
order, sort the results.
Files beginning with a dot (``.``) can only be matched by
patterns that also start with a dot,
unlike :func:`fnmatch.fnmatch` or :func:`pathlib.Path.glob`.
(For tilde and shell variable expansion, use :func:`os.path.expanduser` and
:func:`os.path.expandvars`.)
For tilde and shell variable expansion, use :func:`os.path.expanduser` and
:func:`os.path.expandvars`.
For a literal match, wrap the meta-characters in brackets.
For example, ``'[?]'`` matches the character ``'?'``.
The :mod:`glob` module defines the following functions:
The :mod:`!glob` module defines the following functions:
.. function:: glob(pathname, *, root_dir=None, dir_fd=None, recursive=False, \
@ -51,7 +55,7 @@ The :mod:`glob` module defines the following functions:
If *root_dir* is not ``None``, it should be a :term:`path-like object`
specifying the root directory for searching. It has the same effect on
:func:`glob` as changing the current directory before calling it. If
:func:`!glob` as changing the current directory before calling it. If
*pathname* is relative, the result will contain paths relative to
*root_dir*.

View file

@ -59,7 +59,7 @@ The module defines the following items:
.. versionchanged:: 3.6
Accepts a :term:`path-like object`.
.. versionchanged:: next
.. versionchanged:: 3.15
The default compression level was reduced to 6 (down from 9).
It is the default level used by most compression tools and a better
tradeoff between speed and performance.
@ -186,7 +186,7 @@ The module defines the following items:
Remove the ``filename`` attribute, use the :attr:`~GzipFile.name`
attribute instead.
.. versionchanged:: next
.. versionchanged:: 3.15
The default compression level was reduced to 6 (down from 9).
It is the default level used by most compression tools and a better
tradeoff between speed and performance.
@ -216,7 +216,7 @@ The module defines the following items:
The *mtime* parameter now defaults to 0 for reproducible output.
For the previous behaviour of using the current time,
pass ``None`` to *mtime*.
.. versionchanged:: next
.. versionchanged:: 3.15
The default compression level was reduced to 6 (down from 9).
It is the default level used by most compression tools and a better
tradeoff between speed and performance.

View file

@ -15,14 +15,18 @@
This module defines a class :class:`HTMLParser` which serves as the basis for
parsing text files formatted in HTML (HyperText Mark-up Language) and XHTML.
.. class:: HTMLParser(*, convert_charrefs=True)
.. class:: HTMLParser(*, convert_charrefs=True, scripting=False)
Create a parser instance able to parse invalid markup.
If *convert_charrefs* is ``True`` (the default), all character
references (except the ones in ``script``/``style`` elements) are
If *convert_charrefs* is true (the default), all character
references (except the ones in elements like ``script`` and ``style``) are
automatically converted to the corresponding Unicode characters.
If *scripting* is false (the default), the content of the ``noscript``
element is parsed normally; if it's true, it's returned as is without
being parsed.
An :class:`.HTMLParser` instance is fed HTML data and calls handler methods
when start tags, end tags, text, comments, and other markup elements are
encountered. The user should subclass :class:`.HTMLParser` and override its
@ -37,6 +41,9 @@ parsing text files formatted in HTML (HyperText Mark-up Language) and XHTML.
.. versionchanged:: 3.5
The default value for argument *convert_charrefs* is now ``True``.
.. versionchanged:: 3.14.1
Added the *scripting* parameter.
Example HTML Parser Application
-------------------------------
@ -161,15 +168,15 @@ implementations do nothing (except for :meth:`~HTMLParser.handle_startendtag`):
.. method:: HTMLParser.handle_data(data)
This method is called to process arbitrary data (e.g. text nodes and the
content of ``<script>...</script>`` and ``<style>...</style>``).
content of elements like ``script`` and ``style``).
.. method:: HTMLParser.handle_entityref(name)
This method is called to process a named character reference of the form
``&name;`` (e.g. ``&gt;``), where *name* is a general entity reference
(e.g. ``'gt'``). This method is never called if *convert_charrefs* is
``True``.
(e.g. ``'gt'``).
This method is only called if *convert_charrefs* is false.
.. method:: HTMLParser.handle_charref(name)
@ -177,8 +184,8 @@ implementations do nothing (except for :meth:`~HTMLParser.handle_startendtag`):
This method is called to process decimal and hexadecimal numeric character
references of the form :samp:`&#{NNN};` and :samp:`&#x{NNN};`. For example, the decimal
equivalent for ``&gt;`` is ``&#62;``, whereas the hexadecimal is ``&#x3E;``;
in this case the method will receive ``'62'`` or ``'x3E'``. This method
is never called if *convert_charrefs* is ``True``.
in this case the method will receive ``'62'`` or ``'x3E'``.
This method is only called if *convert_charrefs* is false.
.. method:: HTMLParser.handle_comment(data)
@ -292,8 +299,8 @@ Parsing an element with a few attributes and a title:
Data : Python
End tag : h1
The content of ``script`` and ``style`` elements is returned as is, without
further parsing:
The content of elements like ``script`` and ``style`` is returned as is,
without further parsing:
.. doctest::
@ -304,10 +311,10 @@ further parsing:
End tag : style
>>> parser.feed('<script type="text/javascript">'
... 'alert("<strong>hello!</strong>");</script>')
... 'alert("<strong>hello! &#9786;</strong>");</script>')
Start tag: script
attr: ('type', 'text/javascript')
Data : alert("<strong>hello!</strong>");
Data : alert("<strong>hello! &#9786;</strong>");
End tag : script
Parsing comments:
@ -336,7 +343,7 @@ correct char (note: these 3 references are all equivalent to ``'>'``):
Feeding incomplete chunks to :meth:`~HTMLParser.feed` works, but
:meth:`~HTMLParser.handle_data` might be called more than once
(unless *convert_charrefs* is set to ``True``):
if *convert_charrefs* is false:
.. doctest::

View file

@ -68,7 +68,7 @@ The module provides the following classes:
.. versionchanged:: 3.7
*blocksize* parameter was added.
.. versionchanged:: next
.. versionchanged:: 3.15
*max_response_headers* parameter was added.
@ -114,7 +114,7 @@ The module provides the following classes:
The deprecated *key_file*, *cert_file* and *check_hostname* parameters
have been removed.
.. versionchanged:: next
.. versionchanged:: 3.15
*max_response_headers* parameter was added.
@ -429,7 +429,7 @@ HTTPConnection Objects
The maximum number of allowed response headers to help prevent denial-of-service
attacks. By default, the maximum number of allowed headers is set to 100.
.. versionadded:: next
.. versionadded:: 3.15
As an alternative to using the :meth:`~HTTPConnection.request` method described above, you can

View file

@ -30,7 +30,7 @@ in a cookie name (as :attr:`~Morsel.key`).
.. versionchanged:: 3.3
Allowed '``:``' as a valid cookie name character.
.. versionchanged:: next
.. versionchanged:: 3.15
Allowed '``"``' as a valid cookie value character.
.. note::

View file

@ -139,7 +139,8 @@ equal to the constant name (i.e. ``http.HTTPStatus.OK`` is also available as
.. versionchanged:: 3.13
Implemented RFC9110 naming for status constants. Old constant names are preserved for
backwards compatibility.
backwards compatibility: ``413 REQUEST_ENTITY_TOO_LARGE``, ``414 REQUEST_URI_TOO_LONG``,
``416 REQUESTED_RANGE_NOT_SATISFIABLE`` and ``422 UNPROCESSABLE_ENTITY``.
HTTP status category
--------------------

View file

@ -204,7 +204,7 @@ New Indent Width
Open a dialog to change indent width. The accepted default by the Python
community is 4 spaces.
Strip Trailing Chitespace
Strip Trailing Whitespace
Remove trailing space and other whitespace characters after the last
non-whitespace character of a line by applying str.rstrip to each line,
including lines within multiline strings. Except for Shell windows,

View file

@ -413,7 +413,7 @@ An :class:`IMAP4` instance has the following methods:
the password. Will only work if the server ``CAPABILITY`` response includes the
phrase ``AUTH=CRAM-MD5``.
.. versionchanged:: next
.. versionchanged:: 3.15
An :exc:`IMAP4.error` is raised if MD5 support is not available.

View file

@ -73,12 +73,15 @@ for example, a package and its resources can be imported from a zip file using
.. versionadded:: 3.9
.. versionchanged:: 3.12
*package* parameter was renamed to *anchor*. *anchor* can now
be a non-package module and if omitted will default to the caller's
module. *package* is still accepted for compatibility but will raise
a :exc:`DeprecationWarning`. Consider passing the anchor positionally or
using ``importlib_resources >= 5.10`` for a compatible interface
on older Pythons.
*package* parameter was renamed to *anchor*.
*package* was still accepted, but deprecated.
.. versionchanged:: 3.15
*package* parameter was fully removed. *anchor* can now be a
non-package module and if omitted will default to the caller's module.
*package* is no longer accepted since Python 3.15. Consider passing the
anchor positionally or using ``importlib_resources >= 5.10`` for a
compatible interface on older Pythons.
.. function:: as_file(traversable)

View file

@ -1013,6 +1013,36 @@ find and load modules.
:exc:`ImportError` is raised.
.. class:: NamespacePath(name, path, path_finder)
Represents a :term:`namespace package`'s path (:attr:`module.__path__`).
When its ``__path__`` value is accessed it will be recomputed if necessary.
This keeps it in-sync with the global state (:attr:`sys.modules`).
The *name* argument is the name of the namespace module.
The *path* argument is the initial path value.
The *path_finder* argument is the callable used to recompute the path value.
The callable has the same signature as :meth:`importlib.abc.MetaPathFinder.find_spec`.
When the parent's :attr:`module.__path__` attribute is updated, the path
value is recomputed.
If the parent module is missing from :data:`sys.modules`, then
:exc:`ModuleNotFoundError` will be raised.
For top-level modules, the parent module's path is :data:`sys.path`.
.. note::
:meth:`PathFinder.invalidate_caches` invalidates :class:`NamespacePath`,
forcing the path value to be recomputed next time it is accessed.
.. versionadded:: next
.. class:: SourceFileLoader(fullname, path)
A concrete implementation of :class:`importlib.abc.SourceLoader` by
@ -1257,7 +1287,7 @@ find and load modules.
To accommodate this requirement, when running on iOS, extension module
binaries are *not* packaged as ``.so`` files on ``sys.path``, but as
individual standalone frameworks. To discover those frameworks, this loader
is be registered against the ``.fwork`` file extension, with a ``.fwork``
is registered against the ``.fwork`` file extension, with a ``.fwork``
file acting as a placeholder in the original location of the binary on
``sys.path``. The ``.fwork`` file contains the path of the actual binary in
the ``Frameworks`` folder, relative to the app bundle. To allow for

View file

@ -58,7 +58,7 @@ The :mod:`locale` module defines the following exception and functions:
specified in the :envvar:`LANG` environment variable). If the locale is not
changed thereafter, using multithreading should not cause problems.
.. versionchanged:: next
.. versionchanged:: 3.15
Support language codes with ``@``-modifiers.
@ -374,7 +374,7 @@ The :mod:`locale` module defines the following exception and functions:
determined.
The "C" locale is represented as ``(None, None)``.
.. versionchanged:: next
.. versionchanged:: 3.15
``@``-modifier are no longer silently removed, but included in
the language code.

View file

@ -1082,12 +1082,13 @@ LoggerAdapter Objects
information into logging calls. For a usage example, see the section on
:ref:`adding contextual information to your logging output <context-info>`.
.. class:: LoggerAdapter(logger, extra, merge_extra=False)
.. class:: LoggerAdapter(logger, extra=None, merge_extra=False)
Returns an instance of :class:`LoggerAdapter` initialized with an
underlying :class:`Logger` instance, a dict-like object (*extra*), and a
boolean (*merge_extra*) indicating whether or not the *extra* argument of
individual log calls should be merged with the :class:`LoggerAdapter` extra.
underlying :class:`Logger` instance, an optional dict-like object (*extra*),
and an optional boolean (*merge_extra*) indicating whether or not
the *extra* argument of individual log calls should be merged with
the :class:`LoggerAdapter` extra.
The default behavior is to ignore the *extra* argument of individual log
calls and only use the one of the :class:`LoggerAdapter` instance
@ -1127,9 +1128,13 @@ information into logging calls. For a usage example, see the section on
Attribute :attr:`!manager` and method :meth:`!_log` were added, which
delegate to the underlying logger and allow adapters to be nested.
.. versionchanged:: 3.10
The *extra* argument is now optional.
.. versionchanged:: 3.13
The *merge_extra* argument was added.
The *merge_extra* parameter was added.
Thread Safety

View file

@ -0,0 +1,85 @@
:mod:`math.integer` --- integer-specific mathematics functions
==============================================================
.. module:: math.integer
:synopsis: Integer-specific mathematics functions.
.. versionadded:: next
--------------
This module provides access to the mathematical functions defined for integer arguments.
These functions accept integers and objects that implement the
:meth:`~object.__index__` method which is used to convert the object to an integer
number.
The following functions are provided by this module. All return values are
computed exactly and are integers.
.. function:: comb(n, k, /)
Return the number of ways to choose *k* items from *n* items without repetition
and without order.
Evaluates to ``n! / (k! * (n - k)!)`` when ``k <= n`` and evaluates
to zero when ``k > n``.
Also called the binomial coefficient because it is equivalent
to the coefficient of k-th term in polynomial expansion of
``(1 + x)ⁿ``.
Raises :exc:`ValueError` if either of the arguments are negative.
.. function:: factorial(n, /)
Return factorial of the nonnegative integer *n*.
.. function:: gcd(*integers)
Return the greatest common divisor of the specified integer arguments.
If any of the arguments is nonzero, then the returned value is the largest
positive integer that is a divisor of all arguments. If all arguments
are zero, then the returned value is ``0``. ``gcd()`` without arguments
returns ``0``.
.. function:: isqrt(n, /)
Return the integer square root of the nonnegative integer *n*. This is the
floor of the exact square root of *n*, or equivalently the greatest integer
*a* such that *a*\ ² |nbsp| ≤ |nbsp| *n*.
For some applications, it may be more convenient to have the least integer
*a* such that *n* |nbsp| ≤ |nbsp| *a*\ ², or in other words the ceiling of
the exact square root of *n*. For positive *n*, this can be computed using
``a = 1 + isqrt(n - 1)``.
.. |nbsp| unicode:: 0xA0
:trim:
.. function:: lcm(*integers)
Return the least common multiple of the specified integer arguments.
If all arguments are nonzero, then the returned value is the smallest
positive integer that is a multiple of all arguments. If any of the arguments
is zero, then the returned value is ``0``. ``lcm()`` without arguments
returns ``1``.
.. function:: perm(n, k=None, /)
Return the number of ways to choose *k* items from *n* items
without repetition and with order.
Evaluates to ``n! / (n - k)!`` when ``k <= n`` and evaluates
to zero when ``k > n``.
If *k* is not specified or is ``None``, then *k* defaults to *n*
and the function returns ``n!``.
Raises :exc:`ValueError` if either of the arguments are negative.

View file

@ -27,15 +27,6 @@ noted otherwise, all return values are floats.
==================================================== ============================================
**Number-theoretic functions**
--------------------------------------------------------------------------------------------------
:func:`comb(n, k) <comb>` Number of ways to choose *k* items from *n* items without repetition and without order
:func:`factorial(n) <factorial>` *n* factorial
:func:`gcd(*integers) <gcd>` Greatest common divisor of the integer arguments
:func:`isqrt(n) <isqrt>` Integer square root of a nonnegative integer *n*
:func:`lcm(*integers) <lcm>` Least common multiple of the integer arguments
:func:`perm(n, k) <perm>` Number of ways to choose *k* items from *n* items without repetition and with order
**Floating point arithmetic**
--------------------------------------------------------------------------------------------------
:func:`ceil(x) <ceil>` Ceiling of *x*, the smallest integer greater than or equal to *x*
@ -126,92 +117,6 @@ noted otherwise, all return values are floats.
==================================================== ============================================
Number-theoretic functions
--------------------------
.. function:: comb(n, k)
Return the number of ways to choose *k* items from *n* items without repetition
and without order.
Evaluates to ``n! / (k! * (n - k)!)`` when ``k <= n`` and evaluates
to zero when ``k > n``.
Also called the binomial coefficient because it is equivalent
to the coefficient of k-th term in polynomial expansion of
``(1 + x)ⁿ``.
Raises :exc:`TypeError` if either of the arguments are not integers.
Raises :exc:`ValueError` if either of the arguments are negative.
.. versionadded:: 3.8
.. function:: factorial(n)
Return factorial of the nonnegative integer *n*.
.. versionchanged:: 3.10
Floats with integral values (like ``5.0``) are no longer accepted.
.. function:: gcd(*integers)
Return the greatest common divisor of the specified integer arguments.
If any of the arguments is nonzero, then the returned value is the largest
positive integer that is a divisor of all arguments. If all arguments
are zero, then the returned value is ``0``. ``gcd()`` without arguments
returns ``0``.
.. versionadded:: 3.5
.. versionchanged:: 3.9
Added support for an arbitrary number of arguments. Formerly, only two
arguments were supported.
.. function:: isqrt(n)
Return the integer square root of the nonnegative integer *n*. This is the
floor of the exact square root of *n*, or equivalently the greatest integer
*a* such that *a*\ ² |nbsp| ≤ |nbsp| *n*.
For some applications, it may be more convenient to have the least integer
*a* such that *n* |nbsp| ≤ |nbsp| *a*\ ², or in other words the ceiling of
the exact square root of *n*. For positive *n*, this can be computed using
``a = 1 + isqrt(n - 1)``.
.. versionadded:: 3.8
.. function:: lcm(*integers)
Return the least common multiple of the specified integer arguments.
If all arguments are nonzero, then the returned value is the smallest
positive integer that is a multiple of all arguments. If any of the arguments
is zero, then the returned value is ``0``. ``lcm()`` without arguments
returns ``1``.
.. versionadded:: 3.9
.. function:: perm(n, k=None)
Return the number of ways to choose *k* items from *n* items
without repetition and with order.
Evaluates to ``n! / (n - k)!`` when ``k <= n`` and evaluates
to zero when ``k > n``.
If *k* is not specified or is ``None``, then *k* defaults to *n*
and the function returns ``n!``.
Raises :exc:`TypeError` if either of the arguments are not integers.
Raises :exc:`ValueError` if either of the arguments are negative.
.. versionadded:: 3.8
Floating point arithmetic
-------------------------
@ -259,7 +164,7 @@ Floating point arithmetic
is, :func:`!fmax` is not required to be sensitive to the sign of such
operands (see Annex F of the C11 standard, §F.10.0.3 and §F.10.9.2).
.. versionadded:: next
.. versionadded:: 3.15
.. function:: fmin(x, y)
@ -271,7 +176,7 @@ Floating point arithmetic
is, :func:`!fmin` is not required to be sensitive to the sign of such
operands (see Annex F of the C11 standard, §F.10.0.3 and §F.10.9.3).
.. versionadded:: next
.. versionadded:: 3.15
.. function:: fmod(x, y)
@ -408,7 +313,7 @@ Floating point manipulation functions
nonzero number that is not a subnormal (see :func:`issubnormal`).
Return ``False`` otherwise.
.. versionadded:: next
.. versionadded:: 3.15
.. function:: issubnormal(x)
@ -417,7 +322,7 @@ Floating point manipulation functions
nonzero number with a magnitude smaller than :data:`sys.float_info.min`.
Return ``False`` otherwise.
.. versionadded:: next
.. versionadded:: 3.15
.. function:: isinf(x)
@ -464,7 +369,7 @@ Floating point manipulation functions
This is useful to detect the sign bit of zeroes, infinities and NaNs.
.. versionadded:: next
.. versionadded:: 3.15
.. function:: ulp(x)
@ -812,6 +717,75 @@ Special functions
.. versionadded:: 3.2
Number-theoretic functions
--------------------------
For backward compatibility, the :mod:`math` module provides also aliases of
the following functions from the :mod:`math.integer` module:
.. list-table::
* - .. function:: comb(n, k)
:no-typesetting:
:func:`comb(n, k) <math.integer.comb>`
- Number of ways to choose *k* items from *n* items without repetition
and without order
* - .. function:: factorial(n)
:no-typesetting:
:func:`factorial(n) <math.integer.factorial>`
- *n* factorial
* - .. function:: gcd(*integers)
:no-typesetting:
:func:`gcd(*integers) <math.integer.gcd>`
- Greatest common divisor of the integer arguments
* - .. function:: isqrt(n)
:no-typesetting:
:func:`isqrt(n) <math.integer.isqrt>`
- Integer square root of a nonnegative integer *n*
* - .. function:: lcm(*integers)
:no-typesetting:
:func:`lcm(*integers) <math.integer.lcm>`
- Least common multiple of the integer arguments
* - .. function:: perm(n, k)
:no-typesetting:
:func:`perm(n, k) <math.integer.perm>`
- Number of ways to choose *k* items from *n* items without repetition
and with order
.. versionadded:: 3.5
The :func:`gcd` function.
.. versionadded:: 3.8
The :func:`comb`, :func:`perm` and :func:`isqrt` functions.
.. versionadded:: 3.9
The :func:`lcm` function.
.. versionchanged:: 3.9
Added support for an arbitrary number of arguments in the :func:`gcd`
function.
Formerly, only two arguments were supported.
.. versionchanged:: 3.10
Floats with integral values (like ``5.0``) are no longer accepted in the
:func:`factorial` function.
.. deprecated:: next
These aliases are :term:`soft deprecated` in favor of the
:mod:`math.integer` functions.
Constants
---------
@ -894,5 +868,5 @@ Constants
Module :mod:`cmath`
Complex number versions of many of these functions.
.. |nbsp| unicode:: 0xA0
:trim:
Module :mod:`math.integer`
Integer-specific mathematics functions.

View file

@ -78,7 +78,7 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
This mode is useful to limit the number of open file handles.
The original file can be renamed (but not deleted) after closing *fileno*.
.. versionchanged:: next
.. versionchanged:: 3.15
The *trackfd* parameter was added.
.. audit-event:: mmap.__new__ fileno,length,access,offset mmap.mmap
@ -229,7 +229,7 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
on error under Windows. A zero value was returned on success; an
exception was raised on error under Unix.
.. versionchanged:: next
.. versionchanged:: 3.15
Allow specifying *offset* without *size*. Previously, both *offset*
and *size* parameters were required together. Now *offset* can be
specified alone, and the flush operation will extend from *offset*
@ -334,7 +334,7 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
memory-mapped area.
For an anonymous mapping, return its size.
.. versionchanged:: next
.. versionchanged:: 3.15
Anonymous mappings are now supported on Unix.

View file

@ -19,6 +19,7 @@ The following modules are documented in this chapter:
numbers.rst
math.rst
math.integer.rst
cmath.rst
decimal.rst
fractions.rst

View file

@ -449,7 +449,7 @@ the :mod:`glob` module.)
.. versionchanged:: 3.10
The *strict* parameter was added.
.. versionchanged:: next
.. versionchanged:: 3.15
The :data:`ALL_BUT_LAST` and :data:`ALLOW_MISSING` values for
the *strict* parameter was added.
@ -457,13 +457,13 @@ the :mod:`glob` module.)
Special value used for the *strict* argument in :func:`realpath`.
.. versionadded:: next
.. versionadded:: 3.15
.. data:: ALLOW_MISSING
Special value used for the *strict* argument in :func:`realpath`.
.. versionadded:: next
.. versionadded:: 3.15
.. function:: relpath(path, start=os.curdir)

View file

@ -108,7 +108,7 @@ Python UTF-8 Mode
.. versionadded:: 3.7
See :pep:`540` for more details.
.. versionchanged:: next
.. versionchanged:: 3.15
Python UTF-8 mode is now enabled by default (:pep:`686`).
It may be disabled with by setting :envvar:`PYTHONUTF8=0 <PYTHONUTF8>` as
@ -216,8 +216,8 @@ process and user.
You can delete items in this mapping to unset environment variables.
:func:`unsetenv` will be called automatically when an item is deleted from
:data:`os.environ`, and when one of the :meth:`pop` or :meth:`clear` methods is
called.
:data:`os.environ`, and when one of the :meth:`~dict.pop` or
:meth:`~dict.clear` methods is called.
.. seealso::
@ -430,8 +430,8 @@ process and user.
associated with the effective user id of the process; the group access
list may change over the lifetime of the process, it is not affected by
calls to :func:`setgroups`, and its length is not limited to 16. The
deployment target value, :const:`MACOSX_DEPLOYMENT_TARGET`, can be
obtained with :func:`sysconfig.get_config_var`.
deployment target value can be obtained with
:func:`sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') <sysconfig.get_config_var>`.
.. function:: getlogin()
@ -1553,7 +1553,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo
.. availability:: Linux >= 6.14
.. versionadded:: next
.. versionadded:: 3.15
.. function:: ptsname(fd, /)
@ -2606,10 +2606,10 @@ features:
Create a filesystem node (file, device special file or named pipe) named
*path*. *mode* specifies both the permissions to use and the type of node
to be created, being combined (bitwise OR) with one of ``stat.S_IFREG``,
``stat.S_IFCHR``, ``stat.S_IFBLK``, and ``stat.S_IFIFO`` (those constants are
available in :mod:`stat`). For ``stat.S_IFCHR`` and ``stat.S_IFBLK``,
*device* defines the newly created device special file (probably using
to be created, being combined (bitwise OR) with one of :const:`stat.S_IFREG`,
:const:`stat.S_IFCHR`, :const:`stat.S_IFBLK`, and :const:`stat.S_IFIFO`.
For :const:`stat.S_IFCHR` and :const:`stat.S_IFBLK`, *device* defines the
newly created device special file (probably using
:func:`os.makedev`), otherwise it is ignored.
This function can also support :ref:`paths relative to directory descriptors
@ -2627,13 +2627,13 @@ features:
.. function:: major(device, /)
Extract the device major number from a raw device number (usually the
:attr:`st_dev` or :attr:`st_rdev` field from :c:struct:`stat`).
:attr:`~stat_result.st_dev` or :attr:`~stat_result.st_rdev` field from :c:struct:`stat`).
.. function:: minor(device, /)
Extract the device minor number from a raw device number (usually the
:attr:`st_dev` or :attr:`st_rdev` field from :c:struct:`stat`).
:attr:`~stat_result.st_dev` or :attr:`~stat_result.st_rdev` field from :c:struct:`stat`).
.. function:: makedev(major, minor, /)
@ -2645,7 +2645,7 @@ features:
Non-existent device.
.. versionadded:: next
.. versionadded:: 3.15
.. function:: pathconf(path, name)
@ -3364,8 +3364,8 @@ features:
.. versionchanged:: 3.8
On Windows, the :attr:`st_mode` member now identifies special
files as :const:`S_IFCHR`, :const:`S_IFIFO` or :const:`S_IFBLK`
as appropriate.
files as :const:`~stat.S_IFCHR`, :const:`~stat.S_IFIFO` or
:const:`~stat.S_IFBLK` as appropriate.
.. versionchanged:: 3.12
On Windows, :attr:`st_ctime` is deprecated. Eventually, it will
@ -3383,6 +3383,359 @@ features:
Added the :attr:`st_birthtime` member on Windows.
.. function:: statx(path, mask, *, flags=0, dir_fd=None, follow_symlinks=True)
Get the status of a file or file descriptor by performing a :c:func:`!statx`
system call on the given path.
*path* is a :term:`path-like object` or an open file descriptor. *mask* is a
combination of the module-level :const:`STATX_* <STATX_TYPE>` constants
specifying the information to retrieve. *flags* is a combination of the
module-level :const:`AT_STATX_* <AT_STATX_FORCE_SYNC>` constants and/or
:const:`AT_NO_AUTOMOUNT`. Returns a :class:`statx_result` object whose
:attr:`~os.statx_result.stx_mask` attribute specifies the information
actually retrieved (which may differ from *mask*).
This function supports :ref:`specifying a file descriptor <path_fd>`,
:ref:`paths relative to directory descriptors <dir_fd>`, and
:ref:`not following symlinks <follow_symlinks>`.
.. seealso:: The :manpage:`statx(2)` man page.
.. availability:: Linux >= 4.11 with glibc >= 2.28.
.. versionadded:: next
.. class:: statx_result
Information about a file returned by :func:`os.statx`.
:class:`!statx_result` has the following attributes:
.. attribute:: stx_atime
Time of most recent access expressed in seconds.
Equal to ``None`` if :data:`STATX_ATIME` is missing from
:attr:`~statx_result.stx_mask`.
.. attribute:: stx_atime_ns
Time of most recent access expressed in nanoseconds as an integer.
Equal to ``None`` if :data:`STATX_ATIME` is missing from
:attr:`~statx_result.stx_mask`.
.. attribute:: stx_atomic_write_segments_max
Maximum iovecs for direct I/O with torn-write protection.
Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from
:attr:`~statx_result.stx_mask`.
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
userspace API headers >= 6.11.
.. attribute:: stx_atomic_write_unit_max
Maximum size for direct I/O with torn-write protection.
Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from
:attr:`~statx_result.stx_mask`.
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
userspace API headers >= 6.11.
.. attribute:: stx_atomic_write_unit_max_opt
Maximum optimized size for direct I/O with torn-write protection.
Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from
:attr:`~statx_result.stx_mask`.
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
userspace API headers >= 6.16.
.. attribute:: stx_atomic_write_unit_min
Minimum size for direct I/O with torn-write protection.
Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from
:attr:`~statx_result.stx_mask`.
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
userspace API headers >= 6.11.
.. attribute:: stx_attributes
Bitmask of :const:`STATX_ATTR_* <stat.STATX_ATTR_COMPRESSED>` constants
specifying the attributes of this file.
.. attribute:: stx_attributes_mask
A mask indicating which bits in :attr:`stx_attributes` are supported by
the VFS and the filesystem.
.. attribute:: stx_blksize
"Preferred" blocksize for efficient file system I/O. Writing to a file in
smaller chunks may cause an inefficient read-modify-rewrite.
.. attribute:: stx_blocks
Number of 512-byte blocks allocated for file.
This may be smaller than :attr:`stx_size`/512 when the file has holes.
Equal to ``None`` if :data:`STATX_BLOCKS` is missing from
:attr:`~statx_result.stx_mask`.
.. attribute:: stx_btime
Time of file creation expressed in seconds.
Equal to ``None`` if :data:`STATX_BTIME` is missing from
:attr:`~statx_result.stx_mask`.
.. attribute:: stx_btime_ns
Time of file creation expressed in nanoseconds as an integer.
Equal to ``None`` if :data:`STATX_BTIME` is missing from
:attr:`~statx_result.stx_mask`.
.. attribute:: stx_ctime
Time of most recent metadata change expressed in seconds.
Equal to ``None`` if :data:`STATX_CTIME` is missing from
:attr:`~statx_result.stx_mask`.
.. attribute:: stx_ctime_ns
Time of most recent metadata change expressed in nanoseconds as an
integer.
Equal to ``None`` if :data:`STATX_CTIME` is missing from
:attr:`~statx_result.stx_mask`.
.. attribute:: stx_dev
Identifier of the device on which this file resides.
.. attribute:: stx_dev_major
Major number of the device on which this file resides.
.. attribute:: stx_dev_minor
Minor number of the device on which this file resides.
.. attribute:: stx_dio_mem_align
Direct I/O memory buffer alignment requirement.
Equal to ``None`` if :data:`STATX_DIOALIGN` is missing from
:attr:`~statx_result.stx_mask`.
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
userspace API headers >= 6.1.
.. attribute:: stx_dio_offset_align
Direct I/O file offset alignment requirement.
Equal to ``None`` if :data:`STATX_DIOALIGN` is missing from
:attr:`~statx_result.stx_mask`.
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
userspace API headers >= 6.1.
.. attribute:: stx_dio_read_offset_align
Direct I/O file offset alignment requirement for reads.
Equal to ``None`` if :data:`STATX_DIO_READ_ALIGN` is missing from
:attr:`~statx_result.stx_mask`.
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
userspace API headers >= 6.14.
.. attribute:: stx_gid
Group identifier of the file owner.
Equal to ``None`` if :data:`STATX_GID` is missing from
:attr:`~statx_result.stx_mask`.
.. attribute:: stx_ino
Inode number.
Equal to ``None`` if :data:`STATX_INO` is missing from
:attr:`~statx_result.stx_mask`.
.. attribute:: stx_mask
Bitmask of :const:`STATX_* <STATX_TYPE>` constants specifying the
information retrieved, which may differ from what was requested.
.. attribute:: stx_mnt_id
Mount identifier.
Equal to ``None`` if :data:`STATX_MNT_ID` is missing from
:attr:`~statx_result.stx_mask`.
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
userspace API headers >= 5.8.
.. attribute:: stx_mode
File mode: file type and file mode bits (permissions).
Equal to ``None`` if :data:`STATX_TYPE | STATX_MODE <STATX_TYPE>`
is missing from :attr:`~statx_result.stx_mask`.
.. attribute:: stx_mtime
Time of most recent content modification expressed in seconds.
Equal to ``None`` if :data:`STATX_MTIME` is missing from
:attr:`~statx_result.stx_mask`.
.. attribute:: stx_mtime_ns
Time of most recent content modification expressed in nanoseconds as an
integer.
Equal to ``None`` if :data:`STATX_MTIME` is missing from
:attr:`~statx_result.stx_mask`.
.. attribute:: stx_nlink
Number of hard links.
Equal to ``None`` if :data:`STATX_NLINK` is missing from
:attr:`~statx_result.stx_mask`.
.. attribute:: stx_rdev
Type of device if an inode device.
.. attribute:: stx_rdev_major
Major number of the device this file represents.
.. attribute:: stx_rdev_minor
Minor number of the device this file represents.
.. attribute:: stx_size
Size of the file in bytes, if it is a regular file or a symbolic link.
The size of a symbolic link is the length of the pathname it contains,
without a terminating null byte.
Equal to ``None`` if :data:`STATX_SIZE` is missing from
:attr:`~statx_result.stx_mask`.
.. attribute:: stx_subvol
Subvolume identifier.
Equal to ``None`` if :data:`STATX_SUBVOL` is missing from
:attr:`~statx_result.stx_mask`.
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
userspace API headers >= 6.10.
.. attribute:: stx_uid
User identifier of the file owner.
Equal to ``None`` if :data:`STATX_UID` is missing from
:attr:`~statx_result.stx_mask`.
.. seealso:: The :manpage:`statx(2)` man page.
.. availability:: Linux >= 4.11 with glibc >= 2.28.
.. versionadded:: next
.. data:: STATX_TYPE
STATX_MODE
STATX_NLINK
STATX_UID
STATX_GID
STATX_ATIME
STATX_MTIME
STATX_CTIME
STATX_INO
STATX_SIZE
STATX_BLOCKS
STATX_BASIC_STATS
STATX_BTIME
STATX_MNT_ID
STATX_DIOALIGN
STATX_MNT_ID_UNIQUE
STATX_SUBVOL
STATX_WRITE_ATOMIC
STATX_DIO_READ_ALIGN
Bitflags for use in the *mask* parameter to :func:`os.statx`. Some of these
flags may be available even when their corresponding members in
:class:`statx_result` are not available.
.. availability:: Linux >= 4.11 with glibc >= 2.28.
.. versionadded:: next
.. data:: AT_STATX_FORCE_SYNC
A flag for the :func:`os.statx` function. Requests that the kernel return
up-to-date information even when doing so is expensive (for example,
requiring a round trip to the server for a file on a network filesystem).
.. availability:: Linux >= 4.11 with glibc >= 2.28.
.. versionadded:: next
.. data:: AT_STATX_DONT_SYNC
A flag for the :func:`os.statx` function. Requests that the kernel return
cached information if possible.
.. availability:: Linux >= 4.11 with glibc >= 2.28.
.. versionadded:: next
.. data:: AT_STATX_SYNC_AS_STAT
A flag for the :func:`os.statx` function. This flag is defined as ``0``, so
it has no effect, but it can be used to explicitly indicate neither
:data:`AT_STATX_FORCE_SYNC` nor :data:`AT_STATX_DONT_SYNC` is being passed.
In the absence of the other two flags, the kernel will generally return
information as fresh as :func:`os.stat` would return.
.. availability:: Linux >= 4.11 with glibc >= 2.28.
.. versionadded:: next
.. data:: AT_NO_AUTOMOUNT
If the final component of a path is an automount point, operate on the
automount point instead of performing the automount. On Linux,
:func:`os.stat`, :func:`os.fstat` and :func:`os.lstat` always behave this
way.
.. availability:: Linux.
.. versionadded:: next
.. function:: statvfs(path)
Perform a :c:func:`!statvfs` system call on the given path. The return value is
@ -3646,7 +3999,7 @@ features:
.. versionchanged:: 3.6
Accepts a :term:`path-like object`.
.. versionchanged:: next
.. versionchanged:: 3.15
Accepts any real numbers as *times*, not only integers or floats.
@ -4285,10 +4638,10 @@ to be ignored.
.. function:: abort()
Generate a :const:`SIGABRT` signal to the current process. On Unix, the default
Generate a :const:`~signal.SIGABRT` signal to the current process. On Unix, the default
behavior is to produce a core dump; on Windows, the process immediately returns
an exit code of ``3``. Be aware that calling this function will not call the
Python signal handler registered for :const:`SIGABRT` with
Python signal handler registered for :const:`~signal.SIGABRT` with
:func:`signal.signal`.
@ -4592,6 +4945,8 @@ written in Python, such as a mail server's external command delivery program.
master end of the pseudo-terminal. For a more portable approach, use the
:mod:`pty` module. If an error occurs :exc:`OSError` is raised.
The returned file descriptor *fd* is :ref:`non-inheritable <fd_inheritance>`.
.. audit-event:: os.forkpty "" os.forkpty
.. warning::
@ -4608,6 +4963,9 @@ written in Python, such as a mail server's external command delivery program.
threads, this now raises a :exc:`DeprecationWarning`. See the
longer explanation on :func:`os.fork`.
.. versionchanged:: 3.15
The returned file descriptor is now made non-inheritable.
.. availability:: Unix, not WASI, not Android, not iOS.

View file

@ -22,8 +22,6 @@ The formatted representation keeps objects on a single line if it can, and
breaks them onto multiple lines if they don't fit within the allowed width,
adjustable by the *width* parameter defaulting to 80 characters.
Dictionaries are sorted by key before the display is computed.
.. versionchanged:: 3.9
Added support for pretty-printing :class:`types.SimpleNamespace`.

View file

@ -33,9 +33,14 @@ The :mod:`pty` module defines the following functions:
file descriptor connected to the child's controlling terminal (and also to the
child's standard input and output).
The returned file descriptor *fd* is :ref:`non-inheritable <fd_inheritance>`.
.. warning:: On macOS the use of this function is unsafe when mixed with using
higher-level system APIs, and that includes using :mod:`urllib.request`.
.. versionchanged:: 3.15
The returned file descriptor is now made non-inheritable.
.. function:: openpty()

View file

@ -223,10 +223,10 @@ XMLParser Objects
Calling ``SetReparseDeferralEnabled(True)`` allows re-enabling reparse
deferral.
Note that :meth:`SetReparseDeferralEnabled` has been backported to some
prior releases of CPython as a security fix. Check for availability of
:meth:`SetReparseDeferralEnabled` using :func:`hasattr` if used in code
running across a variety of Python versions.
:meth:`!SetReparseDeferralEnabled`
has been backported to some prior releases of CPython as a security fix.
Check for availability using :func:`hasattr` if used in code running
across a variety of Python versions.
.. versionadded:: 3.13
@ -257,12 +257,17 @@ against some common XML vulnerabilities.
The corresponding :attr:`~ExpatError.lineno` and :attr:`~ExpatError.offset`
should not be used as they may have no special meaning.
:meth:`!SetBillionLaughsAttackProtectionActivationThreshold`
has been backported to some prior releases of CPython as a security fix.
Check for availability using :func:`hasattr` if used in code running
across a variety of Python versions.
.. note::
Activation thresholds below 4 MiB are known to break support for DITA 1.3
payload and are hence not recommended.
.. versionadded:: next
.. versionadded:: 3.15
.. method:: xmlparser.SetBillionLaughsAttackProtectionMaximumAmplification(max_factor, /)
@ -288,13 +293,18 @@ against some common XML vulnerabilities.
The corresponding :attr:`~ExpatError.lineno` and :attr:`~ExpatError.offset`
should not be used as they may have no special meaning.
:meth:`!SetBillionLaughsAttackProtectionMaximumAmplification`
has been backported to some prior releases of CPython as a security fix.
Check for availability using :func:`hasattr` if used in code running
across a variety of Python versions.
.. note::
The maximum amplification factor is only considered if the threshold
that can be adjusted by :meth:`.SetBillionLaughsAttackProtectionActivationThreshold`
is exceeded.
.. versionadded:: next
.. versionadded:: 3.15
.. method:: xmlparser.SetAllocTrackerActivationThreshold(threshold, /)
@ -309,7 +319,12 @@ against some common XML vulnerabilities.
The corresponding :attr:`~ExpatError.lineno` and :attr:`~ExpatError.offset`
should not be used as they may have no special meaning.
.. versionadded:: next
:meth:`!SetAllocTrackerActivationThreshold`
has been backported to some prior releases of CPython as a security fix.
Check for availability using :func:`hasattr` if used in code running
across a variety of Python versions.
.. versionadded:: 3.15
.. method:: xmlparser.SetAllocTrackerMaximumAmplification(max_factor, /)
@ -334,13 +349,18 @@ against some common XML vulnerabilities.
The corresponding :attr:`~ExpatError.lineno` and :attr:`~ExpatError.offset`
should not be used as they may have no special meaning.
:meth:`!SetAllocTrackerMaximumAmplification`
has been backported to some prior releases of CPython as a security fix.
Check for availability using :func:`hasattr` if used in code running
across a variety of Python versions.
.. note::
The maximum amplification factor is only considered if the threshold
that can be adjusted by :meth:`.SetAllocTrackerActivationThreshold`
is exceeded.
.. versionadded:: next
.. versionadded:: 3.15
:class:`xmlparser` objects have the following attributes:

View file

@ -51,7 +51,7 @@ this module for those platforms.
Constant used to represent the limit for an unlimited resource.
.. versionchanged:: next
.. versionchanged:: 3.15
It is now always positive.
Previously, it could be negative, such as -1 or -3.
@ -63,7 +63,7 @@ this module for those platforms.
cannot be represented in the ``rlim_t`` value in C.
Can be equal to :data:`RLIM_INFINITY`.
.. versionadded:: next
.. versionadded:: 3.15
.. function:: getrlimit(resource)
@ -141,7 +141,7 @@ platform.
.. data:: RLIMIT_CPU
The maximum amount of processor time (in seconds) that a process can use. If
this limit is exceeded, a :const:`SIGXCPU` signal is sent to the process. (See
this limit is exceeded, a :const:`~signal.SIGXCPU` signal is sent to the process. (See
the :mod:`signal` module documentation for information about how to catch this
signal and do something useful, e.g. flush open files to disk.)
@ -296,7 +296,7 @@ platform.
.. availability:: NetBSD >= 7.0.
.. versionadded:: next
.. versionadded:: 3.15
.. data:: RLIMIT_PIPEBUF
@ -306,7 +306,7 @@ platform.
.. availability:: FreeBSD >= 14.2.
.. versionadded:: next
.. versionadded:: 3.15
.. data:: RLIMIT_THREADS
@ -315,7 +315,7 @@ platform.
.. availability:: AIX.
.. versionadded:: next
.. versionadded:: 3.15
.. data:: RLIMIT_UMTXP
@ -325,7 +325,7 @@ platform.
.. availability:: FreeBSD >= 11.
.. versionadded:: next
.. versionadded:: 3.15
Resource Usage
@ -363,47 +363,47 @@ These functions are used to retrieve resource usage information:
For backward compatibility, the return value is also accessible as a tuple of 16
elements.
The fields :attr:`ru_utime` and :attr:`ru_stime` of the return value are
The fields :attr:`!ru_utime` and :attr:`!ru_stime` of the return value are
floating-point values representing the amount of time spent executing in user
mode and the amount of time spent executing in system mode, respectively. The
remaining values are integers. Consult the :manpage:`getrusage(2)` man page for
detailed information about these values. A brief summary is presented here:
+--------+---------------------+---------------------------------------+
+--------+----------------------+---------------------------------------+
| Index | Field | Resource |
+========+=====================+=======================================+
| ``0`` | :attr:`ru_utime` | time in user mode (float seconds) |
+--------+---------------------+---------------------------------------+
| ``1`` | :attr:`ru_stime` | time in system mode (float seconds) |
+--------+---------------------+---------------------------------------+
| ``2`` | :attr:`ru_maxrss` | maximum resident set size |
+--------+---------------------+---------------------------------------+
| ``3`` | :attr:`ru_ixrss` | shared memory size |
+--------+---------------------+---------------------------------------+
| ``4`` | :attr:`ru_idrss` | unshared memory size |
+--------+---------------------+---------------------------------------+
| ``5`` | :attr:`ru_isrss` | unshared stack size |
+--------+---------------------+---------------------------------------+
| ``6`` | :attr:`ru_minflt` | page faults not requiring I/O |
+--------+---------------------+---------------------------------------+
| ``7`` | :attr:`ru_majflt` | page faults requiring I/O |
+--------+---------------------+---------------------------------------+
| ``8`` | :attr:`ru_nswap` | number of swap outs |
+--------+---------------------+---------------------------------------+
| ``9`` | :attr:`ru_inblock` | block input operations |
+--------+---------------------+---------------------------------------+
| ``10`` | :attr:`ru_oublock` | block output operations |
+--------+---------------------+---------------------------------------+
| ``11`` | :attr:`ru_msgsnd` | messages sent |
+--------+---------------------+---------------------------------------+
| ``12`` | :attr:`ru_msgrcv` | messages received |
+--------+---------------------+---------------------------------------+
| ``13`` | :attr:`ru_nsignals` | signals received |
+--------+---------------------+---------------------------------------+
| ``14`` | :attr:`ru_nvcsw` | voluntary context switches |
+--------+---------------------+---------------------------------------+
| ``15`` | :attr:`ru_nivcsw` | involuntary context switches |
+--------+---------------------+---------------------------------------+
+========+======================+=======================================+
| ``0`` | :attr:`!ru_utime` | time in user mode (float seconds) |
+--------+----------------------+---------------------------------------+
| ``1`` | :attr:`!ru_stime` | time in system mode (float seconds) |
+--------+----------------------+---------------------------------------+
| ``2`` | :attr:`!ru_maxrss` | maximum resident set size |
+--------+----------------------+---------------------------------------+
| ``3`` | :attr:`!ru_ixrss` | shared memory size |
+--------+----------------------+---------------------------------------+
| ``4`` | :attr:`!ru_idrss` | unshared memory size |
+--------+----------------------+---------------------------------------+
| ``5`` | :attr:`!ru_isrss` | unshared stack size |
+--------+----------------------+---------------------------------------+
| ``6`` | :attr:`!ru_minflt` | page faults not requiring I/O |
+--------+----------------------+---------------------------------------+
| ``7`` | :attr:`!ru_majflt` | page faults requiring I/O |
+--------+----------------------+---------------------------------------+
| ``8`` | :attr:`!ru_nswap` | number of swap outs |
+--------+----------------------+---------------------------------------+
| ``9`` | :attr:`!ru_inblock` | block input operations |
+--------+----------------------+---------------------------------------+
| ``10`` | :attr:`!ru_oublock` | block output operations |
+--------+----------------------+---------------------------------------+
| ``11`` | :attr:`!ru_msgsnd` | messages sent |
+--------+----------------------+---------------------------------------+
| ``12`` | :attr:`!ru_msgrcv` | messages received |
+--------+----------------------+---------------------------------------+
| ``13`` | :attr:`!ru_nsignals` | signals received |
+--------+----------------------+---------------------------------------+
| ``14`` | :attr:`!ru_nvcsw` | voluntary context switches |
+--------+----------------------+---------------------------------------+
| ``15`` | :attr:`!ru_nivcsw` | involuntary context switches |
+--------+----------------------+---------------------------------------+
This function will raise a :exc:`ValueError` if an invalid *who* parameter is
specified. It may also raise :exc:`error` exception in unusual circumstances.

View file

@ -165,7 +165,7 @@ The module defines the following:
:pep:`475` for the rationale), instead of raising
:exc:`InterruptedError`.
.. versionchanged:: next
.. versionchanged:: 3.15
Accepts any real number as *timeout*, not only integer or float.
@ -274,7 +274,7 @@ object.
:pep:`475` for the rationale), instead of raising
:exc:`InterruptedError`.
.. versionchanged:: next
.. versionchanged:: 3.15
Accepts any real number as *timeout*, not only integer or float.
@ -385,7 +385,7 @@ Edge and Level Trigger Polling (epoll) Objects
:pep:`475` for the rationale), instead of raising
:exc:`InterruptedError`.
.. versionchanged:: next
.. versionchanged:: 3.15
Accepts any real number as *timeout*, not only integer or float.
@ -476,7 +476,7 @@ linearly scanned again. :c:func:`!select` is *O*\ (*highest file descriptor*), w
:pep:`475` for the rationale), instead of raising
:exc:`InterruptedError`.
.. versionchanged:: next
.. versionchanged:: 3.15
Accepts any real number as *timeout*, not only integer or float.
@ -520,7 +520,7 @@ Kqueue Objects
:pep:`475` for the rationale), instead of raising
:exc:`InterruptedError`.
.. versionchanged:: next
.. versionchanged:: 3.15
Accepts any real number as *timeout*, not only integer or float.

View file

@ -64,7 +64,7 @@ lots of shared sub-objects. The keys are ordinary strings.
.. versionchanged:: 3.11
Accepts :term:`path-like object` for filename.
.. versionchanged:: next
.. versionchanged:: 3.15
Accepts custom *serializer* and *deserializer* functions in place of
:func:`pickle.dumps` and :func:`pickle.loads`.
@ -103,7 +103,7 @@ Two additional methods are supported:
Calls :meth:`sync` and attempts to shrink space used on disk by removing empty
space resulting from deletions.
.. versionadded:: next
.. versionadded:: 3.15
.. method:: Shelf.close()
@ -185,7 +185,7 @@ Restrictions
:const:`pickle.DEFAULT_PROTOCOL` is now used as the default pickle
protocol.
.. versionchanged:: next
.. versionchanged:: 3.15
Added the *serializer* and *deserializer* parameters.
@ -204,7 +204,7 @@ Restrictions
optional *protocol*, *writeback*, *keyencoding*, *serializer* and *deserializer*
parameters have the same interpretation as in :func:`~shelve.open`.
.. versionchanged:: next
.. versionchanged:: 3.15
Added the *serializer* and *deserializer* parameters.
@ -220,7 +220,7 @@ Restrictions
and *deserializer* parameters have the same interpretation as in
:func:`~shelve.open`.
.. versionchanged:: next
.. versionchanged:: 3.15
Added the *serializer* and *deserializer* parameters.
@ -274,7 +274,7 @@ Exceptions
The *deserializer* and *serializer* arguments must be given together.
.. versionadded:: next
.. versionadded:: 3.15
.. seealso::

View file

@ -205,10 +205,26 @@ The variables defined in the :mod:`signal` module are:
.. availability:: Unix.
.. data:: SIGPROF
Profiling timer expired.
.. availability:: Unix.
.. data:: SIGQUIT
Terminal quit signal.
.. availability:: Unix.
.. data:: SIGSEGV
Segmentation fault: invalid memory reference.
.. data:: SIGSTOP
Stop executing (cannot be caught or ignored).
.. data:: SIGSTKFLT
Stack fault on coprocessor. The Linux kernel does not raise this signal: it
@ -237,18 +253,30 @@ The variables defined in the :mod:`signal` module are:
.. availability:: Unix.
.. data:: SIGVTALRM
Virtual timer expired.
.. availability:: Unix.
.. data:: SIGWINCH
Window resize signal.
.. availability:: Unix.
.. data:: SIGXCPU
CPU time limit exceeded.
.. availability:: Unix.
.. data:: SIG*
All the signal numbers are defined symbolically. For example, the hangup signal
is defined as :const:`signal.SIGHUP`; the variable names are identical to the
names used in C programs, as found in ``<signal.h>``. The Unix man page for
':c:func:`signal`' lists the existing signals (on some systems this is
'``signal``' lists the existing signals (on some systems this is
:manpage:`signal(2)`, on others the list is in :manpage:`signal(7)`). Note that
not all systems define the same set of signal names; only those names defined by
the system are defined by this module.
@ -501,7 +529,7 @@ The :mod:`signal` module defines the following functions:
.. availability:: Unix.
.. versionchanged:: next
.. versionchanged:: 3.15
Accepts any real numbers as *seconds* and *interval*, not only integers
or floats.
@ -644,9 +672,8 @@ The :mod:`signal` module defines the following functions:
*sigset*.
The return value is an object representing the data contained in the
:c:type:`siginfo_t` structure, namely: :attr:`si_signo`, :attr:`si_code`,
:attr:`si_errno`, :attr:`si_pid`, :attr:`si_uid`, :attr:`si_status`,
:attr:`si_band`.
``siginfo_t`` structure, namely: ``si_signo``, ``si_code``,
``si_errno``, ``si_pid``, ``si_uid``, ``si_status``, ``si_band``.
.. availability:: Unix.
@ -681,7 +708,7 @@ The :mod:`signal` module defines the following functions:
by a signal not in *sigset* and the signal handler does not raise an
exception (see :pep:`475` for the rationale).
.. versionchanged:: next
.. versionchanged:: 3.15
Accepts any real number as *timeout*, not only integer or float.

View file

@ -80,8 +80,8 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions).
An :class:`SMTP_SSL` instance behaves exactly the same as instances of
:class:`SMTP`. :class:`SMTP_SSL` should be used for situations where SSL is
required from the beginning of the connection and using :meth:`starttls` is
not appropriate. If *host* is not specified, the local host is used. If
required from the beginning of the connection and using :meth:`~SMTP.starttls`
is not appropriate. If *host* is not specified, the local host is used. If
*port* is zero, the standard SMTP-over-SSL port (465) is used. The optional
arguments *local_hostname*, *timeout* and *source_address* have the same
meaning as they do in the :class:`SMTP` class. *context*, also optional,
@ -112,7 +112,7 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions).
The LMTP protocol, which is very similar to ESMTP, is heavily based on the
standard SMTP client. It's common to use Unix sockets for LMTP, so our
:meth:`connect` method must support that as well as a regular host:port
:meth:`~SMTP.connect` method must support that as well as a regular host:port
server. The optional arguments *local_hostname* and *source_address* have the
same meaning as they do in the :class:`SMTP` class. To specify a Unix
socket, you must use an absolute path for *host*, starting with a '/'.
@ -147,9 +147,15 @@ A nice selection of exceptions is defined as well:
.. exception:: SMTPResponseException
Base class for all exceptions that include an SMTP error code. These exceptions
are generated in some instances when the SMTP server returns an error code. The
error code is stored in the :attr:`smtp_code` attribute of the error, and the
:attr:`smtp_error` attribute is set to the error message.
are generated in some instances when the SMTP server returns an error code.
.. attribute:: smtp_code
The error code.
.. attribute:: smtp_error
The error message.
.. exception:: SMTPSenderRefused
@ -161,9 +167,13 @@ A nice selection of exceptions is defined as well:
.. exception:: SMTPRecipientsRefused
All recipient addresses refused. The errors for each recipient are accessible
through the attribute :attr:`recipients`, which is a dictionary of exactly the
same sort as :meth:`SMTP.sendmail` returns.
All recipient addresses refused.
.. attribute:: recipients
A dictionary of exactly the same sort as returned
by :meth:`SMTP.sendmail` containing the errors for
each recipient.
.. exception:: SMTPDataError
@ -213,7 +223,6 @@ SMTP Objects
An :class:`SMTP` instance has the following methods:
.. method:: SMTP.set_debuglevel(level)
Set the debug output level. A value of 1 or ``True`` for *level* results in
@ -417,7 +426,7 @@ An :class:`SMTP` instance has the following methods:
.. versionchanged:: 3.4
The method now supports hostname check with
:attr:`SSLContext.check_hostname` and *Server Name Indicator* (see
:attr:`ssl.SSLContext.check_hostname` and *Server Name Indicator* (see
:const:`~ssl.HAS_SNI`).
.. versionchanged:: 3.5
@ -435,7 +444,7 @@ An :class:`SMTP` instance has the following methods:
ESMTP options (such as ``DSN`` commands) that should be used with all ``RCPT``
commands can be passed as *rcpt_options*. (If you need to use different ESMTP
options to different recipients you have to use the low-level methods such as
:meth:`mail`, :meth:`rcpt` and :meth:`data` to send the message.)
:meth:`!mail`, :meth:`!rcpt` and :meth:`!data` to send the message.)
.. note::
@ -467,10 +476,7 @@ An :class:`SMTP` instance has the following methods:
This method may raise the following exceptions:
:exc:`SMTPRecipientsRefused`
All recipients were refused. Nobody got the mail. The :attr:`recipients`
attribute of the exception object is a dictionary with information about the
refused recipients (like the one returned when at least one recipient was
accepted).
All recipients were refused. Nobody got the mail.
:exc:`SMTPHeloError`
The server didn't reply properly to the ``HELO`` greeting.
@ -546,6 +552,30 @@ Low-level methods corresponding to the standard SMTP/ESMTP commands ``HELP``,
Normally these do not need to be called directly, so they are not documented
here. For details, consult the module code.
Additionally, an SMTP instance has the following attributes:
.. attribute:: SMTP.helo_resp
The response to the ``HELO`` command, see :meth:`helo`.
.. attribute:: SMTP.ehlo_resp
The response to the ``EHLO`` command, see :meth:`ehlo`.
.. attribute:: SMTP.does_esmtp
A boolean value indicating whether the server supports ESMTP, see
:meth:`ehlo`.
.. attribute:: SMTP.esmtp_features
A dictionary of the names of SMTP service extensions supported by the server,
see :meth:`ehlo`.
.. _smtp-example:

Some files were not shown because too many files have changed in this diff Show more