mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
Merge remote-tracking branch 'origin/main' into HEAD
This commit is contained in:
commit
8d57aca95a
1284 changed files with 27792 additions and 11927 deletions
73
.devcontainer/wasi/devcontainer.json
Normal file
73
.devcontainer/wasi/devcontainer.json
Normal 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
4
.github/CODEOWNERS
vendored
|
|
@ -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
|
||||
|
|
|
|||
3
.github/actionlint.yaml
vendored
3
.github/actionlint.yaml
vendored
|
|
@ -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
|
||||
|
||||
|
|
|
|||
52
.github/workflows/build.yml
vendored
52
.github/workflows/build.yml
vendored
|
|
@ -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,
|
||||
|
|
|
|||
13
.github/workflows/jit.yml
vendored
13
.github/workflows/jit.yml
vendored
|
|
@ -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:
|
||||
|
|
|
|||
1
.github/workflows/mypy.yml
vendored
1
.github/workflows/mypy.yml
vendored
|
|
@ -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"
|
||||
|
|
|
|||
31
.github/workflows/project-updater.yml
vendored
31
.github/workflows/project-updater.yml
vendored
|
|
@ -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 }}
|
||||
10
.github/workflows/reusable-macos.yml
vendored
10
.github/workflows/reusable-macos.yml
vendored
|
|
@ -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
|
||||
|
|
|
|||
2
.github/workflows/reusable-ubuntu.yml
vendored
2
.github/workflows/reusable-ubuntu.yml
vendored
|
|
@ -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:
|
||||
|
|
|
|||
8
.github/workflows/reusable-wasi.yml
vendored
8
.github/workflows/reusable-wasi.yml
vendored
|
|
@ -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
|
||||
|
|
|
|||
9
.github/workflows/tail-call.yml
vendored
9
.github/workflows/tail-call.yml
vendored
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class PythonSuite {
|
|||
val status = PythonTestRunner(
|
||||
InstrumentationRegistry.getInstrumentation().targetContext
|
||||
).run(
|
||||
InstrumentationRegistry.getArguments()
|
||||
InstrumentationRegistry.getArguments().getString("pythonArgs")!!,
|
||||
)
|
||||
assertEquals(0, status)
|
||||
} finally {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}")
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
`translation’s repository <TRANSLATION_REPO_>`_ instead.
|
||||
|
||||
You can also open a discussion item on our
|
||||
`Documentation Discourse forum <https://discuss.python.org/c/documentation/26>`_.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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*,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
20
Doc/conf.py
20
Doc/conf.py
|
|
@ -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
|
||||
# --------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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`.)
|
||||
|
||||
|
|
|
|||
|
|
@ -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`.)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>`.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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::
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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::
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
The :mod:`!compression` package
|
||||
===============================
|
||||
|
||||
.. module:: compression
|
||||
|
||||
.. versionadded:: 3.14
|
||||
|
||||
The :mod:`!compression` package contains the canonical compression modules
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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>`.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
+---------------------------------+---------------------+-------------------------------+
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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*.
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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. ``>``), 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 ``>`` is ``>``, whereas the hexadecimal is ``>``;
|
||||
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! ☺</strong>");</script>')
|
||||
Start tag: script
|
||||
attr: ('type', 'text/javascript')
|
||||
Data : alert("<strong>hello!</strong>");
|
||||
Data : alert("<strong>hello! ☺</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::
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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::
|
||||
|
|
|
|||
|
|
@ -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
|
||||
--------------------
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
85
Doc/library/math.integer.rst
Normal file
85
Doc/library/math.integer.rst
Normal 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.
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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::
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue