mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
Merge remote-tracking branch 'upstream/main' into lazy
This commit is contained in:
commit
db151a5192
869 changed files with 45727 additions and 16994 deletions
1
.gitattributes
vendored
1
.gitattributes
vendored
|
|
@ -83,6 +83,7 @@ Include/opcode_ids.h generated
|
||||||
Include/token.h generated
|
Include/token.h generated
|
||||||
Lib/_opcode_metadata.py generated
|
Lib/_opcode_metadata.py generated
|
||||||
Lib/keyword.py generated
|
Lib/keyword.py generated
|
||||||
|
Lib/idlelib/help.html generated
|
||||||
Lib/test/certdata/*.pem generated
|
Lib/test/certdata/*.pem generated
|
||||||
Lib/test/certdata/*.0 generated
|
Lib/test/certdata/*.0 generated
|
||||||
Lib/test/levenshtein_examples.json generated
|
Lib/test/levenshtein_examples.json generated
|
||||||
|
|
|
||||||
3
.github/CODEOWNERS
vendored
3
.github/CODEOWNERS
vendored
|
|
@ -126,6 +126,9 @@ Doc/howto/clinic.rst @erlend-aasland @AA-Turner
|
||||||
# C Analyser
|
# C Analyser
|
||||||
Tools/c-analyzer/ @ericsnowcurrently
|
Tools/c-analyzer/ @ericsnowcurrently
|
||||||
|
|
||||||
|
# C API Documentation Checks
|
||||||
|
Tools/check-c-api-docs/ @ZeroIntensity
|
||||||
|
|
||||||
# Fuzzing
|
# Fuzzing
|
||||||
Modules/_xxtestfuzz/ @ammaraskar
|
Modules/_xxtestfuzz/ @ammaraskar
|
||||||
|
|
||||||
|
|
|
||||||
11
.github/CONTRIBUTING.rst
vendored
11
.github/CONTRIBUTING.rst
vendored
|
|
@ -28,13 +28,12 @@ Please be aware that our workflow does deviate slightly from the typical GitHub
|
||||||
project. Details on how to properly submit a pull request are covered in
|
project. Details on how to properly submit a pull request are covered in
|
||||||
`Lifecycle of a Pull Request <https://devguide.python.org/getting-started/pull-request-lifecycle.html>`_.
|
`Lifecycle of a Pull Request <https://devguide.python.org/getting-started/pull-request-lifecycle.html>`_.
|
||||||
We utilize various bots and status checks to help with this, so do follow the
|
We utilize various bots and status checks to help with this, so do follow the
|
||||||
comments they leave and their "Details" links, respectively. The key points of
|
comments they leave and their "Details" links, respectively.
|
||||||
our workflow that are not covered by a bot or status check are:
|
|
||||||
|
|
||||||
- All discussions that are not directly related to the code in the pull request
|
The final key part of our workflow is that all discussions that are not
|
||||||
should happen on `GitHub Issues <https://github.com/python/cpython/issues>`_.
|
directly related to the code in the pull request should happen on
|
||||||
- Upon your first non-trivial pull request (which includes documentation changes),
|
`GitHub Issues <https://github.com/python/cpython/issues>`__, generally in the
|
||||||
feel free to add yourself to ``Misc/ACKS``.
|
pull request's parent issue.
|
||||||
|
|
||||||
|
|
||||||
Setting Expectations
|
Setting Expectations
|
||||||
|
|
|
||||||
3
.github/ISSUE_TEMPLATE/config.yml
vendored
3
.github/ISSUE_TEMPLATE/config.yml
vendored
|
|
@ -5,3 +5,6 @@ contact_links:
|
||||||
- name: "Proposing new features"
|
- name: "Proposing new features"
|
||||||
about: "Submit major feature proposal (e.g. syntax changes) to an ideas forum first."
|
about: "Submit major feature proposal (e.g. syntax changes) to an ideas forum first."
|
||||||
url: "https://discuss.python.org/c/ideas/6"
|
url: "https://discuss.python.org/c/ideas/6"
|
||||||
|
- name: "Python Install Manager issues"
|
||||||
|
about: "Report issues with the Python Install Manager (for Windows)"
|
||||||
|
url: "https://github.com/python/pymanager/issues"
|
||||||
|
|
|
||||||
7
.github/dependabot.yml
vendored
7
.github/dependabot.yml
vendored
|
|
@ -12,6 +12,11 @@ updates:
|
||||||
update-types:
|
update-types:
|
||||||
- "version-update:semver-minor"
|
- "version-update:semver-minor"
|
||||||
- "version-update:semver-patch"
|
- "version-update:semver-patch"
|
||||||
|
cooldown:
|
||||||
|
# https://blog.yossarian.net/2025/11/21/We-should-all-be-using-dependency-cooldowns
|
||||||
|
# Cooldowns protect against supply chain attacks by avoiding the
|
||||||
|
# highest-risk window immediately after new releases.
|
||||||
|
default-days: 14
|
||||||
- package-ecosystem: "pip"
|
- package-ecosystem: "pip"
|
||||||
directory: "/Tools/"
|
directory: "/Tools/"
|
||||||
schedule:
|
schedule:
|
||||||
|
|
@ -19,3 +24,5 @@ updates:
|
||||||
labels:
|
labels:
|
||||||
- "skip issue"
|
- "skip issue"
|
||||||
- "skip news"
|
- "skip news"
|
||||||
|
cooldown:
|
||||||
|
default-days: 14
|
||||||
|
|
|
||||||
60
.github/workflows/build.yml
vendored
60
.github/workflows/build.yml
vendored
|
|
@ -109,20 +109,10 @@ jobs:
|
||||||
python-version: '3.x'
|
python-version: '3.x'
|
||||||
- name: Runner image version
|
- name: Runner image version
|
||||||
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
|
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
|
||||||
- name: Restore config.cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: config.cache
|
|
||||||
# Include env.pythonLocation in key to avoid changes in environment when setup-python updates Python
|
|
||||||
key: ${{ github.job }}-${{ env.IMAGE_OS_VERSION }}-${{ needs.build-context.outputs.config-hash }}-${{ env.pythonLocation }}
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo ./.github/workflows/posix-deps-apt.sh
|
run: sudo ./.github/workflows/posix-deps-apt.sh
|
||||||
- name: Add ccache to PATH
|
- name: Add ccache to PATH
|
||||||
run: echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
|
run: echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
|
||||||
- name: Configure ccache action
|
|
||||||
uses: hendrikmuhs/ccache-action@v1.2
|
|
||||||
with:
|
|
||||||
save: false
|
|
||||||
- name: Configure CPython
|
- name: Configure CPython
|
||||||
run: |
|
run: |
|
||||||
# Build Python with the libpython dynamic library
|
# Build Python with the libpython dynamic library
|
||||||
|
|
@ -152,6 +142,9 @@ jobs:
|
||||||
- name: Check for unsupported C global variables
|
- name: Check for unsupported C global variables
|
||||||
if: github.event_name == 'pull_request' # $GITHUB_EVENT_NAME
|
if: github.event_name == 'pull_request' # $GITHUB_EVENT_NAME
|
||||||
run: make check-c-globals
|
run: make check-c-globals
|
||||||
|
- name: Check for undocumented C APIs
|
||||||
|
run: make check-c-api-docs
|
||||||
|
|
||||||
|
|
||||||
build-windows:
|
build-windows:
|
||||||
name: >-
|
name: >-
|
||||||
|
|
@ -215,7 +208,6 @@ jobs:
|
||||||
free-threading: true
|
free-threading: true
|
||||||
uses: ./.github/workflows/reusable-macos.yml
|
uses: ./.github/workflows/reusable-macos.yml
|
||||||
with:
|
with:
|
||||||
config_hash: ${{ needs.build-context.outputs.config-hash }}
|
|
||||||
free-threading: ${{ matrix.free-threading }}
|
free-threading: ${{ matrix.free-threading }}
|
||||||
os: ${{ matrix.os }}
|
os: ${{ matrix.os }}
|
||||||
|
|
||||||
|
|
@ -247,7 +239,6 @@ jobs:
|
||||||
bolt: true
|
bolt: true
|
||||||
uses: ./.github/workflows/reusable-ubuntu.yml
|
uses: ./.github/workflows/reusable-ubuntu.yml
|
||||||
with:
|
with:
|
||||||
config_hash: ${{ needs.build-context.outputs.config-hash }}
|
|
||||||
bolt-optimizations: ${{ matrix.bolt }}
|
bolt-optimizations: ${{ matrix.bolt }}
|
||||||
free-threading: ${{ matrix.free-threading }}
|
free-threading: ${{ matrix.free-threading }}
|
||||||
os: ${{ matrix.os }}
|
os: ${{ matrix.os }}
|
||||||
|
|
@ -278,11 +269,6 @@ jobs:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Runner image version
|
- name: Runner image version
|
||||||
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
|
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
|
||||||
- name: Restore config.cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: config.cache
|
|
||||||
key: ${{ github.job }}-${{ env.IMAGE_OS_VERSION }}-${{ needs.build-context.outputs.config-hash }}
|
|
||||||
- name: Register gcc problem matcher
|
- name: Register gcc problem matcher
|
||||||
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
|
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
|
@ -304,10 +290,6 @@ jobs:
|
||||||
- name: Add ccache to PATH
|
- name: Add ccache to PATH
|
||||||
run: |
|
run: |
|
||||||
echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
|
echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
|
||||||
- name: Configure ccache action
|
|
||||||
uses: hendrikmuhs/ccache-action@v1.2
|
|
||||||
with:
|
|
||||||
save: false
|
|
||||||
- name: Configure CPython
|
- name: Configure CPython
|
||||||
run: ./configure CFLAGS="-fdiagnostics-format=json" --config-cache --enable-slower-safety --with-pydebug --with-openssl="$OPENSSL_DIR"
|
run: ./configure CFLAGS="-fdiagnostics-format=json" --config-cache --enable-slower-safety --with-pydebug --with-openssl="$OPENSSL_DIR"
|
||||||
- name: Build CPython
|
- name: Build CPython
|
||||||
|
|
@ -339,11 +321,6 @@ jobs:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Runner image version
|
- name: Runner image version
|
||||||
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
|
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
|
||||||
- name: Restore config.cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: config.cache
|
|
||||||
key: ${{ github.job }}-${{ env.IMAGE_OS_VERSION }}-${{ needs.build-context.outputs.config-hash }}
|
|
||||||
- name: Register gcc problem matcher
|
- name: Register gcc problem matcher
|
||||||
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
|
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
|
@ -370,10 +347,6 @@ jobs:
|
||||||
- name: Add ccache to PATH
|
- name: Add ccache to PATH
|
||||||
run: |
|
run: |
|
||||||
echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
|
echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
|
||||||
- name: Configure ccache action
|
|
||||||
uses: hendrikmuhs/ccache-action@v1.2
|
|
||||||
with:
|
|
||||||
save: false
|
|
||||||
- name: Configure CPython
|
- name: Configure CPython
|
||||||
run: |
|
run: |
|
||||||
./configure CFLAGS="-fdiagnostics-format=json" \
|
./configure CFLAGS="-fdiagnostics-format=json" \
|
||||||
|
|
@ -442,8 +415,6 @@ jobs:
|
||||||
needs: build-context
|
needs: build-context
|
||||||
if: needs.build-context.outputs.run-tests == 'true'
|
if: needs.build-context.outputs.run-tests == 'true'
|
||||||
uses: ./.github/workflows/reusable-wasi.yml
|
uses: ./.github/workflows/reusable-wasi.yml
|
||||||
with:
|
|
||||||
config_hash: ${{ needs.build-context.outputs.config-hash }}
|
|
||||||
|
|
||||||
test-hypothesis:
|
test-hypothesis:
|
||||||
name: "Hypothesis tests on Ubuntu"
|
name: "Hypothesis tests on Ubuntu"
|
||||||
|
|
@ -479,10 +450,6 @@ jobs:
|
||||||
- name: Add ccache to PATH
|
- name: Add ccache to PATH
|
||||||
run: |
|
run: |
|
||||||
echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
|
echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
|
||||||
- name: Configure ccache action
|
|
||||||
uses: hendrikmuhs/ccache-action@v1.2
|
|
||||||
with:
|
|
||||||
save: false
|
|
||||||
- name: Setup directory envs for out-of-tree builds
|
- name: Setup directory envs for out-of-tree builds
|
||||||
run: |
|
run: |
|
||||||
echo "CPYTHON_RO_SRCDIR=$(realpath -m "${GITHUB_WORKSPACE}"/../cpython-ro-srcdir)" >> "$GITHUB_ENV"
|
echo "CPYTHON_RO_SRCDIR=$(realpath -m "${GITHUB_WORKSPACE}"/../cpython-ro-srcdir)" >> "$GITHUB_ENV"
|
||||||
|
|
@ -493,11 +460,6 @@ jobs:
|
||||||
run: sudo mount --bind -o ro "$GITHUB_WORKSPACE" "$CPYTHON_RO_SRCDIR"
|
run: sudo mount --bind -o ro "$GITHUB_WORKSPACE" "$CPYTHON_RO_SRCDIR"
|
||||||
- name: Runner image version
|
- name: Runner image version
|
||||||
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
|
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
|
||||||
- name: Restore config.cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: ${{ env.CPYTHON_BUILDDIR }}/config.cache
|
|
||||||
key: ${{ github.job }}-${{ env.IMAGE_OS_VERSION }}-${{ needs.build-context.outputs.config-hash }}
|
|
||||||
- name: Configure CPython out-of-tree
|
- name: Configure CPython out-of-tree
|
||||||
working-directory: ${{ env.CPYTHON_BUILDDIR }}
|
working-directory: ${{ env.CPYTHON_BUILDDIR }}
|
||||||
run: |
|
run: |
|
||||||
|
|
@ -581,11 +543,6 @@ jobs:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Runner image version
|
- name: Runner image version
|
||||||
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
|
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
|
||||||
- name: Restore config.cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: config.cache
|
|
||||||
key: ${{ github.job }}-${{ env.IMAGE_OS_VERSION }}-${{ needs.build-context.outputs.config-hash }}
|
|
||||||
- name: Register gcc problem matcher
|
- name: Register gcc problem matcher
|
||||||
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
|
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
|
@ -611,11 +568,6 @@ jobs:
|
||||||
- name: Add ccache to PATH
|
- name: Add ccache to PATH
|
||||||
run: |
|
run: |
|
||||||
echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
|
echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
|
||||||
- name: Configure ccache action
|
|
||||||
uses: hendrikmuhs/ccache-action@v1.2
|
|
||||||
with:
|
|
||||||
save: ${{ github.event_name == 'push' }}
|
|
||||||
max-size: "200M"
|
|
||||||
- name: Configure CPython
|
- name: Configure CPython
|
||||||
run: ./configure --config-cache --with-address-sanitizer --without-pymalloc
|
run: ./configure --config-cache --with-address-sanitizer --without-pymalloc
|
||||||
- name: Build CPython
|
- name: Build CPython
|
||||||
|
|
@ -647,7 +599,6 @@ jobs:
|
||||||
uses: ./.github/workflows/reusable-san.yml
|
uses: ./.github/workflows/reusable-san.yml
|
||||||
with:
|
with:
|
||||||
sanitizer: ${{ matrix.sanitizer }}
|
sanitizer: ${{ matrix.sanitizer }}
|
||||||
config_hash: ${{ needs.build-context.outputs.config-hash }}
|
|
||||||
free-threading: ${{ matrix.free-threading }}
|
free-threading: ${{ matrix.free-threading }}
|
||||||
|
|
||||||
cross-build-linux:
|
cross-build-linux:
|
||||||
|
|
@ -662,11 +613,6 @@ jobs:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Runner image version
|
- name: Runner image version
|
||||||
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
|
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
|
||||||
- name: Restore config.cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: config.cache
|
|
||||||
key: ${{ github.job }}-${{ env.IMAGE_OS_VERSION }}-${{ needs.build-context.outputs.config-hash }}
|
|
||||||
- name: Register gcc problem matcher
|
- name: Register gcc problem matcher
|
||||||
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
|
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
|
||||||
- name: Set build dir
|
- name: Set build dir
|
||||||
|
|
|
||||||
30
.github/workflows/jit.yml
vendored
30
.github/workflows/jit.yml
vendored
|
|
@ -68,7 +68,7 @@ jobs:
|
||||||
- true
|
- true
|
||||||
- false
|
- false
|
||||||
llvm:
|
llvm:
|
||||||
- 20
|
- 21
|
||||||
include:
|
include:
|
||||||
- target: i686-pc-windows-msvc/msvc
|
- target: i686-pc-windows-msvc/msvc
|
||||||
architecture: Win32
|
architecture: Win32
|
||||||
|
|
@ -138,7 +138,7 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
llvm:
|
llvm:
|
||||||
- 20
|
- 21
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
|
|
@ -166,7 +166,7 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
llvm:
|
llvm:
|
||||||
- 20
|
- 21
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
|
|
@ -183,3 +183,27 @@ jobs:
|
||||||
- name: Run tests without optimizations
|
- name: Run tests without optimizations
|
||||||
run: |
|
run: |
|
||||||
PYTHON_UOPS_OPTIMIZE=0 ./python -m test --multiprocess 0 --timeout 4500 --verbose2 --verbose3
|
PYTHON_UOPS_OPTIMIZE=0 ./python -m test --multiprocess 0 --timeout 4500 --verbose2 --verbose3
|
||||||
|
|
||||||
|
tail-call-jit:
|
||||||
|
name: JIT with tail calling interpreter
|
||||||
|
needs: interpreter
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
timeout-minutes: 90
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
llvm:
|
||||||
|
- 21
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
- uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: '3.11'
|
||||||
|
- name: Build with JIT and tailcall
|
||||||
|
run: |
|
||||||
|
sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" ./llvm.sh ${{ matrix.llvm }}
|
||||||
|
export PATH="$(llvm-config-${{ matrix.llvm }} --bindir):$PATH"
|
||||||
|
CC=clang-${{ matrix.llvm }} ./configure --enable-experimental-jit --with-tail-call-interp --with-pydebug
|
||||||
|
make all --jobs 4
|
||||||
|
|
|
||||||
9
.github/workflows/reusable-context.yml
vendored
9
.github/workflows/reusable-context.yml
vendored
|
|
@ -17,9 +17,6 @@ on: # yamllint disable-line rule:truthy
|
||||||
# || 'falsy-branch'
|
# || 'falsy-branch'
|
||||||
# }}
|
# }}
|
||||||
#
|
#
|
||||||
config-hash:
|
|
||||||
description: Config hash value for use in cache keys
|
|
||||||
value: ${{ jobs.compute-changes.outputs.config-hash }} # str
|
|
||||||
run-docs:
|
run-docs:
|
||||||
description: Whether to build the docs
|
description: Whether to build the docs
|
||||||
value: ${{ jobs.compute-changes.outputs.run-docs }} # bool
|
value: ${{ jobs.compute-changes.outputs.run-docs }} # bool
|
||||||
|
|
@ -42,7 +39,6 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
outputs:
|
outputs:
|
||||||
config-hash: ${{ steps.config-hash.outputs.hash }}
|
|
||||||
run-ci-fuzz: ${{ steps.changes.outputs.run-ci-fuzz }}
|
run-ci-fuzz: ${{ steps.changes.outputs.run-ci-fuzz }}
|
||||||
run-docs: ${{ steps.changes.outputs.run-docs }}
|
run-docs: ${{ steps.changes.outputs.run-docs }}
|
||||||
run-tests: ${{ steps.changes.outputs.run-tests }}
|
run-tests: ${{ steps.changes.outputs.run-tests }}
|
||||||
|
|
@ -100,8 +96,3 @@ jobs:
|
||||||
GITHUB_EVENT_NAME: ${{ github.event_name }}
|
GITHUB_EVENT_NAME: ${{ github.event_name }}
|
||||||
CCF_TARGET_REF: ${{ github.base_ref || github.event.repository.default_branch }}
|
CCF_TARGET_REF: ${{ github.base_ref || github.event.repository.default_branch }}
|
||||||
CCF_HEAD_REF: ${{ github.event.pull_request.head.sha || github.sha }}
|
CCF_HEAD_REF: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||||
|
|
||||||
- name: Compute hash for config cache key
|
|
||||||
id: config-hash
|
|
||||||
run: |
|
|
||||||
echo "hash=${{ hashFiles('configure', 'configure.ac', '.github/workflows/build.yml') }}" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
|
||||||
8
.github/workflows/reusable-macos.yml
vendored
8
.github/workflows/reusable-macos.yml
vendored
|
|
@ -3,9 +3,6 @@ name: Reusable macOS
|
||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
inputs:
|
inputs:
|
||||||
config_hash:
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
free-threading:
|
free-threading:
|
||||||
required: false
|
required: false
|
||||||
type: boolean
|
type: boolean
|
||||||
|
|
@ -36,11 +33,6 @@ jobs:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Runner image version
|
- name: Runner image version
|
||||||
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
|
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
|
||||||
- name: Restore config.cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: config.cache
|
|
||||||
key: ${{ github.job }}-${{ env.IMAGE_OS_VERSION }}-${{ inputs.config_hash }}
|
|
||||||
- name: Install Homebrew dependencies
|
- name: Install Homebrew dependencies
|
||||||
run: |
|
run: |
|
||||||
brew install pkg-config openssl@3.0 xz gdbm tcl-tk@9 make
|
brew install pkg-config openssl@3.0 xz gdbm tcl-tk@9 make
|
||||||
|
|
|
||||||
13
.github/workflows/reusable-san.yml
vendored
13
.github/workflows/reusable-san.yml
vendored
|
|
@ -6,9 +6,6 @@ on:
|
||||||
sanitizer:
|
sanitizer:
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
config_hash:
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
free-threading:
|
free-threading:
|
||||||
description: Whether to use free-threaded mode
|
description: Whether to use free-threaded mode
|
||||||
required: false
|
required: false
|
||||||
|
|
@ -34,11 +31,6 @@ jobs:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Runner image version
|
- name: Runner image version
|
||||||
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
|
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
|
||||||
- name: Restore config.cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: config.cache
|
|
||||||
key: ${{ github.job }}-${{ env.IMAGE_OS_VERSION }}-${{ inputs.sanitizer }}-${{ inputs.config_hash }}
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo ./.github/workflows/posix-deps-apt.sh
|
sudo ./.github/workflows/posix-deps-apt.sh
|
||||||
|
|
@ -77,11 +69,6 @@ jobs:
|
||||||
- name: Add ccache to PATH
|
- name: Add ccache to PATH
|
||||||
run: |
|
run: |
|
||||||
echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
|
echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
|
||||||
- name: Configure ccache action
|
|
||||||
uses: hendrikmuhs/ccache-action@v1.2
|
|
||||||
with:
|
|
||||||
save: ${{ github.event_name == 'push' }}
|
|
||||||
max-size: "200M"
|
|
||||||
- name: Configure CPython
|
- name: Configure CPython
|
||||||
run: >-
|
run: >-
|
||||||
./configure
|
./configure
|
||||||
|
|
|
||||||
13
.github/workflows/reusable-ubuntu.yml
vendored
13
.github/workflows/reusable-ubuntu.yml
vendored
|
|
@ -3,9 +3,6 @@ name: Reusable Ubuntu
|
||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
inputs:
|
inputs:
|
||||||
config_hash:
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
bolt-optimizations:
|
bolt-optimizations:
|
||||||
description: Whether to enable BOLT optimizations
|
description: Whether to enable BOLT optimizations
|
||||||
required: false
|
required: false
|
||||||
|
|
@ -64,11 +61,6 @@ jobs:
|
||||||
- name: Add ccache to PATH
|
- name: Add ccache to PATH
|
||||||
run: |
|
run: |
|
||||||
echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
|
echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
|
||||||
- name: Configure ccache action
|
|
||||||
uses: hendrikmuhs/ccache-action@v1.2
|
|
||||||
with:
|
|
||||||
save: ${{ github.event_name == 'push' }}
|
|
||||||
max-size: "200M"
|
|
||||||
- name: Setup directory envs for out-of-tree builds
|
- name: Setup directory envs for out-of-tree builds
|
||||||
run: |
|
run: |
|
||||||
echo "CPYTHON_RO_SRCDIR=$(realpath -m "${GITHUB_WORKSPACE}"/../cpython-ro-srcdir)" >> "$GITHUB_ENV"
|
echo "CPYTHON_RO_SRCDIR=$(realpath -m "${GITHUB_WORKSPACE}"/../cpython-ro-srcdir)" >> "$GITHUB_ENV"
|
||||||
|
|
@ -79,11 +71,6 @@ jobs:
|
||||||
run: sudo mount --bind -o ro "$GITHUB_WORKSPACE" "$CPYTHON_RO_SRCDIR"
|
run: sudo mount --bind -o ro "$GITHUB_WORKSPACE" "$CPYTHON_RO_SRCDIR"
|
||||||
- name: Runner image version
|
- name: Runner image version
|
||||||
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
|
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
|
||||||
- name: Restore config.cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: ${{ env.CPYTHON_BUILDDIR }}/config.cache
|
|
||||||
key: ${{ github.job }}-${{ env.IMAGE_OS_VERSION }}-${{ inputs.config_hash }}
|
|
||||||
- name: Configure CPython out-of-tree
|
- name: Configure CPython out-of-tree
|
||||||
working-directory: ${{ env.CPYTHON_BUILDDIR }}
|
working-directory: ${{ env.CPYTHON_BUILDDIR }}
|
||||||
# `test_unpickle_module_race` writes to the source directory, which is
|
# `test_unpickle_module_race` writes to the source directory, which is
|
||||||
|
|
|
||||||
33
.github/workflows/reusable-wasi.yml
vendored
33
.github/workflows/reusable-wasi.yml
vendored
|
|
@ -2,10 +2,6 @@ name: Reusable WASI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
inputs:
|
|
||||||
config_hash:
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
FORCE_COLOR: 1
|
FORCE_COLOR: 1
|
||||||
|
|
@ -17,7 +13,7 @@ jobs:
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
env:
|
env:
|
||||||
WASMTIME_VERSION: 38.0.3
|
WASMTIME_VERSION: 38.0.3
|
||||||
WASI_SDK_VERSION: 25
|
WASI_SDK_VERSION: 29
|
||||||
WASI_SDK_PATH: /opt/wasi-sdk
|
WASI_SDK_PATH: /opt/wasi-sdk
|
||||||
CROSS_BUILD_PYTHON: cross-build/build
|
CROSS_BUILD_PYTHON: cross-build/build
|
||||||
CROSS_BUILD_WASI: cross-build/wasm32-wasip1
|
CROSS_BUILD_WASI: cross-build/wasm32-wasip1
|
||||||
|
|
@ -42,11 +38,6 @@ jobs:
|
||||||
mkdir "${WASI_SDK_PATH}" && \
|
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-arm64-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
|
tar --strip-components 1 --directory "${WASI_SDK_PATH}" --extract --gunzip
|
||||||
- name: "Configure ccache action"
|
|
||||||
uses: hendrikmuhs/ccache-action@v1.2
|
|
||||||
with:
|
|
||||||
save: ${{ github.event_name == 'push' }}
|
|
||||||
max-size: "200M"
|
|
||||||
- name: "Add ccache to PATH"
|
- name: "Add ccache to PATH"
|
||||||
run: echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
|
run: echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
|
||||||
- name: "Install Python"
|
- name: "Install Python"
|
||||||
|
|
@ -55,29 +46,15 @@ jobs:
|
||||||
python-version: '3.x'
|
python-version: '3.x'
|
||||||
- name: "Runner image version"
|
- name: "Runner image version"
|
||||||
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
|
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
|
||||||
- name: "Restore Python build config.cache"
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: ${{ env.CROSS_BUILD_PYTHON }}/config.cache
|
|
||||||
# Include env.pythonLocation in key to avoid changes in environment when setup-python updates Python.
|
|
||||||
# Include the hash of `Tools/wasm/wasi.py` as it may change the environment variables.
|
|
||||||
# (Make sure to keep the key in sync with the other config.cache step below.)
|
|
||||||
key: ${{ github.job }}-${{ env.IMAGE_OS_VERSION }}-${{ env.WASI_SDK_VERSION }}-${{ env.WASMTIME_VERSION }}-${{ inputs.config_hash }}-${{ hashFiles('Tools/wasm/wasi.py') }}-${{ env.pythonLocation }}
|
|
||||||
- name: "Configure build Python"
|
- name: "Configure build Python"
|
||||||
run: python3 Tools/wasm/wasi.py configure-build-python -- --config-cache --with-pydebug
|
run: python3 Tools/wasm/wasi configure-build-python -- --config-cache --with-pydebug
|
||||||
- name: "Make build Python"
|
- name: "Make build Python"
|
||||||
run: python3 Tools/wasm/wasi.py make-build-python
|
run: python3 Tools/wasm/wasi make-build-python
|
||||||
- name: "Restore host config.cache"
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: ${{ env.CROSS_BUILD_WASI }}/config.cache
|
|
||||||
# Should be kept in sync with the other config.cache step above.
|
|
||||||
key: ${{ github.job }}-${{ env.IMAGE_OS_VERSION }}-${{ env.WASI_SDK_VERSION }}-${{ env.WASMTIME_VERSION }}-${{ inputs.config_hash }}-${{ hashFiles('Tools/wasm/wasi.py') }}-${{ env.pythonLocation }}
|
|
||||||
- name: "Configure host"
|
- name: "Configure host"
|
||||||
# `--with-pydebug` inferred from configure-build-python
|
# `--with-pydebug` inferred from configure-build-python
|
||||||
run: python3 Tools/wasm/wasi.py configure-host -- --config-cache
|
run: python3 Tools/wasm/wasi configure-host -- --config-cache
|
||||||
- name: "Make host"
|
- name: "Make host"
|
||||||
run: python3 Tools/wasm/wasi.py make-host
|
run: python3 Tools/wasm/wasi make-host
|
||||||
- name: "Display build info"
|
- name: "Display build info"
|
||||||
run: make --directory "${CROSS_BUILD_WASI}" pythoninfo
|
run: make --directory "${CROSS_BUILD_WASI}" pythoninfo
|
||||||
- name: "Test"
|
- name: "Test"
|
||||||
|
|
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -135,7 +135,6 @@ Tools/unicode/data/
|
||||||
/config.log
|
/config.log
|
||||||
/config.status
|
/config.status
|
||||||
/config.status.lineno
|
/config.status.lineno
|
||||||
# hendrikmuhs/ccache-action@v1
|
|
||||||
/.ccache
|
/.ccache
|
||||||
/cross-build/
|
/cross-build/
|
||||||
/jit_stencils*.h
|
/jit_stencils*.h
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,10 @@ repos:
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
rev: v0.13.2
|
rev: v0.13.2
|
||||||
hooks:
|
hooks:
|
||||||
|
- id: ruff-check
|
||||||
|
name: Run Ruff (lint) on Apple/
|
||||||
|
args: [--exit-non-zero-on-fix, --config=Apple/.ruff.toml]
|
||||||
|
files: ^Apple/
|
||||||
- id: ruff-check
|
- id: ruff-check
|
||||||
name: Run Ruff (lint) on Doc/
|
name: Run Ruff (lint) on Doc/
|
||||||
args: [--exit-non-zero-on-fix]
|
args: [--exit-non-zero-on-fix]
|
||||||
|
|
@ -30,6 +34,10 @@ repos:
|
||||||
name: Run Ruff (lint) on Tools/wasm/
|
name: Run Ruff (lint) on Tools/wasm/
|
||||||
args: [--exit-non-zero-on-fix, --config=Tools/wasm/.ruff.toml]
|
args: [--exit-non-zero-on-fix, --config=Tools/wasm/.ruff.toml]
|
||||||
files: ^Tools/wasm/
|
files: ^Tools/wasm/
|
||||||
|
- id: ruff-format
|
||||||
|
name: Run Ruff (format) on Apple/
|
||||||
|
args: [--exit-non-zero-on-fix, --config=Apple/.ruff.toml]
|
||||||
|
files: ^Apple
|
||||||
- id: ruff-format
|
- id: ruff-format
|
||||||
name: Run Ruff (format) on Doc/
|
name: Run Ruff (format) on Doc/
|
||||||
args: [--check]
|
args: [--check]
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
ANDROID_DIR.name == "Android" and (PYTHON_DIR / "pyconfig.h.in").exists()
|
ANDROID_DIR.name == "Android" and (PYTHON_DIR / "pyconfig.h.in").exists()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ENV_SCRIPT = ANDROID_DIR / "android-env.sh"
|
||||||
TESTBED_DIR = ANDROID_DIR / "testbed"
|
TESTBED_DIR = ANDROID_DIR / "testbed"
|
||||||
CROSS_BUILD_DIR = PYTHON_DIR / "cross-build"
|
CROSS_BUILD_DIR = PYTHON_DIR / "cross-build"
|
||||||
|
|
||||||
|
|
@ -129,12 +130,11 @@ def android_env(host):
|
||||||
sysconfig_filename = next(sysconfig_files).name
|
sysconfig_filename = next(sysconfig_files).name
|
||||||
host = re.fullmatch(r"_sysconfigdata__android_(.+).py", sysconfig_filename)[1]
|
host = re.fullmatch(r"_sysconfigdata__android_(.+).py", sysconfig_filename)[1]
|
||||||
|
|
||||||
env_script = ANDROID_DIR / "android-env.sh"
|
|
||||||
env_output = subprocess.run(
|
env_output = subprocess.run(
|
||||||
f"set -eu; "
|
f"set -eu; "
|
||||||
f"HOST={host}; "
|
f"HOST={host}; "
|
||||||
f"PREFIX={prefix}; "
|
f"PREFIX={prefix}; "
|
||||||
f". {env_script}; "
|
f". {ENV_SCRIPT}; "
|
||||||
f"export",
|
f"export",
|
||||||
check=True, shell=True, capture_output=True, encoding='utf-8',
|
check=True, shell=True, capture_output=True, encoding='utf-8',
|
||||||
).stdout
|
).stdout
|
||||||
|
|
@ -151,7 +151,7 @@ def android_env(host):
|
||||||
env[key] = value
|
env[key] = value
|
||||||
|
|
||||||
if not env:
|
if not env:
|
||||||
raise ValueError(f"Found no variables in {env_script.name} output:\n"
|
raise ValueError(f"Found no variables in {ENV_SCRIPT.name} output:\n"
|
||||||
+ env_output)
|
+ env_output)
|
||||||
return env
|
return env
|
||||||
|
|
||||||
|
|
@ -281,15 +281,30 @@ def clean_all(context):
|
||||||
|
|
||||||
|
|
||||||
def setup_ci():
|
def setup_ci():
|
||||||
# https://github.blog/changelog/2024-04-02-github-actions-hardware-accelerated-android-virtualization-now-available/
|
if "GITHUB_ACTIONS" in os.environ:
|
||||||
if "GITHUB_ACTIONS" in os.environ and platform.system() == "Linux":
|
# Enable emulator hardware acceleration
|
||||||
run(
|
# (https://github.blog/changelog/2024-04-02-github-actions-hardware-accelerated-android-virtualization-now-available/).
|
||||||
["sudo", "tee", "/etc/udev/rules.d/99-kvm4all.rules"],
|
if platform.system() == "Linux":
|
||||||
input='KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"\n',
|
run(
|
||||||
text=True,
|
["sudo", "tee", "/etc/udev/rules.d/99-kvm4all.rules"],
|
||||||
)
|
input='KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"\n',
|
||||||
run(["sudo", "udevadm", "control", "--reload-rules"])
|
text=True,
|
||||||
run(["sudo", "udevadm", "trigger", "--name-match=kvm"])
|
)
|
||||||
|
run(["sudo", "udevadm", "control", "--reload-rules"])
|
||||||
|
run(["sudo", "udevadm", "trigger", "--name-match=kvm"])
|
||||||
|
|
||||||
|
# Free up disk space by deleting unused versions of the NDK
|
||||||
|
# (https://github.com/freakboy3742/pyspamsum/pull/108).
|
||||||
|
for line in ENV_SCRIPT.read_text().splitlines():
|
||||||
|
if match := re.fullmatch(r"ndk_version=(.+)", line):
|
||||||
|
ndk_version = match[1]
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Failed to find NDK version in {ENV_SCRIPT.name}")
|
||||||
|
|
||||||
|
for item in (android_home / "ndk").iterdir():
|
||||||
|
if item.name[0].isdigit() and item.name != ndk_version:
|
||||||
|
delete_glob(item)
|
||||||
|
|
||||||
|
|
||||||
def setup_sdk():
|
def setup_sdk():
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ android {
|
||||||
val androidEnvFile = file("../../android-env.sh").absoluteFile
|
val androidEnvFile = file("../../android-env.sh").absoluteFile
|
||||||
|
|
||||||
namespace = "org.python.testbed"
|
namespace = "org.python.testbed"
|
||||||
compileSdk = 34
|
compileSdk = 35
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "org.python.testbed"
|
applicationId = "org.python.testbed"
|
||||||
|
|
@ -92,7 +92,7 @@ android {
|
||||||
}
|
}
|
||||||
throw GradleException("Failed to find API level in $androidEnvFile")
|
throw GradleException("Failed to find API level in $androidEnvFile")
|
||||||
}
|
}
|
||||||
targetSdk = 34
|
targetSdk = 35
|
||||||
|
|
||||||
versionCode = 1
|
versionCode = 1
|
||||||
versionName = "1.0"
|
versionName = "1.0"
|
||||||
|
|
|
||||||
22
Apple/.ruff.toml
Normal file
22
Apple/.ruff.toml
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
extend = "../.ruff.toml" # Inherit the project-wide settings
|
||||||
|
|
||||||
|
[format]
|
||||||
|
preview = true
|
||||||
|
docstring-code-format = true
|
||||||
|
|
||||||
|
[lint]
|
||||||
|
select = [
|
||||||
|
"C4", # flake8-comprehensions
|
||||||
|
"E", # pycodestyle
|
||||||
|
"F", # pyflakes
|
||||||
|
"I", # isort
|
||||||
|
"ISC", # flake8-implicit-str-concat
|
||||||
|
"LOG", # flake8-logging
|
||||||
|
"PGH", # pygrep-hooks
|
||||||
|
"PT", # flake8-pytest-style
|
||||||
|
"PYI", # flake8-pyi
|
||||||
|
"RUF100", # Ban unused `# noqa` comments
|
||||||
|
"UP", # pyupgrade
|
||||||
|
"W", # pycodestyle
|
||||||
|
"YTT", # flake8-2020
|
||||||
|
]
|
||||||
|
|
@ -46,13 +46,12 @@
|
||||||
import sys
|
import sys
|
||||||
import sysconfig
|
import sysconfig
|
||||||
import time
|
import time
|
||||||
from collections.abc import Sequence
|
from collections.abc import Callable, Sequence
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from os.path import basename, relpath
|
from os.path import basename, relpath
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from subprocess import CalledProcessError
|
from subprocess import CalledProcessError
|
||||||
from typing import Callable
|
|
||||||
|
|
||||||
EnvironmentT = dict[str, str]
|
EnvironmentT = dict[str, str]
|
||||||
ArgsT = Sequence[str | Path]
|
ArgsT = Sequence[str | Path]
|
||||||
|
|
@ -140,17 +139,15 @@ def print_env(env: EnvironmentT) -> None:
|
||||||
def apple_env(host: str) -> EnvironmentT:
|
def apple_env(host: str) -> EnvironmentT:
|
||||||
"""Construct an Apple development environment for the given host."""
|
"""Construct an Apple development environment for the given host."""
|
||||||
env = {
|
env = {
|
||||||
"PATH": ":".join(
|
"PATH": ":".join([
|
||||||
[
|
str(PYTHON_DIR / "Apple/iOS/Resources/bin"),
|
||||||
str(PYTHON_DIR / "Apple/iOS/Resources/bin"),
|
str(subdir(host) / "prefix"),
|
||||||
str(subdir(host) / "prefix"),
|
"/usr/bin",
|
||||||
"/usr/bin",
|
"/bin",
|
||||||
"/bin",
|
"/usr/sbin",
|
||||||
"/usr/sbin",
|
"/sbin",
|
||||||
"/sbin",
|
"/Library/Apple/usr/bin",
|
||||||
"/Library/Apple/usr/bin",
|
]),
|
||||||
]
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return env
|
return env
|
||||||
|
|
@ -196,14 +193,10 @@ def clean(context: argparse.Namespace, target: str = "all") -> None:
|
||||||
paths.append(target)
|
paths.append(target)
|
||||||
|
|
||||||
if target in {"all", "hosts", "test"}:
|
if target in {"all", "hosts", "test"}:
|
||||||
paths.extend(
|
paths.extend([
|
||||||
[
|
path.name
|
||||||
path.name
|
for path in CROSS_BUILD_DIR.glob(f"{context.platform}-testbed.*")
|
||||||
for path in CROSS_BUILD_DIR.glob(
|
])
|
||||||
f"{context.platform}-testbed.*"
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
for path in paths:
|
for path in paths:
|
||||||
delete_path(path)
|
delete_path(path)
|
||||||
|
|
@ -352,18 +345,16 @@ def download(url: str, target_dir: Path) -> Path:
|
||||||
|
|
||||||
out_path = target_path / basename(url)
|
out_path = target_path / basename(url)
|
||||||
if not Path(out_path).is_file():
|
if not Path(out_path).is_file():
|
||||||
run(
|
run([
|
||||||
[
|
"curl",
|
||||||
"curl",
|
"-Lf",
|
||||||
"-Lf",
|
"--retry",
|
||||||
"--retry",
|
"5",
|
||||||
"5",
|
"--retry-all-errors",
|
||||||
"--retry-all-errors",
|
"-o",
|
||||||
"-o",
|
out_path,
|
||||||
out_path,
|
url,
|
||||||
url,
|
])
|
||||||
]
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
print(f"Using cached version of {basename(url)}")
|
print(f"Using cached version of {basename(url)}")
|
||||||
return out_path
|
return out_path
|
||||||
|
|
@ -468,8 +459,7 @@ def package_version(prefix_path: Path) -> str:
|
||||||
|
|
||||||
|
|
||||||
def lib_platform_files(dirname, names):
|
def lib_platform_files(dirname, names):
|
||||||
"""A file filter that ignores platform-specific files in the lib directory.
|
"""A file filter that ignores platform-specific files in lib."""
|
||||||
"""
|
|
||||||
path = Path(dirname)
|
path = Path(dirname)
|
||||||
if (
|
if (
|
||||||
path.parts[-3] == "lib"
|
path.parts[-3] == "lib"
|
||||||
|
|
@ -478,7 +468,7 @@ def lib_platform_files(dirname, names):
|
||||||
):
|
):
|
||||||
return names
|
return names
|
||||||
elif path.parts[-2] == "lib" and path.parts[-1].startswith("python"):
|
elif path.parts[-2] == "lib" and path.parts[-1].startswith("python"):
|
||||||
ignored_names = set(
|
ignored_names = {
|
||||||
name
|
name
|
||||||
for name in names
|
for name in names
|
||||||
if (
|
if (
|
||||||
|
|
@ -486,7 +476,13 @@ def lib_platform_files(dirname, names):
|
||||||
or name.startswith("_sysconfig_vars_")
|
or name.startswith("_sysconfig_vars_")
|
||||||
or name == "build-details.json"
|
or name == "build-details.json"
|
||||||
)
|
)
|
||||||
)
|
}
|
||||||
|
elif path.parts[-1] == "lib":
|
||||||
|
ignored_names = {
|
||||||
|
name
|
||||||
|
for name in names
|
||||||
|
if name.startswith("libpython") and name.endswith(".dylib")
|
||||||
|
}
|
||||||
else:
|
else:
|
||||||
ignored_names = set()
|
ignored_names = set()
|
||||||
|
|
||||||
|
|
@ -499,7 +495,9 @@ def lib_non_platform_files(dirname, names):
|
||||||
"""
|
"""
|
||||||
path = Path(dirname)
|
path = Path(dirname)
|
||||||
if path.parts[-2] == "lib" and path.parts[-1].startswith("python"):
|
if path.parts[-2] == "lib" and path.parts[-1].startswith("python"):
|
||||||
return set(names) - lib_platform_files(dirname, names) - {"lib-dynload"}
|
return (
|
||||||
|
set(names) - lib_platform_files(dirname, names) - {"lib-dynload"}
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
return set()
|
return set()
|
||||||
|
|
||||||
|
|
@ -507,14 +505,15 @@ def lib_non_platform_files(dirname, names):
|
||||||
def create_xcframework(platform: str) -> str:
|
def create_xcframework(platform: str) -> str:
|
||||||
"""Build an XCframework from the component parts for the platform.
|
"""Build an XCframework from the component parts for the platform.
|
||||||
|
|
||||||
:return: The version number of the Python verion that was packaged.
|
:return: The version number of the Python version that was packaged.
|
||||||
"""
|
"""
|
||||||
package_path = CROSS_BUILD_DIR / platform
|
package_path = CROSS_BUILD_DIR / platform
|
||||||
try:
|
try:
|
||||||
package_path.mkdir()
|
package_path.mkdir()
|
||||||
except FileExistsError:
|
except FileExistsError:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
f"{platform} XCframework already exists; do you need to run with --clean?"
|
f"{platform} XCframework already exists; do you need to run "
|
||||||
|
"with --clean?"
|
||||||
) from None
|
) from None
|
||||||
|
|
||||||
frameworks = []
|
frameworks = []
|
||||||
|
|
@ -607,7 +606,7 @@ def create_xcframework(platform: str) -> str:
|
||||||
print(f" - {slice_name} binaries")
|
print(f" - {slice_name} binaries")
|
||||||
shutil.copytree(first_path / "bin", slice_path / "bin")
|
shutil.copytree(first_path / "bin", slice_path / "bin")
|
||||||
|
|
||||||
# Copy the include path (this will be a symlink to the framework headers)
|
# Copy the include path (a symlink to the framework headers)
|
||||||
print(f" - {slice_name} include files")
|
print(f" - {slice_name} include files")
|
||||||
shutil.copytree(
|
shutil.copytree(
|
||||||
first_path / "include",
|
first_path / "include",
|
||||||
|
|
@ -621,6 +620,12 @@ def create_xcframework(platform: str) -> str:
|
||||||
slice_framework / "Headers/pyconfig.h",
|
slice_framework / "Headers/pyconfig.h",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
print(f" - {slice_name} shared library")
|
||||||
|
# Create a simlink for the fat library
|
||||||
|
shared_lib = slice_path / f"lib/libpython{version_tag}.dylib"
|
||||||
|
shared_lib.parent.mkdir()
|
||||||
|
shared_lib.symlink_to("../Python.framework/Python")
|
||||||
|
|
||||||
print(f" - {slice_name} architecture-specific files")
|
print(f" - {slice_name} architecture-specific files")
|
||||||
for host_triple, multiarch in slice_parts.items():
|
for host_triple, multiarch in slice_parts.items():
|
||||||
print(f" - {multiarch} standard library")
|
print(f" - {multiarch} standard library")
|
||||||
|
|
@ -632,6 +637,7 @@ def create_xcframework(platform: str) -> str:
|
||||||
framework_path(host_triple, multiarch) / "lib",
|
framework_path(host_triple, multiarch) / "lib",
|
||||||
package_path / "Python.xcframework/lib",
|
package_path / "Python.xcframework/lib",
|
||||||
ignore=lib_platform_files,
|
ignore=lib_platform_files,
|
||||||
|
symlinks=True,
|
||||||
)
|
)
|
||||||
has_common_stdlib = True
|
has_common_stdlib = True
|
||||||
|
|
||||||
|
|
@ -639,6 +645,7 @@ def create_xcframework(platform: str) -> str:
|
||||||
framework_path(host_triple, multiarch) / "lib",
|
framework_path(host_triple, multiarch) / "lib",
|
||||||
slice_path / f"lib-{arch}",
|
slice_path / f"lib-{arch}",
|
||||||
ignore=lib_non_platform_files,
|
ignore=lib_non_platform_files,
|
||||||
|
symlinks=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Copy the host's pyconfig.h to an architecture-specific name.
|
# Copy the host's pyconfig.h to an architecture-specific name.
|
||||||
|
|
@ -659,7 +666,8 @@ def create_xcframework(platform: str) -> str:
|
||||||
# statically link those libraries into a Framework, you become
|
# statically link those libraries into a Framework, you become
|
||||||
# responsible for providing a privacy manifest for that framework.
|
# responsible for providing a privacy manifest for that framework.
|
||||||
xcprivacy_file = {
|
xcprivacy_file = {
|
||||||
"OpenSSL": subdir(host_triple) / "prefix/share/OpenSSL.xcprivacy"
|
"OpenSSL": subdir(host_triple)
|
||||||
|
/ "prefix/share/OpenSSL.xcprivacy"
|
||||||
}
|
}
|
||||||
print(f" - {multiarch} xcprivacy files")
|
print(f" - {multiarch} xcprivacy files")
|
||||||
for module, lib in [
|
for module, lib in [
|
||||||
|
|
@ -669,7 +677,8 @@ def create_xcframework(platform: str) -> str:
|
||||||
shutil.copy(
|
shutil.copy(
|
||||||
xcprivacy_file[lib],
|
xcprivacy_file[lib],
|
||||||
slice_path
|
slice_path
|
||||||
/ f"lib-{arch}/python{version_tag}/lib-dynload/{module}.xcprivacy",
|
/ f"lib-{arch}/python{version_tag}"
|
||||||
|
/ f"lib-dynload/{module}.xcprivacy",
|
||||||
)
|
)
|
||||||
|
|
||||||
print(" - build tools")
|
print(" - build tools")
|
||||||
|
|
@ -692,18 +701,16 @@ def package(context: argparse.Namespace) -> None:
|
||||||
|
|
||||||
# Clone testbed
|
# Clone testbed
|
||||||
print()
|
print()
|
||||||
run(
|
run([
|
||||||
[
|
sys.executable,
|
||||||
sys.executable,
|
"Apple/testbed",
|
||||||
"Apple/testbed",
|
"clone",
|
||||||
"clone",
|
"--platform",
|
||||||
"--platform",
|
context.platform,
|
||||||
context.platform,
|
"--framework",
|
||||||
"--framework",
|
CROSS_BUILD_DIR / context.platform / "Python.xcframework",
|
||||||
CROSS_BUILD_DIR / context.platform / "Python.xcframework",
|
CROSS_BUILD_DIR / context.platform / "testbed",
|
||||||
CROSS_BUILD_DIR / context.platform / "testbed",
|
])
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Build the final archive
|
# Build the final archive
|
||||||
archive_name = (
|
archive_name = (
|
||||||
|
|
@ -757,7 +764,7 @@ def build(context: argparse.Namespace, host: str | None = None) -> None:
|
||||||
package(context)
|
package(context)
|
||||||
|
|
||||||
|
|
||||||
def test(context: argparse.Namespace, host: str | None = None) -> None:
|
def test(context: argparse.Namespace, host: str | None = None) -> None: # noqa: PT028
|
||||||
"""The implementation of the "test" command."""
|
"""The implementation of the "test" command."""
|
||||||
if host is None:
|
if host is None:
|
||||||
host = context.host
|
host = context.host
|
||||||
|
|
@ -795,18 +802,16 @@ def test(context: argparse.Namespace, host: str | None = None) -> None:
|
||||||
/ f"Frameworks/{apple_multiarch(host)}"
|
/ f"Frameworks/{apple_multiarch(host)}"
|
||||||
)
|
)
|
||||||
|
|
||||||
run(
|
run([
|
||||||
[
|
sys.executable,
|
||||||
sys.executable,
|
"Apple/testbed",
|
||||||
"Apple/testbed",
|
"clone",
|
||||||
"clone",
|
"--platform",
|
||||||
"--platform",
|
context.platform,
|
||||||
context.platform,
|
"--framework",
|
||||||
"--framework",
|
framework_path,
|
||||||
framework_path,
|
testbed_dir,
|
||||||
testbed_dir,
|
])
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
run(
|
run(
|
||||||
[
|
[
|
||||||
|
|
@ -840,7 +845,7 @@ def apple_sim_host(platform_name: str) -> str:
|
||||||
"""Determine the native simulator target for this platform."""
|
"""Determine the native simulator target for this platform."""
|
||||||
for _, slice_parts in HOSTS[platform_name].items():
|
for _, slice_parts in HOSTS[platform_name].items():
|
||||||
for host_triple in slice_parts:
|
for host_triple in slice_parts:
|
||||||
parts = host_triple.split('-')
|
parts = host_triple.split("-")
|
||||||
if parts[0] == platform.machine() and parts[-1] == "simulator":
|
if parts[0] == platform.machine() and parts[-1] == "simulator":
|
||||||
return host_triple
|
return host_triple
|
||||||
|
|
||||||
|
|
@ -968,20 +973,29 @@ def parse_args() -> argparse.Namespace:
|
||||||
cmd.add_argument(
|
cmd.add_argument(
|
||||||
"--simulator",
|
"--simulator",
|
||||||
help=(
|
help=(
|
||||||
"The name of the simulator to use (eg: 'iPhone 16e'). Defaults to "
|
"The name of the simulator to use (eg: 'iPhone 16e'). "
|
||||||
"the most recently released 'entry level' iPhone device. Device "
|
"Defaults to the most recently released 'entry level' "
|
||||||
"architecture and OS version can also be specified; e.g., "
|
"iPhone device. Device architecture and OS version can also "
|
||||||
"`--simulator 'iPhone 16 Pro,arch=arm64,OS=26.0'` would run on "
|
"be specified; e.g., "
|
||||||
"an ARM64 iPhone 16 Pro simulator running iOS 26.0."
|
"`--simulator 'iPhone 16 Pro,arch=arm64,OS=26.0'` would "
|
||||||
|
"run on an ARM64 iPhone 16 Pro simulator running iOS 26.0."
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
group = cmd.add_mutually_exclusive_group()
|
group = cmd.add_mutually_exclusive_group()
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"--fast-ci", action="store_const", dest="ci_mode", const="fast",
|
"--fast-ci",
|
||||||
help="Add test arguments for GitHub Actions")
|
action="store_const",
|
||||||
|
dest="ci_mode",
|
||||||
|
const="fast",
|
||||||
|
help="Add test arguments for GitHub Actions",
|
||||||
|
)
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"--slow-ci", action="store_const", dest="ci_mode", const="slow",
|
"--slow-ci",
|
||||||
help="Add test arguments for buildbots")
|
action="store_const",
|
||||||
|
dest="ci_mode",
|
||||||
|
const="slow",
|
||||||
|
help="Add test arguments for buildbots",
|
||||||
|
)
|
||||||
|
|
||||||
for subcommand in [configure_build, configure_host, build, ci]:
|
for subcommand in [configure_build, configure_host, build, ci]:
|
||||||
subcommand.add_argument(
|
subcommand.add_argument(
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,8 @@ install_stdlib() {
|
||||||
rsync -au --delete "$PROJECT_DIR/$PYTHON_XCFRAMEWORK_PATH/lib/" "$CODESIGNING_FOLDER_PATH/python/lib/"
|
rsync -au --delete "$PROJECT_DIR/$PYTHON_XCFRAMEWORK_PATH/lib/" "$CODESIGNING_FOLDER_PATH/python/lib/"
|
||||||
rsync -au "$PROJECT_DIR/$PYTHON_XCFRAMEWORK_PATH/$SLICE_FOLDER/lib-$ARCHS/" "$CODESIGNING_FOLDER_PATH/python/lib/"
|
rsync -au "$PROJECT_DIR/$PYTHON_XCFRAMEWORK_PATH/$SLICE_FOLDER/lib-$ARCHS/" "$CODESIGNING_FOLDER_PATH/python/lib/"
|
||||||
else
|
else
|
||||||
rsync -au --delete "$PROJECT_DIR/$PYTHON_XCFRAMEWORK_PATH/$SLICE_FOLDER/lib/" "$CODESIGNING_FOLDER_PATH/python/lib/"
|
# A single-arch framework will have a libpython symlink; that can't be included at runtime
|
||||||
|
rsync -au --delete "$PROJECT_DIR/$PYTHON_XCFRAMEWORK_PATH/$SLICE_FOLDER/lib/" "$CODESIGNING_FOLDER_PATH/python/lib/" --exclude 'libpython*.dylib'
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import shlex
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
@ -31,15 +32,15 @@ def select_simulator_device(platform):
|
||||||
json_data = json.loads(raw_json)
|
json_data = json.loads(raw_json)
|
||||||
|
|
||||||
if platform == "iOS":
|
if platform == "iOS":
|
||||||
# Any iOS device will do; we'll look for "SE" devices - but the name isn't
|
# Any iOS device will do; we'll look for "SE" devices - but the name
|
||||||
# consistent over time. Older Xcode versions will use "iPhone SE (Nth
|
# isn't consistent over time. Older Xcode versions will use "iPhone SE
|
||||||
# generation)"; As of 2025, they've started using "iPhone 16e".
|
# (Nth generation)"; As of 2025, they've started using "iPhone 16e".
|
||||||
#
|
#
|
||||||
# When Xcode is updated after a new release, new devices will be available
|
# When Xcode is updated after a new release, new devices will be
|
||||||
# and old ones will be dropped from the set available on the latest iOS
|
# available and old ones will be dropped from the set available on the
|
||||||
# version. Select the one with the highest minimum runtime version - this
|
# latest iOS version. Select the one with the highest minimum runtime
|
||||||
# is an indicator of the "newest" released device, which should always be
|
# version - this is an indicator of the "newest" released device, which
|
||||||
# supported on the "most recent" iOS version.
|
# should always be supported on the "most recent" iOS version.
|
||||||
se_simulators = sorted(
|
se_simulators = sorted(
|
||||||
(devicetype["minRuntimeVersion"], devicetype["name"])
|
(devicetype["minRuntimeVersion"], devicetype["name"])
|
||||||
for devicetype in json_data["devicetypes"]
|
for devicetype in json_data["devicetypes"]
|
||||||
|
|
@ -252,7 +253,7 @@ def update_test_plan(testbed_path, platform, args):
|
||||||
test_plan = json.load(f)
|
test_plan = json.load(f)
|
||||||
|
|
||||||
test_plan["defaultOptions"]["commandLineArgumentEntries"] = [
|
test_plan["defaultOptions"]["commandLineArgumentEntries"] = [
|
||||||
{"argument": arg} for arg in args
|
{"argument": shlex.quote(arg)} for arg in args
|
||||||
]
|
]
|
||||||
|
|
||||||
with test_plan_path.open("w", encoding="utf-8") as f:
|
with test_plan_path.open("w", encoding="utf-8") as f:
|
||||||
|
|
@ -294,7 +295,8 @@ def main():
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description=(
|
description=(
|
||||||
"Manages the process of testing an Apple Python project through Xcode."
|
"Manages the process of testing an Apple Python project "
|
||||||
|
"through Xcode."
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -335,7 +337,10 @@ def main():
|
||||||
|
|
||||||
run = subcommands.add_parser(
|
run = subcommands.add_parser(
|
||||||
"run",
|
"run",
|
||||||
usage="%(prog)s [-h] [--simulator SIMULATOR] -- <test arg> [<test arg> ...]",
|
usage=(
|
||||||
|
"%(prog)s [-h] [--simulator SIMULATOR] -- "
|
||||||
|
"<test arg> [<test arg> ...]"
|
||||||
|
),
|
||||||
description=(
|
description=(
|
||||||
"Run a testbed project. The arguments provided after `--` will be "
|
"Run a testbed project. The arguments provided after `--` will be "
|
||||||
"passed to the running iOS process as if they were arguments to "
|
"passed to the running iOS process as if they were arguments to "
|
||||||
|
|
@ -396,9 +401,9 @@ def main():
|
||||||
/ "bin"
|
/ "bin"
|
||||||
).is_dir():
|
).is_dir():
|
||||||
print(
|
print(
|
||||||
f"Testbed does not contain a compiled Python framework. Use "
|
"Testbed does not contain a compiled Python framework. "
|
||||||
f"`python {sys.argv[0]} clone ...` to create a runnable "
|
f"Use `python {sys.argv[0]} clone ...` to create a "
|
||||||
f"clone of this testbed."
|
"runnable clone of this testbed."
|
||||||
)
|
)
|
||||||
sys.exit(20)
|
sys.exit(20)
|
||||||
|
|
||||||
|
|
@ -410,7 +415,8 @@ def main():
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
print(
|
print(
|
||||||
f"Must specify test arguments (e.g., {sys.argv[0]} run -- test)"
|
"Must specify test arguments "
|
||||||
|
f"(e.g., {sys.argv[0]} run -- test)"
|
||||||
)
|
)
|
||||||
print()
|
print()
|
||||||
parser.print_help(sys.stderr)
|
parser.print_help(sys.stderr)
|
||||||
|
|
|
||||||
|
|
@ -241,7 +241,8 @@ dist-pdf:
|
||||||
# as otherwise the full latexmk process is run twice.
|
# as otherwise the full latexmk process is run twice.
|
||||||
# ($$ is needed to escape the $; https://www.gnu.org/software/make/manual/make.html#Basics-of-Variable-References)
|
# ($$ is needed to escape the $; https://www.gnu.org/software/make/manual/make.html#Basics-of-Variable-References)
|
||||||
-sed -i 's/: all-$$(FMT)/:/' build/latex/Makefile
|
-sed -i 's/: all-$$(FMT)/:/' build/latex/Makefile
|
||||||
(cd build/latex; $(MAKE) clean && $(MAKE) --jobs=$$((`nproc`+1)) --output-sync LATEXMKOPTS='-quiet' all-pdf && $(MAKE) FMT=pdf zip bz2)
|
if [ -n "$(filter output-sync,$(value .FEATURES))" ]; then OUTPUTSYNC=--output-sync; else OUTPUTSYNC=; fi && \
|
||||||
|
(cd build/latex; $(MAKE) clean && $(MAKE) --jobs=$$((`getconf _NPROCESSORS_ONLN`+1)) $$OUTPUTSYNC LATEXMKOPTS='-quiet' all-pdf && $(MAKE) FMT=pdf zip bz2)
|
||||||
cp build/latex/docs-pdf.zip dist/python-$(DISTVERSION)-docs-pdf-a4.zip
|
cp build/latex/docs-pdf.zip dist/python-$(DISTVERSION)-docs-pdf-a4.zip
|
||||||
cp build/latex/docs-pdf.tar.bz2 dist/python-$(DISTVERSION)-docs-pdf-a4.tar.bz2
|
cp build/latex/docs-pdf.tar.bz2 dist/python-$(DISTVERSION)-docs-pdf-a4.tar.bz2
|
||||||
@echo "Build finished and archived!"
|
@echo "Build finished and archived!"
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,9 @@ Contributors to the Python documentation
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
|
|
||||||
Many people have contributed to the Python language, the Python standard
|
Many people have contributed to the Python language, the Python standard
|
||||||
library, and the Python documentation. See :source:`Misc/ACKS` in the Python
|
library, and the Python documentation. See the `CPython
|
||||||
source distribution for a partial list of contributors.
|
GitHub repository <https://github.com/python/cpython/graphs/contributors>`__
|
||||||
|
for a partial list of contributors.
|
||||||
|
|
||||||
It is only with the input and contributions of the Python community
|
It is only with the input and contributions of the Python community
|
||||||
that Python has such wonderful documentation -- Thank You!
|
that Python has such wonderful documentation -- Thank You!
|
||||||
|
|
|
||||||
|
|
@ -140,10 +140,6 @@ Allocating Objects on the Heap
|
||||||
* :c:member:`~PyTypeObject.tp_alloc`
|
* :c:member:`~PyTypeObject.tp_alloc`
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: void PyObject_Del(void *op)
|
|
||||||
|
|
||||||
Same as :c:func:`PyObject_Free`.
|
|
||||||
|
|
||||||
.. c:var:: PyObject _Py_NoneStruct
|
.. c:var:: PyObject _Py_NoneStruct
|
||||||
|
|
||||||
Object which is visible in Python as ``None``. This should only be accessed
|
Object which is visible in Python as ``None``. This should only be accessed
|
||||||
|
|
@ -156,3 +152,35 @@ Allocating Objects on the Heap
|
||||||
:ref:`moduleobjects`
|
:ref:`moduleobjects`
|
||||||
To allocate and create extension modules.
|
To allocate and create extension modules.
|
||||||
|
|
||||||
|
|
||||||
|
Deprecated aliases
|
||||||
|
^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
These are :term:`soft deprecated` aliases to existing functions and macros.
|
||||||
|
They exist solely for backwards compatibility.
|
||||||
|
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:widths: auto
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
* * Deprecated alias
|
||||||
|
* Function
|
||||||
|
* * .. c:macro:: PyObject_NEW(type, typeobj)
|
||||||
|
* :c:macro:`PyObject_New`
|
||||||
|
* * .. c:macro:: PyObject_NEW_VAR(type, typeobj, n)
|
||||||
|
* :c:macro:`PyObject_NewVar`
|
||||||
|
* * .. c:macro:: PyObject_INIT(op, typeobj)
|
||||||
|
* :c:func:`PyObject_Init`
|
||||||
|
* * .. c:macro:: PyObject_INIT_VAR(op, typeobj, n)
|
||||||
|
* :c:func:`PyObject_InitVar`
|
||||||
|
* * .. c:macro:: PyObject_MALLOC(n)
|
||||||
|
* :c:func:`PyObject_Malloc`
|
||||||
|
* * .. c:macro:: PyObject_REALLOC(p, n)
|
||||||
|
* :c:func:`PyObject_Realloc`
|
||||||
|
* * .. c:macro:: PyObject_FREE(p)
|
||||||
|
* :c:func:`PyObject_Free`
|
||||||
|
* * .. c:macro:: PyObject_DEL(p)
|
||||||
|
* :c:func:`PyObject_Free`
|
||||||
|
* * .. c:macro:: PyObject_Del(p)
|
||||||
|
* :c:func:`PyObject_Free`
|
||||||
|
|
|
||||||
|
|
@ -261,6 +261,10 @@ readonly, format
|
||||||
MUST be consistent for all consumers. For example, :c:expr:`PyBUF_SIMPLE | PyBUF_WRITABLE`
|
MUST be consistent for all consumers. For example, :c:expr:`PyBUF_SIMPLE | PyBUF_WRITABLE`
|
||||||
can be used to request a simple writable buffer.
|
can be used to request a simple writable buffer.
|
||||||
|
|
||||||
|
.. c:macro:: PyBUF_WRITEABLE
|
||||||
|
|
||||||
|
This is a :term:`soft deprecated` alias to :c:macro:`PyBUF_WRITABLE`.
|
||||||
|
|
||||||
.. c:macro:: PyBUF_FORMAT
|
.. c:macro:: PyBUF_FORMAT
|
||||||
|
|
||||||
Controls the :c:member:`~Py_buffer.format` field. If set, this field MUST
|
Controls the :c:member:`~Py_buffer.format` field. If set, this field MUST
|
||||||
|
|
|
||||||
|
|
@ -228,6 +228,42 @@ called with a non-bytes parameter.
|
||||||
The function is :term:`soft deprecated`,
|
The function is :term:`soft deprecated`,
|
||||||
use the :c:type:`PyBytesWriter` API instead.
|
use the :c:type:`PyBytesWriter` API instead.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: PyObject *PyBytes_Repr(PyObject *bytes, int smartquotes)
|
||||||
|
|
||||||
|
Get the string representation of *bytes*. This function is currently used to
|
||||||
|
implement :meth:`!bytes.__repr__` in Python.
|
||||||
|
|
||||||
|
This function does not do type checking; it is undefined behavior to pass
|
||||||
|
*bytes* as a non-bytes object or ``NULL``.
|
||||||
|
|
||||||
|
If *smartquotes* is true, the representation will use a double-quoted string
|
||||||
|
instead of single-quoted string when single-quotes are present in *bytes*.
|
||||||
|
For example, the byte string ``'Python'`` would be represented as
|
||||||
|
``b"'Python'"`` when *smartquotes* is true, or ``b'\'Python\''`` when it is
|
||||||
|
false.
|
||||||
|
|
||||||
|
On success, this function returns a :term:`strong reference` to a
|
||||||
|
:class:`str` object containing the representation. On failure, this
|
||||||
|
returns ``NULL`` with an exception set.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: PyObject *PyBytes_DecodeEscape(const char *s, Py_ssize_t len, const char *errors, Py_ssize_t unicode, const char *recode_encoding)
|
||||||
|
|
||||||
|
Unescape a backslash-escaped string *s*. *s* must not be ``NULL``.
|
||||||
|
*len* must be the size of *s*.
|
||||||
|
|
||||||
|
*errors* must be one of ``"strict"``, ``"replace"``, or ``"ignore"``. If
|
||||||
|
*errors* is ``NULL``, then ``"strict"`` is used by default.
|
||||||
|
|
||||||
|
On success, this function returns a :term:`strong reference` to a Python
|
||||||
|
:class:`bytes` object containing the unescaped string. On failure, this
|
||||||
|
function returns ``NULL`` with an exception set.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.9
|
||||||
|
*unicode* and *recode_encoding* are now unused.
|
||||||
|
|
||||||
|
|
||||||
.. _pybyteswriter:
|
.. _pybyteswriter:
|
||||||
|
|
||||||
PyBytesWriter
|
PyBytesWriter
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,12 @@ Refer to :ref:`using-capsules` for more information on using these objects.
|
||||||
loaded modules.
|
loaded modules.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyCapsule_Type
|
||||||
|
|
||||||
|
The type object corresponding to capsule objects. This is the same object
|
||||||
|
as :class:`types.CapsuleType` in the Python layer.
|
||||||
|
|
||||||
|
|
||||||
.. c:type:: PyCapsule_Destructor
|
.. c:type:: PyCapsule_Destructor
|
||||||
|
|
||||||
The type of a destructor callback for a capsule. Defined as::
|
The type of a destructor callback for a capsule. Defined as::
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ Cell Objects
|
||||||
|
|
||||||
"Cell" objects are used to implement variables referenced by multiple scopes.
|
"Cell" objects are used to implement variables referenced by multiple scopes.
|
||||||
For each such variable, a cell object is created to store the value; the local
|
For each such variable, a cell object is created to store the value; the local
|
||||||
variables of each stack frame that references the value contains a reference to
|
variables of each stack frame that references the value contain a reference to
|
||||||
the cells from outer scopes which also use that variable. When the value is
|
the cells from outer scopes which also use that variable. When the value is
|
||||||
accessed, the value contained in the cell is used instead of the cell object
|
accessed, the value contained in the cell is used instead of the cell object
|
||||||
itself. This de-referencing of the cell object requires support from the
|
itself. This de-referencing of the cell object requires support from the
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,17 @@ bound into a function.
|
||||||
.. versionadded:: 3.12
|
.. versionadded:: 3.12
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: PyObject *PyCode_Optimize(PyObject *code, PyObject *consts, PyObject *names, PyObject *lnotab_obj)
|
||||||
|
|
||||||
|
This is a :term:`soft deprecated` function that does nothing.
|
||||||
|
|
||||||
|
Prior to Python 3.10, this function would perform basic optimizations to a
|
||||||
|
code object.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.10
|
||||||
|
This function now does nothing.
|
||||||
|
|
||||||
|
|
||||||
.. _c_codeobject_flags:
|
.. _c_codeobject_flags:
|
||||||
|
|
||||||
Code Object Flags
|
Code Object Flags
|
||||||
|
|
|
||||||
|
|
@ -129,3 +129,13 @@ Registry API for Unicode encoding error handlers
|
||||||
Replace the unicode encode error with ``\N{...}`` escapes.
|
Replace the unicode encode error with ``\N{...}`` escapes.
|
||||||
|
|
||||||
.. versionadded:: 3.5
|
.. versionadded:: 3.5
|
||||||
|
|
||||||
|
|
||||||
|
Codec utility variables
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
.. c:var:: const char *Py_hexdigits
|
||||||
|
|
||||||
|
A string constant containing the lowercase hexadecimal digits: ``"0123456789abcdef"``.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ Complex Number Objects
|
||||||
|
|
||||||
.. c:type:: Py_complex
|
.. c:type:: Py_complex
|
||||||
|
|
||||||
This C structure defines export format for a Python complex
|
This C structure defines an export format for a Python complex
|
||||||
number object.
|
number object.
|
||||||
|
|
||||||
.. c:member:: double real
|
.. c:member:: double real
|
||||||
|
|
|
||||||
|
|
@ -109,11 +109,20 @@ Other Objects
|
||||||
descriptor.rst
|
descriptor.rst
|
||||||
slice.rst
|
slice.rst
|
||||||
memoryview.rst
|
memoryview.rst
|
||||||
|
picklebuffer.rst
|
||||||
weakref.rst
|
weakref.rst
|
||||||
capsule.rst
|
capsule.rst
|
||||||
frame.rst
|
frame.rst
|
||||||
gen.rst
|
gen.rst
|
||||||
coro.rst
|
coro.rst
|
||||||
contextvars.rst
|
contextvars.rst
|
||||||
datetime.rst
|
|
||||||
typehints.rst
|
typehints.rst
|
||||||
|
|
||||||
|
|
||||||
|
C API for extension modules
|
||||||
|
===========================
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
|
||||||
|
curses.rst
|
||||||
|
datetime.rst
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ The following functions provide locale-independent string to number conversions.
|
||||||
|
|
||||||
If ``s`` represents a value that is too large to store in a float
|
If ``s`` represents a value that is too large to store in a float
|
||||||
(for example, ``"1e500"`` is such a string on many platforms) then
|
(for example, ``"1e500"`` is such a string on many platforms) then
|
||||||
if ``overflow_exception`` is ``NULL`` return ``Py_INFINITY`` (with
|
if ``overflow_exception`` is ``NULL`` return :c:macro:`!INFINITY` (with
|
||||||
an appropriate sign) and don't set any exception. Otherwise,
|
an appropriate sign) and don't set any exception. Otherwise,
|
||||||
``overflow_exception`` must point to a Python exception object;
|
``overflow_exception`` must point to a Python exception object;
|
||||||
raise that exception and return ``-1.0``. In both cases, set
|
raise that exception and return ``-1.0``. In both cases, set
|
||||||
|
|
@ -128,18 +128,28 @@ The following functions provide locale-independent string to number conversions.
|
||||||
must be 0 and is ignored. The ``'r'`` format code specifies the
|
must be 0 and is ignored. The ``'r'`` format code specifies the
|
||||||
standard :func:`repr` format.
|
standard :func:`repr` format.
|
||||||
|
|
||||||
*flags* can be zero or more of the values ``Py_DTSF_SIGN``,
|
*flags* can be zero or more of the following values or-ed together:
|
||||||
``Py_DTSF_ADD_DOT_0``, or ``Py_DTSF_ALT``, or-ed together:
|
|
||||||
|
|
||||||
* ``Py_DTSF_SIGN`` means to always precede the returned string with a sign
|
.. c:macro:: Py_DTSF_SIGN
|
||||||
character, even if *val* is non-negative.
|
|
||||||
|
|
||||||
* ``Py_DTSF_ADD_DOT_0`` means to ensure that the returned string will not look
|
Always precede the returned string with a sign
|
||||||
like an integer.
|
character, even if *val* is non-negative.
|
||||||
|
|
||||||
* ``Py_DTSF_ALT`` means to apply "alternate" formatting rules. See the
|
.. c:macro:: Py_DTSF_ADD_DOT_0
|
||||||
documentation for the :c:func:`PyOS_snprintf` ``'#'`` specifier for
|
|
||||||
details.
|
Ensure that the returned string will not look like an integer.
|
||||||
|
|
||||||
|
.. c:macro:: Py_DTSF_ALT
|
||||||
|
|
||||||
|
Apply "alternate" formatting rules.
|
||||||
|
See the documentation for the :c:func:`PyOS_snprintf` ``'#'`` specifier for
|
||||||
|
details.
|
||||||
|
|
||||||
|
.. c:macro:: Py_DTSF_NO_NEG_0
|
||||||
|
|
||||||
|
Negative zero is converted to positive zero.
|
||||||
|
|
||||||
|
.. versionadded:: 3.11
|
||||||
|
|
||||||
If *ptype* is non-``NULL``, then the value it points to will be set to one of
|
If *ptype* is non-``NULL``, then the value it points to will be set to one of
|
||||||
``Py_DTST_FINITE``, ``Py_DTST_INFINITE``, or ``Py_DTST_NAN``, signifying that
|
``Py_DTST_FINITE``, ``Py_DTST_INFINITE``, or ``Py_DTST_NAN``, signifying that
|
||||||
|
|
@ -152,13 +162,85 @@ The following functions provide locale-independent string to number conversions.
|
||||||
.. versionadded:: 3.1
|
.. versionadded:: 3.1
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyOS_stricmp(const char *s1, const char *s2)
|
.. c:function:: int PyOS_mystricmp(const char *str1, const char *str2)
|
||||||
|
int PyOS_mystrnicmp(const char *str1, const char *str2, Py_ssize_t size)
|
||||||
|
|
||||||
Case insensitive comparison of strings. The function works almost
|
Case insensitive comparison of strings. These functions work almost
|
||||||
identically to :c:func:`!strcmp` except that it ignores the case.
|
identically to :c:func:`!strcmp` and :c:func:`!strncmp` (respectively),
|
||||||
|
except that they ignore the case of ASCII characters.
|
||||||
|
|
||||||
|
Return ``0`` if the strings are equal, a negative value if *str1* sorts
|
||||||
|
lexicographically before *str2*, or a positive value if it sorts after.
|
||||||
|
|
||||||
|
In the *str1* or *str2* arguments, a NUL byte marks the end of the string.
|
||||||
|
For :c:func:`!PyOS_mystrnicmp`, the *size* argument gives the maximum size
|
||||||
|
of the string, as if NUL was present at the index given by *size*.
|
||||||
|
|
||||||
|
These functions do not use the locale.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyOS_strnicmp(const char *s1, const char *s2, Py_ssize_t size)
|
.. c:function:: int PyOS_stricmp(const char *str1, const char *str2)
|
||||||
|
int PyOS_strnicmp(const char *str1, const char *str2, Py_ssize_t size)
|
||||||
|
|
||||||
Case insensitive comparison of strings. The function works almost
|
Case insensitive comparison of strings.
|
||||||
identically to :c:func:`!strncmp` except that it ignores the case.
|
|
||||||
|
On Windows, these are aliases of :c:func:`!stricmp` and :c:func:`!strnicmp`,
|
||||||
|
respectively.
|
||||||
|
|
||||||
|
On other platforms, they are aliases of :c:func:`PyOS_mystricmp` and
|
||||||
|
:c:func:`PyOS_mystrnicmp`, respectively.
|
||||||
|
|
||||||
|
|
||||||
|
Character classification and conversion
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
The following macros provide locale-independent (unlike the C standard library
|
||||||
|
``ctype.h``) character classification and conversion.
|
||||||
|
The argument must be a signed or unsigned :c:expr:`char`.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_ISALNUM(c)
|
||||||
|
|
||||||
|
Return true if the character *c* is an alphanumeric character.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_ISALPHA(c)
|
||||||
|
|
||||||
|
Return true if the character *c* is an alphabetic character (``a-z`` and ``A-Z``).
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_ISDIGIT(c)
|
||||||
|
|
||||||
|
Return true if the character *c* is a decimal digit (``0-9``).
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_ISLOWER(c)
|
||||||
|
|
||||||
|
Return true if the character *c* is a lowercase ASCII letter (``a-z``).
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_ISUPPER(c)
|
||||||
|
|
||||||
|
Return true if the character *c* is an uppercase ASCII letter (``A-Z``).
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_ISSPACE(c)
|
||||||
|
|
||||||
|
Return true if the character *c* is a whitespace character (space, tab,
|
||||||
|
carriage return, newline, vertical tab, or form feed).
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_ISXDIGIT(c)
|
||||||
|
|
||||||
|
Return true if the character *c* is a hexadecimal digit (``0-9``, ``a-f``, and
|
||||||
|
``A-F``).
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_TOLOWER(c)
|
||||||
|
|
||||||
|
Return the lowercase equivalent of the character *c*.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_TOUPPER(c)
|
||||||
|
|
||||||
|
Return the uppercase equivalent of the character *c*.
|
||||||
|
|
|
||||||
138
Doc/c-api/curses.rst
Normal file
138
Doc/c-api/curses.rst
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
.. highlight:: c
|
||||||
|
|
||||||
|
Curses C API
|
||||||
|
------------
|
||||||
|
|
||||||
|
:mod:`curses` exposes a small C interface for extension modules.
|
||||||
|
Consumers must include the header file :file:`py_curses.h` (which is not
|
||||||
|
included by default by :file:`Python.h`) and :c:func:`import_curses` must
|
||||||
|
be invoked, usually as part of the module initialisation function, to populate
|
||||||
|
:c:var:`PyCurses_API`.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
Neither the C API nor the pure Python :mod:`curses` module are compatible
|
||||||
|
with subinterpreters.
|
||||||
|
|
||||||
|
.. c:macro:: import_curses()
|
||||||
|
|
||||||
|
Import the curses C API. The macro does not need a semi-colon to be called.
|
||||||
|
|
||||||
|
On success, populate the :c:var:`PyCurses_API` pointer.
|
||||||
|
|
||||||
|
On failure, set :c:var:`PyCurses_API` to NULL and set an exception.
|
||||||
|
The caller must check if an error occurred via :c:func:`PyErr_Occurred`:
|
||||||
|
|
||||||
|
.. code-block::
|
||||||
|
|
||||||
|
import_curses(); // semi-colon is optional but recommended
|
||||||
|
if (PyErr_Occurred()) { /* cleanup */ }
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: void **PyCurses_API
|
||||||
|
|
||||||
|
Dynamically allocated object containing the curses C API.
|
||||||
|
This variable is only available once :c:macro:`import_curses` succeeds.
|
||||||
|
|
||||||
|
``PyCurses_API[0]`` corresponds to :c:data:`PyCursesWindow_Type`.
|
||||||
|
|
||||||
|
``PyCurses_API[1]``, ``PyCurses_API[2]``, and ``PyCurses_API[3]``
|
||||||
|
are pointers to predicate functions of type ``int (*)(void)``.
|
||||||
|
|
||||||
|
When called, these predicates return whether :func:`curses.setupterm`,
|
||||||
|
:func:`curses.initscr`, and :func:`curses.start_color` have been called
|
||||||
|
respectively.
|
||||||
|
|
||||||
|
See also the convenience macros :c:macro:`PyCursesSetupTermCalled`,
|
||||||
|
:c:macro:`PyCursesInitialised`, and :c:macro:`PyCursesInitialisedColor`.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
The number of entries in this structure is subject to changes.
|
||||||
|
Consider using :c:macro:`PyCurses_API_pointers` to check if
|
||||||
|
new fields are available or not.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: PyCurses_API_pointers
|
||||||
|
|
||||||
|
The number of accessible fields (``4``) in :c:var:`PyCurses_API`.
|
||||||
|
This number is incremented whenever new fields are added.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyCursesWindow_Type
|
||||||
|
|
||||||
|
The :ref:`heap type <heap-types>` corresponding to :class:`curses.window`.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyCursesWindow_Check(PyObject *op)
|
||||||
|
|
||||||
|
Return true if *op* is a :class:`curses.window` instance, false otherwise.
|
||||||
|
|
||||||
|
|
||||||
|
The following macros are convenience macros expanding into C statements.
|
||||||
|
In particular, they can only be used as ``macro;`` or ``macro``, but not
|
||||||
|
``macro()`` or ``macro();``.
|
||||||
|
|
||||||
|
.. c:macro:: PyCursesSetupTermCalled
|
||||||
|
|
||||||
|
Macro checking if :func:`curses.setupterm` has been called.
|
||||||
|
|
||||||
|
The macro expansion is roughly equivalent to:
|
||||||
|
|
||||||
|
.. code-block::
|
||||||
|
|
||||||
|
{
|
||||||
|
typedef int (*predicate_t)(void);
|
||||||
|
predicate_t was_setupterm_called = (predicate_t)PyCurses_API[1];
|
||||||
|
if (!was_setupterm_called()) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: PyCursesInitialised
|
||||||
|
|
||||||
|
Macro checking if :func:`curses.initscr` has been called.
|
||||||
|
|
||||||
|
The macro expansion is roughly equivalent to:
|
||||||
|
|
||||||
|
.. code-block::
|
||||||
|
|
||||||
|
{
|
||||||
|
typedef int (*predicate_t)(void);
|
||||||
|
predicate_t was_initscr_called = (predicate_t)PyCurses_API[2];
|
||||||
|
if (!was_initscr_called()) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: PyCursesInitialisedColor
|
||||||
|
|
||||||
|
Macro checking if :func:`curses.start_color` has been called.
|
||||||
|
|
||||||
|
The macro expansion is roughly equivalent to:
|
||||||
|
|
||||||
|
.. code-block::
|
||||||
|
|
||||||
|
{
|
||||||
|
typedef int (*predicate_t)(void);
|
||||||
|
predicate_t was_start_color_called = (predicate_t)PyCurses_API[3];
|
||||||
|
if (!was_start_color_called()) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Internal data
|
||||||
|
-------------
|
||||||
|
|
||||||
|
The following objects are exposed by the C API but should be considered
|
||||||
|
internal-only.
|
||||||
|
|
||||||
|
.. c:macro:: PyCurses_CAPSULE_NAME
|
||||||
|
|
||||||
|
Name of the curses capsule to pass to :c:func:`PyCapsule_Import`.
|
||||||
|
|
||||||
|
Internal usage only. Use :c:macro:`import_curses` instead.
|
||||||
|
|
||||||
|
|
@ -8,11 +8,42 @@ DateTime Objects
|
||||||
Various date and time objects are supplied by the :mod:`datetime` module.
|
Various date and time objects are supplied by the :mod:`datetime` module.
|
||||||
Before using any of these functions, the header file :file:`datetime.h` must be
|
Before using any of these functions, the header file :file:`datetime.h` must be
|
||||||
included in your source (note that this is not included by :file:`Python.h`),
|
included in your source (note that this is not included by :file:`Python.h`),
|
||||||
and the macro :c:macro:`!PyDateTime_IMPORT` must be invoked, usually as part of
|
and the macro :c:macro:`PyDateTime_IMPORT` must be invoked, usually as part of
|
||||||
the module initialisation function. The macro puts a pointer to a C structure
|
the module initialisation function. The macro puts a pointer to a C structure
|
||||||
into a static variable, :c:data:`!PyDateTimeAPI`, that is used by the following
|
into a static variable, :c:data:`PyDateTimeAPI`, that is used by the following
|
||||||
macros.
|
macros.
|
||||||
|
|
||||||
|
.. c:macro:: PyDateTime_IMPORT()
|
||||||
|
|
||||||
|
Import the datetime C API.
|
||||||
|
|
||||||
|
On success, populate the :c:var:`PyDateTimeAPI` pointer.
|
||||||
|
On failure, set :c:var:`PyDateTimeAPI` to ``NULL`` and set an exception.
|
||||||
|
The caller must check if an error occurred via :c:func:`PyErr_Occurred`:
|
||||||
|
|
||||||
|
.. code-block::
|
||||||
|
|
||||||
|
PyDateTime_IMPORT;
|
||||||
|
if (PyErr_Occurred()) { /* cleanup */ }
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
This is not compatible with subinterpreters.
|
||||||
|
|
||||||
|
.. c:type:: PyDateTime_CAPI
|
||||||
|
|
||||||
|
Structure containing the fields for the datetime C API.
|
||||||
|
|
||||||
|
The fields of this structure are private and subject to change.
|
||||||
|
|
||||||
|
Do not use this directly; prefer ``PyDateTime_*`` APIs instead.
|
||||||
|
|
||||||
|
.. c:var:: PyDateTime_CAPI *PyDateTimeAPI
|
||||||
|
|
||||||
|
Dynamically allocated object containing the datetime C API.
|
||||||
|
|
||||||
|
This variable is only available once :c:macro:`PyDateTime_IMPORT` succeeds.
|
||||||
|
|
||||||
.. c:type:: PyDateTime_Date
|
.. c:type:: PyDateTime_Date
|
||||||
|
|
||||||
This subtype of :c:type:`PyObject` represents a Python date object.
|
This subtype of :c:type:`PyObject` represents a Python date object.
|
||||||
|
|
@ -46,7 +77,7 @@ macros.
|
||||||
|
|
||||||
.. c:var:: PyTypeObject PyDateTime_DeltaType
|
.. c:var:: PyTypeObject PyDateTime_DeltaType
|
||||||
|
|
||||||
This instance of :c:type:`PyTypeObject` represents Python type for
|
This instance of :c:type:`PyTypeObject` represents the Python type for
|
||||||
the difference between two datetime values;
|
the difference between two datetime values;
|
||||||
it is the same object as :class:`datetime.timedelta` in the Python layer.
|
it is the same object as :class:`datetime.timedelta` in the Python layer.
|
||||||
|
|
||||||
|
|
@ -325,3 +356,16 @@ Macros for the convenience of modules implementing the DB API:
|
||||||
|
|
||||||
Create and return a new :class:`datetime.date` object given an argument
|
Create and return a new :class:`datetime.date` object given an argument
|
||||||
tuple suitable for passing to :meth:`datetime.date.fromtimestamp`.
|
tuple suitable for passing to :meth:`datetime.date.fromtimestamp`.
|
||||||
|
|
||||||
|
|
||||||
|
Internal data
|
||||||
|
-------------
|
||||||
|
|
||||||
|
The following symbols are exposed by the C API but should be considered
|
||||||
|
internal-only.
|
||||||
|
|
||||||
|
.. c:macro:: PyDateTime_CAPSULE_NAME
|
||||||
|
|
||||||
|
Name of the datetime capsule to pass to :c:func:`PyCapsule_Import`.
|
||||||
|
|
||||||
|
Internal usage only. Use :c:macro:`PyDateTime_IMPORT` instead.
|
||||||
|
|
|
||||||
|
|
@ -21,20 +21,104 @@ found in the dictionary of type objects.
|
||||||
.. c:function:: PyObject* PyDescr_NewMember(PyTypeObject *type, struct PyMemberDef *meth)
|
.. c:function:: PyObject* PyDescr_NewMember(PyTypeObject *type, struct PyMemberDef *meth)
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyMemberDescr_Type
|
||||||
|
|
||||||
|
The type object for member descriptor objects created from
|
||||||
|
:c:type:`PyMemberDef` structures. These descriptors expose fields of a
|
||||||
|
C struct as attributes on a type, and correspond
|
||||||
|
to :class:`types.MemberDescriptorType` objects in Python.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyGetSetDescr_Type
|
||||||
|
|
||||||
|
The type object for get/set descriptor objects created from
|
||||||
|
:c:type:`PyGetSetDef` structures. These descriptors implement attributes
|
||||||
|
whose value is computed by C getter and setter functions, and are used
|
||||||
|
for many built-in type attributes.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject* PyDescr_NewMethod(PyTypeObject *type, struct PyMethodDef *meth)
|
.. c:function:: PyObject* PyDescr_NewMethod(PyTypeObject *type, struct PyMethodDef *meth)
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyMethodDescr_Type
|
||||||
|
|
||||||
|
The type object for method descriptor objects created from
|
||||||
|
:c:type:`PyMethodDef` structures. These descriptors expose C functions as
|
||||||
|
methods on a type, and correspond to :class:`types.MemberDescriptorType`
|
||||||
|
objects in Python.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject* PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *wrapper, void *wrapped)
|
.. c:function:: PyObject* PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *wrapper, void *wrapped)
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyWrapperDescr_Type
|
||||||
|
|
||||||
|
The type object for wrapper descriptor objects created by
|
||||||
|
:c:func:`PyDescr_NewWrapper` and :c:func:`PyWrapper_New`. Wrapper
|
||||||
|
descriptors are used internally to expose special methods implemented
|
||||||
|
via wrapper structures, and appear in Python as
|
||||||
|
:class:`types.WrapperDescriptorType` objects.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject* PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
|
.. c:function:: PyObject* PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyDescr_IsData(PyObject *descr)
|
.. c:function:: int PyDescr_IsData(PyObject *descr)
|
||||||
|
|
||||||
Return non-zero if the descriptor objects *descr* describes a data attribute, or
|
Return non-zero if the descriptor object *descr* describes a data attribute, or
|
||||||
``0`` if it describes a method. *descr* must be a descriptor object; there is
|
``0`` if it describes a method. *descr* must be a descriptor object; there is
|
||||||
no error checking.
|
no error checking.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject* PyWrapper_New(PyObject *, PyObject *)
|
.. c:function:: PyObject* PyWrapper_New(PyObject *, PyObject *)
|
||||||
|
|
||||||
|
|
||||||
|
Built-in descriptors
|
||||||
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PySuper_Type
|
||||||
|
|
||||||
|
The type object for super objects. This is the same object as
|
||||||
|
:class:`super` in the Python layer.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyClassMethod_Type
|
||||||
|
|
||||||
|
The type of class method objects. This is the same object as
|
||||||
|
:class:`classmethod` in the Python layer.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyClassMethodDescr_Type
|
||||||
|
|
||||||
|
The type object for C-level class method descriptor objects.
|
||||||
|
This is the type of the descriptors created for :func:`classmethod` defined in
|
||||||
|
C extension types, and is the same object as :class:`classmethod`
|
||||||
|
in Python.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: PyObject *PyClassMethod_New(PyObject *callable)
|
||||||
|
|
||||||
|
Create a new :class:`classmethod` object wrapping *callable*.
|
||||||
|
*callable* must be a callable object and must not be ``NULL``.
|
||||||
|
|
||||||
|
On success, this function returns a :term:`strong reference` to a new class
|
||||||
|
method descriptor. On failure, this function returns ``NULL`` with an
|
||||||
|
exception set.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyStaticMethod_Type
|
||||||
|
|
||||||
|
The type of static method objects. This is the same object as
|
||||||
|
:class:`staticmethod` in the Python layer.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: PyObject *PyStaticMethod_New(PyObject *callable)
|
||||||
|
|
||||||
|
Create a new :class:`staticmethod` object wrapping *callable*.
|
||||||
|
*callable* must be a callable object and must not be ``NULL``.
|
||||||
|
|
||||||
|
On success, this function returns a :term:`strong reference` to a new static
|
||||||
|
method descriptor. On failure, this function returns ``NULL`` with an
|
||||||
|
exception set.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,17 @@ Dictionary Objects
|
||||||
prevent modification of the dictionary for non-dynamic class types.
|
prevent modification of the dictionary for non-dynamic class types.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyDictProxy_Type
|
||||||
|
|
||||||
|
The type object for mapping proxy objects created by
|
||||||
|
:c:func:`PyDictProxy_New` and for the read-only ``__dict__`` attribute
|
||||||
|
of many built-in types. A :c:type:`PyDictProxy_Type` instance provides a
|
||||||
|
dynamic, read-only view of an underlying dictionary: changes to the
|
||||||
|
underlying dictionary are reflected in the proxy, but the proxy itself
|
||||||
|
does not support mutation operations. This corresponds to
|
||||||
|
:class:`types.MappingProxyType` in Python.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: void PyDict_Clear(PyObject *p)
|
.. c:function:: void PyDict_Clear(PyObject *p)
|
||||||
|
|
||||||
Empty an existing dictionary of all key-value pairs.
|
Empty an existing dictionary of all key-value pairs.
|
||||||
|
|
@ -245,6 +256,11 @@ Dictionary Objects
|
||||||
``len(p)`` on a dictionary.
|
``len(p)`` on a dictionary.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: Py_ssize_t PyDict_GET_SIZE(PyObject *p)
|
||||||
|
|
||||||
|
Similar to :c:func:`PyDict_Size`, but without error checking.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue)
|
.. c:function:: int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue)
|
||||||
|
|
||||||
Iterate over all key-value pairs in the dictionary *p*. The
|
Iterate over all key-value pairs in the dictionary *p*. The
|
||||||
|
|
@ -426,3 +442,138 @@ Dictionary Objects
|
||||||
it before returning.
|
it before returning.
|
||||||
|
|
||||||
.. versionadded:: 3.12
|
.. versionadded:: 3.12
|
||||||
|
|
||||||
|
|
||||||
|
Dictionary View Objects
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. c:function:: int PyDictViewSet_Check(PyObject *op)
|
||||||
|
|
||||||
|
Return true if *op* is a view of a set inside a dictionary. This is currently
|
||||||
|
equivalent to :c:expr:`PyDictKeys_Check(op) || PyDictItems_Check(op)`. This
|
||||||
|
function always succeeds.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyDictKeys_Type
|
||||||
|
|
||||||
|
Type object for a view of dictionary keys. In Python, this is the type of
|
||||||
|
the object returned by :meth:`dict.keys`.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyDictKeys_Check(PyObject *op)
|
||||||
|
|
||||||
|
Return true if *op* is an instance of a dictionary keys view. This function
|
||||||
|
always succeeds.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyDictValues_Type
|
||||||
|
|
||||||
|
Type object for a view of dictionary values. In Python, this is the type of
|
||||||
|
the object returned by :meth:`dict.values`.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyDictValues_Check(PyObject *op)
|
||||||
|
|
||||||
|
Return true if *op* is an instance of a dictionary values view. This function
|
||||||
|
always succeeds.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyDictItems_Type
|
||||||
|
|
||||||
|
Type object for a view of dictionary items. In Python, this is the type of
|
||||||
|
the object returned by :meth:`dict.items`.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyDictItems_Check(PyObject *op)
|
||||||
|
|
||||||
|
Return true if *op* is an instance of a dictionary items view. This function
|
||||||
|
always succeeds.
|
||||||
|
|
||||||
|
|
||||||
|
Ordered Dictionaries
|
||||||
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Python's C API provides interface for :class:`collections.OrderedDict` from C.
|
||||||
|
Since Python 3.7, dictionaries are ordered by default, so there is usually
|
||||||
|
little need for these functions; prefer ``PyDict*`` where possible.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyODict_Type
|
||||||
|
|
||||||
|
Type object for ordered dictionaries. This is the same object as
|
||||||
|
:class:`collections.OrderedDict` in the Python layer.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyODict_Check(PyObject *od)
|
||||||
|
|
||||||
|
Return true if *od* is an ordered dictionary object or an instance of a
|
||||||
|
subtype of the :class:`~collections.OrderedDict` type. This function
|
||||||
|
always succeeds.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyODict_CheckExact(PyObject *od)
|
||||||
|
|
||||||
|
Return true if *od* is an ordered dictionary object, but not an instance of
|
||||||
|
a subtype of the :class:`~collections.OrderedDict` type.
|
||||||
|
This function always succeeds.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyODictKeys_Type
|
||||||
|
|
||||||
|
Analogous to :c:type:`PyDictKeys_Type` for ordered dictionaries.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyODictValues_Type
|
||||||
|
|
||||||
|
Analogous to :c:type:`PyDictValues_Type` for ordered dictionaries.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyODictItems_Type
|
||||||
|
|
||||||
|
Analogous to :c:type:`PyDictItems_Type` for ordered dictionaries.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: PyObject *PyODict_New(void)
|
||||||
|
|
||||||
|
Return a new empty ordered dictionary, or ``NULL`` on failure.
|
||||||
|
|
||||||
|
This is analogous to :c:func:`PyDict_New`.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyODict_SetItem(PyObject *od, PyObject *key, PyObject *value)
|
||||||
|
|
||||||
|
Insert *value* into the ordered dictionary *od* with a key of *key*.
|
||||||
|
Return ``0`` on success or ``-1`` with an exception set on failure.
|
||||||
|
|
||||||
|
This is analogous to :c:func:`PyDict_SetItem`.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyODict_DelItem(PyObject *od, PyObject *key)
|
||||||
|
|
||||||
|
Remove the entry in the ordered dictionary *od* with key *key*.
|
||||||
|
Return ``0`` on success or ``-1`` with an exception set on failure.
|
||||||
|
|
||||||
|
This is analogous to :c:func:`PyDict_DelItem`.
|
||||||
|
|
||||||
|
|
||||||
|
These are :term:`soft deprecated` aliases to ``PyDict`` APIs:
|
||||||
|
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:widths: auto
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
* * ``PyODict``
|
||||||
|
* ``PyDict``
|
||||||
|
* * .. c:macro:: PyODict_GetItem(od, key)
|
||||||
|
* :c:func:`PyDict_GetItem`
|
||||||
|
* * .. c:macro:: PyODict_GetItemWithError(od, key)
|
||||||
|
* :c:func:`PyDict_GetItemWithError`
|
||||||
|
* * .. c:macro:: PyODict_GetItemString(od, key)
|
||||||
|
* :c:func:`PyDict_GetItemString`
|
||||||
|
* * .. c:macro:: PyODict_Contains(od, key)
|
||||||
|
* :c:func:`PyDict_Contains`
|
||||||
|
* * .. c:macro:: PyODict_Size(od)
|
||||||
|
* :c:func:`PyDict_Size`
|
||||||
|
* * .. c:macro:: PyODict_SIZE(od)
|
||||||
|
* :c:func:`PyDict_GET_SIZE`
|
||||||
|
|
|
||||||
|
|
@ -309,6 +309,14 @@ For convenience, some of these functions will always return a
|
||||||
.. versionadded:: 3.4
|
.. versionadded:: 3.4
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: void PyErr_RangedSyntaxLocationObject(PyObject *filename, int lineno, int col_offset, int end_lineno, int end_col_offset)
|
||||||
|
|
||||||
|
Similar to :c:func:`PyErr_SyntaxLocationObject`, but also sets the
|
||||||
|
*end_lineno* and *end_col_offset* information for the current exception.
|
||||||
|
|
||||||
|
.. versionadded:: 3.10
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: void PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)
|
.. c:function:: void PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)
|
||||||
|
|
||||||
Like :c:func:`PyErr_SyntaxLocationObject`, but *filename* is a byte string
|
Like :c:func:`PyErr_SyntaxLocationObject`, but *filename* is a byte string
|
||||||
|
|
@ -331,6 +339,23 @@ For convenience, some of these functions will always return a
|
||||||
use.
|
use.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: PyObject *PyErr_ProgramTextObject(PyObject *filename, int lineno)
|
||||||
|
|
||||||
|
Get the source line in *filename* at line *lineno*. *filename* should be a
|
||||||
|
Python :class:`str` object.
|
||||||
|
|
||||||
|
On success, this function returns a Python string object with the found line.
|
||||||
|
On failure, this function returns ``NULL`` without an exception set.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: PyObject *PyErr_ProgramText(const char *filename, int lineno)
|
||||||
|
|
||||||
|
Similar to :c:func:`PyErr_ProgramTextObject`, but *filename* is a
|
||||||
|
:c:expr:`const char *`, which is decoded with the
|
||||||
|
:term:`filesystem encoding and error handler`, instead of a
|
||||||
|
Python object reference.
|
||||||
|
|
||||||
|
|
||||||
Issuing warnings
|
Issuing warnings
|
||||||
================
|
================
|
||||||
|
|
||||||
|
|
@ -394,6 +419,15 @@ an error value).
|
||||||
.. versionadded:: 3.2
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyErr_WarnExplicitFormat(PyObject *category, const char *filename, int lineno, const char *module, PyObject *registry, const char *format, ...)
|
||||||
|
|
||||||
|
Similar to :c:func:`PyErr_WarnExplicit`, but uses
|
||||||
|
:c:func:`PyUnicode_FromFormat` to format the warning message. *format* is
|
||||||
|
an ASCII-encoded string.
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level, const char *format, ...)
|
.. c:function:: int PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level, const char *format, ...)
|
||||||
|
|
||||||
Function similar to :c:func:`PyErr_WarnFormat`, but *category* is
|
Function similar to :c:func:`PyErr_WarnFormat`, but *category* is
|
||||||
|
|
@ -762,6 +796,17 @@ Exception Classes
|
||||||
Exception Objects
|
Exception Objects
|
||||||
=================
|
=================
|
||||||
|
|
||||||
|
.. c:function:: int PyExceptionInstance_Check(PyObject *op)
|
||||||
|
|
||||||
|
Return true if *op* is an instance of :class:`BaseException`, false
|
||||||
|
otherwise. This function always succeeds.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: PyExceptionInstance_Class(op)
|
||||||
|
|
||||||
|
Equivalent to :c:func:`Py_TYPE(op) <Py_TYPE>`.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject* PyException_GetTraceback(PyObject *ex)
|
.. c:function:: PyObject* PyException_GetTraceback(PyObject *ex)
|
||||||
|
|
||||||
Return the traceback associated with the exception as a new reference, as
|
Return the traceback associated with the exception as a new reference, as
|
||||||
|
|
@ -939,6 +984,9 @@ because the :ref:`call protocol <call>` takes care of recursion handling.
|
||||||
be concatenated to the :exc:`RecursionError` message caused by the recursion
|
be concatenated to the :exc:`RecursionError` message caused by the recursion
|
||||||
depth limit.
|
depth limit.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
The :c:func:`PyUnstable_ThreadState_SetStackProtection` function.
|
||||||
|
|
||||||
.. versionchanged:: 3.9
|
.. versionchanged:: 3.9
|
||||||
This function is now also available in the :ref:`limited API <limited-c-api>`.
|
This function is now also available in the :ref:`limited API <limited-c-api>`.
|
||||||
|
|
||||||
|
|
@ -979,6 +1027,27 @@ these are the C equivalent to :func:`reprlib.recursive_repr`.
|
||||||
Ends a :c:func:`Py_ReprEnter`. Must be called once for each
|
Ends a :c:func:`Py_ReprEnter`. Must be called once for each
|
||||||
invocation of :c:func:`Py_ReprEnter` that returns zero.
|
invocation of :c:func:`Py_ReprEnter` that returns zero.
|
||||||
|
|
||||||
|
.. c:function:: int Py_GetRecursionLimit(void)
|
||||||
|
|
||||||
|
Get the recursion limit for the current interpreter. It can be set with
|
||||||
|
:c:func:`Py_SetRecursionLimit`. The recursion limit prevents the
|
||||||
|
Python interpreter stack from growing infinitely.
|
||||||
|
|
||||||
|
This function cannot fail, and the caller must hold an
|
||||||
|
:term:`attached thread state`.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
:py:func:`sys.getrecursionlimit`
|
||||||
|
|
||||||
|
.. c:function:: void Py_SetRecursionLimit(int new_limit)
|
||||||
|
|
||||||
|
Set the recursion limit for the current interpreter.
|
||||||
|
|
||||||
|
This function cannot fail, and the caller must hold an
|
||||||
|
:term:`attached thread state`.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
:py:func:`sys.setrecursionlimit`
|
||||||
|
|
||||||
.. _standardexceptions:
|
.. _standardexceptions:
|
||||||
|
|
||||||
|
|
@ -1207,3 +1276,37 @@ Warning types
|
||||||
|
|
||||||
.. versionadded:: 3.10
|
.. versionadded:: 3.10
|
||||||
:c:data:`PyExc_EncodingWarning`.
|
:c:data:`PyExc_EncodingWarning`.
|
||||||
|
|
||||||
|
|
||||||
|
Tracebacks
|
||||||
|
==========
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyTraceBack_Type
|
||||||
|
|
||||||
|
Type object for traceback objects. This is available as
|
||||||
|
:class:`types.TracebackType` in the Python layer.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyTraceBack_Check(PyObject *op)
|
||||||
|
|
||||||
|
Return true if *op* is a traceback object, false otherwise. This function
|
||||||
|
does not account for subtypes.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyTraceBack_Here(PyFrameObject *f)
|
||||||
|
|
||||||
|
Replace the :attr:`~BaseException.__traceback__` attribute on the current
|
||||||
|
exception with a new traceback prepending *f* to the existing chain.
|
||||||
|
|
||||||
|
Calling this function without an exception set is undefined behavior.
|
||||||
|
|
||||||
|
This function returns ``0`` on success, and returns ``-1`` with an
|
||||||
|
exception set on failure.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyTraceBack_Print(PyObject *tb, PyObject *f)
|
||||||
|
|
||||||
|
Write the traceback *tb* into the file *f*.
|
||||||
|
|
||||||
|
This function returns ``0`` on success, and returns ``-1`` with an
|
||||||
|
exception set on failure.
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@ Defining extension modules
|
||||||
A C extension for CPython is a shared library (for example, a ``.so`` file
|
A C extension for CPython is a shared library (for example, a ``.so`` file
|
||||||
on Linux, ``.pyd`` DLL on Windows), which is loadable into the Python process
|
on Linux, ``.pyd`` DLL on Windows), which is loadable into the Python process
|
||||||
(for example, it is compiled with compatible compiler settings), and which
|
(for example, it is compiled with compatible compiler settings), and which
|
||||||
exports an :ref:`initialization function <extension-export-hook>`.
|
exports an :dfn:`export hook` function (or an
|
||||||
|
old-style :ref:`initialization function <extension-pyinit>`).
|
||||||
|
|
||||||
To be importable by default (that is, by
|
To be importable by default (that is, by
|
||||||
:py:class:`importlib.machinery.ExtensionFileLoader`),
|
:py:class:`importlib.machinery.ExtensionFileLoader`),
|
||||||
|
|
@ -23,25 +24,127 @@ and must be named after the module name plus an extension listed in
|
||||||
One suitable tool is Setuptools, whose documentation can be found at
|
One suitable tool is Setuptools, whose documentation can be found at
|
||||||
https://setuptools.pypa.io/en/latest/setuptools.html.
|
https://setuptools.pypa.io/en/latest/setuptools.html.
|
||||||
|
|
||||||
Normally, the initialization function returns a module definition initialized
|
.. _extension-export-hook:
|
||||||
using :c:func:`PyModuleDef_Init`.
|
|
||||||
This allows splitting the creation process into several phases:
|
|
||||||
|
|
||||||
|
Extension export hook
|
||||||
|
.....................
|
||||||
|
|
||||||
|
.. versionadded:: next
|
||||||
|
|
||||||
|
Support for the :samp:`PyModExport_{<name>}` export hook was added in Python
|
||||||
|
3.15. The older way of defining modules is still available: consult either
|
||||||
|
the :ref:`extension-pyinit` section or earlier versions of this
|
||||||
|
documentation if you plan to support earlier Python versions.
|
||||||
|
|
||||||
|
The export hook must be an exported function with the following signature:
|
||||||
|
|
||||||
|
.. c:function:: PyModuleDef_Slot *PyModExport_modulename(void)
|
||||||
|
|
||||||
|
For modules with ASCII-only names, the :ref:`export hook <extension-export-hook>`
|
||||||
|
must be named :samp:`PyModExport_{<name>}`,
|
||||||
|
with ``<name>`` replaced by the module's name.
|
||||||
|
|
||||||
|
For non-ASCII module names, the export hook must instead be named
|
||||||
|
:samp:`PyModExportU_{<name>}` (note the ``U``), with ``<name>`` encoded using
|
||||||
|
Python's *punycode* encoding with hyphens replaced by underscores. In Python:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
def hook_name(name):
|
||||||
|
try:
|
||||||
|
suffix = b'_' + name.encode('ascii')
|
||||||
|
except UnicodeEncodeError:
|
||||||
|
suffix = b'U_' + name.encode('punycode').replace(b'-', b'_')
|
||||||
|
return b'PyModExport' + suffix
|
||||||
|
|
||||||
|
The export hook returns an array of :c:type:`PyModuleDef_Slot` entries,
|
||||||
|
terminated by an entry with a slot ID of ``0``.
|
||||||
|
These slots describe how the module should be created and initialized.
|
||||||
|
|
||||||
|
This array must remain valid and constant until interpreter shutdown.
|
||||||
|
Typically, it should use ``static`` storage.
|
||||||
|
Prefer using the :c:macro:`Py_mod_create` and :c:macro:`Py_mod_exec` slots
|
||||||
|
for any dynamic behavior.
|
||||||
|
|
||||||
|
The export hook may return ``NULL`` with an exception set to signal failure.
|
||||||
|
|
||||||
|
It is recommended to define the export hook function using a helper macro:
|
||||||
|
|
||||||
|
.. c:macro:: PyMODEXPORT_FUNC
|
||||||
|
|
||||||
|
Declare an extension module export hook.
|
||||||
|
This macro:
|
||||||
|
|
||||||
|
* specifies the :c:expr:`PyModuleDef_Slot*` return type,
|
||||||
|
* adds any special linkage declarations required by the platform, and
|
||||||
|
* for C++, declares the function as ``extern "C"``.
|
||||||
|
|
||||||
|
For example, a module called ``spam`` would be defined like this::
|
||||||
|
|
||||||
|
PyABIInfo_VAR(abi_info);
|
||||||
|
|
||||||
|
static PyModuleDef_Slot spam_slots[] = {
|
||||||
|
{Py_mod_abi, &abi_info},
|
||||||
|
{Py_mod_name, "spam"},
|
||||||
|
{Py_mod_init, spam_init_function},
|
||||||
|
...
|
||||||
|
{0, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
PyMODEXPORT_FUNC
|
||||||
|
PyModExport_spam(void)
|
||||||
|
{
|
||||||
|
return spam_slots;
|
||||||
|
}
|
||||||
|
|
||||||
|
The export hook is typically the only non-\ ``static``
|
||||||
|
item defined in the module's C source.
|
||||||
|
|
||||||
|
The hook should be kept short -- ideally, one line as above.
|
||||||
|
If you do need to use Python C API in this function, it is recommended to call
|
||||||
|
``PyABIInfo_Check(&abi_info, "modulename")`` first to raise an exception,
|
||||||
|
rather than crash, in common cases of ABI mismatch.
|
||||||
|
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
It is possible to export multiple modules from a single shared library by
|
||||||
|
defining multiple export hooks.
|
||||||
|
However, importing them requires a custom importer or suitably named
|
||||||
|
copies/links of the extension file, because Python's import machinery only
|
||||||
|
finds the function corresponding to the filename.
|
||||||
|
See the `Multiple modules in one library <https://peps.python.org/pep-0489/#multiple-modules-in-one-library>`__
|
||||||
|
section in :pep:`489` for details.
|
||||||
|
|
||||||
|
|
||||||
|
.. _multi-phase-initialization:
|
||||||
|
|
||||||
|
Multi-phase initialization
|
||||||
|
..........................
|
||||||
|
|
||||||
|
The process of creating an extension module follows several phases:
|
||||||
|
|
||||||
|
- Python finds and calls the export hook to get information on how to
|
||||||
|
create the module.
|
||||||
- Before any substantial code is executed, Python can determine which
|
- Before any substantial code is executed, Python can determine which
|
||||||
capabilities the module supports, and it can adjust the environment or
|
capabilities the module supports, and it can adjust the environment or
|
||||||
refuse loading an incompatible extension.
|
refuse loading an incompatible extension.
|
||||||
- By default, Python itself creates the module object -- that is, it does
|
Slots like :c:data:`Py_mod_abi`, :c:data:`Py_mod_gil` and
|
||||||
the equivalent of :py:meth:`object.__new__` for classes.
|
:c:data:`Py_mod_multiple_interpreters` influence this step.
|
||||||
It also sets initial attributes like :attr:`~module.__package__` and
|
- By default, Python itself then creates the module object -- that is, it does
|
||||||
:attr:`~module.__loader__`.
|
the equivalent of calling :py:meth:`~object.__new__` when creating an object.
|
||||||
- Afterwards, the module object is initialized using extension-specific
|
This step can be overridden using the :c:data:`Py_mod_create` slot.
|
||||||
code -- the equivalent of :py:meth:`~object.__init__` on classes.
|
- Python sets initial module attributes like :attr:`~module.__package__` and
|
||||||
|
:attr:`~module.__loader__`, and inserts the module object into
|
||||||
|
:py:attr:`sys.modules`.
|
||||||
|
- Afterwards, the module object is initialized in an extension-specific way
|
||||||
|
-- the equivalent of :py:meth:`~object.__init__` when creating an object,
|
||||||
|
or of executing top-level code in a Python-language module.
|
||||||
|
The behavior is specified using the :c:data:`Py_mod_exec` slot.
|
||||||
|
|
||||||
This is called *multi-phase initialization* to distinguish it from the legacy
|
This is called *multi-phase initialization* to distinguish it from the legacy
|
||||||
(but still supported) *single-phase initialization* scheme,
|
(but still supported) :ref:`single-phase initialization <single-phase-initialization>`,
|
||||||
where the initialization function returns a fully constructed module.
|
where an initialization function returns a fully constructed module.
|
||||||
See the :ref:`single-phase-initialization section below <single-phase-initialization>`
|
|
||||||
for details.
|
|
||||||
|
|
||||||
.. versionchanged:: 3.5
|
.. versionchanged:: 3.5
|
||||||
|
|
||||||
|
|
@ -53,7 +156,7 @@ Multiple module instances
|
||||||
|
|
||||||
By default, extension modules are not singletons.
|
By default, extension modules are not singletons.
|
||||||
For example, if the :py:attr:`sys.modules` entry is removed and the module
|
For example, if the :py:attr:`sys.modules` entry is removed and the module
|
||||||
is re-imported, a new module object is created, and typically populated with
|
is re-imported, a new module object is created and, typically, populated with
|
||||||
fresh method and type objects.
|
fresh method and type objects.
|
||||||
The old module is subject to normal garbage collection.
|
The old module is subject to normal garbage collection.
|
||||||
This mirrors the behavior of pure-Python modules.
|
This mirrors the behavior of pure-Python modules.
|
||||||
|
|
@ -83,36 +186,34 @@ A module may also be limited to the main interpreter using
|
||||||
the :c:data:`Py_mod_multiple_interpreters` slot.
|
the :c:data:`Py_mod_multiple_interpreters` slot.
|
||||||
|
|
||||||
|
|
||||||
.. _extension-export-hook:
|
.. _extension-pyinit:
|
||||||
|
|
||||||
Initialization function
|
``PyInit`` function
|
||||||
.......................
|
...................
|
||||||
|
|
||||||
The initialization function defined by an extension module has the
|
.. deprecated:: next
|
||||||
following signature:
|
|
||||||
|
This functionality is :term:`soft deprecated`.
|
||||||
|
It will not get new features, but there are no plans to remove it.
|
||||||
|
|
||||||
|
Instead of :c:func:`PyModExport_modulename`, an extension module can define
|
||||||
|
an older-style :dfn:`initialization function` with the signature:
|
||||||
|
|
||||||
.. c:function:: PyObject* PyInit_modulename(void)
|
.. c:function:: PyObject* PyInit_modulename(void)
|
||||||
|
|
||||||
Its name should be :samp:`PyInit_{<name>}`, with ``<name>`` replaced by the
|
Its name should be :samp:`PyInit_{<name>}`, with ``<name>`` replaced by the
|
||||||
name of the module.
|
name of the module.
|
||||||
|
For non-ASCII module names, use :samp:`PyInitU_{<name>}` instead, with
|
||||||
|
``<name>`` encoded in the same way as for the
|
||||||
|
:ref:`export hook <extension-export-hook>` (that is, using Punycode
|
||||||
|
with underscores).
|
||||||
|
|
||||||
For modules with ASCII-only names, the function must instead be named
|
If a module exports both :samp:`PyInit_{<name>}` and
|
||||||
:samp:`PyInit_{<name>}`, with ``<name>`` replaced by the name of the module.
|
:samp:`PyModExport_{<name>}`, the :samp:`PyInit_{<name>}` function
|
||||||
When using :ref:`multi-phase-initialization`, non-ASCII module names
|
is ignored.
|
||||||
are allowed. In this case, the initialization function name is
|
|
||||||
:samp:`PyInitU_{<name>}`, with ``<name>`` encoded using Python's
|
|
||||||
*punycode* encoding with hyphens replaced by underscores. In Python:
|
|
||||||
|
|
||||||
.. code-block:: python
|
Like with :c:macro:`PyMODEXPORT_FUNC`, it is recommended to define the
|
||||||
|
initialization function using a helper macro:
|
||||||
def initfunc_name(name):
|
|
||||||
try:
|
|
||||||
suffix = b'_' + name.encode('ascii')
|
|
||||||
except UnicodeEncodeError:
|
|
||||||
suffix = b'U_' + name.encode('punycode').replace(b'-', b'_')
|
|
||||||
return b'PyInit' + suffix
|
|
||||||
|
|
||||||
It is recommended to define the initialization function using a helper macro:
|
|
||||||
|
|
||||||
.. c:macro:: PyMODINIT_FUNC
|
.. c:macro:: PyMODINIT_FUNC
|
||||||
|
|
||||||
|
|
@ -123,6 +224,34 @@ It is recommended to define the initialization function using a helper macro:
|
||||||
* adds any special linkage declarations required by the platform, and
|
* adds any special linkage declarations required by the platform, and
|
||||||
* for C++, declares the function as ``extern "C"``.
|
* for C++, declares the function as ``extern "C"``.
|
||||||
|
|
||||||
|
|
||||||
|
Normally, the initialization function (``PyInit_modulename``) returns
|
||||||
|
a :c:type:`PyModuleDef` instance with non-``NULL``
|
||||||
|
:c:member:`~PyModuleDef.m_slots`. This allows Python to use
|
||||||
|
:ref:`multi-phase initialization <multi-phase-initialization>`.
|
||||||
|
|
||||||
|
Before it is returned, the ``PyModuleDef`` instance must be initialized
|
||||||
|
using the following function:
|
||||||
|
|
||||||
|
.. c:function:: PyObject* PyModuleDef_Init(PyModuleDef *def)
|
||||||
|
|
||||||
|
Ensure a module definition is a properly initialized Python object that
|
||||||
|
correctly reports its type and a reference count.
|
||||||
|
|
||||||
|
Return *def* cast to ``PyObject*``, or ``NULL`` if an error occurred.
|
||||||
|
|
||||||
|
Calling this function is required before returning a :c:type:`PyModuleDef`
|
||||||
|
from a module initialization function.
|
||||||
|
It should not be used in other contexts.
|
||||||
|
|
||||||
|
Note that Python assumes that ``PyModuleDef`` structures are statically
|
||||||
|
allocated.
|
||||||
|
This function may return either a new reference or a borrowed one;
|
||||||
|
this reference must not be released.
|
||||||
|
|
||||||
|
.. versionadded:: 3.5
|
||||||
|
|
||||||
|
|
||||||
For example, a module called ``spam`` would be defined like this::
|
For example, a module called ``spam`` would be defined like this::
|
||||||
|
|
||||||
static struct PyModuleDef spam_module = {
|
static struct PyModuleDef spam_module = {
|
||||||
|
|
@ -137,59 +266,23 @@ For example, a module called ``spam`` would be defined like this::
|
||||||
return PyModuleDef_Init(&spam_module);
|
return PyModuleDef_Init(&spam_module);
|
||||||
}
|
}
|
||||||
|
|
||||||
It is possible to export multiple modules from a single shared library by
|
|
||||||
defining multiple initialization functions. However, importing them requires
|
|
||||||
using symbolic links or a custom importer, because by default only the
|
|
||||||
function corresponding to the filename is found.
|
|
||||||
See the `Multiple modules in one library <https://peps.python.org/pep-0489/#multiple-modules-in-one-library>`__
|
|
||||||
section in :pep:`489` for details.
|
|
||||||
|
|
||||||
The initialization function is typically the only non-\ ``static``
|
|
||||||
item defined in the module's C source.
|
|
||||||
|
|
||||||
|
|
||||||
.. _multi-phase-initialization:
|
|
||||||
|
|
||||||
Multi-phase initialization
|
|
||||||
..........................
|
|
||||||
|
|
||||||
Normally, the :ref:`initialization function <extension-export-hook>`
|
|
||||||
(``PyInit_modulename``) returns a :c:type:`PyModuleDef` instance with
|
|
||||||
non-``NULL`` :c:member:`~PyModuleDef.m_slots`.
|
|
||||||
Before it is returned, the ``PyModuleDef`` instance must be initialized
|
|
||||||
using the following function:
|
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject* PyModuleDef_Init(PyModuleDef *def)
|
|
||||||
|
|
||||||
Ensure a module definition is a properly initialized Python object that
|
|
||||||
correctly reports its type and a reference count.
|
|
||||||
|
|
||||||
Return *def* cast to ``PyObject*``, or ``NULL`` if an error occurred.
|
|
||||||
|
|
||||||
Calling this function is required for :ref:`multi-phase-initialization`.
|
|
||||||
It should not be used in other contexts.
|
|
||||||
|
|
||||||
Note that Python assumes that ``PyModuleDef`` structures are statically
|
|
||||||
allocated.
|
|
||||||
This function may return either a new reference or a borrowed one;
|
|
||||||
this reference must not be released.
|
|
||||||
|
|
||||||
.. versionadded:: 3.5
|
|
||||||
|
|
||||||
|
|
||||||
.. _single-phase-initialization:
|
.. _single-phase-initialization:
|
||||||
|
|
||||||
Legacy single-phase initialization
|
Legacy single-phase initialization
|
||||||
..................................
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
.. attention::
|
.. deprecated:: next
|
||||||
Single-phase initialization is a legacy mechanism to initialize extension
|
|
||||||
|
Single-phase initialization is :term:`soft deprecated`.
|
||||||
|
It is a legacy mechanism to initialize extension
|
||||||
modules, with known drawbacks and design flaws. Extension module authors
|
modules, with known drawbacks and design flaws. Extension module authors
|
||||||
are encouraged to use multi-phase initialization instead.
|
are encouraged to use multi-phase initialization instead.
|
||||||
|
|
||||||
In single-phase initialization, the
|
However, there are no plans to remove support for it.
|
||||||
:ref:`initialization function <extension-export-hook>` (``PyInit_modulename``)
|
|
||||||
|
In single-phase initialization, the old-style
|
||||||
|
:ref:`initializaton function <extension-pyinit>` (``PyInit_modulename``)
|
||||||
should create, populate and return a module object.
|
should create, populate and return a module object.
|
||||||
This is typically done using :c:func:`PyModule_Create` and functions like
|
This is typically done using :c:func:`PyModule_Create` and functions like
|
||||||
:c:func:`PyModule_AddObjectRef`.
|
:c:func:`PyModule_AddObjectRef`.
|
||||||
|
|
@ -242,6 +335,8 @@ in the following ways:
|
||||||
* Single-phase modules support module lookup functions like
|
* Single-phase modules support module lookup functions like
|
||||||
:c:func:`PyState_FindModule`.
|
:c:func:`PyState_FindModule`.
|
||||||
|
|
||||||
|
* The module's :c:member:`PyModuleDef.m_slots` must be NULL.
|
||||||
|
|
||||||
.. [#testsinglephase] ``_testsinglephase`` is an internal module used
|
.. [#testsinglephase] ``_testsinglephase`` is an internal module used
|
||||||
in CPython's self-test suite; your installation may or may not
|
in CPython's self-test suite; your installation may or may not
|
||||||
include it.
|
include it.
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,29 @@ the :mod:`io` APIs instead.
|
||||||
.. versionadded:: 3.8
|
.. versionadded:: 3.8
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: PyObject *PyFile_OpenCodeObject(PyObject *path)
|
||||||
|
|
||||||
|
Open *path* with the mode ``'rb'``. *path* must be a Python :class:`str`
|
||||||
|
object. The behavior of this function may be overridden by
|
||||||
|
:c:func:`PyFile_SetOpenCodeHook` to allow for some preprocessing of the
|
||||||
|
text.
|
||||||
|
|
||||||
|
This is analogous to :func:`io.open_code` in Python.
|
||||||
|
|
||||||
|
On success, this function returns a :term:`strong reference` to a Python
|
||||||
|
file object. On failure, this function returns ``NULL`` with an exception
|
||||||
|
set.
|
||||||
|
|
||||||
|
.. versionadded:: 3.8
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: PyObject *PyFile_OpenCode(const char *path)
|
||||||
|
|
||||||
|
Similar to :c:func:`PyFile_OpenCodeObject`, but *path* is a
|
||||||
|
UTF-8 encoded :c:expr:`const char*`.
|
||||||
|
|
||||||
|
.. versionadded:: 3.8
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyFile_WriteObject(PyObject *obj, PyObject *p, int flags)
|
.. c:function:: int PyFile_WriteObject(PyObject *obj, PyObject *p, int flags)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,111 @@ Floating-Point Objects
|
||||||
Return the minimum normalized positive float *DBL_MIN* as C :c:expr:`double`.
|
Return the minimum normalized positive float *DBL_MIN* as C :c:expr:`double`.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_INFINITY
|
||||||
|
|
||||||
|
This macro expands a to constant expression of type :c:expr:`double`, that
|
||||||
|
represents the positive infinity.
|
||||||
|
|
||||||
|
It is equivalent to the :c:macro:`!INFINITY` macro from the C11 standard
|
||||||
|
``<math.h>`` header.
|
||||||
|
|
||||||
|
.. deprecated:: 3.15
|
||||||
|
The macro is :term:`soft deprecated`.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_NAN
|
||||||
|
|
||||||
|
This macro expands a to constant expression of type :c:expr:`double`, that
|
||||||
|
represents a quiet not-a-number (qNaN) value.
|
||||||
|
|
||||||
|
On most platforms, this is equivalent to the :c:macro:`!NAN` macro from
|
||||||
|
the C11 standard ``<math.h>`` header.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_HUGE_VAL
|
||||||
|
|
||||||
|
Equivalent to :c:macro:`!INFINITY`.
|
||||||
|
|
||||||
|
.. deprecated:: 3.14
|
||||||
|
The macro is :term:`soft deprecated`.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_MATH_E
|
||||||
|
|
||||||
|
The definition (accurate for a :c:expr:`double` type) of the :data:`math.e` constant.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_MATH_El
|
||||||
|
|
||||||
|
High precision (long double) definition of :data:`~math.e` constant.
|
||||||
|
|
||||||
|
.. deprecated-removed:: 3.15 3.20
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_MATH_PI
|
||||||
|
|
||||||
|
The definition (accurate for a :c:expr:`double` type) of the :data:`math.pi` constant.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_MATH_PIl
|
||||||
|
|
||||||
|
High precision (long double) definition of :data:`~math.pi` constant.
|
||||||
|
|
||||||
|
.. deprecated-removed:: 3.15 3.20
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_MATH_TAU
|
||||||
|
|
||||||
|
The definition (accurate for a :c:expr:`double` type) of the :data:`math.tau` constant.
|
||||||
|
|
||||||
|
.. versionadded:: 3.6
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_RETURN_NAN
|
||||||
|
|
||||||
|
Return :data:`math.nan` from a function.
|
||||||
|
|
||||||
|
On most platforms, this is equivalent to ``return PyFloat_FromDouble(NAN)``.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_RETURN_INF(sign)
|
||||||
|
|
||||||
|
Return :data:`math.inf` or :data:`-math.inf <math.inf>` from a function,
|
||||||
|
depending on the sign of *sign*.
|
||||||
|
|
||||||
|
On most platforms, this is equivalent to the following::
|
||||||
|
|
||||||
|
return PyFloat_FromDouble(copysign(INFINITY, sign));
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_IS_FINITE(X)
|
||||||
|
|
||||||
|
Return ``1`` if the given floating-point number *X* is finite,
|
||||||
|
that is, it is normal, subnormal or zero, but not infinite or NaN.
|
||||||
|
Return ``0`` otherwise.
|
||||||
|
|
||||||
|
.. deprecated:: 3.14
|
||||||
|
The macro is :term:`soft deprecated`. Use :c:macro:`!isfinite` instead.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_IS_INFINITY(X)
|
||||||
|
|
||||||
|
Return ``1`` if the given floating-point number *X* is positive or negative
|
||||||
|
infinity. Return ``0`` otherwise.
|
||||||
|
|
||||||
|
.. deprecated:: 3.14
|
||||||
|
The macro is :term:`soft deprecated`. Use :c:macro:`!isinf` instead.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_IS_NAN(X)
|
||||||
|
|
||||||
|
Return ``1`` if the given floating-point number *X* is a not-a-number (NaN)
|
||||||
|
value. Return ``0`` otherwise.
|
||||||
|
|
||||||
|
.. deprecated:: 3.14
|
||||||
|
The macro is :term:`soft deprecated`. Use :c:macro:`!isnan` instead.
|
||||||
|
|
||||||
|
|
||||||
Pack and Unpack functions
|
Pack and Unpack functions
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
|
|
@ -96,8 +201,8 @@ NaNs (if such things exist on the platform) isn't handled correctly, and
|
||||||
attempting to unpack a bytes string containing an IEEE INF or NaN will raise an
|
attempting to unpack a bytes string containing an IEEE INF or NaN will raise an
|
||||||
exception.
|
exception.
|
||||||
|
|
||||||
Note that NaNs type may not be preserved on IEEE platforms (silent NaN become
|
Note that NaNs type may not be preserved on IEEE platforms (signaling NaN become
|
||||||
quiet), for example on x86 systems in 32-bit mode.
|
quiet NaN), for example on x86 systems in 32-bit mode.
|
||||||
|
|
||||||
On non-IEEE platforms with more precision, or larger dynamic range, than IEEE
|
On non-IEEE platforms with more precision, or larger dynamic range, than IEEE
|
||||||
754 supports, not all values can be packed; on non-IEEE platforms with less
|
754 supports, not all values can be packed; on non-IEEE platforms with less
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,12 @@ See also :ref:`Reflection <reflection>`.
|
||||||
Previously, this type was only available after including
|
Previously, this type was only available after including
|
||||||
``<frameobject.h>``.
|
``<frameobject.h>``.
|
||||||
|
|
||||||
|
.. c:function:: PyFrameObject *PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, PyObject *locals)
|
||||||
|
|
||||||
|
Create a new frame object. This function returns a :term:`strong reference`
|
||||||
|
to the new frame object on success, and returns ``NULL`` with an exception
|
||||||
|
set on failure.
|
||||||
|
|
||||||
.. c:function:: int PyFrame_Check(PyObject *obj)
|
.. c:function:: int PyFrame_Check(PyObject *obj)
|
||||||
|
|
||||||
Return non-zero if *obj* is a frame object.
|
Return non-zero if *obj* is a frame object.
|
||||||
|
|
@ -161,6 +167,57 @@ See :pep:`667` for more information.
|
||||||
|
|
||||||
Return non-zero if *obj* is a frame :func:`locals` proxy.
|
Return non-zero if *obj* is a frame :func:`locals` proxy.
|
||||||
|
|
||||||
|
|
||||||
|
Legacy Local Variable APIs
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
These APIs are :term:`soft deprecated`. As of Python 3.13, they do nothing.
|
||||||
|
They exist solely for backwards compatibility.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: void PyFrame_LocalsToFast(PyFrameObject *f, int clear)
|
||||||
|
|
||||||
|
This function is :term:`soft deprecated` and does nothing.
|
||||||
|
|
||||||
|
Prior to Python 3.13, this function would copy the :attr:`~frame.f_locals`
|
||||||
|
attribute of *f* to the internal "fast" array of local variables, allowing
|
||||||
|
changes in frame objects to be visible to the interpreter. If *clear* was
|
||||||
|
true, this function would process variables that were unset in the locals
|
||||||
|
dictionary.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.13
|
||||||
|
This function now does nothing.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: void PyFrame_FastToLocals(PyFrameObject *f)
|
||||||
|
|
||||||
|
This function is :term:`soft deprecated` and does nothing.
|
||||||
|
|
||||||
|
Prior to Python 3.13, this function would copy the internal "fast" array
|
||||||
|
of local variables (which is used by the interpreter) to the
|
||||||
|
:attr:`~frame.f_locals` attribute of *f*, allowing changes in local
|
||||||
|
variables to be visible to frame objects.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.13
|
||||||
|
This function now does nothing.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyFrame_FastToLocalsWithError(PyFrameObject *f)
|
||||||
|
|
||||||
|
This function is :term:`soft deprecated` and does nothing.
|
||||||
|
|
||||||
|
Prior to Python 3.13, this function was similar to
|
||||||
|
:c:func:`PyFrame_FastToLocals`, but would return ``0`` on success, and
|
||||||
|
``-1`` with an exception set on failure.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.13
|
||||||
|
This function now does nothing.
|
||||||
|
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
:pep:`667`
|
||||||
|
|
||||||
|
|
||||||
Internal Frames
|
Internal Frames
|
||||||
^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,15 @@ There are a few functions specific to Python functions.
|
||||||
dictionary of arguments or ``NULL``.
|
dictionary of arguments or ``NULL``.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyFunction_SetKwDefaults(PyObject *op, PyObject *defaults)
|
||||||
|
|
||||||
|
Set the keyword-only argument default values of the function object *op*.
|
||||||
|
*defaults* must be a dictionary of keyword-only arguments or ``Py_None``.
|
||||||
|
|
||||||
|
This function returns ``0`` on success, and returns ``-1`` with an exception
|
||||||
|
set on failure.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject* PyFunction_GetClosure(PyObject *op)
|
.. c:function:: PyObject* PyFunction_GetClosure(PyObject *op)
|
||||||
|
|
||||||
Return the closure associated with the function object *op*. This can be ``NULL``
|
Return the closure associated with the function object *op*. This can be ``NULL``
|
||||||
|
|
@ -200,7 +209,7 @@ There are a few functions specific to Python functions.
|
||||||
runtime behavior depending on optimization decisions, it does not change
|
runtime behavior depending on optimization decisions, it does not change
|
||||||
the semantics of the Python code being executed.
|
the semantics of the Python code being executed.
|
||||||
|
|
||||||
If *event* is ``PyFunction_EVENT_DESTROY``, Taking a reference in the
|
If *event* is ``PyFunction_EVENT_DESTROY``, taking a reference in the
|
||||||
callback to the about-to-be-destroyed function will resurrect it, preventing
|
callback to the about-to-be-destroyed function will resurrect it, preventing
|
||||||
it from being freed at this time. When the resurrected object is destroyed
|
it from being freed at this time. When the resurrected object is destroyed
|
||||||
later, any watcher callbacks active at that time will be called again.
|
later, any watcher callbacks active at that time will be called again.
|
||||||
|
|
|
||||||
|
|
@ -44,3 +44,41 @@ than explicitly calling :c:func:`PyGen_New` or :c:func:`PyGen_NewWithQualName`.
|
||||||
with ``__name__`` and ``__qualname__`` set to *name* and *qualname*.
|
with ``__name__`` and ``__qualname__`` set to *name* and *qualname*.
|
||||||
A reference to *frame* is stolen by this function. The *frame* argument
|
A reference to *frame* is stolen by this function. The *frame* argument
|
||||||
must not be ``NULL``.
|
must not be ``NULL``.
|
||||||
|
|
||||||
|
.. c:function:: PyCodeObject* PyGen_GetCode(PyGenObject *gen)
|
||||||
|
|
||||||
|
Return a new :term:`strong reference` to the code object wrapped by *gen*.
|
||||||
|
This function always succeeds.
|
||||||
|
|
||||||
|
|
||||||
|
Asynchronous Generator Objects
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
:pep:`525`
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyAsyncGen_Type
|
||||||
|
|
||||||
|
The type object corresponding to asynchronous generator objects. This is
|
||||||
|
available as :class:`types.AsyncGeneratorType` in the Python layer.
|
||||||
|
|
||||||
|
.. versionadded:: 3.6
|
||||||
|
|
||||||
|
.. c:function:: PyObject *PyAsyncGen_New(PyFrameObject *frame, PyObject *name, PyObject *qualname)
|
||||||
|
|
||||||
|
Create a new asynchronous generator wrapping *frame*, with ``__name__`` and
|
||||||
|
``__qualname__`` set to *name* and *qualname*. *frame* is stolen by this
|
||||||
|
function and must not be ``NULL``.
|
||||||
|
|
||||||
|
On success, this function returns a :term:`strong reference` to the
|
||||||
|
new asynchronous generator. On failure, this function returns ``NULL``
|
||||||
|
with an exception set.
|
||||||
|
|
||||||
|
.. versionadded:: 3.6
|
||||||
|
|
||||||
|
.. c:function:: int PyAsyncGen_CheckExact(PyObject *op)
|
||||||
|
|
||||||
|
Return true if *op* is an asynchronous generator object, false otherwise.
|
||||||
|
This function always succeeds.
|
||||||
|
|
||||||
|
.. versionadded:: 3.6
|
||||||
|
|
|
||||||
|
|
@ -11,42 +11,98 @@ See also the :c:member:`PyTypeObject.tp_hash` member and :ref:`numeric-hash`.
|
||||||
|
|
||||||
.. versionadded:: 3.2
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
|
||||||
.. c:type:: Py_uhash_t
|
.. c:type:: Py_uhash_t
|
||||||
|
|
||||||
Hash value type: unsigned integer.
|
Hash value type: unsigned integer.
|
||||||
|
|
||||||
.. versionadded:: 3.2
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_HASH_ALGORITHM
|
||||||
|
|
||||||
|
A numerical value indicating the algorithm for hashing of :class:`str`,
|
||||||
|
:class:`bytes`, and :class:`memoryview`.
|
||||||
|
|
||||||
|
The algorithm name is exposed by :data:`sys.hash_info.algorithm`.
|
||||||
|
|
||||||
|
.. versionadded:: 3.4
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_HASH_FNV
|
||||||
|
Py_HASH_SIPHASH24
|
||||||
|
Py_HASH_SIPHASH13
|
||||||
|
|
||||||
|
Numerical values to compare to :c:macro:`Py_HASH_ALGORITHM` to determine
|
||||||
|
which algorithm is used for hashing. The hash algorithm can be configured
|
||||||
|
via the configure :option:`--with-hash-algorithm` option.
|
||||||
|
|
||||||
|
.. versionadded:: 3.4
|
||||||
|
Add :c:macro:`!Py_HASH_FNV` and :c:macro:`!Py_HASH_SIPHASH24`.
|
||||||
|
|
||||||
|
.. versionadded:: 3.11
|
||||||
|
Add :c:macro:`!Py_HASH_SIPHASH13`.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: Py_HASH_CUTOFF
|
||||||
|
|
||||||
|
Buffers of length in range ``[1, Py_HASH_CUTOFF)`` are hashed using DJBX33A
|
||||||
|
instead of the algorithm described by :c:macro:`Py_HASH_ALGORITHM`.
|
||||||
|
|
||||||
|
- A :c:macro:`!Py_HASH_CUTOFF` of 0 disables the optimization.
|
||||||
|
- :c:macro:`!Py_HASH_CUTOFF` must be non-negative and less or equal than 7.
|
||||||
|
|
||||||
|
32-bit platforms should use a cutoff smaller than 64-bit platforms because
|
||||||
|
it is easier to create colliding strings. A cutoff of 7 on 64-bit platforms
|
||||||
|
and 5 on 32-bit platforms should provide a decent safety margin.
|
||||||
|
|
||||||
|
This corresponds to the :data:`sys.hash_info.cutoff` constant.
|
||||||
|
|
||||||
|
.. versionadded:: 3.4
|
||||||
|
|
||||||
|
|
||||||
.. c:macro:: PyHASH_MODULUS
|
.. c:macro:: PyHASH_MODULUS
|
||||||
|
|
||||||
The `Mersenne prime <https://en.wikipedia.org/wiki/Mersenne_prime>`_ ``P = 2**n -1``, used for numeric hash scheme.
|
The `Mersenne prime <https://en.wikipedia.org/wiki/Mersenne_prime>`_ ``P = 2**n -1``,
|
||||||
|
used for numeric hash scheme.
|
||||||
|
|
||||||
|
This corresponds to the :data:`sys.hash_info.modulus` constant.
|
||||||
|
|
||||||
.. versionadded:: 3.13
|
.. versionadded:: 3.13
|
||||||
|
|
||||||
|
|
||||||
.. c:macro:: PyHASH_BITS
|
.. c:macro:: PyHASH_BITS
|
||||||
|
|
||||||
The exponent ``n`` of ``P`` in :c:macro:`PyHASH_MODULUS`.
|
The exponent ``n`` of ``P`` in :c:macro:`PyHASH_MODULUS`.
|
||||||
|
|
||||||
.. versionadded:: 3.13
|
.. versionadded:: 3.13
|
||||||
|
|
||||||
|
|
||||||
.. c:macro:: PyHASH_MULTIPLIER
|
.. c:macro:: PyHASH_MULTIPLIER
|
||||||
|
|
||||||
Prime multiplier used in string and various other hashes.
|
Prime multiplier used in string and various other hashes.
|
||||||
|
|
||||||
.. versionadded:: 3.13
|
.. versionadded:: 3.13
|
||||||
|
|
||||||
|
|
||||||
.. c:macro:: PyHASH_INF
|
.. c:macro:: PyHASH_INF
|
||||||
|
|
||||||
The hash value returned for a positive infinity.
|
The hash value returned for a positive infinity.
|
||||||
|
|
||||||
|
This corresponds to the :data:`sys.hash_info.inf` constant.
|
||||||
|
|
||||||
.. versionadded:: 3.13
|
.. versionadded:: 3.13
|
||||||
|
|
||||||
|
|
||||||
.. c:macro:: PyHASH_IMAG
|
.. c:macro:: PyHASH_IMAG
|
||||||
|
|
||||||
The multiplier used for the imaginary part of a complex number.
|
The multiplier used for the imaginary part of a complex number.
|
||||||
|
|
||||||
|
This corresponds to the :data:`sys.hash_info.imag` constant.
|
||||||
|
|
||||||
.. versionadded:: 3.13
|
.. versionadded:: 3.13
|
||||||
|
|
||||||
|
|
||||||
.. c:type:: PyHash_FuncDef
|
.. c:type:: PyHash_FuncDef
|
||||||
|
|
||||||
Hash function definition used by :c:func:`PyHash_GetFuncDef`.
|
Hash function definition used by :c:func:`PyHash_GetFuncDef`.
|
||||||
|
|
@ -59,14 +115,20 @@ See also the :c:member:`PyTypeObject.tp_hash` member and :ref:`numeric-hash`.
|
||||||
|
|
||||||
Hash function name (UTF-8 encoded string).
|
Hash function name (UTF-8 encoded string).
|
||||||
|
|
||||||
|
This corresponds to the :data:`sys.hash_info.algorithm` constant.
|
||||||
|
|
||||||
.. c:member:: const int hash_bits
|
.. c:member:: const int hash_bits
|
||||||
|
|
||||||
Internal size of the hash value in bits.
|
Internal size of the hash value in bits.
|
||||||
|
|
||||||
|
This corresponds to the :data:`sys.hash_info.hash_bits` constant.
|
||||||
|
|
||||||
.. c:member:: const int seed_bits
|
.. c:member:: const int seed_bits
|
||||||
|
|
||||||
Size of seed input in bits.
|
Size of seed input in bits.
|
||||||
|
|
||||||
|
This corresponds to the :data:`sys.hash_info.seed_bits` constant.
|
||||||
|
|
||||||
.. versionadded:: 3.4
|
.. versionadded:: 3.4
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -314,6 +314,13 @@ Importing Modules
|
||||||
initialization.
|
initialization.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: struct _inittab *PyImport_Inittab
|
||||||
|
|
||||||
|
The table of built-in modules used by Python initialization. Do not use this directly;
|
||||||
|
use :c:func:`PyImport_AppendInittab` and :c:func:`PyImport_ExtendInittab`
|
||||||
|
instead.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject* PyImport_ImportModuleAttr(PyObject *mod_name, PyObject *attr_name)
|
.. c:function:: PyObject* PyImport_ImportModuleAttr(PyObject *mod_name, PyObject *attr_name)
|
||||||
|
|
||||||
Import the module *mod_name* and get its attribute *attr_name*.
|
Import the module *mod_name* and get its attribute *attr_name*.
|
||||||
|
|
@ -370,3 +377,24 @@ Importing Modules
|
||||||
- ``PyImport_LAZY_NONE``
|
- ``PyImport_LAZY_NONE``
|
||||||
|
|
||||||
.. versionadded:: 3.12
|
.. versionadded:: 3.12
|
||||||
|
|
||||||
|
.. c:function:: PyObject* PyImport_CreateModuleFromInitfunc(PyObject *spec, PyObject* (*initfunc)(void))
|
||||||
|
|
||||||
|
This function is a building block that enables embedders to implement
|
||||||
|
the :py:meth:`~importlib.abc.Loader.create_module` step of custom
|
||||||
|
static extension importers (e.g. of statically-linked extensions).
|
||||||
|
|
||||||
|
*spec* must be a :class:`~importlib.machinery.ModuleSpec` object.
|
||||||
|
|
||||||
|
*initfunc* must be an :ref:`initialization function <extension-export-hook>`,
|
||||||
|
the same as for :c:func:`PyImport_AppendInittab`.
|
||||||
|
|
||||||
|
On success, create and return a module object.
|
||||||
|
This module will not be initialized; call :c:func:`PyModule_Exec`
|
||||||
|
to initialize it.
|
||||||
|
(Custom importers should do this in their
|
||||||
|
:py:meth:`~importlib.abc.Loader.exec_module` method.)
|
||||||
|
|
||||||
|
On error, return NULL with an exception set.
|
||||||
|
|
||||||
|
.. versionadded:: 3.15
|
||||||
|
|
|
||||||
|
|
@ -1366,6 +1366,43 @@ All of the following functions must be called after :c:func:`Py_Initialize`.
|
||||||
.. versionadded:: 3.11
|
.. versionadded:: 3.11
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyUnstable_ThreadState_SetStackProtection(PyThreadState *tstate, void *stack_start_addr, size_t stack_size)
|
||||||
|
|
||||||
|
Set the stack protection start address and stack protection size
|
||||||
|
of a Python thread state.
|
||||||
|
|
||||||
|
On success, return ``0``.
|
||||||
|
On failure, set an exception and return ``-1``.
|
||||||
|
|
||||||
|
CPython implements :ref:`recursion control <recursion>` for C code by raising
|
||||||
|
:py:exc:`RecursionError` when it notices that the machine execution stack is close
|
||||||
|
to overflow. See for example the :c:func:`Py_EnterRecursiveCall` function.
|
||||||
|
For this, it needs to know the location of the current thread's stack, which it
|
||||||
|
normally gets from the operating system.
|
||||||
|
When the stack is changed, for example using context switching techniques like the
|
||||||
|
Boost library's ``boost::context``, you must call
|
||||||
|
:c:func:`~PyUnstable_ThreadState_SetStackProtection` to inform CPython of the change.
|
||||||
|
|
||||||
|
Call :c:func:`~PyUnstable_ThreadState_SetStackProtection` either before
|
||||||
|
or after changing the stack.
|
||||||
|
Do not call any other Python C API between the call and the stack
|
||||||
|
change.
|
||||||
|
|
||||||
|
See :c:func:`PyUnstable_ThreadState_ResetStackProtection` for undoing this operation.
|
||||||
|
|
||||||
|
.. versionadded:: 3.15
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: void PyUnstable_ThreadState_ResetStackProtection(PyThreadState *tstate)
|
||||||
|
|
||||||
|
Reset the stack protection start address and stack protection size
|
||||||
|
of a Python thread state to the operating system defaults.
|
||||||
|
|
||||||
|
See :c:func:`PyUnstable_ThreadState_SetStackProtection` for an explanation.
|
||||||
|
|
||||||
|
.. versionadded:: 3.15
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyInterpreterState* PyInterpreterState_Get(void)
|
.. c:function:: PyInterpreterState* PyInterpreterState_Get(void)
|
||||||
|
|
||||||
Get the current interpreter.
|
Get the current interpreter.
|
||||||
|
|
@ -1680,7 +1717,8 @@ function. You can create and destroy them using the following functions:
|
||||||
Only C-level static and global variables are shared between these
|
Only C-level static and global variables are shared between these
|
||||||
module objects.
|
module objects.
|
||||||
|
|
||||||
* For modules using single-phase initialization,
|
* For modules using legacy
|
||||||
|
:ref:`single-phase initialization <single-phase-initialization>`,
|
||||||
e.g. :c:func:`PyModule_Create`, the first time a particular extension
|
e.g. :c:func:`PyModule_Create`, the first time a particular extension
|
||||||
is imported, it is initialized normally, and a (shallow) copy of its
|
is imported, it is initialized normally, and a (shallow) copy of its
|
||||||
module's dictionary is squirreled away.
|
module's dictionary is squirreled away.
|
||||||
|
|
@ -1854,6 +1892,25 @@ pointer and a void pointer argument.
|
||||||
This function now always schedules *func* to be run in the main
|
This function now always schedules *func* to be run in the main
|
||||||
interpreter.
|
interpreter.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int Py_MakePendingCalls(void)
|
||||||
|
|
||||||
|
Execute all pending calls. This is usually executed automatically by the
|
||||||
|
interpreter.
|
||||||
|
|
||||||
|
This function returns ``0`` on success, and returns ``-1`` with an exception
|
||||||
|
set on failure.
|
||||||
|
|
||||||
|
If this is not called in the main thread of the main
|
||||||
|
interpreter, this function does nothing and returns ``0``.
|
||||||
|
The caller must hold an :term:`attached thread state`.
|
||||||
|
|
||||||
|
.. versionadded:: 3.1
|
||||||
|
|
||||||
|
.. versionchanged:: 3.12
|
||||||
|
This function only runs pending calls in the main interpreter.
|
||||||
|
|
||||||
|
|
||||||
.. _profiling:
|
.. _profiling:
|
||||||
|
|
||||||
Profiling and Tracing
|
Profiling and Tracing
|
||||||
|
|
@ -2483,3 +2540,220 @@ code triggered by the finalizer blocks and calls :c:func:`PyEval_SaveThread`.
|
||||||
In the default build, this macro expands to ``}``.
|
In the default build, this macro expands to ``}``.
|
||||||
|
|
||||||
.. versionadded:: 3.13
|
.. versionadded:: 3.13
|
||||||
|
|
||||||
|
|
||||||
|
Legacy Locking APIs
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
These APIs are obsolete since Python 3.13 with the introduction of
|
||||||
|
:c:type:`PyMutex`.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.15
|
||||||
|
These APIs are now a simple wrapper around ``PyMutex``.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:type:: PyThread_type_lock
|
||||||
|
|
||||||
|
A pointer to a mutual exclusion lock.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:type:: PyLockStatus
|
||||||
|
|
||||||
|
The result of acquiring a lock with a timeout.
|
||||||
|
|
||||||
|
.. c:namespace:: NULL
|
||||||
|
|
||||||
|
.. c:enumerator:: PY_LOCK_FAILURE
|
||||||
|
|
||||||
|
Failed to acquire the lock.
|
||||||
|
|
||||||
|
.. c:enumerator:: PY_LOCK_ACQUIRED
|
||||||
|
|
||||||
|
The lock was successfully acquired.
|
||||||
|
|
||||||
|
.. c:enumerator:: PY_LOCK_INTR
|
||||||
|
|
||||||
|
The lock was interrupted by a signal.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: PyThread_type_lock PyThread_allocate_lock(void)
|
||||||
|
|
||||||
|
Allocate a new lock.
|
||||||
|
|
||||||
|
On success, this function returns a lock; on failure, this
|
||||||
|
function returns ``0`` without an exception set.
|
||||||
|
|
||||||
|
The caller does not need to hold an :term:`attached thread state`.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.15
|
||||||
|
This function now always uses :c:type:`PyMutex`. In prior versions, this
|
||||||
|
would use a lock provided by the operating system.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: void PyThread_free_lock(PyThread_type_lock lock)
|
||||||
|
|
||||||
|
Destroy *lock*. The lock should not be held by any thread when calling
|
||||||
|
this.
|
||||||
|
|
||||||
|
The caller does not need to hold an :term:`attached thread state`.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: PyLockStatus PyThread_acquire_lock_timed(PyThread_type_lock lock, long long microseconds, int intr_flag)
|
||||||
|
|
||||||
|
Acquire *lock* with a timeout.
|
||||||
|
|
||||||
|
This will wait for *microseconds* microseconds to acquire the lock. If the
|
||||||
|
timeout expires, this function returns :c:enumerator:`PY_LOCK_FAILURE`.
|
||||||
|
If *microseconds* is ``-1``, this will wait indefinitely until the lock has
|
||||||
|
been released.
|
||||||
|
|
||||||
|
If *intr_flag* is ``1``, acquiring the lock may be interrupted by a signal,
|
||||||
|
in which case this function returns :c:enumerator:`PY_LOCK_INTR`. Upon
|
||||||
|
interruption, it's generally expected that the caller makes a call to
|
||||||
|
:c:func:`Py_MakePendingCalls` to propagate an exception to Python code.
|
||||||
|
|
||||||
|
If the lock is successfully acquired, this function returns
|
||||||
|
:c:enumerator:`PY_LOCK_ACQUIRED`.
|
||||||
|
|
||||||
|
The caller does not need to hold an :term:`attached thread state`.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
|
||||||
|
|
||||||
|
Acquire *lock*.
|
||||||
|
|
||||||
|
If *waitflag* is ``1`` and another thread currently holds the lock, this
|
||||||
|
function will wait until the lock can be acquired and will always return
|
||||||
|
``1``.
|
||||||
|
|
||||||
|
If *waitflag* is ``0`` and another thread holds the lock, this function will
|
||||||
|
not wait and instead return ``0``. If the lock is not held by any other
|
||||||
|
thread, then this function will acquire it and return ``1``.
|
||||||
|
|
||||||
|
Unlike :c:func:`PyThread_acquire_lock_timed`, acquiring the lock cannot be
|
||||||
|
interrupted by a signal.
|
||||||
|
|
||||||
|
The caller does not need to hold an :term:`attached thread state`.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyThread_release_lock(PyThread_type_lock lock)
|
||||||
|
|
||||||
|
Release *lock*. If *lock* is not held, then this function issues a
|
||||||
|
fatal error.
|
||||||
|
|
||||||
|
The caller does not need to hold an :term:`attached thread state`.
|
||||||
|
|
||||||
|
|
||||||
|
Operating System Thread APIs
|
||||||
|
============================
|
||||||
|
|
||||||
|
.. c:macro:: PYTHREAD_INVALID_THREAD_ID
|
||||||
|
|
||||||
|
Sentinel value for an invalid thread ID.
|
||||||
|
|
||||||
|
This is currently equivalent to ``(unsigned long)-1``.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: unsigned long PyThread_start_new_thread(void (*func)(void *), void *arg)
|
||||||
|
|
||||||
|
Start function *func* in a new thread with argument *arg*.
|
||||||
|
The resulting thread is not intended to be joined.
|
||||||
|
|
||||||
|
*func* must not be ``NULL``, but *arg* may be ``NULL``.
|
||||||
|
|
||||||
|
On success, this function returns the identifier of the new thread; on failure,
|
||||||
|
this returns :c:macro:`PYTHREAD_INVALID_THREAD_ID`.
|
||||||
|
|
||||||
|
The caller does not need to hold an :term:`attached thread state`.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: unsigned long PyThread_get_thread_ident(void)
|
||||||
|
|
||||||
|
Return the identifier of the current thread, which will never be zero.
|
||||||
|
|
||||||
|
This function cannot fail, and the caller does not need to hold an
|
||||||
|
:term:`attached thread state`.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
:py:func:`threading.get_ident`
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: PyObject *PyThread_GetInfo(void)
|
||||||
|
|
||||||
|
Get general information about the current thread in the form of a
|
||||||
|
:ref:`struct sequence <struct-sequence-objects>` object. This information is
|
||||||
|
accessible as :py:attr:`sys.thread_info` in Python.
|
||||||
|
|
||||||
|
On success, this returns a new :term:`strong reference` to the thread
|
||||||
|
information; on failure, this returns ``NULL`` with an exception set.
|
||||||
|
|
||||||
|
The caller must hold an :term:`attached thread state`.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: PY_HAVE_THREAD_NATIVE_ID
|
||||||
|
|
||||||
|
This macro is defined when the system supports native thread IDs.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: unsigned long PyThread_get_thread_native_id(void)
|
||||||
|
|
||||||
|
Get the native identifier of the current thread as it was assigned by the operating
|
||||||
|
system's kernel, which will never be less than zero.
|
||||||
|
|
||||||
|
This function is only available when :c:macro:`PY_HAVE_THREAD_NATIVE_ID` is
|
||||||
|
defined.
|
||||||
|
|
||||||
|
This function cannot fail, and the caller does not need to hold an
|
||||||
|
:term:`attached thread state`.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
:py:func:`threading.get_native_id`
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: void PyThread_exit_thread(void)
|
||||||
|
|
||||||
|
Terminate the current thread. This function is generally considered unsafe
|
||||||
|
and should be avoided. It is kept solely for backwards compatibility.
|
||||||
|
|
||||||
|
This function is only safe to call if all functions in the full call
|
||||||
|
stack are written to safely allow it.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
If the current system uses POSIX threads (also known as "pthreads"),
|
||||||
|
this calls :manpage:`pthread_exit(3)`, which attempts to unwind the stack
|
||||||
|
and call C++ destructors on some libc implementations. However, if a
|
||||||
|
``noexcept`` function is reached, it may terminate the process.
|
||||||
|
Other systems, such as macOS, do unwinding.
|
||||||
|
|
||||||
|
On Windows, this function calls ``_endthreadex()``, which kills the thread
|
||||||
|
without calling C++ destructors.
|
||||||
|
|
||||||
|
In any case, there is a risk of corruption on the thread's stack.
|
||||||
|
|
||||||
|
.. deprecated:: 3.14
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: void PyThread_init_thread(void)
|
||||||
|
|
||||||
|
Initialize ``PyThread*`` APIs. Python executes this function automatically,
|
||||||
|
so there's little need to call it from an extension module.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyThread_set_stacksize(size_t size)
|
||||||
|
|
||||||
|
Set the stack size of the current thread to *size* bytes.
|
||||||
|
|
||||||
|
This function returns ``0`` on success, ``-1`` if *size* is invalid, or
|
||||||
|
``-2`` if the system does not support changing the stack size. This function
|
||||||
|
does not set exceptions.
|
||||||
|
|
||||||
|
The caller does not need to hold an :term:`attached thread state`.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: size_t PyThread_get_stacksize(void)
|
||||||
|
|
||||||
|
Return the stack size of the current thread in bytes, or ``0`` if the system's
|
||||||
|
default stack size is in use.
|
||||||
|
|
||||||
|
The caller does not need to hold an :term:`attached thread state`.
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ Error Handling
|
||||||
* Set *\*err_msg* and return ``1`` if an error is set.
|
* Set *\*err_msg* and return ``1`` if an error is set.
|
||||||
* Set *\*err_msg* to ``NULL`` and return ``0`` otherwise.
|
* Set *\*err_msg* to ``NULL`` and return ``0`` otherwise.
|
||||||
|
|
||||||
An error message is an UTF-8 encoded string.
|
An error message is a UTF-8 encoded string.
|
||||||
|
|
||||||
If *config* has an exit code, format the exit code as an error
|
If *config* has an exit code, format the exit code as an error
|
||||||
message.
|
message.
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,10 @@ complete listing.
|
||||||
|
|
||||||
Return the absolute value of ``x``.
|
Return the absolute value of ``x``.
|
||||||
|
|
||||||
|
If the result cannot be represented (for example, if ``x`` has
|
||||||
|
:c:macro:`!INT_MIN` value for :c:expr:`int` type), the behavior is
|
||||||
|
undefined.
|
||||||
|
|
||||||
.. versionadded:: 3.3
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
.. c:macro:: Py_ALWAYS_INLINE
|
.. c:macro:: Py_ALWAYS_INLINE
|
||||||
|
|
@ -167,6 +171,17 @@ complete listing.
|
||||||
Like ``getenv(s)``, but returns ``NULL`` if :option:`-E` was passed on the
|
Like ``getenv(s)``, but returns ``NULL`` if :option:`-E` was passed on the
|
||||||
command line (see :c:member:`PyConfig.use_environment`).
|
command line (see :c:member:`PyConfig.use_environment`).
|
||||||
|
|
||||||
|
.. c:macro:: Py_LOCAL(type)
|
||||||
|
|
||||||
|
Declare a function returning the specified *type* using a fast-calling
|
||||||
|
qualifier for functions that are local to the current file.
|
||||||
|
Semantically, this is equivalent to ``static type``.
|
||||||
|
|
||||||
|
.. c:macro:: Py_LOCAL_INLINE(type)
|
||||||
|
|
||||||
|
Equivalent to :c:macro:`Py_LOCAL` but additionally requests the function
|
||||||
|
be inlined.
|
||||||
|
|
||||||
.. c:macro:: Py_MAX(x, y)
|
.. c:macro:: Py_MAX(x, y)
|
||||||
|
|
||||||
Return the maximum value between ``x`` and ``y``.
|
Return the maximum value between ``x`` and ``y``.
|
||||||
|
|
@ -179,6 +194,14 @@ complete listing.
|
||||||
|
|
||||||
.. versionadded:: 3.6
|
.. versionadded:: 3.6
|
||||||
|
|
||||||
|
.. c:macro:: Py_MEMCPY(dest, src, n)
|
||||||
|
|
||||||
|
This is a :term:`soft deprecated` alias to :c:func:`!memcpy`.
|
||||||
|
Use :c:func:`!memcpy` directly instead.
|
||||||
|
|
||||||
|
.. deprecated:: 3.14
|
||||||
|
The macro is :term:`soft deprecated`.
|
||||||
|
|
||||||
.. c:macro:: Py_MIN(x, y)
|
.. c:macro:: Py_MIN(x, y)
|
||||||
|
|
||||||
Return the minimum value between ``x`` and ``y``.
|
Return the minimum value between ``x`` and ``y``.
|
||||||
|
|
@ -233,9 +256,32 @@ complete listing.
|
||||||
|
|
||||||
.. versionadded:: 3.4
|
.. versionadded:: 3.4
|
||||||
|
|
||||||
|
.. c:macro:: Py_BUILD_ASSERT(cond)
|
||||||
|
|
||||||
|
Asserts a compile-time condition *cond*, as a statement.
|
||||||
|
The build will fail if the condition is false or cannot be evaluated at compile time.
|
||||||
|
|
||||||
|
For example::
|
||||||
|
|
||||||
|
Py_BUILD_ASSERT(sizeof(PyTime_t) == sizeof(int64_t));
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
.. c:macro:: Py_BUILD_ASSERT_EXPR(cond)
|
||||||
|
|
||||||
|
Asserts a compile-time condition *cond*, as an expression that evaluates to ``0``.
|
||||||
|
The build will fail if the condition is false or cannot be evaluated at compile time.
|
||||||
|
|
||||||
|
For example::
|
||||||
|
|
||||||
|
#define foo_to_char(foo) \
|
||||||
|
((char *)(foo) + Py_BUILD_ASSERT_EXPR(offsetof(struct foo, string) == 0))
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
.. c:macro:: PyDoc_STRVAR(name, str)
|
.. c:macro:: PyDoc_STRVAR(name, str)
|
||||||
|
|
||||||
Creates a variable with name ``name`` that can be used in docstrings.
|
Creates a variable with name *name* that can be used in docstrings.
|
||||||
If Python is built without docstrings, the value will be empty.
|
If Python is built without docstrings, the value will be empty.
|
||||||
|
|
||||||
Use :c:macro:`PyDoc_STRVAR` for docstrings to support building
|
Use :c:macro:`PyDoc_STRVAR` for docstrings to support building
|
||||||
|
|
@ -267,6 +313,28 @@ complete listing.
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
.. c:macro:: PyDoc_VAR(name)
|
||||||
|
|
||||||
|
Declares a static character array variable with the given name *name*.
|
||||||
|
|
||||||
|
For example::
|
||||||
|
|
||||||
|
PyDoc_VAR(python_doc) = PyDoc_STR("A genus of constricting snakes in the Pythonidae family native "
|
||||||
|
"to the tropics and subtropics of the Eastern Hemisphere.");
|
||||||
|
|
||||||
|
.. c:macro:: Py_ARRAY_LENGTH(array)
|
||||||
|
|
||||||
|
Compute the length of a statically allocated C array at compile time.
|
||||||
|
|
||||||
|
The *array* argument must be a C array with a size known at compile time.
|
||||||
|
Passing an array with an unknown size, such as a heap-allocated array,
|
||||||
|
will result in a compilation error on some compilers, or otherwise produce
|
||||||
|
incorrect results.
|
||||||
|
|
||||||
|
This is roughly equivalent to::
|
||||||
|
|
||||||
|
sizeof(array) / sizeof((array)[0])
|
||||||
|
|
||||||
|
|
||||||
.. _api-objects:
|
.. _api-objects:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,3 +50,72 @@ sentinel value is returned.
|
||||||
callable object that can be called with no parameters; each call to it should
|
callable object that can be called with no parameters; each call to it should
|
||||||
return the next item in the iteration. When *callable* returns a value equal to
|
return the next item in the iteration. When *callable* returns a value equal to
|
||||||
*sentinel*, the iteration will be terminated.
|
*sentinel*, the iteration will be terminated.
|
||||||
|
|
||||||
|
|
||||||
|
Range Objects
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyRange_Type
|
||||||
|
|
||||||
|
The type object for :class:`range` objects.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyRange_Check(PyObject *o)
|
||||||
|
|
||||||
|
Return true if the object *o* is an instance of a :class:`range` object.
|
||||||
|
This function always succeeds.
|
||||||
|
|
||||||
|
|
||||||
|
Builtin Iterator Types
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
These are built-in iteration types that are included in Python's C API, but
|
||||||
|
provide no additional functions. They are here for completeness.
|
||||||
|
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:widths: auto
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
* * C type
|
||||||
|
* Python type
|
||||||
|
* * .. c:var:: PyTypeObject PyEnum_Type
|
||||||
|
* :py:class:`enumerate`
|
||||||
|
* * .. c:var:: PyTypeObject PyFilter_Type
|
||||||
|
* :py:class:`filter`
|
||||||
|
* * .. c:var:: PyTypeObject PyMap_Type
|
||||||
|
* :py:class:`map`
|
||||||
|
* * .. c:var:: PyTypeObject PyReversed_Type
|
||||||
|
* :py:class:`reversed`
|
||||||
|
* * .. c:var:: PyTypeObject PyZip_Type
|
||||||
|
* :py:class:`zip`
|
||||||
|
|
||||||
|
|
||||||
|
Other Iterator Objects
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyByteArrayIter_Type
|
||||||
|
.. c:var:: PyTypeObject PyBytesIter_Type
|
||||||
|
.. c:var:: PyTypeObject PyListIter_Type
|
||||||
|
.. c:var:: PyTypeObject PyListRevIter_Type
|
||||||
|
.. c:var:: PyTypeObject PySetIter_Type
|
||||||
|
.. c:var:: PyTypeObject PyTupleIter_Type
|
||||||
|
.. c:var:: PyTypeObject PyRangeIter_Type
|
||||||
|
.. c:var:: PyTypeObject PyLongRangeIter_Type
|
||||||
|
.. c:var:: PyTypeObject PyDictIterKey_Type
|
||||||
|
.. c:var:: PyTypeObject PyDictRevIterKey_Type
|
||||||
|
.. c:var:: PyTypeObject PyDictIterValue_Type
|
||||||
|
.. c:var:: PyTypeObject PyDictRevIterValue_Type
|
||||||
|
.. c:var:: PyTypeObject PyDictIterItem_Type
|
||||||
|
.. c:var:: PyTypeObject PyDictRevIterItem_Type
|
||||||
|
.. c:var:: PyTypeObject PyODictIter_Type
|
||||||
|
|
||||||
|
Type objects for iterators of various built-in objects.
|
||||||
|
|
||||||
|
Do not create instances of these directly; prefer calling
|
||||||
|
:c:func:`PyObject_GetIter` instead.
|
||||||
|
|
||||||
|
Note that there is no guarantee that a given built-in type uses a given iterator
|
||||||
|
type. For example, iterating over :class:`range` will use one of two iterator
|
||||||
|
types depending on the size of the range. Other types may start using a
|
||||||
|
similar scheme in the future, without warning.
|
||||||
|
|
|
||||||
|
|
@ -161,6 +161,17 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
|
||||||
.. versionadded:: 3.13
|
.. versionadded:: 3.13
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: PyLong_FromPid(pid)
|
||||||
|
|
||||||
|
Macro for creating a Python integer from a process identifier.
|
||||||
|
|
||||||
|
This can be defined as an alias to :c:func:`PyLong_FromLong` or
|
||||||
|
:c:func:`PyLong_FromLongLong`, depending on the size of the system's
|
||||||
|
PID type.
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: long PyLong_AsLong(PyObject *obj)
|
.. c:function:: long PyLong_AsLong(PyObject *obj)
|
||||||
|
|
||||||
.. index::
|
.. index::
|
||||||
|
|
@ -575,6 +586,17 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
|
||||||
.. versionadded:: 3.13
|
.. versionadded:: 3.13
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: PyLong_AsPid(pid)
|
||||||
|
|
||||||
|
Macro for converting a Python integer into a process identifier.
|
||||||
|
|
||||||
|
This can be defined as an alias to :c:func:`PyLong_AsLong`,
|
||||||
|
:c:func:`PyLong_FromLongLong`, or :c:func:`PyLong_AsInt`, depending on the
|
||||||
|
size of the system's PID type.
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyLong_GetSign(PyObject *obj, int *sign)
|
.. c:function:: int PyLong_GetSign(PyObject *obj, int *sign)
|
||||||
|
|
||||||
Get the sign of the integer object *obj*.
|
Get the sign of the integer object *obj*.
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Exceptions which occur when this calls :meth:`~object.__getitem__`
|
Exceptions which occur when this calls the :meth:`~object.__getitem__`
|
||||||
method are silently ignored.
|
method are silently ignored.
|
||||||
For proper error handling, use :c:func:`PyMapping_HasKeyWithError`,
|
For proper error handling, use :c:func:`PyMapping_HasKeyWithError`,
|
||||||
:c:func:`PyMapping_GetOptionalItem` or :c:func:`PyObject_GetItem()` instead.
|
:c:func:`PyMapping_GetOptionalItem` or :c:func:`PyObject_GetItem()` instead.
|
||||||
|
|
@ -116,7 +116,7 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Exceptions that occur when this calls :meth:`~object.__getitem__`
|
Exceptions that occur when this calls the :meth:`~object.__getitem__`
|
||||||
method or while creating the temporary :class:`str`
|
method or while creating the temporary :class:`str`
|
||||||
object are silently ignored.
|
object are silently ignored.
|
||||||
For proper error handling, use :c:func:`PyMapping_HasKeyStringWithError`,
|
For proper error handling, use :c:func:`PyMapping_HasKeyStringWithError`,
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ The following functions allow marshalled values to be read back in.
|
||||||
assumes that no further objects will be read from the file, allowing it to
|
assumes that no further objects will be read from the file, allowing it to
|
||||||
aggressively load file data into memory so that the de-serialization can
|
aggressively load file data into memory so that the de-serialization can
|
||||||
operate from data in memory rather than reading a byte at a time from the
|
operate from data in memory rather than reading a byte at a time from the
|
||||||
file. Only use these variant if you are certain that you won't be reading
|
file. Only use this variant if you are certain that you won't be reading
|
||||||
anything else from the file.
|
anything else from the file.
|
||||||
|
|
||||||
On error, sets the appropriate exception (:exc:`EOFError`, :exc:`ValueError`
|
On error, sets the appropriate exception (:exc:`EOFError`, :exc:`ValueError`
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ All allocating functions belong to one of three different "domains" (see also
|
||||||
strategies and are optimized for different purposes. The specific details on
|
strategies and are optimized for different purposes. The specific details on
|
||||||
how every domain allocates memory or what internal functions each domain calls
|
how every domain allocates memory or what internal functions each domain calls
|
||||||
is considered an implementation detail, but for debugging purposes a simplified
|
is considered an implementation detail, but for debugging purposes a simplified
|
||||||
table can be found at :ref:`here <default-memory-allocators>`.
|
table can be found at :ref:`default-memory-allocators`.
|
||||||
The APIs used to allocate and free a block of memory must be from the same domain.
|
The APIs used to allocate and free a block of memory must be from the same domain.
|
||||||
For example, :c:func:`PyMem_Free` must be used to free memory allocated using :c:func:`PyMem_Malloc`.
|
For example, :c:func:`PyMem_Free` must be used to free memory allocated using :c:func:`PyMem_Malloc`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,12 @@ A :class:`memoryview` object exposes the C level :ref:`buffer interface
|
||||||
any other object.
|
any other object.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyMemoryView_Type
|
||||||
|
|
||||||
|
This instance of :c:type:`PyTypeObject` represents the Python memoryview
|
||||||
|
type. This is the same object as :class:`memoryview` in the Python layer.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject *PyMemoryView_FromObject(PyObject *obj)
|
.. c:function:: PyObject *PyMemoryView_FromObject(PyObject *obj)
|
||||||
|
|
||||||
Create a memoryview object from an object that provides the buffer interface.
|
Create a memoryview object from an object that provides the buffer interface.
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,16 @@
|
||||||
.. _moduleobjects:
|
.. _moduleobjects:
|
||||||
|
|
||||||
Module Objects
|
Module Objects
|
||||||
--------------
|
==============
|
||||||
|
|
||||||
.. index:: pair: object; module
|
.. index:: pair: object; module
|
||||||
|
|
||||||
|
|
||||||
.. c:var:: PyTypeObject PyModule_Type
|
.. c:var:: PyTypeObject PyModule_Type
|
||||||
|
|
||||||
.. index:: single: ModuleType (in module types)
|
.. index:: single: ModuleType (in module types)
|
||||||
|
|
||||||
This instance of :c:type:`PyTypeObject` represents the Python module type. This
|
This instance of :c:type:`PyTypeObject` represents the Python module type. This
|
||||||
is exposed to Python programs as ``types.ModuleType``.
|
is exposed to Python programs as :py:class:`types.ModuleType`.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyModule_Check(PyObject *p)
|
.. c:function:: int PyModule_Check(PyObject *p)
|
||||||
|
|
@ -71,6 +70,9 @@ Module Objects
|
||||||
``PyObject_*`` functions rather than directly manipulate a module's
|
``PyObject_*`` functions rather than directly manipulate a module's
|
||||||
:attr:`~object.__dict__`.
|
:attr:`~object.__dict__`.
|
||||||
|
|
||||||
|
The returned reference is borrowed from the module; it is valid until
|
||||||
|
the module is destroyed.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject* PyModule_GetNameObject(PyObject *module)
|
.. c:function:: PyObject* PyModule_GetNameObject(PyObject *module)
|
||||||
|
|
||||||
|
|
@ -90,12 +92,9 @@ Module Objects
|
||||||
Similar to :c:func:`PyModule_GetNameObject` but return the name encoded to
|
Similar to :c:func:`PyModule_GetNameObject` but return the name encoded to
|
||||||
``'utf-8'``.
|
``'utf-8'``.
|
||||||
|
|
||||||
.. c:function:: void* PyModule_GetState(PyObject *module)
|
The returned buffer is only valid until the module is renamed or destroyed.
|
||||||
|
Note that Python code may rename a module by setting its :py:attr:`~module.__name__`
|
||||||
Return the "state" of the module, that is, a pointer to the block of memory
|
attribute.
|
||||||
allocated at module creation time, or ``NULL``. See
|
|
||||||
:c:member:`PyModuleDef.m_size`.
|
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyModuleDef* PyModule_GetDef(PyObject *module)
|
.. c:function:: PyModuleDef* PyModule_GetDef(PyObject *module)
|
||||||
|
|
||||||
|
|
@ -103,7 +102,7 @@ Module Objects
|
||||||
created, or ``NULL`` if the module wasn't created from a definition.
|
created, or ``NULL`` if the module wasn't created from a definition.
|
||||||
|
|
||||||
On error, return ``NULL`` with an exception set.
|
On error, return ``NULL`` with an exception set.
|
||||||
Use :c:func:`PyErr_Occurred` to tell this case apart from a mising
|
Use :c:func:`PyErr_Occurred` to tell this case apart from a missing
|
||||||
:c:type:`!PyModuleDef`.
|
:c:type:`!PyModuleDef`.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -126,215 +125,116 @@ Module Objects
|
||||||
Similar to :c:func:`PyModule_GetFilenameObject` but return the filename
|
Similar to :c:func:`PyModule_GetFilenameObject` but return the filename
|
||||||
encoded to 'utf-8'.
|
encoded to 'utf-8'.
|
||||||
|
|
||||||
|
The returned buffer is only valid until the module's :py:attr:`~module.__file__` attribute
|
||||||
|
is reassigned or the module is destroyed.
|
||||||
|
|
||||||
.. deprecated:: 3.2
|
.. deprecated:: 3.2
|
||||||
:c:func:`PyModule_GetFilename` raises :exc:`UnicodeEncodeError` on
|
:c:func:`PyModule_GetFilename` raises :exc:`UnicodeEncodeError` on
|
||||||
unencodable filenames, use :c:func:`PyModule_GetFilenameObject` instead.
|
unencodable filenames, use :c:func:`PyModule_GetFilenameObject` instead.
|
||||||
|
|
||||||
|
|
||||||
.. _pymoduledef:
|
.. _pymoduledef_slot:
|
||||||
|
|
||||||
Module definitions
|
Module definition
|
||||||
------------------
|
-----------------
|
||||||
|
|
||||||
The functions in the previous section work on any module object, including
|
Modules created using the C API are typically defined using an
|
||||||
modules imported from Python code.
|
array of :dfn:`slots`.
|
||||||
|
The slots provide a "description" of how a module should be created.
|
||||||
|
|
||||||
Modules defined using the C API typically use a *module definition*,
|
.. versionchanged:: next
|
||||||
:c:type:`PyModuleDef` -- a statically allocated, constant “description" of
|
|
||||||
how a module should be created.
|
|
||||||
|
|
||||||
The definition is usually used to define an extension's “main” module object
|
Previously, a :c:type:`PyModuleDef` struct was necessary to define modules.
|
||||||
(see :ref:`extension-modules` for details).
|
The older way of defining modules is still available: consult either the
|
||||||
It is also used to
|
:ref:`pymoduledef` section or earlier versions of this documentation
|
||||||
:ref:`create extension modules dynamically <moduledef-dynamic>`.
|
if you plan to support earlier Python versions.
|
||||||
|
|
||||||
Unlike :c:func:`PyModule_New`, the definition allows management of
|
The slots array is usually used to define an extension module's “main”
|
||||||
*module state* -- a piece of memory that is allocated and cleared together
|
module object (see :ref:`extension-modules` for details).
|
||||||
with the module object.
|
It can also be used to
|
||||||
Unlike the module's Python attributes, Python code cannot replace or delete
|
:ref:`create extension modules dynamically <module-from-slots>`.
|
||||||
data stored in module state.
|
|
||||||
|
|
||||||
.. c:type:: PyModuleDef
|
Unless specified otherwise, the same slot ID may not be repeated
|
||||||
|
in an array of slots.
|
||||||
|
|
||||||
The module definition struct, which holds all information needed to create
|
|
||||||
a module object.
|
|
||||||
This structure must be statically allocated (or be otherwise guaranteed
|
|
||||||
to be valid while any modules created from it exist).
|
|
||||||
Usually, there is only one variable of this type for each extension module.
|
|
||||||
|
|
||||||
.. c:member:: PyModuleDef_Base m_base
|
|
||||||
|
|
||||||
Always initialize this member to :c:macro:`PyModuleDef_HEAD_INIT`.
|
|
||||||
|
|
||||||
.. c:member:: const char *m_name
|
|
||||||
|
|
||||||
Name for the new module.
|
|
||||||
|
|
||||||
.. c:member:: const char *m_doc
|
|
||||||
|
|
||||||
Docstring for the module; usually a docstring variable created with
|
|
||||||
:c:macro:`PyDoc_STRVAR` is used.
|
|
||||||
|
|
||||||
.. c:member:: Py_ssize_t m_size
|
|
||||||
|
|
||||||
Module state may be kept in a per-module memory area that can be
|
|
||||||
retrieved with :c:func:`PyModule_GetState`, rather than in static globals.
|
|
||||||
This makes modules safe for use in multiple sub-interpreters.
|
|
||||||
|
|
||||||
This memory area is allocated based on *m_size* on module creation,
|
|
||||||
and freed when the module object is deallocated, after the
|
|
||||||
:c:member:`~PyModuleDef.m_free` function has been called, if present.
|
|
||||||
|
|
||||||
Setting it to a non-negative value means that the module can be
|
|
||||||
re-initialized and specifies the additional amount of memory it requires
|
|
||||||
for its state.
|
|
||||||
|
|
||||||
Setting ``m_size`` to ``-1`` means that the module does not support
|
|
||||||
sub-interpreters, because it has global state.
|
|
||||||
Negative ``m_size`` is only allowed when using
|
|
||||||
:ref:`legacy single-phase initialization <single-phase-initialization>`
|
|
||||||
or when :ref:`creating modules dynamically <moduledef-dynamic>`.
|
|
||||||
|
|
||||||
See :PEP:`3121` for more details.
|
|
||||||
|
|
||||||
.. c:member:: PyMethodDef* m_methods
|
|
||||||
|
|
||||||
A pointer to a table of module-level functions, described by
|
|
||||||
:c:type:`PyMethodDef` values. Can be ``NULL`` if no functions are present.
|
|
||||||
|
|
||||||
.. c:member:: PyModuleDef_Slot* m_slots
|
|
||||||
|
|
||||||
An array of slot definitions for multi-phase initialization, terminated by
|
|
||||||
a ``{0, NULL}`` entry.
|
|
||||||
When using legacy single-phase initialization, *m_slots* must be ``NULL``.
|
|
||||||
|
|
||||||
.. versionchanged:: 3.5
|
|
||||||
|
|
||||||
Prior to version 3.5, this member was always set to ``NULL``,
|
|
||||||
and was defined as:
|
|
||||||
|
|
||||||
.. c:member:: inquiry m_reload
|
|
||||||
|
|
||||||
.. c:member:: traverseproc m_traverse
|
|
||||||
|
|
||||||
A traversal function to call during GC traversal of the module object, or
|
|
||||||
``NULL`` if not needed.
|
|
||||||
|
|
||||||
This function is not called if the module state was requested but is not
|
|
||||||
allocated yet. This is the case immediately after the module is created
|
|
||||||
and before the module is executed (:c:data:`Py_mod_exec` function). More
|
|
||||||
precisely, this function is not called if :c:member:`~PyModuleDef.m_size` is greater
|
|
||||||
than 0 and the module state (as returned by :c:func:`PyModule_GetState`)
|
|
||||||
is ``NULL``.
|
|
||||||
|
|
||||||
.. versionchanged:: 3.9
|
|
||||||
No longer called before the module state is allocated.
|
|
||||||
|
|
||||||
.. c:member:: inquiry m_clear
|
|
||||||
|
|
||||||
A clear function to call during GC clearing of the module object, or
|
|
||||||
``NULL`` if not needed.
|
|
||||||
|
|
||||||
This function is not called if the module state was requested but is not
|
|
||||||
allocated yet. This is the case immediately after the module is created
|
|
||||||
and before the module is executed (:c:data:`Py_mod_exec` function). More
|
|
||||||
precisely, this function is not called if :c:member:`~PyModuleDef.m_size` is greater
|
|
||||||
than 0 and the module state (as returned by :c:func:`PyModule_GetState`)
|
|
||||||
is ``NULL``.
|
|
||||||
|
|
||||||
Like :c:member:`PyTypeObject.tp_clear`, this function is not *always*
|
|
||||||
called before a module is deallocated. For example, when reference
|
|
||||||
counting is enough to determine that an object is no longer used,
|
|
||||||
the cyclic garbage collector is not involved and
|
|
||||||
:c:member:`~PyModuleDef.m_free` is called directly.
|
|
||||||
|
|
||||||
.. versionchanged:: 3.9
|
|
||||||
No longer called before the module state is allocated.
|
|
||||||
|
|
||||||
.. c:member:: freefunc m_free
|
|
||||||
|
|
||||||
A function to call during deallocation of the module object, or ``NULL``
|
|
||||||
if not needed.
|
|
||||||
|
|
||||||
This function is not called if the module state was requested but is not
|
|
||||||
allocated yet. This is the case immediately after the module is created
|
|
||||||
and before the module is executed (:c:data:`Py_mod_exec` function). More
|
|
||||||
precisely, this function is not called if :c:member:`~PyModuleDef.m_size` is greater
|
|
||||||
than 0 and the module state (as returned by :c:func:`PyModule_GetState`)
|
|
||||||
is ``NULL``.
|
|
||||||
|
|
||||||
.. versionchanged:: 3.9
|
|
||||||
No longer called before the module state is allocated.
|
|
||||||
|
|
||||||
|
|
||||||
Module slots
|
|
||||||
............
|
|
||||||
|
|
||||||
.. c:type:: PyModuleDef_Slot
|
.. c:type:: PyModuleDef_Slot
|
||||||
|
|
||||||
.. c:member:: int slot
|
.. c:member:: int slot
|
||||||
|
|
||||||
A slot ID, chosen from the available values explained below.
|
A slot ID, chosen from the available ``Py_mod_*`` values explained below.
|
||||||
|
|
||||||
|
An ID of 0 marks the end of a :c:type:`!PyModuleDef_Slot` array.
|
||||||
|
|
||||||
.. c:member:: void* value
|
.. c:member:: void* value
|
||||||
|
|
||||||
Value of the slot, whose meaning depends on the slot ID.
|
Value of the slot, whose meaning depends on the slot ID.
|
||||||
|
|
||||||
|
The value may not be NULL.
|
||||||
|
To leave a slot out, omit the :c:type:`PyModuleDef_Slot` entry entirely.
|
||||||
|
|
||||||
.. versionadded:: 3.5
|
.. versionadded:: 3.5
|
||||||
|
|
||||||
The available slot types are:
|
|
||||||
|
|
||||||
.. c:macro:: Py_mod_create
|
Metadata slots
|
||||||
|
..............
|
||||||
|
|
||||||
Specifies a function that is called to create the module object itself.
|
.. c:macro:: Py_mod_name
|
||||||
The *value* pointer of this slot must point to a function of the signature:
|
|
||||||
|
|
||||||
.. c:function:: PyObject* create_module(PyObject *spec, PyModuleDef *def)
|
:c:type:`Slot ID <PyModuleDef_Slot.slot>` for the name of the new module,
|
||||||
:no-index-entry:
|
as a NUL-terminated UTF8-encoded ``const char *``.
|
||||||
:no-contents-entry:
|
|
||||||
|
|
||||||
The function receives a :py:class:`~importlib.machinery.ModuleSpec`
|
Note that modules are typically created using a
|
||||||
instance, as defined in :PEP:`451`, and the module definition.
|
:py:class:`~importlib.machinery.ModuleSpec`, and when they are, the
|
||||||
It should return a new module object, or set an error
|
name from the spec will be used instead of :c:data:`!Py_mod_name`.
|
||||||
and return ``NULL``.
|
However, it is still recommended to include this slot for introspection
|
||||||
|
and debugging purposes.
|
||||||
|
|
||||||
This function should be kept minimal. In particular, it should not
|
.. versionadded:: next
|
||||||
call arbitrary Python code, as trying to import the same module again may
|
|
||||||
result in an infinite loop.
|
|
||||||
|
|
||||||
Multiple ``Py_mod_create`` slots may not be specified in one module
|
Use :c:member:`PyModuleDef.m_name` instead to support previous versions.
|
||||||
definition.
|
|
||||||
|
|
||||||
If ``Py_mod_create`` is not specified, the import machinery will create
|
.. c:macro:: Py_mod_doc
|
||||||
a normal module object using :c:func:`PyModule_New`. The name is taken from
|
|
||||||
*spec*, not the definition, to allow extension modules to dynamically adjust
|
|
||||||
to their place in the module hierarchy and be imported under different
|
|
||||||
names through symlinks, all while sharing a single module definition.
|
|
||||||
|
|
||||||
There is no requirement for the returned object to be an instance of
|
:c:type:`Slot ID <PyModuleDef_Slot.slot>` for the docstring of the new
|
||||||
:c:type:`PyModule_Type`. Any type can be used, as long as it supports
|
module, as a NUL-terminated UTF8-encoded ``const char *``.
|
||||||
setting and getting import-related attributes.
|
|
||||||
However, only ``PyModule_Type`` instances may be returned if the
|
|
||||||
``PyModuleDef`` has non-``NULL`` ``m_traverse``, ``m_clear``,
|
|
||||||
``m_free``; non-zero ``m_size``; or slots other than ``Py_mod_create``.
|
|
||||||
|
|
||||||
.. c:macro:: Py_mod_exec
|
Usually it is set to a variable created with :c:macro:`PyDoc_STRVAR`.
|
||||||
|
|
||||||
Specifies a function that is called to *execute* the module.
|
.. versionadded:: next
|
||||||
This is equivalent to executing the code of a Python module: typically,
|
|
||||||
this function adds classes and constants to the module.
|
|
||||||
The signature of the function is:
|
|
||||||
|
|
||||||
.. c:function:: int exec_module(PyObject* module)
|
Use :c:member:`PyModuleDef.m_doc` instead to support previous versions.
|
||||||
:no-index-entry:
|
|
||||||
:no-contents-entry:
|
|
||||||
|
|
||||||
If multiple ``Py_mod_exec`` slots are specified, they are processed in the
|
|
||||||
order they appear in the *m_slots* array.
|
Feature slots
|
||||||
|
.............
|
||||||
|
|
||||||
|
.. c:macro:: Py_mod_abi
|
||||||
|
|
||||||
|
:c:type:`Slot ID <PyModuleDef_Slot.slot>` whose value points to
|
||||||
|
a :c:struct:`PyABIInfo` structure describing the ABI that
|
||||||
|
the extension is using.
|
||||||
|
|
||||||
|
A suitable :c:struct:`!PyABIInfo` variable can be defined using the
|
||||||
|
:c:macro:`PyABIInfo_VAR` macro, as in:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
PyABIInfo_VAR(abi_info);
|
||||||
|
|
||||||
|
static PyModuleDef_Slot mymodule_slots[] = {
|
||||||
|
{Py_mod_abi, &abi_info},
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
|
When creating a module, Python checks the value of this slot
|
||||||
|
using :c:func:`PyABIInfo_Check`.
|
||||||
|
|
||||||
|
.. versionadded:: 3.15
|
||||||
|
|
||||||
.. c:macro:: Py_mod_multiple_interpreters
|
.. c:macro:: Py_mod_multiple_interpreters
|
||||||
|
|
||||||
Specifies one of the following values:
|
:c:type:`Slot ID <PyModuleDef_Slot.slot>` whose value is one of:
|
||||||
|
|
||||||
.. c:namespace:: NULL
|
.. c:namespace:: NULL
|
||||||
|
|
||||||
|
|
@ -357,9 +257,6 @@ The available slot types are:
|
||||||
This slot determines whether or not importing this module
|
This slot determines whether or not importing this module
|
||||||
in a subinterpreter will fail.
|
in a subinterpreter will fail.
|
||||||
|
|
||||||
Multiple ``Py_mod_multiple_interpreters`` slots may not be specified
|
|
||||||
in one module definition.
|
|
||||||
|
|
||||||
If ``Py_mod_multiple_interpreters`` is not specified, the import
|
If ``Py_mod_multiple_interpreters`` is not specified, the import
|
||||||
machinery defaults to ``Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED``.
|
machinery defaults to ``Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED``.
|
||||||
|
|
||||||
|
|
@ -367,7 +264,7 @@ The available slot types are:
|
||||||
|
|
||||||
.. c:macro:: Py_mod_gil
|
.. c:macro:: Py_mod_gil
|
||||||
|
|
||||||
Specifies one of the following values:
|
:c:type:`Slot ID <PyModuleDef_Slot.slot>` whose value is one of:
|
||||||
|
|
||||||
.. c:namespace:: NULL
|
.. c:namespace:: NULL
|
||||||
|
|
||||||
|
|
@ -385,45 +282,482 @@ The available slot types are:
|
||||||
this module will cause the GIL to be automatically enabled. See
|
this module will cause the GIL to be automatically enabled. See
|
||||||
:ref:`whatsnew313-free-threaded-cpython` for more detail.
|
:ref:`whatsnew313-free-threaded-cpython` for more detail.
|
||||||
|
|
||||||
Multiple ``Py_mod_gil`` slots may not be specified in one module definition.
|
|
||||||
|
|
||||||
If ``Py_mod_gil`` is not specified, the import machinery defaults to
|
If ``Py_mod_gil`` is not specified, the import machinery defaults to
|
||||||
``Py_MOD_GIL_USED``.
|
``Py_MOD_GIL_USED``.
|
||||||
|
|
||||||
.. versionadded:: 3.13
|
.. versionadded:: 3.13
|
||||||
|
|
||||||
.. c:macro:: Py_mod_abi
|
|
||||||
|
|
||||||
A pointer to a :c:struct:`PyABIInfo` structure that describes the ABI that
|
Creation and initialization slots
|
||||||
the extension is using.
|
.................................
|
||||||
|
|
||||||
When the module is loaded, the :c:struct:`!PyABIInfo` in this slot is checked
|
.. c:macro:: Py_mod_create
|
||||||
using :c:func:`PyABIInfo_Check`.
|
|
||||||
|
|
||||||
A suitable :c:struct:`!PyABIInfo` variable can be defined using the
|
:c:type:`Slot ID <PyModuleDef_Slot.slot>` for a function that creates
|
||||||
:c:macro:`PyABIInfo_VAR` macro, as in:
|
the module object itself.
|
||||||
|
The function must have the signature:
|
||||||
|
|
||||||
.. code-block:: c
|
.. c:function:: PyObject* create_module(PyObject *spec, PyModuleDef *def)
|
||||||
|
:no-index-entry:
|
||||||
|
:no-contents-entry:
|
||||||
|
|
||||||
PyABIInfo_VAR(abi_info);
|
The function will be called with:
|
||||||
|
|
||||||
static PyModuleDef_Slot mymodule_slots[] = {
|
- *spec*: a ``ModuleSpec``-like object, meaning that any attributes defined
|
||||||
{Py_mod_abi, &abi_info},
|
for :py:class:`importlib.machinery.ModuleSpec` have matching semantics.
|
||||||
...
|
However, any of the attributes may be missing.
|
||||||
};
|
- *def*: ``NULL``, or the module definition if the module is created from one.
|
||||||
|
|
||||||
.. versionadded:: 3.15
|
The function should return a new module object, or set an error
|
||||||
|
and return ``NULL``.
|
||||||
|
|
||||||
|
This function should be kept minimal. In particular, it should not
|
||||||
|
call arbitrary Python code, as trying to import the same module again may
|
||||||
|
result in an infinite loop.
|
||||||
|
|
||||||
|
If ``Py_mod_create`` is not specified, the import machinery will create
|
||||||
|
a normal module object using :c:func:`PyModule_New`. The name is taken from
|
||||||
|
*spec*, not the definition, to allow extension modules to dynamically adjust
|
||||||
|
to their place in the module hierarchy and be imported under different
|
||||||
|
names through symlinks, all while sharing a single module definition.
|
||||||
|
|
||||||
|
There is no requirement for the returned object to be an instance of
|
||||||
|
:c:type:`PyModule_Type`.
|
||||||
|
However, some slots may only be used with
|
||||||
|
:c:type:`!PyModule_Type` instances; in particular:
|
||||||
|
|
||||||
|
- :c:macro:`Py_mod_exec`,
|
||||||
|
- :ref:`module state slots <ext-module-state-slots>` (``Py_mod_state_*``),
|
||||||
|
- :c:macro:`Py_mod_token`.
|
||||||
|
|
||||||
|
.. versionadded:: 3.5
|
||||||
|
|
||||||
|
.. versionchanged:: next
|
||||||
|
|
||||||
|
The *slots* argument may be a ``ModuleSpec``-like object, rather than
|
||||||
|
a true :py:class:`~importlib.machinery.ModuleSpec` instance.
|
||||||
|
Note that previous versions of CPython did not enforce this.
|
||||||
|
|
||||||
|
The *def* argument may now be ``NULL``, since modules are not necessarily
|
||||||
|
made from definitions.
|
||||||
|
|
||||||
|
.. c:macro:: Py_mod_exec
|
||||||
|
|
||||||
|
:c:type:`Slot ID <PyModuleDef_Slot.slot>` for a function that will
|
||||||
|
:dfn:`execute`, or initialize, the module.
|
||||||
|
This function does the equivalent to executing the code of a Python module:
|
||||||
|
typically, it adds classes and constants to the module.
|
||||||
|
The signature of the function is:
|
||||||
|
|
||||||
|
.. c:function:: int exec_module(PyObject* module)
|
||||||
|
:no-index-entry:
|
||||||
|
:no-contents-entry:
|
||||||
|
|
||||||
|
See the :ref:`capi-module-support-functions` section for some useful
|
||||||
|
functions to call.
|
||||||
|
|
||||||
|
For backwards compatibility, the :c:type:`PyModuleDef.m_slots` array may
|
||||||
|
contain multiple :c:macro:`!Py_mod_exec` slots; these are processed in the
|
||||||
|
order they appear in the array.
|
||||||
|
Elsewhere (that is, in arguments to :c:func:`PyModule_FromSlotsAndSpec`
|
||||||
|
and in return values of :samp:`PyModExport_{<name>}`), repeating the slot
|
||||||
|
is not allowed.
|
||||||
|
|
||||||
|
.. versionadded:: 3.5
|
||||||
|
|
||||||
|
.. versionchanged:: next
|
||||||
|
|
||||||
|
Repeated ``Py_mod_exec`` slots are disallowed, except in
|
||||||
|
:c:type:`PyModuleDef.m_slots`.
|
||||||
|
|
||||||
|
.. c:macro:: Py_mod_methods
|
||||||
|
|
||||||
|
:c:type:`Slot ID <PyModuleDef_Slot.slot>` for a table of module-level
|
||||||
|
functions, as an array of :c:type:`PyMethodDef` values suitable as the
|
||||||
|
*functions* argument to :c:func:`PyModule_AddFunctions`.
|
||||||
|
|
||||||
|
Like other slot IDs, a slots array may only contain one
|
||||||
|
:c:macro:`!Py_mod_methods` entry.
|
||||||
|
To add functions from multiple :c:type:`PyMethodDef` arrays, call
|
||||||
|
:c:func:`PyModule_AddFunctions` in the :c:macro:`Py_mod_exec` function.
|
||||||
|
|
||||||
|
The table must be statically allocated (or otherwise guaranteed to outlive
|
||||||
|
the module object).
|
||||||
|
|
||||||
|
.. versionadded:: next
|
||||||
|
|
||||||
|
Use :c:member:`PyModuleDef.m_methods` instead to support previous versions.
|
||||||
|
|
||||||
|
.. _ext-module-state:
|
||||||
|
|
||||||
|
Module state
|
||||||
|
------------
|
||||||
|
|
||||||
|
Extension modules can have *module state* -- a
|
||||||
|
piece of memory that is allocated on module creation,
|
||||||
|
and freed when the module object is deallocated.
|
||||||
|
The module state is specified using :ref:`dedicated slots <ext-module-state-slots>`.
|
||||||
|
|
||||||
|
A typical use of module state is storing an exception type -- or indeed *any*
|
||||||
|
type object defined by the module --
|
||||||
|
|
||||||
|
Unlike the module's Python attributes, Python code cannot replace or delete
|
||||||
|
data stored in module state.
|
||||||
|
|
||||||
|
Keeping per-module information in attributes and module state, rather than in
|
||||||
|
static globals, makes module objects *isolated* and safer for use in
|
||||||
|
multiple sub-interpreters.
|
||||||
|
It also helps Python do an orderly clean-up when it shuts down.
|
||||||
|
|
||||||
|
Extensions that keep references to Python objects as part of module state must
|
||||||
|
implement :c:macro:`Py_mod_state_traverse` and :c:macro:`Py_mod_state_clear`
|
||||||
|
functions to avoid reference leaks.
|
||||||
|
|
||||||
|
To retrieve the state from a given module, use the following functions:
|
||||||
|
|
||||||
|
.. c:function:: void* PyModule_GetState(PyObject *module)
|
||||||
|
|
||||||
|
Return the "state" of the module, that is, a pointer to the block of memory
|
||||||
|
allocated at module creation time, or ``NULL``. See
|
||||||
|
:c:macro:`Py_mod_state_size`.
|
||||||
|
|
||||||
|
On error, return ``NULL`` with an exception set.
|
||||||
|
Use :c:func:`PyErr_Occurred` to tell this case apart from missing
|
||||||
|
module state.
|
||||||
|
|
||||||
|
|
||||||
.. _moduledef-dynamic:
|
.. c:function:: int PyModule_GetStateSize(PyObject *, Py_ssize_t *result)
|
||||||
|
|
||||||
|
Set *\*result* to the size of the module's state, as specified using
|
||||||
|
:c:macro:`Py_mod_state_size` (or :c:member:`PyModuleDef.m_size`),
|
||||||
|
and return 0.
|
||||||
|
|
||||||
|
On error, set *\*result* to -1, and return -1 with an exception set.
|
||||||
|
|
||||||
|
.. versionadded:: next
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. _ext-module-state-slots:
|
||||||
|
|
||||||
|
Slots for defining module state
|
||||||
|
...............................
|
||||||
|
|
||||||
|
The following :c:member:`PyModuleDef_Slot.slot` IDs are available for
|
||||||
|
defining the module state.
|
||||||
|
|
||||||
|
.. c:macro:: Py_mod_state_size
|
||||||
|
|
||||||
|
:c:type:`Slot ID <PyModuleDef_Slot.slot>` for the size of the module state,
|
||||||
|
in bytes.
|
||||||
|
|
||||||
|
Setting the value to a non-negative value means that the module can be
|
||||||
|
re-initialized and specifies the additional amount of memory it requires
|
||||||
|
for its state.
|
||||||
|
|
||||||
|
See :PEP:`3121` for more details.
|
||||||
|
|
||||||
|
Use :c:func:`PyModule_GetStateSize` to retrieve the size of a given module.
|
||||||
|
|
||||||
|
.. versionadded:: next
|
||||||
|
|
||||||
|
Use :c:member:`PyModuleDef.m_size` instead to support previous versions.
|
||||||
|
|
||||||
|
.. c:macro:: Py_mod_state_traverse
|
||||||
|
|
||||||
|
:c:type:`Slot ID <PyModuleDef_Slot.slot>` for a traversal function to call
|
||||||
|
during GC traversal of the module object.
|
||||||
|
|
||||||
|
The signature of the function, and meanings of the arguments,
|
||||||
|
is similar as for :c:member:`PyTypeObject.tp_traverse`:
|
||||||
|
|
||||||
|
.. c:function:: int traverse_module_state(PyObject *module, visitproc visit, void *arg)
|
||||||
|
:no-index-entry:
|
||||||
|
:no-contents-entry:
|
||||||
|
|
||||||
|
This function is not called if the module state was requested but is not
|
||||||
|
allocated yet. This is the case immediately after the module is created
|
||||||
|
and before the module is executed (:c:data:`Py_mod_exec` function). More
|
||||||
|
precisely, this function is not called if the state size
|
||||||
|
(:c:data:`Py_mod_state_size`) is greater than 0 and the module state
|
||||||
|
(as returned by :c:func:`PyModule_GetState`) is ``NULL``.
|
||||||
|
|
||||||
|
.. versionadded:: next
|
||||||
|
|
||||||
|
Use :c:member:`PyModuleDef.m_size` instead to support previous versions.
|
||||||
|
|
||||||
|
.. c:macro:: Py_mod_state_clear
|
||||||
|
|
||||||
|
:c:type:`Slot ID <PyModuleDef_Slot.slot>` for a clear function to call
|
||||||
|
during GC clearing of the module object.
|
||||||
|
|
||||||
|
The signature of the function is:
|
||||||
|
|
||||||
|
.. c:function:: int clear_module_state(PyObject* module)
|
||||||
|
:no-index-entry:
|
||||||
|
:no-contents-entry:
|
||||||
|
|
||||||
|
This function is not called if the module state was requested but is not
|
||||||
|
allocated yet. This is the case immediately after the module is created
|
||||||
|
and before the module is executed (:c:data:`Py_mod_exec` function). More
|
||||||
|
precisely, this function is not called if the state size
|
||||||
|
(:c:data:`Py_mod_state_size`) is greater than 0 and the module state
|
||||||
|
(as returned by :c:func:`PyModule_GetState`) is ``NULL``.
|
||||||
|
|
||||||
|
Like :c:member:`PyTypeObject.tp_clear`, this function is not *always*
|
||||||
|
called before a module is deallocated. For example, when reference
|
||||||
|
counting is enough to determine that an object is no longer used,
|
||||||
|
the cyclic garbage collector is not involved and
|
||||||
|
the :c:macro:`Py_mod_state_free` function is called directly.
|
||||||
|
|
||||||
|
.. versionadded:: next
|
||||||
|
|
||||||
|
Use :c:member:`PyModuleDef.m_clear` instead to support previous versions.
|
||||||
|
|
||||||
|
.. c:macro:: Py_mod_state_free
|
||||||
|
|
||||||
|
:c:type:`Slot ID <PyModuleDef_Slot.slot>` for a function to call during
|
||||||
|
deallocation of the module object.
|
||||||
|
|
||||||
|
The signature of the function is:
|
||||||
|
|
||||||
|
.. c:function:: int free_module_state(PyObject* module)
|
||||||
|
:no-index-entry:
|
||||||
|
:no-contents-entry:
|
||||||
|
|
||||||
|
This function is not called if the module state was requested but is not
|
||||||
|
allocated yet. This is the case immediately after the module is created
|
||||||
|
and before the module is executed (:c:data:`Py_mod_exec` function). More
|
||||||
|
precisely, this function is not called if the state size
|
||||||
|
(:c:data:`Py_mod_state_size`) is greater than 0 and the module state
|
||||||
|
(as returned by :c:func:`PyModule_GetState`) is ``NULL``.
|
||||||
|
|
||||||
|
.. versionadded:: next
|
||||||
|
|
||||||
|
Use :c:member:`PyModuleDef.m_free` instead to support previous versions.
|
||||||
|
|
||||||
|
|
||||||
|
.. _ext-module-token:
|
||||||
|
|
||||||
|
Module token
|
||||||
|
............
|
||||||
|
|
||||||
|
Each module may have an associated *token*: a pointer-sized value intended to
|
||||||
|
identify of the module state's memory layout.
|
||||||
|
This means that if you have a module object, but you are not sure if it
|
||||||
|
“belongs” to your extension, you can check using code like this:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
PyObject *module = <the module in question>
|
||||||
|
|
||||||
|
void *module_token;
|
||||||
|
if (PyModule_GetToken(module, &module_token) < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (module_token != your_token) {
|
||||||
|
PyErr_SetString(PyExc_ValueError, "unexpected module")
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This module's state has the expected memory layout; it's safe to cast
|
||||||
|
struct my_state state = (struct my_state*)PyModule_GetState(module)
|
||||||
|
|
||||||
|
A module's token -- and the *your_token* value to use in the above code -- is:
|
||||||
|
|
||||||
|
- For modules created with :c:type:`PyModuleDef`: the address of that
|
||||||
|
:c:type:`PyModuleDef`;
|
||||||
|
- For modules defined with the :c:macro:`Py_mod_token` slot: the value
|
||||||
|
of that slot;
|
||||||
|
- For modules created from an ``PyModExport_*``
|
||||||
|
:ref:`export hook <extension-export-hook>`: the slots array that the export
|
||||||
|
hook returned (unless overriden with :c:macro:`Py_mod_token`).
|
||||||
|
|
||||||
|
.. c:macro:: Py_mod_token
|
||||||
|
|
||||||
|
:c:type:`Slot ID <PyModuleDef_Slot.slot>` for the module token.
|
||||||
|
|
||||||
|
If you use this slot to set the module token (rather than rely on the
|
||||||
|
default), you must ensure that:
|
||||||
|
|
||||||
|
* The pointer outlives the class, so it's not reused for something else
|
||||||
|
while the class exists.
|
||||||
|
* It "belongs" to the extension module where the class lives, so it will not
|
||||||
|
clash with other extensions.
|
||||||
|
* If the token points to a :c:type:`PyModuleDef` struct, the module should
|
||||||
|
behave as if it was created from that :c:type:`PyModuleDef`.
|
||||||
|
In particular, the module state must have matching layout and semantics.
|
||||||
|
|
||||||
|
Modules created from :c:type:`PyModuleDef` allways use the address of
|
||||||
|
the :c:type:`PyModuleDef` as the token.
|
||||||
|
This means that :c:macro:`!Py_mod_token` cannot be used in
|
||||||
|
:c:member:`PyModuleDef.m_slots`.
|
||||||
|
|
||||||
|
.. versionadded:: next
|
||||||
|
|
||||||
|
.. c:function:: int PyModule_GetToken(PyObject *module, void** result)
|
||||||
|
|
||||||
|
Set *\*result* to the module's token and return 0.
|
||||||
|
|
||||||
|
On error, set *\*result* to NULL, and return -1 with an exception set.
|
||||||
|
|
||||||
|
.. versionadded:: next
|
||||||
|
|
||||||
|
See also :c:func:`PyType_GetModuleByToken`.
|
||||||
|
|
||||||
|
|
||||||
|
.. _module-from-slots:
|
||||||
|
|
||||||
Creating extension modules dynamically
|
Creating extension modules dynamically
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
The following functions may be used to create a module outside of an
|
The following functions may be used to create an extension module dynamically,
|
||||||
extension's :ref:`initialization function <extension-export-hook>`.
|
rather than from an extension's :ref:`export hook <extension-export-hook>`.
|
||||||
They are also used in
|
|
||||||
:ref:`single-phase initialization <single-phase-initialization>`.
|
.. c:function:: PyObject *PyModule_FromSlotsAndSpec(const PyModuleDef_Slot *slots, PyObject *spec)
|
||||||
|
|
||||||
|
Create a new module object, given an array of :ref:`slots <pymoduledef_slot>`
|
||||||
|
and the :py:class:`~importlib.machinery.ModuleSpec` *spec*.
|
||||||
|
|
||||||
|
The *slots* argument must point to an array of :c:type:`PyModuleDef_Slot`
|
||||||
|
structures, terminated by an entry slot with slot ID of 0
|
||||||
|
(typically written as ``{0}`` or ``{0, NULL}`` in C).
|
||||||
|
The *slots* argument may not be ``NULL``.
|
||||||
|
|
||||||
|
The *spec* argument may be any ``ModuleSpec``-like object, as described
|
||||||
|
in :c:macro:`Py_mod_create` documentation.
|
||||||
|
Currently, the *spec* must have a ``name`` attribute.
|
||||||
|
|
||||||
|
On success, return the new module.
|
||||||
|
On error, return ``NULL`` with an exception set.
|
||||||
|
|
||||||
|
Note that this does not process the module's execution slot
|
||||||
|
(:c:data:`Py_mod_exec`).
|
||||||
|
Both :c:func:`!PyModule_FromSlotsAndSpec` and :c:func:`PyModule_Exec`
|
||||||
|
must be called to fully initialize a module.
|
||||||
|
(See also :ref:`multi-phase-initialization`.)
|
||||||
|
|
||||||
|
The *slots* array only needs to be valid for the duration of the
|
||||||
|
:c:func:`!PyModule_FromSlotsAndSpec` call.
|
||||||
|
In particular, it may be heap-allocated.
|
||||||
|
|
||||||
|
.. versionadded:: next
|
||||||
|
|
||||||
|
.. c:function:: int PyModule_Exec(PyObject *module)
|
||||||
|
|
||||||
|
Execute the :c:data:`Py_mod_exec` slot(s) of the given *module*.
|
||||||
|
|
||||||
|
On success, return 0.
|
||||||
|
On error, return -1 with an exception set.
|
||||||
|
|
||||||
|
For clarity: If *module* has no slots, for example if it uses
|
||||||
|
:ref:`legacy single-phase initialization <single-phase-initialization>`,
|
||||||
|
this function does nothing and returns 0.
|
||||||
|
|
||||||
|
.. versionadded:: next
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. _pymoduledef:
|
||||||
|
|
||||||
|
Module definition struct
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
Traditionally, extension modules were defined using a *module definition*
|
||||||
|
as the “description" of how a module should be created.
|
||||||
|
Rather than using an array of :ref:`slots <pymoduledef_slot>` directly,
|
||||||
|
the definition has dedicated members for most common functionality,
|
||||||
|
and allows additional slots as an extension mechanism.
|
||||||
|
|
||||||
|
This way of defining modules is still available and there are no plans to
|
||||||
|
remove it.
|
||||||
|
|
||||||
|
.. c:type:: PyModuleDef
|
||||||
|
|
||||||
|
The module definition struct, which holds information needed to create
|
||||||
|
a module object.
|
||||||
|
|
||||||
|
This structure must be statically allocated (or be otherwise guaranteed
|
||||||
|
to be valid while any modules created from it exist).
|
||||||
|
Usually, there is only one variable of this type for each extension module
|
||||||
|
defined this way.
|
||||||
|
|
||||||
|
.. c:member:: PyModuleDef_Base m_base
|
||||||
|
|
||||||
|
Always initialize this member to :c:macro:`PyModuleDef_HEAD_INIT`:
|
||||||
|
|
||||||
|
.. c:namespace:: NULL
|
||||||
|
|
||||||
|
.. c:type:: PyModuleDef_Base
|
||||||
|
|
||||||
|
The type of :c:member:`!PyModuleDef.m_base`.
|
||||||
|
|
||||||
|
.. c:macro:: PyModuleDef_HEAD_INIT
|
||||||
|
|
||||||
|
The required initial value for :c:member:`!PyModuleDef.m_base`.
|
||||||
|
|
||||||
|
.. c:member:: const char *m_name
|
||||||
|
|
||||||
|
Corresponds to the :c:macro:`Py_mod_name` slot.
|
||||||
|
|
||||||
|
.. c:member:: const char *m_doc
|
||||||
|
|
||||||
|
These members correspond to the :c:macro:`Py_mod_doc` slot.
|
||||||
|
Setting this to NULL is equivalent to omitting the slot.
|
||||||
|
|
||||||
|
.. c:member:: Py_ssize_t m_size
|
||||||
|
|
||||||
|
Corresponds to the :c:macro:`Py_mod_state_size` slot.
|
||||||
|
Setting this to zero is equivalent to omitting the slot.
|
||||||
|
|
||||||
|
When using :ref:`legacy single-phase initialization <single-phase-initialization>`
|
||||||
|
or when creating modules dynamically using :c:func:`PyModule_Create`
|
||||||
|
or :c:func:`PyModule_Create2`, :c:member:`!m_size` may be set to -1.
|
||||||
|
This indicates that the module does not support sub-interpreters,
|
||||||
|
because it has global state.
|
||||||
|
|
||||||
|
.. c:member:: PyMethodDef *m_methods
|
||||||
|
|
||||||
|
Corresponds to the :c:macro:`Py_mod_methods` slot.
|
||||||
|
Setting this to NULL is equivalent to omitting the slot.
|
||||||
|
|
||||||
|
.. c:member:: PyModuleDef_Slot* m_slots
|
||||||
|
|
||||||
|
An array of additional slots, terminated by a ``{0, NULL}`` entry.
|
||||||
|
|
||||||
|
This array may not contain slots corresponding to :c:type:`PyModuleDef`
|
||||||
|
members.
|
||||||
|
For example, you cannot use :c:macro:`Py_mod_name` in :c:member:`!m_slots`;
|
||||||
|
the module name must be given as :c:member:`PyModuleDef.m_name`.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.5
|
||||||
|
|
||||||
|
Prior to version 3.5, this member was always set to ``NULL``,
|
||||||
|
and was defined as:
|
||||||
|
|
||||||
|
.. c:member:: inquiry m_reload
|
||||||
|
|
||||||
|
.. c:member:: traverseproc m_traverse
|
||||||
|
inquiry m_clear
|
||||||
|
freefunc m_free
|
||||||
|
|
||||||
|
These members correspond to the :c:macro:`Py_mod_state_traverse`,
|
||||||
|
:c:macro:`Py_mod_state_clear`, and :c:macro:`Py_mod_state_free` slots,
|
||||||
|
respectively.
|
||||||
|
|
||||||
|
Setting these members to NULL is equivalent to omitting the
|
||||||
|
corresponding slots.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.9
|
||||||
|
|
||||||
|
:c:member:`m_traverse`, :c:member:`m_clear` and :c:member:`m_free`
|
||||||
|
functions are longer called before the module state is allocated.
|
||||||
|
|
||||||
|
|
||||||
|
.. _moduledef-dynamic:
|
||||||
|
|
||||||
|
The following API can be used to create modules from a :c:type:`!PyModuleDef`
|
||||||
|
struct:
|
||||||
|
|
||||||
.. c:function:: PyObject* PyModule_Create(PyModuleDef *def)
|
.. c:function:: PyObject* PyModule_Create(PyModuleDef *def)
|
||||||
|
|
||||||
|
|
@ -500,12 +834,13 @@ They are also used in
|
||||||
useful for versioning. This may change in the future.
|
useful for versioning. This may change in the future.
|
||||||
|
|
||||||
|
|
||||||
|
.. _capi-module-support-functions:
|
||||||
|
|
||||||
Support functions
|
Support functions
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
The following functions are provided to help initialize a module
|
The following functions are provided to help initialize a module object.
|
||||||
state.
|
They are intended for a module's execution slot (:c:data:`Py_mod_exec`),
|
||||||
They are intended for a module's execution slots (:c:data:`Py_mod_exec`),
|
|
||||||
the initialization function for legacy :ref:`single-phase initialization <single-phase-initialization>`,
|
the initialization function for legacy :ref:`single-phase initialization <single-phase-initialization>`,
|
||||||
or code that creates modules dynamically.
|
or code that creates modules dynamically.
|
||||||
|
|
||||||
|
|
@ -671,6 +1006,9 @@ or code that creates modules dynamically.
|
||||||
:c:type:`PyMethodDef` arrays; in that case they should call this function
|
:c:type:`PyMethodDef` arrays; in that case they should call this function
|
||||||
directly.
|
directly.
|
||||||
|
|
||||||
|
The *functions* array must be statically allocated (or otherwise guaranteed
|
||||||
|
to outlive the module object).
|
||||||
|
|
||||||
.. versionadded:: 3.5
|
.. versionadded:: 3.5
|
||||||
|
|
||||||
.. c:function:: int PyModule_SetDocString(PyObject *module, const char *docstring)
|
.. c:function:: int PyModule_SetDocString(PyObject *module, const char *docstring)
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ Managing the Monitoring State
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
Monitoring states can be managed with the help of monitoring scopes. A scope
|
Monitoring states can be managed with the help of monitoring scopes. A scope
|
||||||
would typically correspond to a python function.
|
would typically correspond to a Python function.
|
||||||
|
|
||||||
.. c:function:: int PyMonitoring_EnterScope(PyMonitoringState *state_array, uint64_t *version, const uint8_t *event_types, Py_ssize_t length)
|
.. c:function:: int PyMonitoring_EnterScope(PyMonitoringState *state_array, uint64_t *version, const uint8_t *event_types, Py_ssize_t length)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ Object Protocol
|
||||||
|
|
||||||
Flag to be used with multiple functions that print the object (like
|
Flag to be used with multiple functions that print the object (like
|
||||||
:c:func:`PyObject_Print` and :c:func:`PyFile_WriteObject`).
|
:c:func:`PyObject_Print` and :c:func:`PyFile_WriteObject`).
|
||||||
If passed, these function would use the :func:`str` of the object
|
If passed, these functions use the :func:`str` of the object
|
||||||
instead of the :func:`repr`.
|
instead of the :func:`repr`.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -85,6 +85,35 @@ Object Protocol
|
||||||
instead of the :func:`repr`.
|
instead of the :func:`repr`.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: void PyUnstable_Object_Dump(PyObject *op)
|
||||||
|
|
||||||
|
Dump an object *op* to ``stderr``. This should only be used for debugging.
|
||||||
|
|
||||||
|
The output is intended to try dumping objects even after memory corruption:
|
||||||
|
|
||||||
|
* Information is written starting with fields that are the least likely to
|
||||||
|
crash when accessed.
|
||||||
|
* This function can be called without an :term:`attached thread state`, but
|
||||||
|
it's not recommended to do so: it can cause deadlocks.
|
||||||
|
* An object that does not belong to the current interpreter may be dumped,
|
||||||
|
but this may also cause crashes or unintended behavior.
|
||||||
|
* Implement a heuristic to detect if the object memory has been freed. Don't
|
||||||
|
display the object contents in this case, only its memory address.
|
||||||
|
* The output format may change at any time.
|
||||||
|
|
||||||
|
Example of output:
|
||||||
|
|
||||||
|
.. code-block:: output
|
||||||
|
|
||||||
|
object address : 0x7f80124702c0
|
||||||
|
object refcount : 2
|
||||||
|
object type : 0x9902e0
|
||||||
|
object type name: str
|
||||||
|
object repr : 'abcdef'
|
||||||
|
|
||||||
|
.. versionadded:: next
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyObject_HasAttrWithError(PyObject *o, PyObject *attr_name)
|
.. c:function:: int PyObject_HasAttrWithError(PyObject *o, PyObject *attr_name)
|
||||||
|
|
||||||
Returns ``1`` if *o* has the attribute *attr_name*, and ``0`` otherwise.
|
Returns ``1`` if *o* has the attribute *attr_name*, and ``0`` otherwise.
|
||||||
|
|
|
||||||
59
Doc/c-api/picklebuffer.rst
Normal file
59
Doc/c-api/picklebuffer.rst
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
.. highlight:: c
|
||||||
|
|
||||||
|
.. _picklebuffer-objects:
|
||||||
|
|
||||||
|
.. index::
|
||||||
|
pair: object; PickleBuffer
|
||||||
|
|
||||||
|
Pickle buffer objects
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
.. versionadded:: 3.8
|
||||||
|
|
||||||
|
A :class:`pickle.PickleBuffer` object wraps a :ref:`buffer-providing object
|
||||||
|
<bufferobjects>` for out-of-band data transfer with the :mod:`pickle` module.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyPickleBuffer_Type
|
||||||
|
|
||||||
|
This instance of :c:type:`PyTypeObject` represents the Python pickle buffer type.
|
||||||
|
This is the same object as :class:`pickle.PickleBuffer` in the Python layer.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyPickleBuffer_Check(PyObject *op)
|
||||||
|
|
||||||
|
Return true if *op* is a pickle buffer instance.
|
||||||
|
This function always succeeds.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: PyObject *PyPickleBuffer_FromObject(PyObject *obj)
|
||||||
|
|
||||||
|
Create a pickle buffer from the object *obj*.
|
||||||
|
|
||||||
|
This function will fail if *obj* doesn't support the :ref:`buffer protocol <bufferobjects>`.
|
||||||
|
|
||||||
|
On success, return a new pickle buffer instance.
|
||||||
|
On failure, set an exception and return ``NULL``.
|
||||||
|
|
||||||
|
Analogous to calling :class:`pickle.PickleBuffer` with *obj* in Python.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: const Py_buffer *PyPickleBuffer_GetBuffer(PyObject *picklebuf)
|
||||||
|
|
||||||
|
Get a pointer to the underlying :c:type:`Py_buffer` that the pickle buffer wraps.
|
||||||
|
|
||||||
|
The returned pointer is valid as long as *picklebuf* is alive and has not been
|
||||||
|
released. The caller must not modify or free the returned :c:type:`Py_buffer`.
|
||||||
|
If the pickle buffer has been released, raise :exc:`ValueError`.
|
||||||
|
|
||||||
|
On success, return a pointer to the buffer view.
|
||||||
|
On failure, set an exception and return ``NULL``.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyPickleBuffer_Release(PyObject *picklebuf)
|
||||||
|
|
||||||
|
Release the underlying buffer held by the pickle buffer.
|
||||||
|
|
||||||
|
Return ``0`` on success. On failure, set an exception and return ``-1``.
|
||||||
|
|
||||||
|
Analogous to calling :meth:`pickle.PickleBuffer.release` in Python.
|
||||||
|
|
@ -147,7 +147,7 @@ subtypes but not for instances of :class:`frozenset` or its subtypes.
|
||||||
|
|
||||||
Return ``1`` if found and removed, ``0`` if not found (no action taken), and ``-1`` if an
|
Return ``1`` if found and removed, ``0`` if not found (no action taken), and ``-1`` if an
|
||||||
error is encountered. Does not raise :exc:`KeyError` for missing keys. Raise a
|
error is encountered. Does not raise :exc:`KeyError` for missing keys. Raise a
|
||||||
:exc:`TypeError` if the *key* is unhashable. Unlike the Python :meth:`~frozenset.discard`
|
:exc:`TypeError` if the *key* is unhashable. Unlike the Python :meth:`~set.discard`
|
||||||
method, this function does not automatically convert unhashable sets into
|
method, this function does not automatically convert unhashable sets into
|
||||||
temporary frozensets. Raise :exc:`SystemError` if *set* is not an
|
temporary frozensets. Raise :exc:`SystemError` if *set* is not an
|
||||||
instance of :class:`set` or its subtype.
|
instance of :class:`set` or its subtype.
|
||||||
|
|
|
||||||
|
|
@ -279,7 +279,7 @@ The full API is described below for advanced use cases.
|
||||||
|
|
||||||
.. c:member:: uint8_t abiinfo_minor_version
|
.. c:member:: uint8_t abiinfo_minor_version
|
||||||
|
|
||||||
The major version of :c:struct:`PyABIInfo`.
|
The minor version of :c:struct:`PyABIInfo`.
|
||||||
Must be set to ``0``; larger values are reserved for backwards-compatible
|
Must be set to ``0``; larger values are reserved for backwards-compatible
|
||||||
future versions of :c:struct:`!PyABIInfo`.
|
future versions of :c:struct:`!PyABIInfo`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -280,6 +280,8 @@ Implementing functions and methods
|
||||||
|
|
||||||
Name of the method.
|
Name of the method.
|
||||||
|
|
||||||
|
A ``NULL`` *ml_name* marks the end of a :c:type:`!PyMethodDef` array.
|
||||||
|
|
||||||
.. c:member:: PyCFunction ml_meth
|
.. c:member:: PyCFunction ml_meth
|
||||||
|
|
||||||
Pointer to the C implementation.
|
Pointer to the C implementation.
|
||||||
|
|
@ -447,6 +449,25 @@ definition with the same method name.
|
||||||
slot. This is helpful because calls to PyCFunctions are optimized more
|
slot. This is helpful because calls to PyCFunctions are optimized more
|
||||||
than wrapper object calls.
|
than wrapper object calls.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyCMethod_Type
|
||||||
|
|
||||||
|
The type object corresponding to Python C method objects. This is
|
||||||
|
available as :class:`types.BuiltinMethodType` in the Python layer.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyCMethod_Check(PyObject *op)
|
||||||
|
|
||||||
|
Return true if *op* is an instance of the :c:type:`PyCMethod_Type` type
|
||||||
|
or a subtype of it. This function always succeeds.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyCMethod_CheckExact(PyObject *op)
|
||||||
|
|
||||||
|
This is the same as :c:func:`PyCMethod_Check`, but does not account for
|
||||||
|
subtypes.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject * PyCMethod_New(PyMethodDef *ml, PyObject *self, PyObject *module, PyTypeObject *cls)
|
.. c:function:: PyObject * PyCMethod_New(PyMethodDef *ml, PyObject *self, PyObject *module, PyTypeObject *cls)
|
||||||
|
|
||||||
Turn *ml* into a Python :term:`callable` object.
|
Turn *ml* into a Python :term:`callable` object.
|
||||||
|
|
@ -472,6 +493,24 @@ definition with the same method name.
|
||||||
.. versionadded:: 3.9
|
.. versionadded:: 3.9
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: PyTypeObject PyCFunction_Type
|
||||||
|
|
||||||
|
The type object corresponding to Python C function objects. This is
|
||||||
|
available as :class:`types.BuiltinFunctionType` in the Python layer.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyCFunction_Check(PyObject *op)
|
||||||
|
|
||||||
|
Return true if *op* is an instance of the :c:type:`PyCFunction_Type` type
|
||||||
|
or a subtype of it. This function always succeeds.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyCFunction_CheckExact(PyObject *op)
|
||||||
|
|
||||||
|
This is the same as :c:func:`PyCFunction_Check`, but does not account for
|
||||||
|
subtypes.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject * PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
|
.. c:function:: PyObject * PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
|
||||||
|
|
||||||
Equivalent to ``PyCMethod_New(ml, self, module, NULL)``.
|
Equivalent to ``PyCMethod_New(ml, self, module, NULL)``.
|
||||||
|
|
@ -482,6 +521,62 @@ definition with the same method name.
|
||||||
Equivalent to ``PyCMethod_New(ml, self, NULL, NULL)``.
|
Equivalent to ``PyCMethod_New(ml, self, NULL, NULL)``.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyCFunction_GetFlags(PyObject *func)
|
||||||
|
|
||||||
|
Get the function's flags on *func* as they were passed to
|
||||||
|
:c:member:`~PyMethodDef.ml_flags`.
|
||||||
|
|
||||||
|
If *func* is not a C function object, this fails with an exception.
|
||||||
|
*func* must not be ``NULL``.
|
||||||
|
|
||||||
|
This function returns the function's flags on success, and ``-1`` with an
|
||||||
|
exception set on failure.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyCFunction_GET_FLAGS(PyObject *func)
|
||||||
|
|
||||||
|
This is the same as :c:func:`PyCFunction_GetFlags`, but without error
|
||||||
|
or type checking.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: PyCFunction PyCFunction_GetFunction(PyObject *func)
|
||||||
|
|
||||||
|
Get the function pointer on *func* as it was passed to
|
||||||
|
:c:member:`~PyMethodDef.ml_meth`.
|
||||||
|
|
||||||
|
If *func* is not a C function object, this fails with an exception.
|
||||||
|
*func* must not be ``NULL``.
|
||||||
|
|
||||||
|
This function returns the function pointer on success, and ``NULL`` with an
|
||||||
|
exception set on failure.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyCFunction_GET_FUNCTION(PyObject *func)
|
||||||
|
|
||||||
|
This is the same as :c:func:`PyCFunction_GetFunction`, but without error
|
||||||
|
or type checking.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: PyObject *PyCFunction_GetSelf(PyObject *func)
|
||||||
|
|
||||||
|
Get the "self" object on *func*. This is the object that would be passed
|
||||||
|
to the first argument of a :c:type:`PyCFunction`. For C function objects
|
||||||
|
created through a :c:type:`PyMethodDef` on a :c:type:`PyModuleDef`, this
|
||||||
|
is the resulting module object.
|
||||||
|
|
||||||
|
If *func* is not a C function object, this fails with an exception.
|
||||||
|
*func* must not be ``NULL``.
|
||||||
|
|
||||||
|
This function returns a :term:`borrowed reference` to the "self" object
|
||||||
|
on success, and ``NULL`` with an exception set on failure.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: PyObject *PyCFunction_GET_SELF(PyObject *func)
|
||||||
|
|
||||||
|
This is the same as :c:func:`PyCFunction_GetSelf`, but without error or
|
||||||
|
type checking.
|
||||||
|
|
||||||
|
|
||||||
Accessing attributes of extension types
|
Accessing attributes of extension types
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
|
|
@ -605,14 +700,12 @@ The following flags can be used with :c:member:`PyMemberDef.flags`:
|
||||||
entry indicates an offset from the subclass-specific data, rather than
|
entry indicates an offset from the subclass-specific data, rather than
|
||||||
from ``PyObject``.
|
from ``PyObject``.
|
||||||
|
|
||||||
Can only be used as part of :c:member:`Py_tp_members <PyTypeObject.tp_members>`
|
Can only be used as part of the :c:data:`Py_tp_members`
|
||||||
:c:type:`slot <PyType_Slot>` when creating a class using negative
|
:c:type:`slot <PyType_Slot>` when creating a class using negative
|
||||||
:c:member:`~PyType_Spec.basicsize`.
|
:c:member:`~PyType_Spec.basicsize`.
|
||||||
It is mandatory in that case.
|
It is mandatory in that case.
|
||||||
|
When setting :c:member:`~PyTypeObject.tp_members` from the slot during
|
||||||
This flag is only used in :c:type:`PyType_Slot`.
|
class creation, Python clears the flag and sets
|
||||||
When setting :c:member:`~PyTypeObject.tp_members` during
|
|
||||||
class creation, Python clears it and sets
|
|
||||||
:c:member:`PyMemberDef.offset` to the offset from the ``PyObject`` struct.
|
:c:member:`PyMemberDef.offset` to the offset from the ``PyObject`` struct.
|
||||||
|
|
||||||
.. index::
|
.. index::
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,24 @@ Operating System Utilities
|
||||||
This is a thin wrapper around either :c:func:`!sigaction` or :c:func:`!signal`. Do
|
This is a thin wrapper around either :c:func:`!sigaction` or :c:func:`!signal`. Do
|
||||||
not call those functions directly!
|
not call those functions directly!
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyOS_InterruptOccurred(void)
|
||||||
|
|
||||||
|
Check if a :c:macro:`!SIGINT` signal has been received.
|
||||||
|
|
||||||
|
Returns ``1`` if a :c:macro:`!SIGINT` has occurred and clears the signal flag,
|
||||||
|
or ``0`` otherwise.
|
||||||
|
|
||||||
|
In most cases, you should prefer :c:func:`PyErr_CheckSignals` over this function.
|
||||||
|
:c:func:`!PyErr_CheckSignals` invokes the appropriate signal handlers
|
||||||
|
for all pending signals, allowing Python code to handle the signal properly.
|
||||||
|
This function only detects :c:macro:`!SIGINT` and does not invoke any Python
|
||||||
|
signal handlers.
|
||||||
|
|
||||||
|
This function is async-signal-safe and this function cannot fail.
|
||||||
|
The caller must hold an :term:`attached thread state`.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: wchar_t* Py_DecodeLocale(const char* arg, size_t *size)
|
.. c:function:: wchar_t* Py_DecodeLocale(const char* arg, size_t *size)
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ Tuple Objects
|
||||||
.. c:function:: Py_ssize_t PyTuple_Size(PyObject *p)
|
.. c:function:: Py_ssize_t PyTuple_Size(PyObject *p)
|
||||||
|
|
||||||
Take a pointer to a tuple object, and return the size of that tuple.
|
Take a pointer to a tuple object, and return the size of that tuple.
|
||||||
On error, return ``-1`` and with an exception set.
|
On error, return ``-1`` with an exception set.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: Py_ssize_t PyTuple_GET_SIZE(PyObject *p)
|
.. c:function:: Py_ssize_t PyTuple_GET_SIZE(PyObject *p)
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,20 @@ Type Objects
|
||||||
.. versionadded:: 3.12
|
.. versionadded:: 3.12
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyType_Unwatch(int watcher_id, PyObject *type)
|
||||||
|
|
||||||
|
Mark *type* as not watched. This undoes a previous call to
|
||||||
|
:c:func:`PyType_Watch`. *type* must not be ``NULL``.
|
||||||
|
|
||||||
|
An extension should never call this function with a *watcher_id* that was
|
||||||
|
not returned to it by a previous call to :c:func:`PyType_AddWatcher`.
|
||||||
|
|
||||||
|
On success, this function returns ``0``. On failure, this function returns
|
||||||
|
``-1`` with an exception set.
|
||||||
|
|
||||||
|
.. versionadded:: 3.12
|
||||||
|
|
||||||
|
|
||||||
.. c:type:: int (*PyType_WatchCallback)(PyObject *type)
|
.. c:type:: int (*PyType_WatchCallback)(PyObject *type)
|
||||||
|
|
||||||
Type of a type-watcher callback function.
|
Type of a type-watcher callback function.
|
||||||
|
|
@ -133,6 +147,18 @@ Type Objects
|
||||||
Type features are denoted by single bit flags.
|
Type features are denoted by single bit flags.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyType_FastSubclass(PyTypeObject *type, int flag)
|
||||||
|
|
||||||
|
Return non-zero if the type object *type* sets the subclass flag *flag*.
|
||||||
|
Subclass flags are denoted by
|
||||||
|
:c:macro:`Py_TPFLAGS_*_SUBCLASS <Py_TPFLAGS_LONG_SUBCLASS>`.
|
||||||
|
This function is used by many ``_Check`` functions for common types.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
:c:func:`PyObject_TypeCheck`, which is used as a slower alternative in
|
||||||
|
``_Check`` functions for types that don't come with subclass flags.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyType_IS_GC(PyTypeObject *o)
|
.. c:function:: int PyType_IS_GC(PyTypeObject *o)
|
||||||
|
|
||||||
Return true if the type object includes support for the cycle detector; this
|
Return true if the type object includes support for the cycle detector; this
|
||||||
|
|
@ -169,12 +195,14 @@ Type Objects
|
||||||
before initialization) and should be paired with :c:func:`PyObject_Free` in
|
before initialization) and should be paired with :c:func:`PyObject_Free` in
|
||||||
:c:member:`~PyTypeObject.tp_free`.
|
:c:member:`~PyTypeObject.tp_free`.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject* PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
.. c:function:: PyObject* PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
|
|
||||||
Generic handler for the :c:member:`~PyTypeObject.tp_new` slot of a type
|
Generic handler for the :c:member:`~PyTypeObject.tp_new` slot of a type
|
||||||
object. Creates a new instance using the type's
|
object. Creates a new instance using the type's
|
||||||
:c:member:`~PyTypeObject.tp_alloc` slot and returns the resulting object.
|
:c:member:`~PyTypeObject.tp_alloc` slot and returns the resulting object.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyType_Ready(PyTypeObject *type)
|
.. c:function:: int PyType_Ready(PyTypeObject *type)
|
||||||
|
|
||||||
Finalize a type object. This should be called on all type objects to finish
|
Finalize a type object. This should be called on all type objects to finish
|
||||||
|
|
@ -191,6 +219,7 @@ Type Objects
|
||||||
GC protocol itself by at least implementing the
|
GC protocol itself by at least implementing the
|
||||||
:c:member:`~PyTypeObject.tp_traverse` handle.
|
:c:member:`~PyTypeObject.tp_traverse` handle.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject* PyType_GetName(PyTypeObject *type)
|
.. c:function:: PyObject* PyType_GetName(PyTypeObject *type)
|
||||||
|
|
||||||
Return the type's name. Equivalent to getting the type's
|
Return the type's name. Equivalent to getting the type's
|
||||||
|
|
@ -198,6 +227,7 @@ Type Objects
|
||||||
|
|
||||||
.. versionadded:: 3.11
|
.. versionadded:: 3.11
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject* PyType_GetQualName(PyTypeObject *type)
|
.. c:function:: PyObject* PyType_GetQualName(PyTypeObject *type)
|
||||||
|
|
||||||
Return the type's qualified name. Equivalent to getting the
|
Return the type's qualified name. Equivalent to getting the
|
||||||
|
|
@ -213,6 +243,7 @@ Type Objects
|
||||||
|
|
||||||
.. versionadded:: 3.13
|
.. versionadded:: 3.13
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject* PyType_GetModuleName(PyTypeObject *type)
|
.. c:function:: PyObject* PyType_GetModuleName(PyTypeObject *type)
|
||||||
|
|
||||||
Return the type's module name. Equivalent to getting the
|
Return the type's module name. Equivalent to getting the
|
||||||
|
|
@ -220,6 +251,7 @@ Type Objects
|
||||||
|
|
||||||
.. versionadded:: 3.13
|
.. versionadded:: 3.13
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: void* PyType_GetSlot(PyTypeObject *type, int slot)
|
.. c:function:: void* PyType_GetSlot(PyTypeObject *type, int slot)
|
||||||
|
|
||||||
Return the function pointer stored in the given slot. If the
|
Return the function pointer stored in the given slot. If the
|
||||||
|
|
@ -236,6 +268,7 @@ Type Objects
|
||||||
:c:func:`PyType_GetSlot` can now accept all types.
|
:c:func:`PyType_GetSlot` can now accept all types.
|
||||||
Previously, it was limited to :ref:`heap types <heap-types>`.
|
Previously, it was limited to :ref:`heap types <heap-types>`.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject* PyType_GetModule(PyTypeObject *type)
|
.. c:function:: PyObject* PyType_GetModule(PyTypeObject *type)
|
||||||
|
|
||||||
Return the module object associated with the given type when the type was
|
Return the module object associated with the given type when the type was
|
||||||
|
|
@ -250,11 +283,12 @@ Type Objects
|
||||||
``Py_TYPE(self)`` may be a *subclass* of the intended class, and subclasses
|
``Py_TYPE(self)`` may be a *subclass* of the intended class, and subclasses
|
||||||
are not necessarily defined in the same module as their superclass.
|
are not necessarily defined in the same module as their superclass.
|
||||||
See :c:type:`PyCMethod` to get the class that defines the method.
|
See :c:type:`PyCMethod` to get the class that defines the method.
|
||||||
See :c:func:`PyType_GetModuleByDef` for cases when :c:type:`!PyCMethod` cannot
|
See :c:func:`PyType_GetModuleByToken` for cases when :c:type:`!PyCMethod`
|
||||||
be used.
|
cannot be used.
|
||||||
|
|
||||||
.. versionadded:: 3.9
|
.. versionadded:: 3.9
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: void* PyType_GetModuleState(PyTypeObject *type)
|
.. c:function:: void* PyType_GetModuleState(PyTypeObject *type)
|
||||||
|
|
||||||
Return the state of the module object associated with the given type.
|
Return the state of the module object associated with the given type.
|
||||||
|
|
@ -269,10 +303,11 @@ Type Objects
|
||||||
|
|
||||||
.. versionadded:: 3.9
|
.. versionadded:: 3.9
|
||||||
|
|
||||||
.. c:function:: PyObject* PyType_GetModuleByDef(PyTypeObject *type, struct PyModuleDef *def)
|
|
||||||
|
|
||||||
Find the first superclass whose module was created from
|
.. c:function:: PyObject* PyType_GetModuleByToken(PyTypeObject *type, const void *mod_token)
|
||||||
the given :c:type:`PyModuleDef` *def*, and return that module.
|
|
||||||
|
Find the first superclass whose module has the given
|
||||||
|
:ref:`module token <ext-module-token>`, and return that module.
|
||||||
|
|
||||||
If no module is found, raises a :py:class:`TypeError` and returns ``NULL``.
|
If no module is found, raises a :py:class:`TypeError` and returns ``NULL``.
|
||||||
|
|
||||||
|
|
@ -282,16 +317,34 @@ Type Objects
|
||||||
and other places where a method's defining class cannot be passed using the
|
and other places where a method's defining class cannot be passed using the
|
||||||
:c:type:`PyCMethod` calling convention.
|
:c:type:`PyCMethod` calling convention.
|
||||||
|
|
||||||
|
.. versionadded:: next
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: PyObject* PyType_GetModuleByDef(PyTypeObject *type, struct PyModuleDef *def)
|
||||||
|
|
||||||
|
Find the first superclass whose module was created from the given
|
||||||
|
:c:type:`PyModuleDef` *def*, or whose :ref:`module token <ext-module-token>`
|
||||||
|
is equal to *def*, and return that module.
|
||||||
|
|
||||||
|
Note that modules created from a :c:type:`PyModuleDef` always have their
|
||||||
|
token set to the :c:type:`PyModuleDef`'s address.
|
||||||
|
In other words, this function is equivalent to
|
||||||
|
:c:func:`PyType_GetModuleByToken`, except that it:
|
||||||
|
|
||||||
|
- returns a borrowed reference, and
|
||||||
|
- has a non-``void*`` argument type (which is a cosmetic difference in C).
|
||||||
|
|
||||||
The returned reference is :term:`borrowed <borrowed reference>` from *type*,
|
The returned reference is :term:`borrowed <borrowed reference>` from *type*,
|
||||||
and will be valid as long as you hold a reference to *type*.
|
and will be valid as long as you hold a reference to *type*.
|
||||||
Do not release it with :c:func:`Py_DECREF` or similar.
|
Do not release it with :c:func:`Py_DECREF` or similar.
|
||||||
|
|
||||||
.. versionadded:: 3.11
|
.. versionadded:: 3.11
|
||||||
|
|
||||||
.. c:function:: int PyType_GetBaseByToken(PyTypeObject *type, void *token, PyTypeObject **result)
|
|
||||||
|
.. c:function:: int PyType_GetBaseByToken(PyTypeObject *type, void *tp_token, PyTypeObject **result)
|
||||||
|
|
||||||
Find the first superclass in *type*'s :term:`method resolution order` whose
|
Find the first superclass in *type*'s :term:`method resolution order` whose
|
||||||
:c:macro:`Py_tp_token` token is equal to the given one.
|
:c:macro:`Py_tp_token` token is equal to *tp_token*.
|
||||||
|
|
||||||
* If found, set *\*result* to a new :term:`strong reference`
|
* If found, set *\*result* to a new :term:`strong reference`
|
||||||
to it and return ``1``.
|
to it and return ``1``.
|
||||||
|
|
@ -302,10 +355,11 @@ Type Objects
|
||||||
The *result* argument may be ``NULL``, in which case *\*result* is not set.
|
The *result* argument may be ``NULL``, in which case *\*result* is not set.
|
||||||
Use this if you need only the return value.
|
Use this if you need only the return value.
|
||||||
|
|
||||||
The *token* argument may not be ``NULL``.
|
The *tp_token* argument may not be ``NULL``.
|
||||||
|
|
||||||
.. versionadded:: 3.14
|
.. versionadded:: 3.14
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyUnstable_Type_AssignVersionTag(PyTypeObject *type)
|
.. c:function:: int PyUnstable_Type_AssignVersionTag(PyTypeObject *type)
|
||||||
|
|
||||||
Attempt to assign a version tag to the given type.
|
Attempt to assign a version tag to the given type.
|
||||||
|
|
@ -316,6 +370,16 @@ Type Objects
|
||||||
.. versionadded:: 3.12
|
.. versionadded:: 3.12
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyType_SUPPORTS_WEAKREFS(PyTypeObject *type)
|
||||||
|
|
||||||
|
Return true if instances of *type* support creating weak references, false
|
||||||
|
otherwise. This function always succeeds. *type* must not be ``NULL``.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
* :ref:`weakrefobjects`
|
||||||
|
* :py:mod:`weakref`
|
||||||
|
|
||||||
|
|
||||||
Creating Heap-Allocated Types
|
Creating Heap-Allocated Types
|
||||||
.............................
|
.............................
|
||||||
|
|
||||||
|
|
@ -336,8 +400,8 @@ The following functions and structs are used to create
|
||||||
|
|
||||||
The *bases* argument can be used to specify base classes; it can either
|
The *bases* argument can be used to specify base classes; it can either
|
||||||
be only one class or a tuple of classes.
|
be only one class or a tuple of classes.
|
||||||
If *bases* is ``NULL``, the *Py_tp_bases* slot is used instead.
|
If *bases* is ``NULL``, the :c:data:`Py_tp_bases` slot is used instead.
|
||||||
If that also is ``NULL``, the *Py_tp_base* slot is used instead.
|
If that also is ``NULL``, the :c:data:`Py_tp_base` slot is used instead.
|
||||||
If that also is ``NULL``, the new type derives from :class:`object`.
|
If that also is ``NULL``, the new type derives from :class:`object`.
|
||||||
|
|
||||||
The *module* argument can be used to record the module in which the new
|
The *module* argument can be used to record the module in which the new
|
||||||
|
|
@ -364,6 +428,7 @@ The following functions and structs are used to create
|
||||||
|
|
||||||
.. versionadded:: 3.12
|
.. versionadded:: 3.12
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject* PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)
|
.. c:function:: PyObject* PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)
|
||||||
|
|
||||||
Equivalent to ``PyType_FromMetaclass(NULL, module, spec, bases)``.
|
Equivalent to ``PyType_FromMetaclass(NULL, module, spec, bases)``.
|
||||||
|
|
@ -390,6 +455,7 @@ The following functions and structs are used to create
|
||||||
Creating classes whose metaclass overrides
|
Creating classes whose metaclass overrides
|
||||||
:c:member:`~PyTypeObject.tp_new` is no longer allowed.
|
:c:member:`~PyTypeObject.tp_new` is no longer allowed.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject* PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
|
.. c:function:: PyObject* PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
|
||||||
|
|
||||||
Equivalent to ``PyType_FromMetaclass(NULL, NULL, spec, bases)``.
|
Equivalent to ``PyType_FromMetaclass(NULL, NULL, spec, bases)``.
|
||||||
|
|
@ -411,6 +477,7 @@ The following functions and structs are used to create
|
||||||
Creating classes whose metaclass overrides
|
Creating classes whose metaclass overrides
|
||||||
:c:member:`~PyTypeObject.tp_new` is no longer allowed.
|
:c:member:`~PyTypeObject.tp_new` is no longer allowed.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject* PyType_FromSpec(PyType_Spec *spec)
|
.. c:function:: PyObject* PyType_FromSpec(PyType_Spec *spec)
|
||||||
|
|
||||||
Equivalent to ``PyType_FromMetaclass(NULL, NULL, spec, NULL)``.
|
Equivalent to ``PyType_FromMetaclass(NULL, NULL, spec, NULL)``.
|
||||||
|
|
@ -431,6 +498,7 @@ The following functions and structs are used to create
|
||||||
Creating classes whose metaclass overrides
|
Creating classes whose metaclass overrides
|
||||||
:c:member:`~PyTypeObject.tp_new` is no longer allowed.
|
:c:member:`~PyTypeObject.tp_new` is no longer allowed.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyType_Freeze(PyTypeObject *type)
|
.. c:function:: int PyType_Freeze(PyTypeObject *type)
|
||||||
|
|
||||||
Make a type immutable: set the :c:macro:`Py_TPFLAGS_IMMUTABLETYPE` flag.
|
Make a type immutable: set the :c:macro:`Py_TPFLAGS_IMMUTABLETYPE` flag.
|
||||||
|
|
@ -539,9 +607,9 @@ The following functions and structs are used to create
|
||||||
:c:type:`PyAsyncMethods` with an added ``Py_`` prefix.
|
:c:type:`PyAsyncMethods` with an added ``Py_`` prefix.
|
||||||
For example, use:
|
For example, use:
|
||||||
|
|
||||||
* ``Py_tp_dealloc`` to set :c:member:`PyTypeObject.tp_dealloc`
|
* :c:data:`Py_tp_dealloc` to set :c:member:`PyTypeObject.tp_dealloc`
|
||||||
* ``Py_nb_add`` to set :c:member:`PyNumberMethods.nb_add`
|
* :c:data:`Py_nb_add` to set :c:member:`PyNumberMethods.nb_add`
|
||||||
* ``Py_sq_length`` to set :c:member:`PySequenceMethods.sq_length`
|
* :c:data:`Py_sq_length` to set :c:member:`PySequenceMethods.sq_length`
|
||||||
|
|
||||||
An additional slot is supported that does not correspond to a
|
An additional slot is supported that does not correspond to a
|
||||||
:c:type:`!PyTypeObject` struct field:
|
:c:type:`!PyTypeObject` struct field:
|
||||||
|
|
@ -560,7 +628,7 @@ The following functions and structs are used to create
|
||||||
|
|
||||||
If it is not possible to switch to a ``MANAGED`` flag (for example,
|
If it is not possible to switch to a ``MANAGED`` flag (for example,
|
||||||
for vectorcall or to support Python older than 3.12), specify the
|
for vectorcall or to support Python older than 3.12), specify the
|
||||||
offset in :c:member:`Py_tp_members <PyTypeObject.tp_members>`.
|
offset in :c:data:`Py_tp_members`.
|
||||||
See :ref:`PyMemberDef documentation <pymemberdef-offsets>`
|
See :ref:`PyMemberDef documentation <pymemberdef-offsets>`
|
||||||
for details.
|
for details.
|
||||||
|
|
||||||
|
|
@ -587,8 +655,8 @@ The following functions and structs are used to create
|
||||||
under the :ref:`limited API <limited-c-api>`.
|
under the :ref:`limited API <limited-c-api>`.
|
||||||
|
|
||||||
.. versionchanged:: 3.14
|
.. versionchanged:: 3.14
|
||||||
The field :c:member:`~PyTypeObject.tp_vectorcall` can now set
|
The field :c:member:`~PyTypeObject.tp_vectorcall` can now be set
|
||||||
using ``Py_tp_vectorcall``. See the field's documentation
|
using :c:data:`Py_tp_vectorcall`. See the field's documentation
|
||||||
for details.
|
for details.
|
||||||
|
|
||||||
.. c:member:: void *pfunc
|
.. c:member:: void *pfunc
|
||||||
|
|
@ -598,10 +666,11 @@ The following functions and structs are used to create
|
||||||
|
|
||||||
*pfunc* values may not be ``NULL``, except for the following slots:
|
*pfunc* values may not be ``NULL``, except for the following slots:
|
||||||
|
|
||||||
* ``Py_tp_doc``
|
* :c:data:`Py_tp_doc`
|
||||||
* :c:data:`Py_tp_token` (for clarity, prefer :c:data:`Py_TP_USE_SPEC`
|
* :c:data:`Py_tp_token` (for clarity, prefer :c:data:`Py_TP_USE_SPEC`
|
||||||
rather than ``NULL``)
|
rather than ``NULL``)
|
||||||
|
|
||||||
|
|
||||||
.. c:macro:: Py_tp_token
|
.. c:macro:: Py_tp_token
|
||||||
|
|
||||||
A :c:member:`~PyType_Slot.slot` that records a static memory layout ID
|
A :c:member:`~PyType_Slot.slot` that records a static memory layout ID
|
||||||
|
|
|
||||||
|
|
@ -676,6 +676,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: destructor PyTypeObject.tp_dealloc
|
.. c:member:: destructor PyTypeObject.tp_dealloc
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_dealloc
|
||||||
|
|
||||||
A pointer to the instance destructor function. The function signature is::
|
A pointer to the instance destructor function. The function signature is::
|
||||||
|
|
||||||
void tp_dealloc(PyObject *self);
|
void tp_dealloc(PyObject *self);
|
||||||
|
|
@ -860,6 +862,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: getattrfunc PyTypeObject.tp_getattr
|
.. c:member:: getattrfunc PyTypeObject.tp_getattr
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_getattr
|
||||||
|
|
||||||
An optional pointer to the get-attribute-string function.
|
An optional pointer to the get-attribute-string function.
|
||||||
|
|
||||||
This field is deprecated. When it is defined, it should point to a function
|
This field is deprecated. When it is defined, it should point to a function
|
||||||
|
|
@ -877,6 +881,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: setattrfunc PyTypeObject.tp_setattr
|
.. c:member:: setattrfunc PyTypeObject.tp_setattr
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_setattr
|
||||||
|
|
||||||
An optional pointer to the function for setting and deleting attributes.
|
An optional pointer to the function for setting and deleting attributes.
|
||||||
|
|
||||||
This field is deprecated. When it is defined, it should point to a function
|
This field is deprecated. When it is defined, it should point to a function
|
||||||
|
|
@ -909,6 +915,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: reprfunc PyTypeObject.tp_repr
|
.. c:member:: reprfunc PyTypeObject.tp_repr
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_repr
|
||||||
|
|
||||||
.. index:: pair: built-in function; repr
|
.. index:: pair: built-in function; repr
|
||||||
|
|
||||||
An optional pointer to a function that implements the built-in function
|
An optional pointer to a function that implements the built-in function
|
||||||
|
|
@ -974,6 +982,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: hashfunc PyTypeObject.tp_hash
|
.. c:member:: hashfunc PyTypeObject.tp_hash
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_hash
|
||||||
|
|
||||||
.. index:: pair: built-in function; hash
|
.. index:: pair: built-in function; hash
|
||||||
|
|
||||||
An optional pointer to a function that implements the built-in function
|
An optional pointer to a function that implements the built-in function
|
||||||
|
|
@ -1015,6 +1025,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: ternaryfunc PyTypeObject.tp_call
|
.. c:member:: ternaryfunc PyTypeObject.tp_call
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_call
|
||||||
|
|
||||||
An optional pointer to a function that implements calling the object. This
|
An optional pointer to a function that implements calling the object. This
|
||||||
should be ``NULL`` if the object is not callable. The signature is the same as
|
should be ``NULL`` if the object is not callable. The signature is the same as
|
||||||
for :c:func:`PyObject_Call`::
|
for :c:func:`PyObject_Call`::
|
||||||
|
|
@ -1028,6 +1040,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: reprfunc PyTypeObject.tp_str
|
.. c:member:: reprfunc PyTypeObject.tp_str
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_str
|
||||||
|
|
||||||
An optional pointer to a function that implements the built-in operation
|
An optional pointer to a function that implements the built-in operation
|
||||||
:func:`str`. (Note that :class:`str` is a type now, and :func:`str` calls the
|
:func:`str`. (Note that :class:`str` is a type now, and :func:`str` calls the
|
||||||
constructor for that type. This constructor calls :c:func:`PyObject_Str` to do
|
constructor for that type. This constructor calls :c:func:`PyObject_Str` to do
|
||||||
|
|
@ -1053,6 +1067,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: getattrofunc PyTypeObject.tp_getattro
|
.. c:member:: getattrofunc PyTypeObject.tp_getattro
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_getattro
|
||||||
|
|
||||||
An optional pointer to the get-attribute function.
|
An optional pointer to the get-attribute function.
|
||||||
|
|
||||||
The signature is the same as for :c:func:`PyObject_GetAttr`::
|
The signature is the same as for :c:func:`PyObject_GetAttr`::
|
||||||
|
|
@ -1077,6 +1093,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: setattrofunc PyTypeObject.tp_setattro
|
.. c:member:: setattrofunc PyTypeObject.tp_setattro
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_setattro
|
||||||
|
|
||||||
An optional pointer to the function for setting and deleting attributes.
|
An optional pointer to the function for setting and deleting attributes.
|
||||||
|
|
||||||
The signature is the same as for :c:func:`PyObject_SetAttr`::
|
The signature is the same as for :c:func:`PyObject_SetAttr`::
|
||||||
|
|
@ -1333,8 +1351,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
.. c:macro:: Py_TPFLAGS_BASE_EXC_SUBCLASS
|
.. c:macro:: Py_TPFLAGS_BASE_EXC_SUBCLASS
|
||||||
.. c:macro:: Py_TPFLAGS_TYPE_SUBCLASS
|
.. c:macro:: Py_TPFLAGS_TYPE_SUBCLASS
|
||||||
|
|
||||||
These flags are used by functions such as
|
Functions such as :c:func:`PyLong_Check` will call :c:func:`PyType_FastSubclass`
|
||||||
:c:func:`PyLong_Check` to quickly determine if a type is a subclass
|
with one of these flags to quickly determine if a type is a subclass
|
||||||
of a built-in type; such specific checks are faster than a generic
|
of a built-in type; such specific checks are faster than a generic
|
||||||
check, like :c:func:`PyObject_IsInstance`. Custom types that inherit
|
check, like :c:func:`PyObject_IsInstance`. Custom types that inherit
|
||||||
from built-ins should have their :c:member:`~PyTypeObject.tp_flags`
|
from built-ins should have their :c:member:`~PyTypeObject.tp_flags`
|
||||||
|
|
@ -1475,6 +1493,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: const char* PyTypeObject.tp_doc
|
.. c:member:: const char* PyTypeObject.tp_doc
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_doc
|
||||||
|
|
||||||
An optional pointer to a NUL-terminated C string giving the docstring for this
|
An optional pointer to a NUL-terminated C string giving the docstring for this
|
||||||
type object. This is exposed as the :attr:`~type.__doc__` attribute on the
|
type object. This is exposed as the :attr:`~type.__doc__` attribute on the
|
||||||
type and instances of the type.
|
type and instances of the type.
|
||||||
|
|
@ -1486,6 +1506,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: traverseproc PyTypeObject.tp_traverse
|
.. c:member:: traverseproc PyTypeObject.tp_traverse
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_traverse
|
||||||
|
|
||||||
An optional pointer to a traversal function for the garbage collector. This is
|
An optional pointer to a traversal function for the garbage collector. This is
|
||||||
only used if the :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit is set. The signature is::
|
only used if the :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit is set. The signature is::
|
||||||
|
|
||||||
|
|
@ -1582,6 +1604,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: inquiry PyTypeObject.tp_clear
|
.. c:member:: inquiry PyTypeObject.tp_clear
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_clear
|
||||||
|
|
||||||
An optional pointer to a clear function. The signature is::
|
An optional pointer to a clear function. The signature is::
|
||||||
|
|
||||||
int tp_clear(PyObject *);
|
int tp_clear(PyObject *);
|
||||||
|
|
@ -1730,6 +1754,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: richcmpfunc PyTypeObject.tp_richcompare
|
.. c:member:: richcmpfunc PyTypeObject.tp_richcompare
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_richcompare
|
||||||
|
|
||||||
An optional pointer to the rich comparison function, whose signature is::
|
An optional pointer to the rich comparison function, whose signature is::
|
||||||
|
|
||||||
PyObject *tp_richcompare(PyObject *self, PyObject *other, int op);
|
PyObject *tp_richcompare(PyObject *self, PyObject *other, int op);
|
||||||
|
|
@ -1832,6 +1858,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: getiterfunc PyTypeObject.tp_iter
|
.. c:member:: getiterfunc PyTypeObject.tp_iter
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_iter
|
||||||
|
|
||||||
An optional pointer to a function that returns an :term:`iterator` for the
|
An optional pointer to a function that returns an :term:`iterator` for the
|
||||||
object. Its presence normally signals that the instances of this type are
|
object. Its presence normally signals that the instances of this type are
|
||||||
:term:`iterable` (although sequences may be iterable without this function).
|
:term:`iterable` (although sequences may be iterable without this function).
|
||||||
|
|
@ -1847,6 +1875,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: iternextfunc PyTypeObject.tp_iternext
|
.. c:member:: iternextfunc PyTypeObject.tp_iternext
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_iternext
|
||||||
|
|
||||||
An optional pointer to a function that returns the next item in an
|
An optional pointer to a function that returns the next item in an
|
||||||
:term:`iterator`. The signature is::
|
:term:`iterator`. The signature is::
|
||||||
|
|
||||||
|
|
@ -1870,6 +1900,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: struct PyMethodDef* PyTypeObject.tp_methods
|
.. c:member:: struct PyMethodDef* PyTypeObject.tp_methods
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_methods
|
||||||
|
|
||||||
An optional pointer to a static ``NULL``-terminated array of :c:type:`PyMethodDef`
|
An optional pointer to a static ``NULL``-terminated array of :c:type:`PyMethodDef`
|
||||||
structures, declaring regular methods of this type.
|
structures, declaring regular methods of this type.
|
||||||
|
|
||||||
|
|
@ -1884,6 +1916,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: struct PyMemberDef* PyTypeObject.tp_members
|
.. c:member:: struct PyMemberDef* PyTypeObject.tp_members
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_members
|
||||||
|
|
||||||
An optional pointer to a static ``NULL``-terminated array of :c:type:`PyMemberDef`
|
An optional pointer to a static ``NULL``-terminated array of :c:type:`PyMemberDef`
|
||||||
structures, declaring regular data members (fields or slots) of instances of
|
structures, declaring regular data members (fields or slots) of instances of
|
||||||
this type.
|
this type.
|
||||||
|
|
@ -1899,6 +1933,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: struct PyGetSetDef* PyTypeObject.tp_getset
|
.. c:member:: struct PyGetSetDef* PyTypeObject.tp_getset
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_getset
|
||||||
|
|
||||||
An optional pointer to a static ``NULL``-terminated array of :c:type:`PyGetSetDef`
|
An optional pointer to a static ``NULL``-terminated array of :c:type:`PyGetSetDef`
|
||||||
structures, declaring computed attributes of instances of this type.
|
structures, declaring computed attributes of instances of this type.
|
||||||
|
|
||||||
|
|
@ -1913,6 +1949,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: PyTypeObject* PyTypeObject.tp_base
|
.. c:member:: PyTypeObject* PyTypeObject.tp_base
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_base
|
||||||
|
|
||||||
An optional pointer to a base type from which type properties are inherited. At
|
An optional pointer to a base type from which type properties are inherited. At
|
||||||
this level, only single inheritance is supported; multiple inheritance require
|
this level, only single inheritance is supported; multiple inheritance require
|
||||||
dynamically creating a type object by calling the metatype.
|
dynamically creating a type object by calling the metatype.
|
||||||
|
|
@ -1985,6 +2023,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: descrgetfunc PyTypeObject.tp_descr_get
|
.. c:member:: descrgetfunc PyTypeObject.tp_descr_get
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_descr_get
|
||||||
|
|
||||||
An optional pointer to a "descriptor get" function.
|
An optional pointer to a "descriptor get" function.
|
||||||
|
|
||||||
The function signature is::
|
The function signature is::
|
||||||
|
|
@ -2000,6 +2040,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: descrsetfunc PyTypeObject.tp_descr_set
|
.. c:member:: descrsetfunc PyTypeObject.tp_descr_set
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_descr_set
|
||||||
|
|
||||||
An optional pointer to a function for setting and deleting
|
An optional pointer to a function for setting and deleting
|
||||||
a descriptor's value.
|
a descriptor's value.
|
||||||
|
|
||||||
|
|
@ -2060,6 +2102,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: initproc PyTypeObject.tp_init
|
.. c:member:: initproc PyTypeObject.tp_init
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_init
|
||||||
|
|
||||||
An optional pointer to an instance initialization function.
|
An optional pointer to an instance initialization function.
|
||||||
|
|
||||||
This function corresponds to the :meth:`~object.__init__` method of classes. Like
|
This function corresponds to the :meth:`~object.__init__` method of classes. Like
|
||||||
|
|
@ -2095,6 +2139,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: allocfunc PyTypeObject.tp_alloc
|
.. c:member:: allocfunc PyTypeObject.tp_alloc
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_alloc
|
||||||
|
|
||||||
An optional pointer to an instance allocation function.
|
An optional pointer to an instance allocation function.
|
||||||
|
|
||||||
The function signature is::
|
The function signature is::
|
||||||
|
|
@ -2118,6 +2164,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: newfunc PyTypeObject.tp_new
|
.. c:member:: newfunc PyTypeObject.tp_new
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_new
|
||||||
|
|
||||||
An optional pointer to an instance creation function.
|
An optional pointer to an instance creation function.
|
||||||
|
|
||||||
The function signature is::
|
The function signature is::
|
||||||
|
|
@ -2157,6 +2205,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: freefunc PyTypeObject.tp_free
|
.. c:member:: freefunc PyTypeObject.tp_free
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_free
|
||||||
|
|
||||||
An optional pointer to an instance deallocation function. Its signature is::
|
An optional pointer to an instance deallocation function. Its signature is::
|
||||||
|
|
||||||
void tp_free(void *self);
|
void tp_free(void *self);
|
||||||
|
|
@ -2186,6 +2236,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: inquiry PyTypeObject.tp_is_gc
|
.. c:member:: inquiry PyTypeObject.tp_is_gc
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_is_gc
|
||||||
|
|
||||||
An optional pointer to a function called by the garbage collector.
|
An optional pointer to a function called by the garbage collector.
|
||||||
|
|
||||||
The garbage collector needs to know whether a particular object is collectible
|
The garbage collector needs to know whether a particular object is collectible
|
||||||
|
|
@ -2214,12 +2266,14 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: PyObject* PyTypeObject.tp_bases
|
.. c:member:: PyObject* PyTypeObject.tp_bases
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_bases
|
||||||
|
|
||||||
Tuple of base types.
|
Tuple of base types.
|
||||||
|
|
||||||
This field should be set to ``NULL`` and treated as read-only.
|
This field should be set to ``NULL`` and treated as read-only.
|
||||||
Python will fill it in when the type is :c:func:`initialized <PyType_Ready>`.
|
Python will fill it in when the type is :c:func:`initialized <PyType_Ready>`.
|
||||||
|
|
||||||
For dynamically created classes, the ``Py_tp_bases``
|
For dynamically created classes, the :c:data:`Py_tp_bases`
|
||||||
:c:type:`slot <PyType_Slot>` can be used instead of the *bases* argument
|
:c:type:`slot <PyType_Slot>` can be used instead of the *bases* argument
|
||||||
of :c:func:`PyType_FromSpecWithBases`.
|
of :c:func:`PyType_FromSpecWithBases`.
|
||||||
The argument form is preferred.
|
The argument form is preferred.
|
||||||
|
|
@ -2294,6 +2348,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: destructor PyTypeObject.tp_del
|
.. c:member:: destructor PyTypeObject.tp_del
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_del
|
||||||
|
|
||||||
This field is deprecated. Use :c:member:`~PyTypeObject.tp_finalize` instead.
|
This field is deprecated. Use :c:member:`~PyTypeObject.tp_finalize` instead.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2308,6 +2364,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: destructor PyTypeObject.tp_finalize
|
.. c:member:: destructor PyTypeObject.tp_finalize
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_finalize
|
||||||
|
|
||||||
An optional pointer to an instance finalization function. This is the C
|
An optional pointer to an instance finalization function. This is the C
|
||||||
implementation of the :meth:`~object.__del__` special method. Its signature
|
implementation of the :meth:`~object.__del__` special method. Its signature
|
||||||
is::
|
is::
|
||||||
|
|
@ -2466,6 +2524,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. c:member:: vectorcallfunc PyTypeObject.tp_vectorcall
|
.. c:member:: vectorcallfunc PyTypeObject.tp_vectorcall
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_tp_vectorcall
|
||||||
|
|
||||||
A :ref:`vectorcall function <vectorcall>` to use for calls of this type
|
A :ref:`vectorcall function <vectorcall>` to use for calls of this type
|
||||||
object (rather than instances).
|
object (rather than instances).
|
||||||
In other words, ``tp_vectorcall`` can be used to optimize ``type.__call__``,
|
In other words, ``tp_vectorcall`` can be used to optimize ``type.__call__``,
|
||||||
|
|
@ -2631,42 +2691,148 @@ Number Object Structures
|
||||||
Python 3.0.1.
|
Python 3.0.1.
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_add
|
.. c:member:: binaryfunc PyNumberMethods.nb_add
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_add
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_subtract
|
.. c:member:: binaryfunc PyNumberMethods.nb_subtract
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_subtract
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_multiply
|
.. c:member:: binaryfunc PyNumberMethods.nb_multiply
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_multiply
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_remainder
|
.. c:member:: binaryfunc PyNumberMethods.nb_remainder
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_remainder
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_divmod
|
.. c:member:: binaryfunc PyNumberMethods.nb_divmod
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_divmod
|
||||||
|
|
||||||
.. c:member:: ternaryfunc PyNumberMethods.nb_power
|
.. c:member:: ternaryfunc PyNumberMethods.nb_power
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_power
|
||||||
|
|
||||||
.. c:member:: unaryfunc PyNumberMethods.nb_negative
|
.. c:member:: unaryfunc PyNumberMethods.nb_negative
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_negative
|
||||||
|
|
||||||
.. c:member:: unaryfunc PyNumberMethods.nb_positive
|
.. c:member:: unaryfunc PyNumberMethods.nb_positive
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_positive
|
||||||
|
|
||||||
.. c:member:: unaryfunc PyNumberMethods.nb_absolute
|
.. c:member:: unaryfunc PyNumberMethods.nb_absolute
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_absolute
|
||||||
|
|
||||||
.. c:member:: inquiry PyNumberMethods.nb_bool
|
.. c:member:: inquiry PyNumberMethods.nb_bool
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_bool
|
||||||
|
|
||||||
.. c:member:: unaryfunc PyNumberMethods.nb_invert
|
.. c:member:: unaryfunc PyNumberMethods.nb_invert
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_invert
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_lshift
|
.. c:member:: binaryfunc PyNumberMethods.nb_lshift
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_lshift
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_rshift
|
.. c:member:: binaryfunc PyNumberMethods.nb_rshift
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_rshift
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_and
|
.. c:member:: binaryfunc PyNumberMethods.nb_and
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_and
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_xor
|
.. c:member:: binaryfunc PyNumberMethods.nb_xor
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_xor
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_or
|
.. c:member:: binaryfunc PyNumberMethods.nb_or
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_or
|
||||||
|
|
||||||
.. c:member:: unaryfunc PyNumberMethods.nb_int
|
.. c:member:: unaryfunc PyNumberMethods.nb_int
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_int
|
||||||
|
|
||||||
.. c:member:: void *PyNumberMethods.nb_reserved
|
.. c:member:: void *PyNumberMethods.nb_reserved
|
||||||
|
|
||||||
.. c:member:: unaryfunc PyNumberMethods.nb_float
|
.. c:member:: unaryfunc PyNumberMethods.nb_float
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_float
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_add
|
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_add
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_inplace_add
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_subtract
|
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_subtract
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_inplace_subtract
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_multiply
|
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_multiply
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_inplace_multiply
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_remainder
|
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_remainder
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_inplace_remainder
|
||||||
|
|
||||||
.. c:member:: ternaryfunc PyNumberMethods.nb_inplace_power
|
.. c:member:: ternaryfunc PyNumberMethods.nb_inplace_power
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_inplace_power
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_lshift
|
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_lshift
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_inplace_lshift
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_rshift
|
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_rshift
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_inplace_rshift
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_and
|
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_and
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_inplace_and
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_xor
|
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_xor
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_inplace_xor
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_or
|
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_or
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_inplace_or
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_floor_divide
|
.. c:member:: binaryfunc PyNumberMethods.nb_floor_divide
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_floor_divide
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_true_divide
|
.. c:member:: binaryfunc PyNumberMethods.nb_true_divide
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_true_divide
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_floor_divide
|
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_floor_divide
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_inplace_floor_divide
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_true_divide
|
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_true_divide
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_inplace_true_divide
|
||||||
|
|
||||||
.. c:member:: unaryfunc PyNumberMethods.nb_index
|
.. c:member:: unaryfunc PyNumberMethods.nb_index
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_index
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_matrix_multiply
|
.. c:member:: binaryfunc PyNumberMethods.nb_matrix_multiply
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_matrix_multiply
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_matrix_multiply
|
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_matrix_multiply
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_nb_inplace_matrix_multiply
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _mapping-structs:
|
.. _mapping-structs:
|
||||||
|
|
||||||
|
|
@ -2683,12 +2849,16 @@ Mapping Object Structures
|
||||||
|
|
||||||
.. c:member:: lenfunc PyMappingMethods.mp_length
|
.. c:member:: lenfunc PyMappingMethods.mp_length
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_mp_length
|
||||||
|
|
||||||
This function is used by :c:func:`PyMapping_Size` and
|
This function is used by :c:func:`PyMapping_Size` and
|
||||||
:c:func:`PyObject_Size`, and has the same signature. This slot may be set to
|
:c:func:`PyObject_Size`, and has the same signature. This slot may be set to
|
||||||
``NULL`` if the object has no defined length.
|
``NULL`` if the object has no defined length.
|
||||||
|
|
||||||
.. c:member:: binaryfunc PyMappingMethods.mp_subscript
|
.. c:member:: binaryfunc PyMappingMethods.mp_subscript
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_mp_subscript
|
||||||
|
|
||||||
This function is used by :c:func:`PyObject_GetItem` and
|
This function is used by :c:func:`PyObject_GetItem` and
|
||||||
:c:func:`PySequence_GetSlice`, and has the same signature as
|
:c:func:`PySequence_GetSlice`, and has the same signature as
|
||||||
:c:func:`!PyObject_GetItem`. This slot must be filled for the
|
:c:func:`!PyObject_GetItem`. This slot must be filled for the
|
||||||
|
|
@ -2697,6 +2867,8 @@ Mapping Object Structures
|
||||||
|
|
||||||
.. c:member:: objobjargproc PyMappingMethods.mp_ass_subscript
|
.. c:member:: objobjargproc PyMappingMethods.mp_ass_subscript
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_mp_ass_subscript
|
||||||
|
|
||||||
This function is used by :c:func:`PyObject_SetItem`,
|
This function is used by :c:func:`PyObject_SetItem`,
|
||||||
:c:func:`PyObject_DelItem`, :c:func:`PySequence_SetSlice` and
|
:c:func:`PyObject_DelItem`, :c:func:`PySequence_SetSlice` and
|
||||||
:c:func:`PySequence_DelSlice`. It has the same signature as
|
:c:func:`PySequence_DelSlice`. It has the same signature as
|
||||||
|
|
@ -2720,6 +2892,8 @@ Sequence Object Structures
|
||||||
|
|
||||||
.. c:member:: lenfunc PySequenceMethods.sq_length
|
.. c:member:: lenfunc PySequenceMethods.sq_length
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_sq_length
|
||||||
|
|
||||||
This function is used by :c:func:`PySequence_Size` and
|
This function is used by :c:func:`PySequence_Size` and
|
||||||
:c:func:`PyObject_Size`, and has the same signature. It is also used for
|
:c:func:`PyObject_Size`, and has the same signature. It is also used for
|
||||||
handling negative indices via the :c:member:`~PySequenceMethods.sq_item`
|
handling negative indices via the :c:member:`~PySequenceMethods.sq_item`
|
||||||
|
|
@ -2727,18 +2901,24 @@ Sequence Object Structures
|
||||||
|
|
||||||
.. c:member:: binaryfunc PySequenceMethods.sq_concat
|
.. c:member:: binaryfunc PySequenceMethods.sq_concat
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_sq_concat
|
||||||
|
|
||||||
This function is used by :c:func:`PySequence_Concat` and has the same
|
This function is used by :c:func:`PySequence_Concat` and has the same
|
||||||
signature. It is also used by the ``+`` operator, after trying the numeric
|
signature. It is also used by the ``+`` operator, after trying the numeric
|
||||||
addition via the :c:member:`~PyNumberMethods.nb_add` slot.
|
addition via the :c:member:`~PyNumberMethods.nb_add` slot.
|
||||||
|
|
||||||
.. c:member:: ssizeargfunc PySequenceMethods.sq_repeat
|
.. c:member:: ssizeargfunc PySequenceMethods.sq_repeat
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_sq_repeat
|
||||||
|
|
||||||
This function is used by :c:func:`PySequence_Repeat` and has the same
|
This function is used by :c:func:`PySequence_Repeat` and has the same
|
||||||
signature. It is also used by the ``*`` operator, after trying numeric
|
signature. It is also used by the ``*`` operator, after trying numeric
|
||||||
multiplication via the :c:member:`~PyNumberMethods.nb_multiply` slot.
|
multiplication via the :c:member:`~PyNumberMethods.nb_multiply` slot.
|
||||||
|
|
||||||
.. c:member:: ssizeargfunc PySequenceMethods.sq_item
|
.. c:member:: ssizeargfunc PySequenceMethods.sq_item
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_sq_item
|
||||||
|
|
||||||
This function is used by :c:func:`PySequence_GetItem` and has the same
|
This function is used by :c:func:`PySequence_GetItem` and has the same
|
||||||
signature. It is also used by :c:func:`PyObject_GetItem`, after trying
|
signature. It is also used by :c:func:`PyObject_GetItem`, after trying
|
||||||
the subscription via the :c:member:`~PyMappingMethods.mp_subscript` slot.
|
the subscription via the :c:member:`~PyMappingMethods.mp_subscript` slot.
|
||||||
|
|
@ -2752,6 +2932,8 @@ Sequence Object Structures
|
||||||
|
|
||||||
.. c:member:: ssizeobjargproc PySequenceMethods.sq_ass_item
|
.. c:member:: ssizeobjargproc PySequenceMethods.sq_ass_item
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_sq_ass_item
|
||||||
|
|
||||||
This function is used by :c:func:`PySequence_SetItem` and has the same
|
This function is used by :c:func:`PySequence_SetItem` and has the same
|
||||||
signature. It is also used by :c:func:`PyObject_SetItem` and
|
signature. It is also used by :c:func:`PyObject_SetItem` and
|
||||||
:c:func:`PyObject_DelItem`, after trying the item assignment and deletion
|
:c:func:`PyObject_DelItem`, after trying the item assignment and deletion
|
||||||
|
|
@ -2761,6 +2943,8 @@ Sequence Object Structures
|
||||||
|
|
||||||
.. c:member:: objobjproc PySequenceMethods.sq_contains
|
.. c:member:: objobjproc PySequenceMethods.sq_contains
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_sq_contains
|
||||||
|
|
||||||
This function may be used by :c:func:`PySequence_Contains` and has the same
|
This function may be used by :c:func:`PySequence_Contains` and has the same
|
||||||
signature. This slot may be left to ``NULL``, in this case
|
signature. This slot may be left to ``NULL``, in this case
|
||||||
:c:func:`!PySequence_Contains` simply traverses the sequence until it
|
:c:func:`!PySequence_Contains` simply traverses the sequence until it
|
||||||
|
|
@ -2768,6 +2952,8 @@ Sequence Object Structures
|
||||||
|
|
||||||
.. c:member:: binaryfunc PySequenceMethods.sq_inplace_concat
|
.. c:member:: binaryfunc PySequenceMethods.sq_inplace_concat
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_sq_inplace_concat
|
||||||
|
|
||||||
This function is used by :c:func:`PySequence_InPlaceConcat` and has the same
|
This function is used by :c:func:`PySequence_InPlaceConcat` and has the same
|
||||||
signature. It should modify its first operand, and return it. This slot
|
signature. It should modify its first operand, and return it. This slot
|
||||||
may be left to ``NULL``, in this case :c:func:`!PySequence_InPlaceConcat`
|
may be left to ``NULL``, in this case :c:func:`!PySequence_InPlaceConcat`
|
||||||
|
|
@ -2777,6 +2963,8 @@ Sequence Object Structures
|
||||||
|
|
||||||
.. c:member:: ssizeargfunc PySequenceMethods.sq_inplace_repeat
|
.. c:member:: ssizeargfunc PySequenceMethods.sq_inplace_repeat
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_sq_inplace_repeat
|
||||||
|
|
||||||
This function is used by :c:func:`PySequence_InPlaceRepeat` and has the same
|
This function is used by :c:func:`PySequence_InPlaceRepeat` and has the same
|
||||||
signature. It should modify its first operand, and return it. This slot
|
signature. It should modify its first operand, and return it. This slot
|
||||||
may be left to ``NULL``, in this case :c:func:`!PySequence_InPlaceRepeat`
|
may be left to ``NULL``, in this case :c:func:`!PySequence_InPlaceRepeat`
|
||||||
|
|
@ -2802,6 +2990,8 @@ Buffer Object Structures
|
||||||
|
|
||||||
.. c:member:: getbufferproc PyBufferProcs.bf_getbuffer
|
.. c:member:: getbufferproc PyBufferProcs.bf_getbuffer
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_bf_getbuffer
|
||||||
|
|
||||||
The signature of this function is::
|
The signature of this function is::
|
||||||
|
|
||||||
int (PyObject *exporter, Py_buffer *view, int flags);
|
int (PyObject *exporter, Py_buffer *view, int flags);
|
||||||
|
|
@ -2851,6 +3041,8 @@ Buffer Object Structures
|
||||||
|
|
||||||
.. c:member:: releasebufferproc PyBufferProcs.bf_releasebuffer
|
.. c:member:: releasebufferproc PyBufferProcs.bf_releasebuffer
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_bf_releasebuffer
|
||||||
|
|
||||||
The signature of this function is::
|
The signature of this function is::
|
||||||
|
|
||||||
void (PyObject *exporter, Py_buffer *view);
|
void (PyObject *exporter, Py_buffer *view);
|
||||||
|
|
@ -2905,6 +3097,8 @@ Async Object Structures
|
||||||
|
|
||||||
.. c:member:: unaryfunc PyAsyncMethods.am_await
|
.. c:member:: unaryfunc PyAsyncMethods.am_await
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_am_await
|
||||||
|
|
||||||
The signature of this function is::
|
The signature of this function is::
|
||||||
|
|
||||||
PyObject *am_await(PyObject *self);
|
PyObject *am_await(PyObject *self);
|
||||||
|
|
@ -2916,6 +3110,8 @@ Async Object Structures
|
||||||
|
|
||||||
.. c:member:: unaryfunc PyAsyncMethods.am_aiter
|
.. c:member:: unaryfunc PyAsyncMethods.am_aiter
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_am_aiter
|
||||||
|
|
||||||
The signature of this function is::
|
The signature of this function is::
|
||||||
|
|
||||||
PyObject *am_aiter(PyObject *self);
|
PyObject *am_aiter(PyObject *self);
|
||||||
|
|
@ -2928,6 +3124,8 @@ Async Object Structures
|
||||||
|
|
||||||
.. c:member:: unaryfunc PyAsyncMethods.am_anext
|
.. c:member:: unaryfunc PyAsyncMethods.am_anext
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_am_anext
|
||||||
|
|
||||||
The signature of this function is::
|
The signature of this function is::
|
||||||
|
|
||||||
PyObject *am_anext(PyObject *self);
|
PyObject *am_anext(PyObject *self);
|
||||||
|
|
@ -2938,6 +3136,8 @@ Async Object Structures
|
||||||
|
|
||||||
.. c:member:: sendfunc PyAsyncMethods.am_send
|
.. c:member:: sendfunc PyAsyncMethods.am_send
|
||||||
|
|
||||||
|
.. corresponding-type-slot:: Py_am_send
|
||||||
|
|
||||||
The signature of this function is::
|
The signature of this function is::
|
||||||
|
|
||||||
PySendResult am_send(PyObject *self, PyObject *arg, PyObject **result);
|
PySendResult am_send(PyObject *self, PyObject *arg, PyObject **result);
|
||||||
|
|
|
||||||
|
|
@ -321,12 +321,22 @@ These APIs can be used to work with surrogates:
|
||||||
|
|
||||||
Check if *ch* is a low surrogate (``0xDC00 <= ch <= 0xDFFF``).
|
Check if *ch* is a low surrogate (``0xDC00 <= ch <= 0xDFFF``).
|
||||||
|
|
||||||
|
.. c:function:: Py_UCS4 Py_UNICODE_HIGH_SURROGATE(Py_UCS4 ch)
|
||||||
|
|
||||||
|
Return the high UTF-16 surrogate (``0xD800`` to ``0xDBFF``) for a Unicode
|
||||||
|
code point in the range ``[0x10000; 0x10FFFF]``.
|
||||||
|
|
||||||
|
.. c:function:: Py_UCS4 Py_UNICODE_LOW_SURROGATE(Py_UCS4 ch)
|
||||||
|
|
||||||
|
Return the low UTF-16 surrogate (``0xDC00`` to ``0xDFFF``) for a Unicode
|
||||||
|
code point in the range ``[0x10000; 0x10FFFF]``.
|
||||||
|
|
||||||
.. c:function:: Py_UCS4 Py_UNICODE_JOIN_SURROGATES(Py_UCS4 high, Py_UCS4 low)
|
.. c:function:: Py_UCS4 Py_UNICODE_JOIN_SURROGATES(Py_UCS4 high, Py_UCS4 low)
|
||||||
|
|
||||||
Join two surrogate code points and return a single :c:type:`Py_UCS4` value.
|
Join two surrogate code points and return a single :c:type:`Py_UCS4` value.
|
||||||
*high* and *low* are respectively the leading and trailing surrogates in a
|
*high* and *low* are respectively the leading and trailing surrogates in a
|
||||||
surrogate pair. *high* must be in the range [0xD800; 0xDBFF] and *low* must
|
surrogate pair. *high* must be in the range ``[0xD800; 0xDBFF]`` and *low* must
|
||||||
be in the range [0xDC00; 0xDFFF].
|
be in the range ``[0xDC00; 0xDFFF]``.
|
||||||
|
|
||||||
|
|
||||||
Creating and accessing Unicode strings
|
Creating and accessing Unicode strings
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,9 @@ the interpreter.
|
||||||
|
|
||||||
Several of these functions accept a start symbol from the grammar as a
|
Several of these functions accept a start symbol from the grammar as a
|
||||||
parameter. The available start symbols are :c:data:`Py_eval_input`,
|
parameter. The available start symbols are :c:data:`Py_eval_input`,
|
||||||
:c:data:`Py_file_input`, and :c:data:`Py_single_input`. These are described
|
:c:data:`Py_file_input`, :c:data:`Py_single_input`, and
|
||||||
following the functions which accept them as parameters.
|
:c:data:`Py_func_type_input`. These are described following the functions
|
||||||
|
which accept them as parameters.
|
||||||
|
|
||||||
Note also that several of these functions take :c:expr:`FILE*` parameters. One
|
Note also that several of these functions take :c:expr:`FILE*` parameters. One
|
||||||
particular issue which needs to be handled carefully is that the :c:type:`FILE`
|
particular issue which needs to be handled carefully is that the :c:type:`FILE`
|
||||||
|
|
@ -99,6 +100,20 @@ the same library that the Python runtime is using.
|
||||||
Otherwise, Python may not handle script file with LF line ending correctly.
|
Otherwise, Python may not handle script file with LF line ending correctly.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)
|
||||||
|
|
||||||
|
Read and execute a single statement from a file associated with an
|
||||||
|
interactive device according to the *flags* argument. The user will be
|
||||||
|
prompted using ``sys.ps1`` and ``sys.ps2``. *filename* must be a Python
|
||||||
|
:class:`str` object.
|
||||||
|
|
||||||
|
Returns ``0`` when the input was
|
||||||
|
executed successfully, ``-1`` if there was an exception, or an error code
|
||||||
|
from the :file:`errcode.h` include file distributed as part of Python if
|
||||||
|
there was a parse error. (Note that :file:`errcode.h` is not included by
|
||||||
|
:file:`Python.h`, so must be included specifically if needed.)
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyRun_InteractiveOne(FILE *fp, const char *filename)
|
.. c:function:: int PyRun_InteractiveOne(FILE *fp, const char *filename)
|
||||||
|
|
||||||
This is a simplified interface to :c:func:`PyRun_InteractiveOneFlags` below,
|
This is a simplified interface to :c:func:`PyRun_InteractiveOneFlags` below,
|
||||||
|
|
@ -107,17 +122,10 @@ the same library that the Python runtime is using.
|
||||||
|
|
||||||
.. c:function:: int PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
|
.. c:function:: int PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
|
||||||
|
|
||||||
Read and execute a single statement from a file associated with an
|
Similar to :c:func:`PyRun_InteractiveOneObject`, but *filename* is a
|
||||||
interactive device according to the *flags* argument. The user will be
|
:c:expr:`const char*`, which is decoded from the
|
||||||
prompted using ``sys.ps1`` and ``sys.ps2``. *filename* is decoded from the
|
|
||||||
:term:`filesystem encoding and error handler`.
|
:term:`filesystem encoding and error handler`.
|
||||||
|
|
||||||
Returns ``0`` when the input was
|
|
||||||
executed successfully, ``-1`` if there was an exception, or an error code
|
|
||||||
from the :file:`errcode.h` include file distributed as part of Python if
|
|
||||||
there was a parse error. (Note that :file:`errcode.h` is not included by
|
|
||||||
:file:`Python.h`, so must be included specifically if needed.)
|
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyRun_InteractiveLoop(FILE *fp, const char *filename)
|
.. c:function:: int PyRun_InteractiveLoop(FILE *fp, const char *filename)
|
||||||
|
|
||||||
|
|
@ -140,7 +148,7 @@ the same library that the Python runtime is using.
|
||||||
interpreter prompt is about to become idle and wait for user input
|
interpreter prompt is about to become idle and wait for user input
|
||||||
from the terminal. The return value is ignored. Overriding this
|
from the terminal. The return value is ignored. Overriding this
|
||||||
hook can be used to integrate the interpreter's prompt with other
|
hook can be used to integrate the interpreter's prompt with other
|
||||||
event loops, as done in the :file:`Modules/_tkinter.c` in the
|
event loops, as done in :file:`Modules/_tkinter.c` in the
|
||||||
Python source code.
|
Python source code.
|
||||||
|
|
||||||
.. versionchanged:: 3.12
|
.. versionchanged:: 3.12
|
||||||
|
|
@ -183,8 +191,7 @@ the same library that the Python runtime is using.
|
||||||
objects *globals* and *locals* with the compiler flags specified by
|
objects *globals* and *locals* with the compiler flags specified by
|
||||||
*flags*. *globals* must be a dictionary; *locals* can be any object
|
*flags*. *globals* must be a dictionary; *locals* can be any object
|
||||||
that implements the mapping protocol. The parameter *start* specifies
|
that implements the mapping protocol. The parameter *start* specifies
|
||||||
the start symbol and must one of the following:
|
the start symbol and must one of the :ref:`available start symbols <start-symbols>`.
|
||||||
:c:data:`Py_eval_input`, :c:data:`Py_file_input`, or :c:data:`Py_single_input`.
|
|
||||||
|
|
||||||
Returns the result of executing the code as a Python object, or ``NULL`` if an
|
Returns the result of executing the code as a Python object, or ``NULL`` if an
|
||||||
exception was raised.
|
exception was raised.
|
||||||
|
|
@ -233,8 +240,8 @@ the same library that the Python runtime is using.
|
||||||
|
|
||||||
Parse and compile the Python source code in *str*, returning the resulting code
|
Parse and compile the Python source code in *str*, returning the resulting code
|
||||||
object. The start symbol is given by *start*; this can be used to constrain the
|
object. The start symbol is given by *start*; this can be used to constrain the
|
||||||
code which can be compiled and should be :c:data:`Py_eval_input`,
|
code which can be compiled and should be :ref:`available start symbols
|
||||||
:c:data:`Py_file_input`, or :c:data:`Py_single_input`. The filename specified by
|
<start-symbols>`. The filename specified by
|
||||||
*filename* is used to construct the code object and may appear in tracebacks or
|
*filename* is used to construct the code object and may appear in tracebacks or
|
||||||
:exc:`SyntaxError` exception messages. This returns ``NULL`` if the code
|
:exc:`SyntaxError` exception messages. This returns ``NULL`` if the code
|
||||||
cannot be parsed or compiled.
|
cannot be parsed or compiled.
|
||||||
|
|
@ -297,32 +304,6 @@ the same library that the Python runtime is using.
|
||||||
true on success, false on failure.
|
true on success, false on failure.
|
||||||
|
|
||||||
|
|
||||||
.. c:var:: int Py_eval_input
|
|
||||||
|
|
||||||
.. index:: single: Py_CompileString (C function)
|
|
||||||
|
|
||||||
The start symbol from the Python grammar for isolated expressions; for use with
|
|
||||||
:c:func:`Py_CompileString`.
|
|
||||||
|
|
||||||
|
|
||||||
.. c:var:: int Py_file_input
|
|
||||||
|
|
||||||
.. index:: single: Py_CompileString (C function)
|
|
||||||
|
|
||||||
The start symbol from the Python grammar for sequences of statements as read
|
|
||||||
from a file or other source; for use with :c:func:`Py_CompileString`. This is
|
|
||||||
the symbol to use when compiling arbitrarily long Python source code.
|
|
||||||
|
|
||||||
|
|
||||||
.. c:var:: int Py_single_input
|
|
||||||
|
|
||||||
.. index:: single: Py_CompileString (C function)
|
|
||||||
|
|
||||||
The start symbol from the Python grammar for a single statement; for use with
|
|
||||||
:c:func:`Py_CompileString`. This is the symbol used for the interactive
|
|
||||||
interpreter loop.
|
|
||||||
|
|
||||||
|
|
||||||
.. c:struct:: PyCompilerFlags
|
.. c:struct:: PyCompilerFlags
|
||||||
|
|
||||||
This is the structure used to hold compiler flags. In cases where code is only
|
This is the structure used to hold compiler flags. In cases where code is only
|
||||||
|
|
@ -366,3 +347,92 @@ the same library that the Python runtime is using.
|
||||||
as :c:macro:`CO_FUTURE_ANNOTATIONS` to enable features normally
|
as :c:macro:`CO_FUTURE_ANNOTATIONS` to enable features normally
|
||||||
selectable using :ref:`future statements <future>`.
|
selectable using :ref:`future statements <future>`.
|
||||||
See :ref:`c_codeobject_flags` for a complete list.
|
See :ref:`c_codeobject_flags` for a complete list.
|
||||||
|
|
||||||
|
|
||||||
|
.. _start-symbols:
|
||||||
|
|
||||||
|
Available start symbols
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: int Py_eval_input
|
||||||
|
|
||||||
|
.. index:: single: Py_CompileString (C function)
|
||||||
|
|
||||||
|
The start symbol from the Python grammar for isolated expressions; for use with
|
||||||
|
:c:func:`Py_CompileString`.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: int Py_file_input
|
||||||
|
|
||||||
|
.. index:: single: Py_CompileString (C function)
|
||||||
|
|
||||||
|
The start symbol from the Python grammar for sequences of statements as read
|
||||||
|
from a file or other source; for use with :c:func:`Py_CompileString`. This is
|
||||||
|
the symbol to use when compiling arbitrarily long Python source code.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: int Py_single_input
|
||||||
|
|
||||||
|
.. index:: single: Py_CompileString (C function)
|
||||||
|
|
||||||
|
The start symbol from the Python grammar for a single statement; for use with
|
||||||
|
:c:func:`Py_CompileString`. This is the symbol used for the interactive
|
||||||
|
interpreter loop.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:var:: int Py_func_type_input
|
||||||
|
|
||||||
|
.. index:: single: Py_CompileString (C function)
|
||||||
|
|
||||||
|
The start symbol from the Python grammar for a function type; for use with
|
||||||
|
:c:func:`Py_CompileString`. This is used to parse "signature type comments"
|
||||||
|
from :pep:`484`.
|
||||||
|
|
||||||
|
This requires the :c:macro:`PyCF_ONLY_AST` flag to be set.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
* :py:class:`ast.FunctionType`
|
||||||
|
* :pep:`484`
|
||||||
|
|
||||||
|
.. versionadded:: 3.8
|
||||||
|
|
||||||
|
|
||||||
|
Stack Effects
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
:py:func:`dis.stack_effect`
|
||||||
|
|
||||||
|
|
||||||
|
.. c:macro:: PY_INVALID_STACK_EFFECT
|
||||||
|
|
||||||
|
Sentinel value representing an invalid stack effect.
|
||||||
|
|
||||||
|
This is currently equivalent to ``INT_MAX``.
|
||||||
|
|
||||||
|
.. versionadded:: 3.8
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyCompile_OpcodeStackEffect(int opcode, int oparg)
|
||||||
|
|
||||||
|
Compute the stack effect of *opcode* with argument *oparg*.
|
||||||
|
|
||||||
|
On success, this function returns the stack effect; on failure, this
|
||||||
|
returns :c:macro:`PY_INVALID_STACK_EFFECT`.
|
||||||
|
|
||||||
|
.. versionadded:: 3.4
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyCompile_OpcodeStackEffectWithJump(int opcode, int oparg, int jump)
|
||||||
|
|
||||||
|
Similar to :c:func:`PyCompile_OpcodeStackEffect`, but don't include the
|
||||||
|
stack effect of jumping if *jump* is zero.
|
||||||
|
|
||||||
|
If *jump* is ``0``, this will not include the stack effect of jumping, but
|
||||||
|
if *jump* is ``1`` or ``-1``, this will include it.
|
||||||
|
|
||||||
|
On success, this function returns the stack effect; on failure, this
|
||||||
|
returns :c:macro:`PY_INVALID_STACK_EFFECT`.
|
||||||
|
|
||||||
|
.. versionadded:: 3.8
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,14 @@ as much as it can.
|
||||||
|
|
||||||
.. c:function:: int PyWeakref_CheckRef(PyObject *ob)
|
.. c:function:: int PyWeakref_CheckRef(PyObject *ob)
|
||||||
|
|
||||||
Return non-zero if *ob* is a reference object. This function always succeeds.
|
Return non-zero if *ob* is a reference object or a subclass of the reference
|
||||||
|
type. This function always succeeds.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PyWeakref_CheckRefExact(PyObject *ob)
|
||||||
|
|
||||||
|
Return non-zero if *ob* is a reference object, but not a subclass of the
|
||||||
|
reference type. This function always succeeds.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyWeakref_CheckProxy(PyObject *ob)
|
.. c:function:: int PyWeakref_CheckProxy(PyObject *ob)
|
||||||
|
|
@ -38,6 +45,10 @@ as much as it can.
|
||||||
weakly referenceable object, or if *callback* is not callable, ``None``, or
|
weakly referenceable object, or if *callback* is not callable, ``None``, or
|
||||||
``NULL``, this will return ``NULL`` and raise :exc:`TypeError`.
|
``NULL``, this will return ``NULL`` and raise :exc:`TypeError`.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
:c:func:`PyType_SUPPORTS_WEAKREFS` for checking if *ob* is weakly
|
||||||
|
referenceable.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: PyObject* PyWeakref_NewProxy(PyObject *ob, PyObject *callback)
|
.. c:function:: PyObject* PyWeakref_NewProxy(PyObject *ob, PyObject *callback)
|
||||||
|
|
||||||
|
|
@ -50,6 +61,10 @@ as much as it can.
|
||||||
is not a weakly referenceable object, or if *callback* is not callable,
|
is not a weakly referenceable object, or if *callback* is not callable,
|
||||||
``None``, or ``NULL``, this will return ``NULL`` and raise :exc:`TypeError`.
|
``None``, or ``NULL``, this will return ``NULL`` and raise :exc:`TypeError`.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
:c:func:`PyType_SUPPORTS_WEAKREFS` for checking if *ob* is weakly
|
||||||
|
referenceable.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyWeakref_GetRef(PyObject *ref, PyObject **pobj)
|
.. c:function:: int PyWeakref_GetRef(PyObject *ref, PyObject **pobj)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -226,9 +226,6 @@
|
||||||
# Temporary undocumented names.
|
# Temporary undocumented names.
|
||||||
# In future this list must be empty.
|
# In future this list must be empty.
|
||||||
nitpick_ignore += [
|
nitpick_ignore += [
|
||||||
# Undocumented public C macros
|
|
||||||
('c:macro', 'Py_BUILD_ASSERT'),
|
|
||||||
('c:macro', 'Py_BUILD_ASSERT_EXPR'),
|
|
||||||
# Do not error nit-picky mode builds when _SubParsersAction.add_parser cannot
|
# Do not error nit-picky mode builds when _SubParsersAction.add_parser cannot
|
||||||
# be resolved, as the method is currently undocumented. For context, see
|
# be resolved, as the method is currently undocumented. For context, see
|
||||||
# https://github.com/python/cpython/pull/103289.
|
# https://github.com/python/cpython/pull/103289.
|
||||||
|
|
@ -364,7 +361,7 @@
|
||||||
|
|
||||||
# Grouping the document tree into LaTeX files. List of tuples
|
# Grouping the document tree into LaTeX files. List of tuples
|
||||||
# (source start file, target name, title, author, document class [howto/manual]).
|
# (source start file, target name, title, author, document class [howto/manual]).
|
||||||
_stdauthor = 'Guido van Rossum and the Python development team'
|
_stdauthor = 'The Python development team'
|
||||||
latex_documents = [
|
latex_documents = [
|
||||||
('c-api/index', 'c-api.tex', 'The Python/C API', _stdauthor, 'manual'),
|
('c-api/index', 'c-api.tex', 'The Python/C API', _stdauthor, 'manual'),
|
||||||
(
|
(
|
||||||
|
|
|
||||||
|
|
@ -1472,6 +1472,9 @@ PyModule_Create2:PyObject*::+1:
|
||||||
PyModule_Create2:PyModuleDef*:def::
|
PyModule_Create2:PyModuleDef*:def::
|
||||||
PyModule_Create2:int:module_api_version::
|
PyModule_Create2:int:module_api_version::
|
||||||
|
|
||||||
|
PyModule_Exec:int:::
|
||||||
|
PyModule_ExecDef:PyObject*:module:0:
|
||||||
|
|
||||||
PyModule_ExecDef:int:::
|
PyModule_ExecDef:int:::
|
||||||
PyModule_ExecDef:PyObject*:module:0:
|
PyModule_ExecDef:PyObject*:module:0:
|
||||||
PyModule_ExecDef:PyModuleDef*:def::
|
PyModule_ExecDef:PyModuleDef*:def::
|
||||||
|
|
@ -1485,6 +1488,10 @@ PyModule_FromDefAndSpec2:PyModuleDef*:def::
|
||||||
PyModule_FromDefAndSpec2:PyObject*:spec:0:
|
PyModule_FromDefAndSpec2:PyObject*:spec:0:
|
||||||
PyModule_FromDefAndSpec2:int:module_api_version::
|
PyModule_FromDefAndSpec2:int:module_api_version::
|
||||||
|
|
||||||
|
PyModule_FromSlotsAndSpec:PyObject*::+1:
|
||||||
|
PyModule_FromSlotsAndSpec:const PyModuleDef_Slot *:slots::
|
||||||
|
PyModule_FromSlotsAndSpec:PyObject*:spec:0:
|
||||||
|
|
||||||
PyModule_GetDef:PyModuleDef*::0:
|
PyModule_GetDef:PyModuleDef*::0:
|
||||||
PyModule_GetDef:PyObject*:module:0:
|
PyModule_GetDef:PyObject*:module:0:
|
||||||
|
|
||||||
|
|
@ -1506,6 +1513,14 @@ PyModule_GetNameObject:PyObject*:module:0:
|
||||||
PyModule_GetState:void*:::
|
PyModule_GetState:void*:::
|
||||||
PyModule_GetState:PyObject*:module:0:
|
PyModule_GetState:PyObject*:module:0:
|
||||||
|
|
||||||
|
PyModule_GetStateSize:int:::
|
||||||
|
PyModule_GetStateSize:PyObject*:module:0:
|
||||||
|
PyModule_GetToken:Py_ssize_t**:result::
|
||||||
|
|
||||||
|
PyModule_GetToken:int:::
|
||||||
|
PyModule_GetToken:PyObject*:module:0:
|
||||||
|
PyModule_GetToken:void**:result::
|
||||||
|
|
||||||
PyModule_New:PyObject*::+1:
|
PyModule_New:PyObject*::+1:
|
||||||
PyModule_New:char*:name::
|
PyModule_New:char*:name::
|
||||||
|
|
||||||
|
|
@ -2412,6 +2427,10 @@ PyType_GetFlags:PyTypeObject*:type:0:
|
||||||
PyType_GetName:PyObject*::+1:
|
PyType_GetName:PyObject*::+1:
|
||||||
PyType_GetName:PyTypeObject*:type:0:
|
PyType_GetName:PyTypeObject*:type:0:
|
||||||
|
|
||||||
|
PyType_GetModuleByToken:PyObject*::+1:
|
||||||
|
PyType_GetModuleByToken:PyTypeObject*:type:0:
|
||||||
|
PyType_GetModuleByToken:PyModuleDef*:def::
|
||||||
|
|
||||||
PyType_GetModuleByDef:PyObject*::0:
|
PyType_GetModuleByDef:PyObject*::0:
|
||||||
PyType_GetModuleByDef:PyTypeObject*:type:0:
|
PyType_GetModuleByDef:PyTypeObject*:type:0:
|
||||||
PyType_GetModuleByDef:PyModuleDef*:def::
|
PyType_GetModuleByDef:PyModuleDef*:def::
|
||||||
|
|
|
||||||
176
Doc/data/stable_abi.dat
generated
176
Doc/data/stable_abi.dat
generated
|
|
@ -1,7 +1,21 @@
|
||||||
role,name,added,ifdef_note,struct_abi_kind
|
role,name,added,ifdef_note,struct_abi_kind
|
||||||
|
macro,METH_CLASS,3.2,,
|
||||||
|
macro,METH_COEXIST,3.2,,
|
||||||
|
macro,METH_FASTCALL,3.7,,
|
||||||
|
macro,METH_METHOD,3.7,,
|
||||||
|
macro,METH_NOARGS,3.2,,
|
||||||
|
macro,METH_O,3.2,,
|
||||||
|
macro,METH_STATIC,3.2,,
|
||||||
|
macro,METH_VARARGS,3.2,,
|
||||||
macro,PY_VECTORCALL_ARGUMENTS_OFFSET,3.12,,
|
macro,PY_VECTORCALL_ARGUMENTS_OFFSET,3.12,,
|
||||||
type,PyABIInfo,3.15,,full-abi
|
type,PyABIInfo,3.15,,full-abi
|
||||||
func,PyABIInfo_Check,3.15,,
|
func,PyABIInfo_Check,3.15,,
|
||||||
|
macro,PyABIInfo_DEFAULT_ABI_VERSION,3.15,,
|
||||||
|
macro,PyABIInfo_DEFAULT_FLAGS,3.15,,
|
||||||
|
macro,PyABIInfo_FREETHREADED,3.15,,
|
||||||
|
macro,PyABIInfo_FREETHREADING_AGNOSTIC,3.15,,
|
||||||
|
macro,PyABIInfo_GIL,3.15,,
|
||||||
|
macro,PyABIInfo_STABLE,3.15,,
|
||||||
macro,PyABIInfo_VAR,3.15,,
|
macro,PyABIInfo_VAR,3.15,,
|
||||||
func,PyAIter_Check,3.10,,
|
func,PyAIter_Check,3.10,,
|
||||||
func,PyArg_Parse,3.2,,
|
func,PyArg_Parse,3.2,,
|
||||||
|
|
@ -11,6 +25,26 @@ func,PyArg_UnpackTuple,3.2,,
|
||||||
func,PyArg_VaParse,3.2,,
|
func,PyArg_VaParse,3.2,,
|
||||||
func,PyArg_VaParseTupleAndKeywords,3.2,,
|
func,PyArg_VaParseTupleAndKeywords,3.2,,
|
||||||
func,PyArg_ValidateKeywordArguments,3.2,,
|
func,PyArg_ValidateKeywordArguments,3.2,,
|
||||||
|
macro,PyBUF_ANY_CONTIGUOUS,3.11,,
|
||||||
|
macro,PyBUF_CONTIG,3.11,,
|
||||||
|
macro,PyBUF_CONTIG_RO,3.11,,
|
||||||
|
macro,PyBUF_C_CONTIGUOUS,3.11,,
|
||||||
|
macro,PyBUF_FORMAT,3.11,,
|
||||||
|
macro,PyBUF_FULL,3.11,,
|
||||||
|
macro,PyBUF_FULL_RO,3.11,,
|
||||||
|
macro,PyBUF_F_CONTIGUOUS,3.11,,
|
||||||
|
macro,PyBUF_INDIRECT,3.11,,
|
||||||
|
macro,PyBUF_MAX_NDIM,3.11,,
|
||||||
|
macro,PyBUF_ND,3.11,,
|
||||||
|
macro,PyBUF_READ,3.11,,
|
||||||
|
macro,PyBUF_RECORDS,3.11,,
|
||||||
|
macro,PyBUF_RECORDS_RO,3.11,,
|
||||||
|
macro,PyBUF_SIMPLE,3.11,,
|
||||||
|
macro,PyBUF_STRIDED,3.11,,
|
||||||
|
macro,PyBUF_STRIDED_RO,3.11,,
|
||||||
|
macro,PyBUF_STRIDES,3.11,,
|
||||||
|
macro,PyBUF_WRITABLE,3.11,,
|
||||||
|
macro,PyBUF_WRITE,3.11,,
|
||||||
data,PyBaseObject_Type,3.2,,
|
data,PyBaseObject_Type,3.2,,
|
||||||
func,PyBool_FromLong,3.2,,
|
func,PyBool_FromLong,3.2,,
|
||||||
data,PyBool_Type,3.2,,
|
data,PyBool_Type,3.2,,
|
||||||
|
|
@ -126,6 +160,7 @@ func,PyDict_Merge,3.2,,
|
||||||
func,PyDict_MergeFromSeq2,3.2,,
|
func,PyDict_MergeFromSeq2,3.2,,
|
||||||
func,PyDict_New,3.2,,
|
func,PyDict_New,3.2,,
|
||||||
func,PyDict_Next,3.2,,
|
func,PyDict_Next,3.2,,
|
||||||
|
func,PyDict_SetDefaultRef,3.15,,
|
||||||
func,PyDict_SetItem,3.2,,
|
func,PyDict_SetItem,3.2,,
|
||||||
func,PyDict_SetItemString,3.2,,
|
func,PyDict_SetItemString,3.2,,
|
||||||
func,PyDict_Size,3.2,,
|
func,PyDict_Size,3.2,,
|
||||||
|
|
@ -391,6 +426,7 @@ func,PyLong_FromUnsignedNativeBytes,3.14,,
|
||||||
func,PyLong_FromVoidPtr,3.2,,
|
func,PyLong_FromVoidPtr,3.2,,
|
||||||
func,PyLong_GetInfo,3.2,,
|
func,PyLong_GetInfo,3.2,,
|
||||||
data,PyLong_Type,3.2,,
|
data,PyLong_Type,3.2,,
|
||||||
|
macro,PyMODEXPORT_FUNC,3.15,,
|
||||||
data,PyMap_Type,3.2,,
|
data,PyMap_Type,3.2,,
|
||||||
func,PyMapping_Check,3.2,,
|
func,PyMapping_Check,3.2,,
|
||||||
func,PyMapping_GetItemString,3.2,,
|
func,PyMapping_GetItemString,3.2,,
|
||||||
|
|
@ -428,6 +464,7 @@ data,PyMethodDescr_Type,3.2,,
|
||||||
type,PyModuleDef,3.2,,full-abi
|
type,PyModuleDef,3.2,,full-abi
|
||||||
type,PyModuleDef_Base,3.2,,full-abi
|
type,PyModuleDef_Base,3.2,,full-abi
|
||||||
func,PyModuleDef_Init,3.5,,
|
func,PyModuleDef_Init,3.5,,
|
||||||
|
type,PyModuleDef_Slot,3.5,,full-abi
|
||||||
data,PyModuleDef_Type,3.5,,
|
data,PyModuleDef_Type,3.5,,
|
||||||
func,PyModule_Add,3.13,,
|
func,PyModule_Add,3.13,,
|
||||||
func,PyModule_AddFunctions,3.7,,
|
func,PyModule_AddFunctions,3.7,,
|
||||||
|
|
@ -437,8 +474,10 @@ func,PyModule_AddObjectRef,3.10,,
|
||||||
func,PyModule_AddStringConstant,3.2,,
|
func,PyModule_AddStringConstant,3.2,,
|
||||||
func,PyModule_AddType,3.10,,
|
func,PyModule_AddType,3.10,,
|
||||||
func,PyModule_Create2,3.2,,
|
func,PyModule_Create2,3.2,,
|
||||||
|
func,PyModule_Exec,3.15,,
|
||||||
func,PyModule_ExecDef,3.7,,
|
func,PyModule_ExecDef,3.7,,
|
||||||
func,PyModule_FromDefAndSpec2,3.7,,
|
func,PyModule_FromDefAndSpec2,3.7,,
|
||||||
|
func,PyModule_FromSlotsAndSpec,3.15,,
|
||||||
func,PyModule_GetDef,3.2,,
|
func,PyModule_GetDef,3.2,,
|
||||||
func,PyModule_GetDict,3.2,,
|
func,PyModule_GetDict,3.2,,
|
||||||
func,PyModule_GetFilename,3.2,,
|
func,PyModule_GetFilename,3.2,,
|
||||||
|
|
@ -446,6 +485,8 @@ func,PyModule_GetFilenameObject,3.2,,
|
||||||
func,PyModule_GetName,3.2,,
|
func,PyModule_GetName,3.2,,
|
||||||
func,PyModule_GetNameObject,3.7,,
|
func,PyModule_GetNameObject,3.7,,
|
||||||
func,PyModule_GetState,3.2,,
|
func,PyModule_GetState,3.2,,
|
||||||
|
func,PyModule_GetStateSize,3.15,,
|
||||||
|
func,PyModule_GetToken,3.15,,
|
||||||
func,PyModule_New,3.2,,
|
func,PyModule_New,3.2,,
|
||||||
func,PyModule_NewObject,3.7,,
|
func,PyModule_NewObject,3.7,,
|
||||||
func,PyModule_SetDocString,3.7,,
|
func,PyModule_SetDocString,3.7,,
|
||||||
|
|
@ -704,6 +745,7 @@ func,PyType_GetFlags,3.2,,
|
||||||
func,PyType_GetFullyQualifiedName,3.13,,
|
func,PyType_GetFullyQualifiedName,3.13,,
|
||||||
func,PyType_GetModule,3.10,,
|
func,PyType_GetModule,3.10,,
|
||||||
func,PyType_GetModuleByDef,3.13,,
|
func,PyType_GetModuleByDef,3.13,,
|
||||||
|
func,PyType_GetModuleByToken,3.15,,
|
||||||
func,PyType_GetModuleName,3.13,,
|
func,PyType_GetModuleName,3.13,,
|
||||||
func,PyType_GetModuleState,3.10,,
|
func,PyType_GetModuleState,3.10,,
|
||||||
func,PyType_GetName,3.11,,
|
func,PyType_GetName,3.11,,
|
||||||
|
|
@ -836,6 +878,14 @@ func,PyWeakref_NewRef,3.2,,
|
||||||
data,PyWrapperDescr_Type,3.2,,
|
data,PyWrapperDescr_Type,3.2,,
|
||||||
func,PyWrapper_New,3.2,,
|
func,PyWrapper_New,3.2,,
|
||||||
data,PyZip_Type,3.2,,
|
data,PyZip_Type,3.2,,
|
||||||
|
macro,Py_ASNATIVEBYTES_ALLOW_INDEX,3.14,,
|
||||||
|
macro,Py_ASNATIVEBYTES_BIG_ENDIAN,3.14,,
|
||||||
|
macro,Py_ASNATIVEBYTES_DEFAULTS,3.14,,
|
||||||
|
macro,Py_ASNATIVEBYTES_LITTLE_ENDIAN,3.14,,
|
||||||
|
macro,Py_ASNATIVEBYTES_NATIVE_ENDIAN,3.14,,
|
||||||
|
macro,Py_ASNATIVEBYTES_REJECT_NEGATIVE,3.14,,
|
||||||
|
macro,Py_ASNATIVEBYTES_UNSIGNED_BUFFER,3.14,,
|
||||||
|
macro,Py_AUDIT_READ,3.12,,
|
||||||
func,Py_AddPendingCall,3.2,,
|
func,Py_AddPendingCall,3.2,,
|
||||||
func,Py_AtExit,3.2,,
|
func,Py_AtExit,3.2,,
|
||||||
macro,Py_BEGIN_ALLOW_THREADS,3.2,,
|
macro,Py_BEGIN_ALLOW_THREADS,3.2,,
|
||||||
|
|
@ -866,6 +916,7 @@ func,Py_GetPlatform,3.2,,
|
||||||
func,Py_GetRecursionLimit,3.2,,
|
func,Py_GetRecursionLimit,3.2,,
|
||||||
func,Py_GetVersion,3.2,,
|
func,Py_GetVersion,3.2,,
|
||||||
data,Py_HasFileSystemDefaultEncoding,3.2,,
|
data,Py_HasFileSystemDefaultEncoding,3.2,,
|
||||||
|
func,Py_IS_TYPE,3.15,,
|
||||||
func,Py_IncRef,3.2,,
|
func,Py_IncRef,3.2,,
|
||||||
func,Py_Initialize,3.2,,
|
func,Py_Initialize,3.2,,
|
||||||
func,Py_InitializeEx,3.2,,
|
func,Py_InitializeEx,3.2,,
|
||||||
|
|
@ -882,22 +933,147 @@ func,Py_NewInterpreter,3.2,,
|
||||||
func,Py_NewRef,3.10,,
|
func,Py_NewRef,3.10,,
|
||||||
func,Py_PACK_FULL_VERSION,3.14,,
|
func,Py_PACK_FULL_VERSION,3.14,,
|
||||||
func,Py_PACK_VERSION,3.14,,
|
func,Py_PACK_VERSION,3.14,,
|
||||||
|
macro,Py_READONLY,3.12,,
|
||||||
func,Py_REFCNT,3.14,,
|
func,Py_REFCNT,3.14,,
|
||||||
|
macro,Py_RELATIVE_OFFSET,3.12,,
|
||||||
func,Py_ReprEnter,3.2,,
|
func,Py_ReprEnter,3.2,,
|
||||||
func,Py_ReprLeave,3.2,,
|
func,Py_ReprLeave,3.2,,
|
||||||
|
func,Py_SET_SIZE,3.15,,
|
||||||
|
func,Py_SIZE,3.15,,
|
||||||
func,Py_SetProgramName,3.2,,
|
func,Py_SetProgramName,3.2,,
|
||||||
func,Py_SetPythonHome,3.2,,
|
func,Py_SetPythonHome,3.2,,
|
||||||
func,Py_SetRecursionLimit,3.2,,
|
func,Py_SetRecursionLimit,3.2,,
|
||||||
|
macro,Py_TPFLAGS_BASETYPE,3.2,,
|
||||||
|
macro,Py_TPFLAGS_DEFAULT,3.2,,
|
||||||
|
macro,Py_TPFLAGS_HAVE_GC,3.2,,
|
||||||
|
macro,Py_TPFLAGS_HAVE_VECTORCALL,3.12,,
|
||||||
|
macro,Py_TPFLAGS_ITEMS_AT_END,3.12,,
|
||||||
|
macro,Py_TPFLAGS_METHOD_DESCRIPTOR,3.8,,
|
||||||
|
macro,Py_TP_USE_SPEC,3.14,,
|
||||||
func,Py_TYPE,3.14,,
|
func,Py_TYPE,3.14,,
|
||||||
|
macro,Py_T_BOOL,3.12,,
|
||||||
|
macro,Py_T_BYTE,3.12,,
|
||||||
|
macro,Py_T_CHAR,3.12,,
|
||||||
|
macro,Py_T_DOUBLE,3.12,,
|
||||||
|
macro,Py_T_FLOAT,3.12,,
|
||||||
|
macro,Py_T_INT,3.12,,
|
||||||
|
macro,Py_T_LONG,3.12,,
|
||||||
|
macro,Py_T_LONGLONG,3.12,,
|
||||||
|
macro,Py_T_OBJECT_EX,3.12,,
|
||||||
|
macro,Py_T_PYSSIZET,3.12,,
|
||||||
|
macro,Py_T_SHORT,3.12,,
|
||||||
|
macro,Py_T_STRING,3.12,,
|
||||||
|
macro,Py_T_STRING_INPLACE,3.12,,
|
||||||
|
macro,Py_T_UBYTE,3.12,,
|
||||||
|
macro,Py_T_UINT,3.12,,
|
||||||
|
macro,Py_T_ULONG,3.12,,
|
||||||
|
macro,Py_T_ULONGLONG,3.12,,
|
||||||
|
macro,Py_T_USHORT,3.12,,
|
||||||
type,Py_UCS4,3.2,,
|
type,Py_UCS4,3.2,,
|
||||||
macro,Py_UNBLOCK_THREADS,3.2,,
|
macro,Py_UNBLOCK_THREADS,3.2,,
|
||||||
data,Py_UTF8Mode,3.8,,
|
data,Py_UTF8Mode,3.8,,
|
||||||
func,Py_VaBuildValue,3.2,,
|
func,Py_VaBuildValue,3.2,,
|
||||||
data,Py_Version,3.11,,
|
data,Py_Version,3.11,,
|
||||||
func,Py_XNewRef,3.10,,
|
func,Py_XNewRef,3.10,,
|
||||||
|
macro,Py_am_aiter,3.5,,
|
||||||
|
macro,Py_am_anext,3.5,,
|
||||||
|
macro,Py_am_await,3.5,,
|
||||||
|
macro,Py_am_send,3.10,,
|
||||||
|
macro,Py_bf_getbuffer,3.11,,
|
||||||
|
macro,Py_bf_releasebuffer,3.11,,
|
||||||
type,Py_buffer,3.11,,full-abi
|
type,Py_buffer,3.11,,full-abi
|
||||||
type,Py_intptr_t,3.2,,
|
type,Py_intptr_t,3.2,,
|
||||||
|
macro,Py_mod_abi,3.15,,
|
||||||
|
macro,Py_mod_create,3.5,,
|
||||||
|
macro,Py_mod_doc,3.15,,
|
||||||
|
macro,Py_mod_exec,3.5,,
|
||||||
|
macro,Py_mod_gil,3.13,,
|
||||||
|
macro,Py_mod_methods,3.15,,
|
||||||
|
macro,Py_mod_multiple_interpreters,3.12,,
|
||||||
|
macro,Py_mod_name,3.15,,
|
||||||
|
macro,Py_mod_state_clear,3.15,,
|
||||||
|
macro,Py_mod_state_free,3.15,,
|
||||||
|
macro,Py_mod_state_size,3.15,,
|
||||||
|
macro,Py_mod_state_traverse,3.15,,
|
||||||
|
macro,Py_mod_token,3.15,,
|
||||||
|
macro,Py_mp_ass_subscript,3.2,,
|
||||||
|
macro,Py_mp_length,3.2,,
|
||||||
|
macro,Py_mp_subscript,3.2,,
|
||||||
|
macro,Py_nb_absolute,3.2,,
|
||||||
|
macro,Py_nb_add,3.2,,
|
||||||
|
macro,Py_nb_and,3.2,,
|
||||||
|
macro,Py_nb_bool,3.2,,
|
||||||
|
macro,Py_nb_divmod,3.2,,
|
||||||
|
macro,Py_nb_float,3.2,,
|
||||||
|
macro,Py_nb_floor_divide,3.2,,
|
||||||
|
macro,Py_nb_index,3.2,,
|
||||||
|
macro,Py_nb_inplace_add,3.2,,
|
||||||
|
macro,Py_nb_inplace_and,3.2,,
|
||||||
|
macro,Py_nb_inplace_floor_divide,3.2,,
|
||||||
|
macro,Py_nb_inplace_lshift,3.2,,
|
||||||
|
macro,Py_nb_inplace_matrix_multiply,3.5,,
|
||||||
|
macro,Py_nb_inplace_multiply,3.2,,
|
||||||
|
macro,Py_nb_inplace_or,3.2,,
|
||||||
|
macro,Py_nb_inplace_power,3.2,,
|
||||||
|
macro,Py_nb_inplace_remainder,3.2,,
|
||||||
|
macro,Py_nb_inplace_rshift,3.2,,
|
||||||
|
macro,Py_nb_inplace_subtract,3.2,,
|
||||||
|
macro,Py_nb_inplace_true_divide,3.2,,
|
||||||
|
macro,Py_nb_inplace_xor,3.2,,
|
||||||
|
macro,Py_nb_int,3.2,,
|
||||||
|
macro,Py_nb_invert,3.2,,
|
||||||
|
macro,Py_nb_lshift,3.2,,
|
||||||
|
macro,Py_nb_matrix_multiply,3.5,,
|
||||||
|
macro,Py_nb_multiply,3.2,,
|
||||||
|
macro,Py_nb_negative,3.2,,
|
||||||
|
macro,Py_nb_or,3.2,,
|
||||||
|
macro,Py_nb_positive,3.2,,
|
||||||
|
macro,Py_nb_power,3.2,,
|
||||||
|
macro,Py_nb_remainder,3.2,,
|
||||||
|
macro,Py_nb_rshift,3.2,,
|
||||||
|
macro,Py_nb_subtract,3.2,,
|
||||||
|
macro,Py_nb_true_divide,3.2,,
|
||||||
|
macro,Py_nb_xor,3.2,,
|
||||||
|
macro,Py_sq_ass_item,3.2,,
|
||||||
|
macro,Py_sq_concat,3.2,,
|
||||||
|
macro,Py_sq_contains,3.2,,
|
||||||
|
macro,Py_sq_inplace_concat,3.2,,
|
||||||
|
macro,Py_sq_inplace_repeat,3.2,,
|
||||||
|
macro,Py_sq_item,3.2,,
|
||||||
|
macro,Py_sq_length,3.2,,
|
||||||
|
macro,Py_sq_repeat,3.2,,
|
||||||
type,Py_ssize_t,3.2,,
|
type,Py_ssize_t,3.2,,
|
||||||
|
macro,Py_tp_alloc,3.2,,
|
||||||
|
macro,Py_tp_base,3.2,,
|
||||||
|
macro,Py_tp_bases,3.2,,
|
||||||
|
macro,Py_tp_call,3.2,,
|
||||||
|
macro,Py_tp_clear,3.2,,
|
||||||
|
macro,Py_tp_dealloc,3.2,,
|
||||||
|
macro,Py_tp_del,3.2,,
|
||||||
|
macro,Py_tp_descr_get,3.2,,
|
||||||
|
macro,Py_tp_descr_set,3.2,,
|
||||||
|
macro,Py_tp_doc,3.2,,
|
||||||
|
macro,Py_tp_finalize,3.5,,
|
||||||
|
macro,Py_tp_free,3.2,,
|
||||||
|
macro,Py_tp_getattr,3.2,,
|
||||||
|
macro,Py_tp_getattro,3.2,,
|
||||||
|
macro,Py_tp_getset,3.2,,
|
||||||
|
macro,Py_tp_hash,3.2,,
|
||||||
|
macro,Py_tp_init,3.2,,
|
||||||
|
macro,Py_tp_is_gc,3.2,,
|
||||||
|
macro,Py_tp_iter,3.2,,
|
||||||
|
macro,Py_tp_iternext,3.2,,
|
||||||
|
macro,Py_tp_members,3.2,,
|
||||||
|
macro,Py_tp_methods,3.2,,
|
||||||
|
macro,Py_tp_new,3.2,,
|
||||||
|
macro,Py_tp_repr,3.2,,
|
||||||
|
macro,Py_tp_richcompare,3.2,,
|
||||||
|
macro,Py_tp_setattr,3.2,,
|
||||||
|
macro,Py_tp_setattro,3.2,,
|
||||||
|
macro,Py_tp_str,3.2,,
|
||||||
|
macro,Py_tp_token,3.14,,
|
||||||
|
macro,Py_tp_traverse,3.2,,
|
||||||
|
macro,Py_tp_vectorcall,3.14,,
|
||||||
type,Py_uintptr_t,3.2,,
|
type,Py_uintptr_t,3.2,,
|
||||||
type,allocfunc,3.2,,
|
type,allocfunc,3.2,,
|
||||||
type,binaryfunc,3.2,,
|
type,binaryfunc,3.2,,
|
||||||
|
|
|
||||||
|
|
@ -5,3 +5,5 @@ Pending removal in Python 3.20
|
||||||
Use :c:func:`PyComplex_AsCComplex` and :c:func:`PyComplex_FromCComplex`
|
Use :c:func:`PyComplex_AsCComplex` and :c:func:`PyComplex_FromCComplex`
|
||||||
to convert a Python complex number to/from the C :c:type:`Py_complex`
|
to convert a Python complex number to/from the C :c:type:`Py_complex`
|
||||||
representation.
|
representation.
|
||||||
|
|
||||||
|
* Macros :c:macro:`!Py_MATH_PIl` and :c:macro:`!Py_MATH_El`.
|
||||||
|
|
|
||||||
|
|
@ -38,15 +38,3 @@ APIs:
|
||||||
* :meth:`!unittest.TestProgram.usageExit` (:gh:`67048`)
|
* :meth:`!unittest.TestProgram.usageExit` (:gh:`67048`)
|
||||||
* :class:`!webbrowser.MacOSX` (:gh:`86421`)
|
* :class:`!webbrowser.MacOSX` (:gh:`86421`)
|
||||||
* :class:`classmethod` descriptor chaining (:gh:`89519`)
|
* :class:`classmethod` descriptor chaining (:gh:`89519`)
|
||||||
* :mod:`importlib.resources` deprecated methods:
|
|
||||||
|
|
||||||
* ``contents()``
|
|
||||||
* ``is_resource()``
|
|
||||||
* ``open_binary()``
|
|
||||||
* ``open_text()``
|
|
||||||
* ``path()``
|
|
||||||
* ``read_binary()``
|
|
||||||
* ``read_text()``
|
|
||||||
|
|
||||||
Use :func:`importlib.resources.files` instead. Refer to `importlib-resources: Migrating from Legacy
|
|
||||||
<https://importlib-resources.readthedocs.io/en/latest/using.html#migrating-from-legacy>`_ (:gh:`106531`)
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,12 @@ Pending removal in Python 3.17
|
||||||
(Contributed by Shantanu Jain in :gh:`91896`.)
|
(Contributed by Shantanu Jain in :gh:`91896`.)
|
||||||
|
|
||||||
|
|
||||||
|
* :mod:`encodings`:
|
||||||
|
|
||||||
|
- Passing non-ascii *encoding* names to :func:`encodings.normalize_encoding`
|
||||||
|
is deprecated and scheduled for removal in Python 3.17.
|
||||||
|
(Contributed by Stan Ulbrych in :gh:`136702`)
|
||||||
|
|
||||||
* :mod:`typing`:
|
* :mod:`typing`:
|
||||||
|
|
||||||
- Before Python 3.14, old-style unions were implemented using the private class
|
- Before Python 3.14, old-style unions were implemented using the private class
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ although there is currently no date scheduled for their removal.
|
||||||
* :mod:`mailbox`: Use of StringIO input and text mode is deprecated, use
|
* :mod:`mailbox`: Use of StringIO input and text mode is deprecated, use
|
||||||
BytesIO and binary mode instead.
|
BytesIO and binary mode instead.
|
||||||
|
|
||||||
* :mod:`os`: Calling :func:`os.register_at_fork` in multi-threaded process.
|
* :mod:`os`: Calling :func:`os.register_at_fork` in a multi-threaded process.
|
||||||
|
|
||||||
* :class:`!pydoc.ErrorDuringImport`: A tuple value for *exc_info* parameter is
|
* :class:`!pydoc.ErrorDuringImport`: A tuple value for *exc_info* parameter is
|
||||||
deprecated, use an exception instance.
|
deprecated, use an exception instance.
|
||||||
|
|
|
||||||
|
|
@ -426,7 +426,7 @@ A pointer to the module definition must be returned via :c:func:`PyModuleDef_Ini
|
||||||
so that the import machinery can create the module and store it in ``sys.modules``.
|
so that the import machinery can create the module and store it in ``sys.modules``.
|
||||||
|
|
||||||
When embedding Python, the :c:func:`!PyInit_spam` function is not called
|
When embedding Python, the :c:func:`!PyInit_spam` function is not called
|
||||||
automatically unless there's an entry in the :c:data:`!PyImport_Inittab` table.
|
automatically unless there's an entry in the :c:data:`PyImport_Inittab` table.
|
||||||
To add the module to the initialization table, use :c:func:`PyImport_AppendInittab`,
|
To add the module to the initialization table, use :c:func:`PyImport_AppendInittab`,
|
||||||
optionally followed by an import of the module::
|
optionally followed by an import of the module::
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1025,6 +1025,15 @@ Glossary
|
||||||
applied to all scopes, only those relying on a known set of local
|
applied to all scopes, only those relying on a known set of local
|
||||||
and nonlocal variable names are restricted to optimized scopes.
|
and nonlocal variable names are restricted to optimized scopes.
|
||||||
|
|
||||||
|
optional module
|
||||||
|
An :term:`extension module` that is part of the :term:`standard library`,
|
||||||
|
but may be absent in some builds of :term:`CPython`,
|
||||||
|
usually due to missing third-party libraries or because the module
|
||||||
|
is not available for a given platform.
|
||||||
|
|
||||||
|
See :ref:`optional-module-requirements` for a list of optional modules
|
||||||
|
that require third-party libraries.
|
||||||
|
|
||||||
package
|
package
|
||||||
A Python :term:`module` which can contain submodules or recursively,
|
A Python :term:`module` which can contain submodules or recursively,
|
||||||
subpackages. Technically, a package is a Python module with a
|
subpackages. Technically, a package is a Python module with a
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
.. _a-conceptual-overview-of-asyncio:
|
.. _a-conceptual-overview-of-asyncio:
|
||||||
|
|
||||||
****************************************
|
****************************************
|
||||||
A Conceptual Overview of :mod:`!asyncio`
|
A conceptual overview of :mod:`!asyncio`
|
||||||
****************************************
|
****************************************
|
||||||
|
|
||||||
This :ref:`HOWTO <how-tos>` article seeks to help you build a sturdy mental
|
This :ref:`HOWTO <how-tos>` article seeks to help you build a sturdy mental
|
||||||
|
|
@ -37,15 +37,15 @@ 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
|
Event loop
|
||||||
==========
|
==========
|
||||||
|
|
||||||
Everything in :mod:`!asyncio` happens relative to the event loop.
|
Everything in :mod:`!asyncio` happens relative to the event loop.
|
||||||
It's the star of the show.
|
It's the star of the show, but prefers to work behind the scenes, managing
|
||||||
|
and coordinating resources.
|
||||||
It's like an orchestra conductor.
|
It's like an orchestra conductor.
|
||||||
It's behind the scenes managing resources.
|
|
||||||
Some power is explicitly granted to it, but a lot of its ability to get things
|
Some power is explicitly granted to it, but a lot of its ability to get things
|
||||||
done comes from the respect and cooperation of its worker bees.
|
done comes from the respect and cooperation of its band members.
|
||||||
|
|
||||||
In more technical terms, the event loop contains a collection of jobs to be run.
|
In more technical terms, the event loop contains a collection of jobs to be run.
|
||||||
Some jobs are added directly by you, and some indirectly by :mod:`!asyncio`.
|
Some jobs are added directly by you, and some indirectly by :mod:`!asyncio`.
|
||||||
|
|
@ -59,7 +59,7 @@ This process repeats indefinitely, with the event loop cycling endlessly
|
||||||
onwards.
|
onwards.
|
||||||
If there are no more jobs pending execution, the event loop is smart enough to
|
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
|
rest and avoid needlessly wasting CPU cycles, and will come back when there's
|
||||||
more work to be done.
|
more work to be done, such as when I/O operations complete or timers expire.
|
||||||
|
|
||||||
Effective execution relies on jobs sharing well and cooperating; a greedy job
|
Effective execution relies on jobs sharing well and cooperating; a greedy job
|
||||||
could hog control and leave the other jobs to starve, rendering the overall
|
could hog control and leave the other jobs to starve, rendering the overall
|
||||||
|
|
@ -170,14 +170,17 @@ Roughly speaking, :ref:`tasks <asyncio-task-obj>` are coroutines (not coroutine
|
||||||
functions) tied to an event loop.
|
functions) tied to an event loop.
|
||||||
A task also maintains a list of callback functions whose importance will become
|
A task also maintains a list of callback functions whose importance will become
|
||||||
clear in a moment when we discuss :keyword:`await`.
|
clear in a moment when we discuss :keyword:`await`.
|
||||||
The recommended way to create tasks is via :func:`asyncio.create_task`.
|
|
||||||
|
|
||||||
Creating a task automatically schedules it for execution (by adding a
|
Creating a task automatically schedules it for execution (by adding a
|
||||||
callback to run it in the event loop's to-do list, that is, collection of jobs).
|
callback to run it in the event loop's to-do list, that is, collection of jobs).
|
||||||
|
The recommended way to create tasks is via :func:`asyncio.create_task`.
|
||||||
|
|
||||||
Since there's only one event loop (in each thread), :mod:`!asyncio` takes care of
|
:mod:`!asyncio` automatically associates tasks with the event loop for you.
|
||||||
associating the task with the event loop for you. As such, there's no need
|
This automatic association was purposely designed into :mod:`!asyncio` for
|
||||||
to specify the event loop.
|
the sake of simplicity.
|
||||||
|
Without it, you'd have to keep track of the event loop object and pass it to
|
||||||
|
any coroutine function that wants to create tasks, adding redundant clutter
|
||||||
|
to your code.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
|
@ -250,6 +253,10 @@ different ways::
|
||||||
In a crucial way, the behavior of ``await`` depends on the type of object
|
In a crucial way, the behavior of ``await`` depends on the type of object
|
||||||
being awaited.
|
being awaited.
|
||||||
|
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
Awaiting tasks
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Awaiting a task will cede control from the current task or coroutine to
|
Awaiting a task will cede control from the current task or coroutine to
|
||||||
the event loop.
|
the event loop.
|
||||||
In the process of relinquishing control, a few important things happen.
|
In the process of relinquishing control, a few important things happen.
|
||||||
|
|
@ -281,6 +288,10 @@ This is a basic, yet reliable mental model.
|
||||||
In practice, the control handoffs are slightly more complex, but not by much.
|
In practice, the control handoffs are slightly more complex, but not by much.
|
||||||
In part 2, we'll walk through the details that make this possible.
|
In part 2, we'll walk through the details that make this possible.
|
||||||
|
|
||||||
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
Awaiting coroutines
|
||||||
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
**Unlike tasks, awaiting a coroutine does not hand control back to the event
|
**Unlike tasks, awaiting a coroutine does not hand control back to the event
|
||||||
loop!**
|
loop!**
|
||||||
Wrapping a coroutine in a task first, then awaiting that would cede
|
Wrapping a coroutine in a task first, then awaiting that would cede
|
||||||
|
|
@ -347,8 +358,10 @@ The design intentionally trades off some conceptual clarity around usage of
|
||||||
``await`` for improved performance.
|
``await`` for improved performance.
|
||||||
Each time a task is awaited, control needs to be passed all the way up the
|
Each time a task is awaited, control needs to be passed all the way up the
|
||||||
call stack to the event loop.
|
call stack to the event loop.
|
||||||
That might sound minor, but in a large program with many ``await`` statements and a deep
|
Then, the event loop needs to manage its internal state and work through
|
||||||
call stack, that overhead can add up to a meaningful performance drag.
|
its processing logic to resume the next job.
|
||||||
|
That might sound minor, but in a large program with many ``await``\ s, that
|
||||||
|
overhead can add up to a non-negligible performance drag.
|
||||||
|
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
A conceptual overview part 2: the nuts and bolts
|
A conceptual overview part 2: the nuts and bolts
|
||||||
|
|
@ -364,7 +377,8 @@ and how to make your own asynchronous operators.
|
||||||
The inner workings of coroutines
|
The inner workings of coroutines
|
||||||
================================
|
================================
|
||||||
|
|
||||||
:mod:`!asyncio` leverages four components to pass around control.
|
:mod:`!asyncio` leverages four components of Python to pass
|
||||||
|
around control.
|
||||||
|
|
||||||
:meth:`coroutine.send(arg) <generator.send>` is the method used to start or
|
:meth:`coroutine.send(arg) <generator.send>` is the method used to start or
|
||||||
resume a coroutine.
|
resume a coroutine.
|
||||||
|
|
@ -448,9 +462,9 @@ That might sound odd to you. You might be thinking:
|
||||||
That causes the error: ``SyntaxError: yield from not allowed in a coroutine.``
|
That causes the error: ``SyntaxError: yield from not allowed in a coroutine.``
|
||||||
This was intentionally designed for the sake of simplicity -- mandating only
|
This was intentionally designed for the sake of simplicity -- mandating only
|
||||||
one way of using coroutines.
|
one way of using coroutines.
|
||||||
|
Despite that, ``yield from`` and ``await`` effectively do the same thing.
|
||||||
Initially ``yield`` was barred as well, but was re-accepted to allow for
|
Initially ``yield`` was barred as well, but was re-accepted to allow for
|
||||||
async generators.
|
async generators.
|
||||||
Despite that, ``yield from`` and ``await`` effectively do the same thing.
|
|
||||||
|
|
||||||
=======
|
=======
|
||||||
Futures
|
Futures
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,12 @@ single-phase initialization.
|
||||||
Multi-Phase Initialization
|
Multi-Phase Initialization
|
||||||
..........................
|
..........................
|
||||||
|
|
||||||
Extensions that use multi-phase initialization (i.e.,
|
Extensions that use :ref:`multi-phase initialization <multi-phase-initialization>`
|
||||||
:c:func:`PyModuleDef_Init`) should add a :c:data:`Py_mod_gil` slot in the
|
(functions like :c:func:`PyModuleDef_Init`,
|
||||||
module definition. If your extension supports older versions of CPython,
|
:c:func:`PyModExport_* <PyModExport_modulename>` export hook,
|
||||||
|
:c:func:`PyModule_FromSlotsAndSpec`) should add a
|
||||||
|
:c:data:`Py_mod_gil` slot in the module definition.
|
||||||
|
If your extension supports older versions of CPython,
|
||||||
you should guard the slot with a :c:data:`PY_VERSION_HEX` check.
|
you should guard the slot with a :c:data:`PY_VERSION_HEX` check.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
@ -60,18 +63,12 @@ you should guard the slot with a :c:data:`PY_VERSION_HEX` check.
|
||||||
{0, NULL}
|
{0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct PyModuleDef moduledef = {
|
|
||||||
PyModuleDef_HEAD_INIT,
|
|
||||||
.m_slots = module_slots,
|
|
||||||
...
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
Single-Phase Initialization
|
Single-Phase Initialization
|
||||||
...........................
|
...........................
|
||||||
|
|
||||||
Extensions that use single-phase initialization (i.e.,
|
Extensions that use legacy :ref:`single-phase initialization <single-phase-initialization>`
|
||||||
:c:func:`PyModule_Create`) should call :c:func:`PyUnstable_Module_SetGIL` to
|
(that is, :c:func:`PyModule_Create`) should call :c:func:`PyUnstable_Module_SetGIL` to
|
||||||
indicate that they support running with the GIL disabled. The function is
|
indicate that they support running with the GIL disabled. The function is
|
||||||
only defined in the free-threaded build, so you should guard the call with
|
only defined in the free-threaded build, so you should guard the call with
|
||||||
``#ifdef Py_GIL_DISABLED`` to avoid compilation errors in the regular build.
|
``#ifdef Py_GIL_DISABLED`` to avoid compilation errors in the regular build.
|
||||||
|
|
@ -203,7 +200,7 @@ Memory Allocation APIs
|
||||||
Python's memory management C API provides functions in three different
|
Python's memory management C API provides functions in three different
|
||||||
:ref:`allocation domains <allocator-domains>`: "raw", "mem", and "object".
|
:ref:`allocation domains <allocator-domains>`: "raw", "mem", and "object".
|
||||||
For thread-safety, the free-threaded build requires that only Python objects
|
For thread-safety, the free-threaded build requires that only Python objects
|
||||||
are allocated using the object domain, and that all Python object are
|
are allocated using the object domain, and that all Python objects are
|
||||||
allocated using that domain. This differs from the prior Python versions,
|
allocated using that domain. This differs from the prior Python versions,
|
||||||
where this was only a best practice and not a hard requirement.
|
where this was only a best practice and not a hard requirement.
|
||||||
|
|
||||||
|
|
@ -344,12 +341,12 @@ This means you cannot rely on nested critical sections to lock multiple objects
|
||||||
at once, as the inner critical section may suspend the outer ones. Instead, use
|
at once, as the inner critical section may suspend the outer ones. Instead, use
|
||||||
:c:macro:`Py_BEGIN_CRITICAL_SECTION2` to lock two objects simultaneously.
|
:c:macro:`Py_BEGIN_CRITICAL_SECTION2` to lock two objects simultaneously.
|
||||||
|
|
||||||
Note that the locks described above are only :c:type:`!PyMutex` based locks.
|
Note that the locks described above are only :c:type:`PyMutex` based locks.
|
||||||
The critical section implementation does not know about or affect other locking
|
The critical section implementation does not know about or affect other locking
|
||||||
mechanisms that might be in use, like POSIX mutexes. Also note that while
|
mechanisms that might be in use, like POSIX mutexes. Also note that while
|
||||||
blocking on any :c:type:`!PyMutex` causes the critical sections to be
|
blocking on any :c:type:`PyMutex` causes the critical sections to be
|
||||||
suspended, only the mutexes that are part of the critical sections are
|
suspended, only the mutexes that are part of the critical sections are
|
||||||
released. If :c:type:`!PyMutex` is used without a critical section, it will
|
released. If :c:type:`PyMutex` is used without a critical section, it will
|
||||||
not be released and therefore does not get the same deadlock avoidance.
|
not be released and therefore does not get the same deadlock avoidance.
|
||||||
|
|
||||||
Important Considerations
|
Important Considerations
|
||||||
|
|
@ -397,7 +394,8 @@ The wheels, shared libraries, and binaries are indicated by a ``t`` suffix.
|
||||||
* `pypa/manylinux <https://github.com/pypa/manylinux>`_ supports the
|
* `pypa/manylinux <https://github.com/pypa/manylinux>`_ supports the
|
||||||
free-threaded build, with the ``t`` suffix, such as ``python3.13t``.
|
free-threaded build, with the ``t`` suffix, such as ``python3.13t``.
|
||||||
* `pypa/cibuildwheel <https://github.com/pypa/cibuildwheel>`_ supports the
|
* `pypa/cibuildwheel <https://github.com/pypa/cibuildwheel>`_ supports the
|
||||||
free-threaded build if you set
|
free-threaded build on Python 3.13 and 3.14. On Python 3.14, free-threaded
|
||||||
|
wheels will be built by default. On Python 3.13, you will need to set
|
||||||
`CIBW_ENABLE to cpython-freethreading <https://cibuildwheel.pypa.io/en/stable/options/#enable>`_.
|
`CIBW_ENABLE to cpython-freethreading <https://cibuildwheel.pypa.io/en/stable/options/#enable>`_.
|
||||||
|
|
||||||
Limited C API and Stable ABI
|
Limited C API and Stable ABI
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,7 @@ available processing power by running threads in parallel on available CPU cores
|
||||||
While not all software will benefit from this automatically, programs
|
While not all software will benefit from this automatically, programs
|
||||||
designed with threading in mind will run faster on multi-core hardware.
|
designed with threading in mind will run faster on multi-core hardware.
|
||||||
|
|
||||||
The free-threaded mode is working and continues to be improved, but
|
Some third-party packages, in particular ones
|
||||||
there is some additional overhead in single-threaded workloads compared
|
|
||||||
to the regular build. Additionally, third-party packages, in particular ones
|
|
||||||
with an :term:`extension module`, may not be ready for use in a
|
with an :term:`extension module`, may not be ready for use in a
|
||||||
free-threaded build, and will re-enable the :term:`GIL`.
|
free-threaded build, and will re-enable the :term:`GIL`.
|
||||||
|
|
||||||
|
|
@ -101,60 +99,42 @@ This section describes known limitations of the free-threaded CPython build.
|
||||||
Immortalization
|
Immortalization
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
The free-threaded build of the 3.13 release makes some objects :term:`immortal`.
|
In the free-threaded build, some objects are :term:`immortal`.
|
||||||
Immortal objects are not deallocated and have reference counts that are
|
Immortal objects are not deallocated and have reference counts that are
|
||||||
never modified. This is done to avoid reference count contention that would
|
never modified. This is done to avoid reference count contention that would
|
||||||
prevent efficient multi-threaded scaling.
|
prevent efficient multi-threaded scaling.
|
||||||
|
|
||||||
An object will be made immortal when a new thread is started for the first time
|
As of the 3.14 release, immortalization is limited to:
|
||||||
after the main thread is running. The following objects are immortalized:
|
|
||||||
|
|
||||||
* :ref:`function <user-defined-funcs>` objects declared at the module level
|
* Code constants: numeric literals, string literals, and tuple literals
|
||||||
* :ref:`method <instance-methods>` descriptors
|
composed of other constants.
|
||||||
* :ref:`code <code-objects>` objects
|
* Strings interned by :func:`sys.intern`.
|
||||||
* :term:`module` objects and their dictionaries
|
|
||||||
* :ref:`classes <classes>` (type objects)
|
|
||||||
|
|
||||||
Because immortal objects are never deallocated, applications that create many
|
|
||||||
objects of these types may see increased memory usage. This is expected to be
|
|
||||||
addressed in the 3.14 release.
|
|
||||||
|
|
||||||
Additionally, numeric and string literals in the code as well as strings
|
|
||||||
returned by :func:`sys.intern` are also immortalized. This behavior is
|
|
||||||
expected to remain in the 3.14 free-threaded build.
|
|
||||||
|
|
||||||
|
|
||||||
Frame objects
|
Frame objects
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
It is not safe to access :ref:`frame <frame-objects>` objects from other
|
It is not safe to access :attr:`frame.f_locals` from a :ref:`frame <frame-objects>`
|
||||||
threads and doing so may cause your program to crash . This means that
|
object if that frame is currently executing in another thread, and doing so may
|
||||||
:func:`sys._current_frames` is generally not safe to use in a free-threaded
|
crash the interpreter.
|
||||||
build. Functions like :func:`inspect.currentframe` and :func:`sys._getframe`
|
|
||||||
are generally safe as long as the resulting frame object is not passed to
|
|
||||||
another thread.
|
|
||||||
|
|
||||||
Iterators
|
Iterators
|
||||||
---------
|
---------
|
||||||
|
|
||||||
Sharing the same iterator object between multiple threads is generally not
|
It is generally not thread-safe to access the same iterator object from
|
||||||
safe and threads may see duplicate or missing elements when iterating or crash
|
multiple threads concurrently, and threads may see duplicate or missing
|
||||||
the interpreter.
|
elements.
|
||||||
|
|
||||||
|
|
||||||
Single-threaded performance
|
Single-threaded performance
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
The free-threaded build has additional overhead when executing Python code
|
The free-threaded build has additional overhead when executing Python code
|
||||||
compared to the default GIL-enabled build. In 3.13, this overhead is about
|
compared to the default GIL-enabled build. The amount of overhead depends
|
||||||
40% on the `pyperformance <https://pyperformance.readthedocs.io/>`_ suite.
|
on the workload and hardware. On the pyperformance benchmark suite, the
|
||||||
Programs that spend most of their time in C extensions or I/O will see
|
average overhead ranges from about 1% on macOS aarch64 to 8% on x86-64 Linux
|
||||||
less of an impact. The largest impact is because the specializing adaptive
|
systems.
|
||||||
interpreter (:pep:`659`) is disabled in the free-threaded build. We expect
|
|
||||||
to re-enable it in a thread-safe way in the 3.14 release. This overhead is
|
|
||||||
expected to be reduced in upcoming Python release. We are aiming for an
|
|
||||||
overhead of 10% or less on the pyperformance suite compared to the default
|
|
||||||
GIL-enabled build.
|
|
||||||
|
|
||||||
|
|
||||||
Behavioral changes
|
Behavioral changes
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
Functional Programming HOWTO
|
Functional Programming HOWTO
|
||||||
********************************
|
********************************
|
||||||
|
|
||||||
:Author: A. M. Kuchling
|
:Author: \A. M. Kuchling
|
||||||
:Release: 0.32
|
:Release: 0.32
|
||||||
|
|
||||||
In this document, we'll take a tour of Python's features suitable for
|
In this document, we'll take a tour of Python's features suitable for
|
||||||
|
|
|
||||||
|
|
@ -353,7 +353,7 @@ garbage collection protocol.
|
||||||
That is, heap types should:
|
That is, heap types should:
|
||||||
|
|
||||||
- Have the :c:macro:`Py_TPFLAGS_HAVE_GC` flag.
|
- Have the :c:macro:`Py_TPFLAGS_HAVE_GC` flag.
|
||||||
- Define a traverse function using ``Py_tp_traverse``, which
|
- Define a traverse function using :c:data:`Py_tp_traverse`, which
|
||||||
visits the type (e.g. using ``Py_VISIT(Py_TYPE(self))``).
|
visits the type (e.g. using ``Py_VISIT(Py_TYPE(self))``).
|
||||||
|
|
||||||
Please refer to the documentation of
|
Please refer to the documentation of
|
||||||
|
|
|
||||||
|
|
@ -352,6 +352,8 @@ If you don't include such a comment, the default encoding used will be UTF-8 as
|
||||||
already mentioned. See also :pep:`263` for more information.
|
already mentioned. See also :pep:`263` for more information.
|
||||||
|
|
||||||
|
|
||||||
|
.. _unicode-properties:
|
||||||
|
|
||||||
Unicode Properties
|
Unicode Properties
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ Introduction
|
||||||
You may also find useful the following article on fetching web resources
|
You may also find useful the following article on fetching web resources
|
||||||
with Python:
|
with Python:
|
||||||
|
|
||||||
* `Basic Authentication <https://web.archive.org/web/20201215133350/http://www.voidspace.org.uk/python/articles/authentication.shtml>`_
|
* `Basic Authentication <https://web.archive.org/web/20201215133350/http://www.voidspace.org.uk/python/articles/authentication.shtml>`__
|
||||||
|
|
||||||
A tutorial on *Basic Authentication*, with examples in Python.
|
A tutorial on *Basic Authentication*, with examples in Python.
|
||||||
|
|
||||||
|
|
|
||||||
9
Doc/includes/optional-module.rst
Normal file
9
Doc/includes/optional-module.rst
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
This is an :term:`optional module`.
|
||||||
|
If it is missing from your copy of CPython,
|
||||||
|
look for documentation from your distributor (that is,
|
||||||
|
whoever provided Python to you).
|
||||||
|
If you are the distributor, see :ref:`optional-module-requirements`.
|
||||||
|
|
||||||
|
.. Similar notes appear in the docs of the modules:
|
||||||
|
- zipfile
|
||||||
|
- tarfile
|
||||||
|
|
@ -767,9 +767,9 @@ how the command-line arguments should be handled. The supplied actions are:
|
||||||
Namespace(foo=42)
|
Namespace(foo=42)
|
||||||
|
|
||||||
* ``'store_true'`` and ``'store_false'`` - These are special cases of
|
* ``'store_true'`` and ``'store_false'`` - These are special cases of
|
||||||
``'store_const'`` used for storing the values ``True`` and ``False``
|
``'store_const'`` that respectively store the values ``True`` and ``False``
|
||||||
respectively. In addition, they create default values of ``False`` and
|
with default values of ``False`` and
|
||||||
``True`` respectively::
|
``True``::
|
||||||
|
|
||||||
>>> parser = argparse.ArgumentParser()
|
>>> parser = argparse.ArgumentParser()
|
||||||
>>> parser.add_argument('--foo', action='store_true')
|
>>> parser.add_argument('--foo', action='store_true')
|
||||||
|
|
@ -789,8 +789,8 @@ how the command-line arguments should be handled. The supplied actions are:
|
||||||
>>> parser.parse_args('--foo 1 --foo 2'.split())
|
>>> parser.parse_args('--foo 1 --foo 2'.split())
|
||||||
Namespace(foo=['0', '1', '2'])
|
Namespace(foo=['0', '1', '2'])
|
||||||
|
|
||||||
* ``'append_const'`` - This stores a list, and appends the value specified by
|
* ``'append_const'`` - This appends the value specified by
|
||||||
the const_ keyword argument to the list; note that the const_ keyword
|
the const_ keyword argument to a list; note that the const_ keyword
|
||||||
argument defaults to ``None``. The ``'append_const'`` action is typically
|
argument defaults to ``None``. The ``'append_const'`` action is typically
|
||||||
useful when multiple arguments need to store constants to the same list. For
|
useful when multiple arguments need to store constants to the same list. For
|
||||||
example::
|
example::
|
||||||
|
|
@ -801,8 +801,8 @@ how the command-line arguments should be handled. The supplied actions are:
|
||||||
>>> parser.parse_args('--str --int'.split())
|
>>> parser.parse_args('--str --int'.split())
|
||||||
Namespace(types=[<class 'str'>, <class 'int'>])
|
Namespace(types=[<class 'str'>, <class 'int'>])
|
||||||
|
|
||||||
* ``'extend'`` - This stores a list and appends each item from the multi-value
|
* ``'extend'`` - This appends each item from a multi-value
|
||||||
argument list to it.
|
argument to a list.
|
||||||
The ``'extend'`` action is typically used with the nargs_ keyword argument
|
The ``'extend'`` action is typically used with the nargs_ keyword argument
|
||||||
value ``'+'`` or ``'*'``.
|
value ``'+'`` or ``'*'``.
|
||||||
Note that when nargs_ is ``None`` (the default) or ``'?'``, each
|
Note that when nargs_ is ``None`` (the default) or ``'?'``, each
|
||||||
|
|
@ -816,7 +816,7 @@ how the command-line arguments should be handled. The supplied actions are:
|
||||||
|
|
||||||
.. versionadded:: 3.8
|
.. versionadded:: 3.8
|
||||||
|
|
||||||
* ``'count'`` - This counts the number of times a keyword argument occurs. For
|
* ``'count'`` - This counts the number of times an argument occurs. For
|
||||||
example, this is useful for increasing verbosity levels::
|
example, this is useful for increasing verbosity levels::
|
||||||
|
|
||||||
>>> parser = argparse.ArgumentParser()
|
>>> parser = argparse.ArgumentParser()
|
||||||
|
|
@ -1322,8 +1322,12 @@ attribute is determined by the ``dest`` keyword argument of
|
||||||
|
|
||||||
For optional argument actions, the value of ``dest`` is normally inferred from
|
For optional argument actions, the value of ``dest`` is normally inferred from
|
||||||
the option strings. :class:`ArgumentParser` generates the value of ``dest`` by
|
the option strings. :class:`ArgumentParser` generates the value of ``dest`` by
|
||||||
taking the first long option string and stripping away the initial ``--``
|
taking the first double-dash long option string and stripping away the initial
|
||||||
string. If no long option strings were supplied, ``dest`` will be derived from
|
``-`` characters.
|
||||||
|
If no double-dash long option strings were supplied, ``dest`` will be derived
|
||||||
|
from the first single-dash long option string by stripping the initial ``-``
|
||||||
|
character.
|
||||||
|
If no long option strings were supplied, ``dest`` will be derived from
|
||||||
the first short option string by stripping the initial ``-`` character. Any
|
the first short option string by stripping the initial ``-`` character. Any
|
||||||
internal ``-`` characters will be converted to ``_`` characters to make sure
|
internal ``-`` characters will be converted to ``_`` characters to make sure
|
||||||
the string is a valid attribute name. The examples below illustrate this
|
the string is a valid attribute name. The examples below illustrate this
|
||||||
|
|
@ -1331,11 +1335,12 @@ behavior::
|
||||||
|
|
||||||
>>> parser = argparse.ArgumentParser()
|
>>> parser = argparse.ArgumentParser()
|
||||||
>>> parser.add_argument('-f', '--foo-bar', '--foo')
|
>>> parser.add_argument('-f', '--foo-bar', '--foo')
|
||||||
|
>>> parser.add_argument('-q', '-quz')
|
||||||
>>> parser.add_argument('-x', '-y')
|
>>> parser.add_argument('-x', '-y')
|
||||||
>>> parser.parse_args('-f 1 -x 2'.split())
|
>>> parser.parse_args('-f 1 -q 2 -x 3'.split())
|
||||||
Namespace(foo_bar='1', x='2')
|
Namespace(foo_bar='1', quz='2', x='3')
|
||||||
>>> parser.parse_args('--foo 1 -y 2'.split())
|
>>> parser.parse_args('--foo 1 -quz 2 -y 3'.split())
|
||||||
Namespace(foo_bar='1', x='2')
|
Namespace(foo_bar='1', quz='2', x='2')
|
||||||
|
|
||||||
``dest`` allows a custom attribute name to be provided::
|
``dest`` allows a custom attribute name to be provided::
|
||||||
|
|
||||||
|
|
@ -1344,6 +1349,9 @@ behavior::
|
||||||
>>> parser.parse_args('--foo XXX'.split())
|
>>> parser.parse_args('--foo XXX'.split())
|
||||||
Namespace(bar='XXX')
|
Namespace(bar='XXX')
|
||||||
|
|
||||||
|
.. versionchanged:: next
|
||||||
|
Single-dash long option now takes precedence over short options.
|
||||||
|
|
||||||
|
|
||||||
.. _deprecated:
|
.. _deprecated:
|
||||||
|
|
||||||
|
|
@ -1437,8 +1445,18 @@ this API may be passed as the ``action`` parameter to
|
||||||
>>> parser.parse_args(['--no-foo'])
|
>>> parser.parse_args(['--no-foo'])
|
||||||
Namespace(foo=False)
|
Namespace(foo=False)
|
||||||
|
|
||||||
|
Single-dash long options are also supported.
|
||||||
|
For example, negative option ``-nofoo`` is automatically added for
|
||||||
|
positive option ``-foo``.
|
||||||
|
But no additional options are added for short options such as ``-f``.
|
||||||
|
|
||||||
.. versionadded:: 3.9
|
.. versionadded:: 3.9
|
||||||
|
|
||||||
|
.. versionchanged:: next
|
||||||
|
Added support for single-dash options.
|
||||||
|
|
||||||
|
Added support for alternate prefix_chars_.
|
||||||
|
|
||||||
|
|
||||||
The parse_args() method
|
The parse_args() method
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
@ -2070,7 +2088,9 @@ Parser defaults
|
||||||
>>> parser.parse_args(['736'])
|
>>> parser.parse_args(['736'])
|
||||||
Namespace(bar=42, baz='badger', foo=736)
|
Namespace(bar=42, baz='badger', foo=736)
|
||||||
|
|
||||||
Note that parser-level defaults always override argument-level defaults::
|
Note that defaults can be set at both the parser level using :meth:`set_defaults`
|
||||||
|
and at the argument level using :meth:`add_argument`. If both are called for the
|
||||||
|
same argument, the last default set for an argument is used::
|
||||||
|
|
||||||
>>> parser = argparse.ArgumentParser()
|
>>> parser = argparse.ArgumentParser()
|
||||||
>>> parser.add_argument('--foo', default='bar')
|
>>> parser.add_argument('--foo', default='bar')
|
||||||
|
|
|
||||||
|
|
@ -2205,10 +2205,10 @@ Async and await
|
||||||
Apart from the node classes, the :mod:`ast` module defines these utility functions
|
Apart from the node classes, the :mod:`ast` module defines these utility functions
|
||||||
and classes for traversing abstract syntax trees:
|
and classes for traversing abstract syntax trees:
|
||||||
|
|
||||||
.. function:: parse(source, filename='<unknown>', mode='exec', *, type_comments=False, feature_version=None, optimize=-1)
|
.. function:: parse(source, filename='<unknown>', mode='exec', *, type_comments=False, feature_version=None, optimize=-1, module=None)
|
||||||
|
|
||||||
Parse the source into an AST node. Equivalent to ``compile(source,
|
Parse the source into an AST node. Equivalent to ``compile(source,
|
||||||
filename, mode, flags=FLAGS_VALUE, optimize=optimize)``,
|
filename, mode, flags=FLAGS_VALUE, optimize=optimize, module=module)``,
|
||||||
where ``FLAGS_VALUE`` is ``ast.PyCF_ONLY_AST`` if ``optimize <= 0``
|
where ``FLAGS_VALUE`` is ``ast.PyCF_ONLY_AST`` if ``optimize <= 0``
|
||||||
and ``ast.PyCF_OPTIMIZED_AST`` otherwise.
|
and ``ast.PyCF_OPTIMIZED_AST`` otherwise.
|
||||||
|
|
||||||
|
|
@ -2261,6 +2261,9 @@ and classes for traversing abstract syntax trees:
|
||||||
The minimum supported version for ``feature_version`` is now ``(3, 7)``.
|
The minimum supported version for ``feature_version`` is now ``(3, 7)``.
|
||||||
The ``optimize`` argument was added.
|
The ``optimize`` argument was added.
|
||||||
|
|
||||||
|
.. versionadded:: 3.15
|
||||||
|
Added the *module* parameter.
|
||||||
|
|
||||||
|
|
||||||
.. function:: unparse(ast_obj)
|
.. function:: unparse(ast_obj)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1631,6 +1631,9 @@ async/await code consider using the high-level
|
||||||
conforms to the :class:`asyncio.SubprocessTransport` base class and
|
conforms to the :class:`asyncio.SubprocessTransport` base class and
|
||||||
*protocol* is an object instantiated by the *protocol_factory*.
|
*protocol* is an object instantiated by the *protocol_factory*.
|
||||||
|
|
||||||
|
If the transport is closed or is garbage collected, the child process
|
||||||
|
is killed if it is still running.
|
||||||
|
|
||||||
.. method:: loop.subprocess_shell(protocol_factory, cmd, *, \
|
.. method:: loop.subprocess_shell(protocol_factory, cmd, *, \
|
||||||
stdin=subprocess.PIPE, stdout=subprocess.PIPE, \
|
stdin=subprocess.PIPE, stdout=subprocess.PIPE, \
|
||||||
stderr=subprocess.PIPE, **kwargs)
|
stderr=subprocess.PIPE, **kwargs)
|
||||||
|
|
@ -1654,6 +1657,9 @@ async/await code consider using the high-level
|
||||||
conforms to the :class:`SubprocessTransport` base class and
|
conforms to the :class:`SubprocessTransport` base class and
|
||||||
*protocol* is an object instantiated by the *protocol_factory*.
|
*protocol* is an object instantiated by the *protocol_factory*.
|
||||||
|
|
||||||
|
If the transport is closed or is garbage collected, the child process
|
||||||
|
is killed if it is still running.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
It is the application's responsibility to ensure that all whitespace
|
It is the application's responsibility to ensure that all whitespace
|
||||||
and special characters are quoted appropriately to avoid `shell injection
|
and special characters are quoted appropriately to avoid `shell injection
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,9 @@ Creating Subprocesses
|
||||||
See the documentation of :meth:`loop.subprocess_exec` for other
|
See the documentation of :meth:`loop.subprocess_exec` for other
|
||||||
parameters.
|
parameters.
|
||||||
|
|
||||||
|
If the process object is garbage collected while the process is still
|
||||||
|
running, the child process will be killed.
|
||||||
|
|
||||||
.. versionchanged:: 3.10
|
.. versionchanged:: 3.10
|
||||||
Removed the *loop* parameter.
|
Removed the *loop* parameter.
|
||||||
|
|
||||||
|
|
@ -95,6 +98,9 @@ Creating Subprocesses
|
||||||
See the documentation of :meth:`loop.subprocess_shell` for other
|
See the documentation of :meth:`loop.subprocess_shell` for other
|
||||||
parameters.
|
parameters.
|
||||||
|
|
||||||
|
If the process object is garbage collected while the process is still
|
||||||
|
running, the child process will be killed.
|
||||||
|
|
||||||
.. important::
|
.. important::
|
||||||
|
|
||||||
It is the application's responsibility to ensure that all whitespace and
|
It is the application's responsibility to ensure that all whitespace and
|
||||||
|
|
|
||||||
|
|
@ -1221,8 +1221,8 @@ Task Object
|
||||||
|
|
||||||
To cancel a running Task use the :meth:`cancel` method. Calling it
|
To cancel a running Task use the :meth:`cancel` method. Calling it
|
||||||
will cause the Task to throw a :exc:`CancelledError` exception into
|
will cause the Task to throw a :exc:`CancelledError` exception into
|
||||||
the wrapped coroutine. If a coroutine is awaiting on a Future
|
the wrapped coroutine. If a coroutine is awaiting on a future-like
|
||||||
object during cancellation, the Future object will be cancelled.
|
object during cancellation, the awaited object will be cancelled.
|
||||||
|
|
||||||
:meth:`cancelled` can be used to check if the Task was cancelled.
|
:meth:`cancelled` can be used to check if the Task was cancelled.
|
||||||
The method returns ``True`` if the wrapped coroutine did not
|
The method returns ``True`` if the wrapped coroutine did not
|
||||||
|
|
@ -1411,6 +1411,10 @@ Task Object
|
||||||
the cancellation, it needs to call :meth:`Task.uncancel` in addition
|
the cancellation, it needs to call :meth:`Task.uncancel` in addition
|
||||||
to catching the exception.
|
to catching the exception.
|
||||||
|
|
||||||
|
If the Task being cancelled is currently awaiting on a future-like
|
||||||
|
object, that awaited object will also be cancelled. This cancellation
|
||||||
|
propagates down the entire chain of awaited objects.
|
||||||
|
|
||||||
.. versionchanged:: 3.9
|
.. versionchanged:: 3.9
|
||||||
Added the *msg* parameter.
|
Added the *msg* parameter.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,10 @@ You can experiment with an ``asyncio`` concurrent context in the :term:`REPL`:
|
||||||
>>> await asyncio.sleep(10, result='hello')
|
>>> await asyncio.sleep(10, result='hello')
|
||||||
'hello'
|
'hello'
|
||||||
|
|
||||||
|
This REPL provides limited compatibility with :envvar:`PYTHON_BASIC_REPL`.
|
||||||
|
It is recommended that the default REPL is used
|
||||||
|
for full functionality and the latest features.
|
||||||
|
|
||||||
.. audit-event:: cpython.run_stdin "" ""
|
.. audit-event:: cpython.run_stdin "" ""
|
||||||
|
|
||||||
.. versionchanged:: 3.12.5 (also 3.11.10, 3.10.15, 3.9.20, and 3.8.20)
|
.. versionchanged:: 3.12.5 (also 3.11.10, 3.10.15, 3.9.20, and 3.8.20)
|
||||||
|
|
|
||||||
|
|
@ -236,7 +236,7 @@ The :mod:`bdb` module also defines two classes:
|
||||||
Normally derived classes don't override the following methods, but they may
|
Normally derived classes don't override the following methods, but they may
|
||||||
if they want to redefine the definition of stopping and breakpoints.
|
if they want to redefine the definition of stopping and breakpoints.
|
||||||
|
|
||||||
.. method:: is_skipped_line(module_name)
|
.. method:: is_skipped_module(module_name)
|
||||||
|
|
||||||
Return ``True`` if *module_name* matches any skip pattern.
|
Return ``True`` if *module_name* matches any skip pattern.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ The :mod:`bz2` module contains:
|
||||||
* The :func:`compress` and :func:`decompress` functions for one-shot
|
* The :func:`compress` and :func:`decompress` functions for one-shot
|
||||||
(de)compression.
|
(de)compression.
|
||||||
|
|
||||||
|
.. include:: ../includes/optional-module.rst
|
||||||
|
|
||||||
|
|
||||||
(De)compression of files
|
(De)compression of files
|
||||||
------------------------
|
------------------------
|
||||||
|
|
|
||||||
|
|
@ -16,17 +16,17 @@ The following modules have a command-line interface.
|
||||||
* :ref:`dis <dis-cli>`
|
* :ref:`dis <dis-cli>`
|
||||||
* :ref:`doctest <doctest-cli>`
|
* :ref:`doctest <doctest-cli>`
|
||||||
* :mod:`!encodings.rot_13`
|
* :mod:`!encodings.rot_13`
|
||||||
* :mod:`ensurepip`
|
* :ref:`ensurepip <ensurepip-cli>`
|
||||||
* :mod:`filecmp`
|
* :mod:`filecmp`
|
||||||
* :mod:`fileinput`
|
* :mod:`fileinput`
|
||||||
* :mod:`ftplib`
|
* :mod:`ftplib`
|
||||||
* :ref:`gzip <gzip-cli>`
|
* :ref:`gzip <gzip-cli>`
|
||||||
* :ref:`http.server <http-server-cli>`
|
* :ref:`http.server <http-server-cli>`
|
||||||
* :mod:`!idlelib`
|
* :ref:`idlelib <idlelib-cli>`
|
||||||
* :ref:`inspect <inspect-module-cli>`
|
* :ref:`inspect <inspect-module-cli>`
|
||||||
* :ref:`json <json-commandline>`
|
* :ref:`json <json-commandline>`
|
||||||
* :ref:`mimetypes <mimetypes-cli>`
|
* :ref:`mimetypes <mimetypes-cli>`
|
||||||
* :mod:`pdb`
|
* :ref:`pdb <pdb-cli>`
|
||||||
* :ref:`pickle <pickle-cli>`
|
* :ref:`pickle <pickle-cli>`
|
||||||
* :ref:`pickletools <pickletools-cli>`
|
* :ref:`pickletools <pickletools-cli>`
|
||||||
* :ref:`platform <platform-cli>`
|
* :ref:`platform <platform-cli>`
|
||||||
|
|
@ -52,8 +52,8 @@ The following modules have a command-line interface.
|
||||||
* :mod:`turtledemo`
|
* :mod:`turtledemo`
|
||||||
* :ref:`unittest <unittest-command-line-interface>`
|
* :ref:`unittest <unittest-command-line-interface>`
|
||||||
* :ref:`uuid <uuid-cli>`
|
* :ref:`uuid <uuid-cli>`
|
||||||
* :mod:`venv`
|
* :ref:`venv <venv-cli>`
|
||||||
* :mod:`webbrowser`
|
* :ref:`webbrowser <webbrowser-cli>`
|
||||||
* :ref:`zipapp <zipapp-command-line-interface>`
|
* :ref:`zipapp <zipapp-command-line-interface>`
|
||||||
* :ref:`zipfile <zipfile-commandline>`
|
* :ref:`zipfile <zipfile-commandline>`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1209,7 +1209,7 @@ If a new entry overwrites an existing entry, the
|
||||||
original insertion position is changed and moved to the end::
|
original insertion position is changed and moved to the end::
|
||||||
|
|
||||||
class LastUpdatedOrderedDict(OrderedDict):
|
class LastUpdatedOrderedDict(OrderedDict):
|
||||||
'Store items in the order the keys were last added'
|
'Store items in the order that the keys were last updated.'
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
def __setitem__(self, key, value):
|
||||||
super().__setitem__(key, value)
|
super().__setitem__(key, value)
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,8 @@ The :mod:`!compression.zstd` module contains:
|
||||||
* The :class:`CompressionParameter`, :class:`DecompressionParameter`, and
|
* The :class:`CompressionParameter`, :class:`DecompressionParameter`, and
|
||||||
:class:`Strategy` classes for setting advanced (de)compression parameters.
|
:class:`Strategy` classes for setting advanced (de)compression parameters.
|
||||||
|
|
||||||
|
.. include:: ../includes/optional-module.rst
|
||||||
|
|
||||||
|
|
||||||
Exceptions
|
Exceptions
|
||||||
----------
|
----------
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,12 @@ Actual concurrency is available separately through
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
:class:`~concurrent.futures.InterpreterPoolExecutor`
|
:class:`~concurrent.futures.InterpreterPoolExecutor`
|
||||||
combines threads with interpreters in a familiar interface.
|
Combines threads with interpreters in a familiar interface.
|
||||||
|
|
||||||
.. XXX Add references to the upcoming HOWTO docs in the seealso block.
|
.. XXX Add references to the upcoming HOWTO docs in the seealso block.
|
||||||
|
|
||||||
:ref:`isolating-extensions-howto`
|
:ref:`isolating-extensions-howto`
|
||||||
how to update an extension module to support multiple interpreters
|
How to update an extension module to support multiple interpreters.
|
||||||
|
|
||||||
:pep:`554`
|
:pep:`554`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -313,7 +313,7 @@ client::
|
||||||
addr = writer.transport.get_extra_info('socket').getpeername()
|
addr = writer.transport.get_extra_info('socket').getpeername()
|
||||||
client_addr_var.set(addr)
|
client_addr_var.set(addr)
|
||||||
|
|
||||||
# In any code that we call is now possible to get
|
# In any code that we call, it is now possible to get the
|
||||||
# client's address by calling 'client_addr_var.get()'.
|
# client's address by calling 'client_addr_var.get()'.
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
|
||||||
|
|
@ -295,8 +295,8 @@ The :mod:`csv` module defines the following classes:
|
||||||
- the second through n-th rows contain strings where at least one value's
|
- the second through n-th rows contain strings where at least one value's
|
||||||
length differs from that of the putative header of that column.
|
length differs from that of the putative header of that column.
|
||||||
|
|
||||||
Twenty rows after the first row are sampled; if more than half of columns +
|
Twenty-one rows after the header are sampled; if more than half of the
|
||||||
rows meet the criteria, :const:`True` is returned.
|
columns + rows meet the criteria, :const:`True` is returned.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@
|
||||||
data types, and allows calling functions in DLLs or shared libraries. It can be
|
data types, and allows calling functions in DLLs or shared libraries. It can be
|
||||||
used to wrap these libraries in pure Python.
|
used to wrap these libraries in pure Python.
|
||||||
|
|
||||||
|
.. include:: ../includes/optional-module.rst
|
||||||
|
|
||||||
|
|
||||||
.. _ctypes-ctypes-tutorial:
|
.. _ctypes-ctypes-tutorial:
|
||||||
|
|
||||||
|
|
|
||||||
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