diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 000000000..5230b7695
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,15 @@
+root = true
+
+[*.{py,c,cpp,h,rst,md,yml}]
+trim_trailing_whitespace = true
+insert_final_newline = true
+indent_style = space
+
+[*.{py,c,cpp,h}]
+indent_size = 4
+
+[*.rst]
+indent_size = 3
+
+[*.{css,yml}]
+indent_size = 2
diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md
index ab0fa8421..235382276 100644
--- a/.github/CODE_OF_CONDUCT.md
+++ b/.github/CODE_OF_CONDUCT.md
@@ -4,9 +4,9 @@ Code of Conduct
Please note that all interactions on
[Python Software Foundation](https://www.python.org/psf-landing/)-supported
infrastructure is [covered](https://www.python.org/psf/records/board/minutes/2014-01-06/#management-of-the-psfs-web-properties)
-by the [PSF Code of Conduct](https://www.python.org/psf/codeofconduct/),
+by the [PSF Code of Conduct](https://policies.python.org/python.org/code-of-conduct/),
which includes all infrastructure used in the development of Python itself
-(e.g. mailing lists, issue trackers, GitHub, etc.).
+(for example, mailing lists, issue trackers, GitHub, etc.).
In general this means everyone is expected to be open, considerate, and
respectful of others no matter what their position is within the project.
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 4b29950db..028715319 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -22,24 +22,24 @@ comments they leave and their "Details" links, respectively. The key points of
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
- should happen on [bugs.python.org](https://bugs.python.org/)
+ should happen on the [issue tracker](https://devguide.python.org/tracker/)
- Upon your first non-trivial pull request (which includes documentation changes),
feel free to add yourself to [`Misc/ACKS`](https://github.com/python/cpython/blob/main/Misc/ACKS)
## Setting Expectations
-Due to the fact that this project is entirely volunteer-run (i.e. no one is paid
+Due to the fact that this project is entirely volunteer-run (that is, no one is paid
to work on Python full-time), we unfortunately can make no guarantees as to if
or when a core developer will get around to reviewing your pull request.
If no core developer has done a review or responded to changes made because of a
-"changes requested" review, please feel free to email [python-dev](https://mail.python.org/mailman3/lists/python-dev.python.org/) to ask if
-someone could take a look at your pull request.
+"changes requested" review, please consider seeking assistance through the
+[Core Development Discourse category](https://discuss.python.org/c/core-dev/23).
## Code of Conduct
All interactions for this project are covered by the
-[PSF Code of Conduct](https://www.python.org/psf/codeofconduct/). Everyone is
+[PSF Code of Conduct](https://policies.python.org/python.org/code-of-conduct/). Everyone is
expected to be open, considerate, and respectful of others no matter their
position within the project.
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
deleted file mode 100644
index 46c21cbe7..000000000
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-name: Bug report
-about: Create a report to help us improve
-title: ''
-labels: ''
-assignees: ''
-
----
-
-> Note: This repo is for the Python devguide. If you are requesting an
-enhancementfor the Python language or CPython interpreter,
-then the CPython issue tracker is better
-suited for this report: https://bugs.python.org
-
-**Describe the bug**
-A clear and concise description of what the bug is.
-
-**Expected behavior**
-A clear and concise description of what you expected to happen.
-
-**Screenshots**
-If applicable, add screenshots to help explain your problem.
-
-**Additional context**
-Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 000000000..b160c6ea1
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,39 @@
+name: "Bug report"
+description: Create a report to help us improve the Python devguide
+title: "Bug:
"
+labels: ["bug"]
+assignees: []
+
+body:
+ - type: markdown
+ attributes:
+ value: |
+ > [!NOTE]
+ > This repo is for the [Python developer's guide](https://devguide.python.org/).
+ > If you are reporting a bug for the Python language or
+ > CPython interpreter, then use the
+ > [CPython issue tracker](https://github.com/python/cpython/issues) instead.
+
+ - type: textarea
+ id: bug_description
+ attributes:
+ label: "Describe the bug"
+ description: A clear and concise description of what the bug is and, optionally, what you expected to happen.
+ validations:
+ required: true
+
+ - type: textarea
+ id: screenshots
+ attributes:
+ label: "Screenshots"
+ description: If applicable, add screenshots to help explain your problem.
+ validations:
+ required: false
+
+ - type: textarea
+ id: additional_context
+ attributes:
+ label: "Additional context"
+ description: Add any other context about the problem here.
+ validations:
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 000000000..cd8c31d2a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,14 @@
+blank_issues_enabled: false
+contact_links:
+ - name: CPython Documentation
+ url: https://docs.python.org/
+ about: Official CPython documentation - please check here before opening an issue.
+ - name: Python Website
+ url: https://python.org/
+ about: For all things Python
+ - name: PyPI Issues / Support
+ url: https://github.com/pypi/support
+ about: For issues with PyPI itself, PyPI accounts, or with packages hosted on PyPI.
+ - name: CPython Issues
+ url: https://github.com/python/cpython/issues
+ about: For issues with the CPython interpreter itself.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
deleted file mode 100644
index d9e580720..000000000
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ /dev/null
@@ -1,22 +0,0 @@
----
-name: Feature request
-about: Suggest an idea for this project
-title: ''
-labels: ''
-assignees: ''
-
----
-
-> Note: This repo is for the Python devguide. If you are requesting an
-enhancement for the Python language or CPython interpreter,
-then the CPython issue tracker is better
-suited for this report: https://bugs.python.org
-
-**Describe the enhancement or feature you'd like**
-A clear and concise description of what you want to happen.
-
-**Describe alternatives you've considered**
-A clear and concise description of any alternative solutions or features you've considered.
-
-**Additional context**
-Add any other context or screenshots about the feature request here.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
new file mode 100644
index 000000000..a4413c137
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -0,0 +1,39 @@
+name: "Feature request"
+description: Suggest an idea for the Python devguide
+title: "Feature: "
+labels: ["enhancement"]
+assignees: []
+
+body:
+ - type: markdown
+ attributes:
+ value: |
+ > [!NOTE]
+ > This repo is for the [Python developer's guide](https://devguide.python.org/).
+ > If you are requesting an enhancement for the Python language or
+ > CPython interpreter, then use the
+ > [CPython issue tracker](https://github.com/python/cpython/issues) instead.
+
+ - type: textarea
+ id: feature_description
+ attributes:
+ label: "Describe the enhancement or feature you would like"
+ description: A clear and concise description of what you want to happen.
+ validations:
+ required: true
+
+ - type: textarea
+ id: alternatives
+ attributes:
+ label: "Describe alternatives you have considered"
+ description: A clear and concise description of any alternative solutions or features you have considered.
+ validations:
+ required: false
+
+ - type: textarea
+ id: additional_context
+ attributes:
+ label: "Additional context"
+ description: Add any other context or screenshots about the feature request here.
+ validations:
+ required: false
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 839471ed0..b1d63fbf3 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -8,4 +8,4 @@ It should describe the change to be made.
Most PRs will require an issue number. Trivial changes, like fixing a typo,
do not need an issue.
--->
\ No newline at end of file
+-->
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 491deae0a..c99075280 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -3,5 +3,5 @@ updates:
- package-ecosystem: pip
directory: "/"
schedule:
- interval: daily
+ interval: monthly
open-pull-requests-limit: 10
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 09cd927e7..22ad254eb 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,35 +1,25 @@
name: Tests
-on:
- pull_request:
- push:
- branches: master
+on: [pull_request, push, workflow_dispatch]
+
+env:
+ FORCE_COLOR: 1
jobs:
test:
- name: test w/ Python ${{ matrix.python-version }}
-
+ name: Check build, markup, and links
runs-on: ubuntu-latest
-
- strategy:
- matrix:
- python-version: ["3.9"]
+ timeout-minutes: 10
steps:
- - uses: actions/checkout@v2
- - uses: actions/cache@v1
- with:
- path: ~/.cache/pip
- key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}
- restore-keys: |
- ${{ runner.os }}-pip-
- - uses: actions/setup-python@v2
+ - uses: actions/checkout@v4
+ - uses: actions/setup-python@v5
with:
- python-version: ${{ matrix.python-version }}
- - name: Install Dependencies
- run: python3 -m pip install -U pip -r requirements.txt
- - name: Build Docs
- run: sphinx-build -n -W -q -b html -d _build/doctrees . _build/html
- - name: Link Check
- run: sphinx-build -b linkcheck -d _build/doctrees . _build/linkcheck
+ python-version: "3"
+ - name: Install uv
+ uses: hynek/setup-cached-uv@v2
+ - name: Build docs
+ run: make html
+ - name: Link check
+ run: make linkcheck
continue-on-error: true
diff --git a/.github/workflows/documentation-links.yml b/.github/workflows/documentation-links.yml
new file mode 100644
index 000000000..bacb37d07
--- /dev/null
+++ b/.github/workflows/documentation-links.yml
@@ -0,0 +1,18 @@
+name: Read the Docs PR preview
+on:
+ pull_request_target:
+ types:
+ - opened
+
+permissions:
+ pull-requests: write
+
+jobs:
+ documentation-links:
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - uses: readthedocs/actions/preview@v1
+ with:
+ project-slug: "cpython-devguide"
+ single-version: "true"
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 000000000..5c9caf026
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,15 @@
+name: Lint
+
+on: [push, pull_request, workflow_dispatch]
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-python@v4
+ with:
+ python-version: "3.x"
+ - uses: pre-commit/action@v3.0.0
diff --git a/.gitignore b/.gitignore
index c74e78d0f..b71249201 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@ __pycache__/
# Distribution / packaging
.Python
env/
+ENV/
venv/
build/
develop-eggs/
@@ -80,13 +81,14 @@ celerybeat-schedule
# dotenv
.env
-# virtualenv
-venv/
-ENV/
-venv/
-
# Spyder project settings
.spyderproject
# Rope project settings
.ropeproject
+
+# Generated CSV and SVG files
+include/branches.csv
+include/end-of-life.csv
+include/release-cycle.svg
+include/release-cycle-all.svg
diff --git a/.hgignore b/.hgignore
deleted file mode 100644
index 8e34d3d6a..000000000
--- a/.hgignore
+++ /dev/null
@@ -1,6 +0,0 @@
-syntax: glob
-
-*.swp
-*~
-_build
-venv
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 000000000..ae27fd1f2
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,35 @@
+repos:
+ - repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: v0.5.7
+ hooks:
+ - id: ruff
+ name: Run Ruff (lint)
+ args: [--exit-non-zero-on-fix]
+ - id: ruff-format
+ name: Run Ruff (format)
+ args: [--check]
+
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v4.5.0
+ hooks:
+ - id: check-case-conflict
+ - id: check-merge-conflict
+ - id: check-json
+ - id: check-yaml
+ - id: debug-statements
+ - id: end-of-file-fixer
+ - id: trailing-whitespace
+
+ - repo: https://github.com/sphinx-contrib/sphinx-lint
+ rev: v0.9.1
+ hooks:
+ - id: sphinx-lint
+ args: [--enable=default-role]
+
+ - repo: meta
+ hooks:
+ - id: check-hooks-apply
+ - id: check-useless-excludes
+
+ci:
+ autoupdate_schedule: quarterly
diff --git a/.readthedocs.yml b/.readthedocs.yml
new file mode 100644
index 000000000..26e5be967
--- /dev/null
+++ b/.readthedocs.yml
@@ -0,0 +1,21 @@
+# Read the Docs configuration file
+# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
+# Project page: https://readthedocs.org/projects/cpython-devguide/
+
+version: 2
+
+sphinx:
+ builder: dirhtml
+ configuration: conf.py
+
+build:
+ os: ubuntu-22.04
+ tools:
+ python: "3"
+
+ commands:
+ - asdf plugin add uv
+ - asdf install uv latest
+ - asdf global uv latest
+ - make dirhtml BUILDDIR=_readthedocs
+ - mv _readthedocs/dirhtml _readthedocs/html
diff --git a/.ruff.toml b/.ruff.toml
new file mode 100644
index 000000000..af448e5b6
--- /dev/null
+++ b/.ruff.toml
@@ -0,0 +1,35 @@
+target-version = "py310"
+fix = true
+output-format = "full"
+line-length = 88
+
+[lint]
+preview = true
+select = [
+ "C4", # flake8-comprehensions
+ "B", # flake8-bugbear
+ "E", # pycodestyle
+ "F", # pyflakes
+ "FA", # flake8-future-annotations
+ "FLY", # flynt
+ "FURB", # refurb
+ "G", # flake8-logging-format
+ "I", # isort
+ "ISC", # flake8-implicit-str-concat
+ "LOG", # flake8-logging
+ "PERF", # perflint
+ "PGH", # pygrep-hooks
+ "PT", # flake8-pytest-style
+ "TCH", # flake8-type-checking
+ "UP", # pyupgrade
+ "W", # pycodestyle
+ "YTT", # flake8-2020
+]
+ignore = [
+ "E501", # Ignore line length errors (we use auto-formatting)
+]
+
+[format]
+preview = true
+quote-style = "preserve"
+docstring-code-format = true
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 5608206df..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-language: python
-python: 3.6
-cache: pip
-
-install: python3 -m pip install -U pip -r requirements.txt
-
-jobs:
- include:
- - stage: build-docs
- script: sphinx-build -n -W -q -b html -d _build/doctrees . _build/html
-
- - stage: link-check
- script: sphinx-build -b linkcheck -d _build/doctrees . _build/linkcheck
-
- allow_failures:
- - stage: link-check
diff --git a/LICENSE b/LICENSE
index 28289e879..4594fb738 100644
--- a/LICENSE
+++ b/LICENSE
@@ -113,4 +113,4 @@ Affirmer's express Statement of Purpose.
CC0 or use of the Work.
For more information, please see
-
\ No newline at end of file
+
diff --git a/Makefile b/Makefile
index 3f3963296..3d485ae2d 100644
--- a/Makefile
+++ b/Makefile
@@ -2,145 +2,118 @@
#
# You can set these variables from the command line.
-PYTHON = python3
-SPHINXOPTS =
-SPHINXBUILD = ./venv/bin/sphinx-build
-PAPER =
-BUILDDIR = _build
+PYTHON = python3
+VENVDIR = ./venv
+UV = uv
+SPHINXBUILD = $(VENVDIR)/bin/sphinx-build
+# Temporary: while we are using ..include:: to show the reorganization,
+# there are duplicate labels. These cause warnings, which prevent the
+# build from finishing. Turn off --fail-on-warning so we can see the
+# finished results.
+#SPHINXOPTS = --fail-on-warning
+SPHINXOPTS =
+BUILDDIR = _build
+BUILDER = html
+JOBS = auto
+SPHINXLINT = $(VENVDIR)/bin/sphinx-lint
+REQUIREMENTS = requirements.txt
# Internal variables.
-PAPEROPT_a4 = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-
-.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp \
- devhelp epub latex latexpdf text man changes linkcheck doctest check \
- serve
+_ALL_SPHINX_OPTS = --jobs $(JOBS) $(SPHINXOPTS)
+_RELEASE_CYCLE = include/branches.csv \
+ include/end-of-life.csv \
+ include/release-cycle-all.svg \
+ include/release-cycle.svg
+.PHONY: help
help:
@echo "Please use \`make ' where is one of"
+ @echo " venv to create a venv with necessary tools"
@echo " html to make standalone HTML files"
- @echo " dirhtml to make HTML files named index.html in directories"
- @echo " singlehtml to make a single large HTML file"
- @echo " pickle to make pickle files"
- @echo " json to make JSON files"
- @echo " htmlhelp to make HTML files and a HTML help project"
- @echo " qthelp to make HTML files and a qthelp project"
- @echo " devhelp to make HTML files and a Devhelp project"
- @echo " epub to make an epub"
- @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
- @echo " latexpdf to make LaTeX files and run them through pdflatex"
- @echo " text to make text files"
- @echo " man to make manual pages"
- @echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
- @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+ @echo " htmlview to open the index page built by the html target in your browser"
+ @echo " htmllive to rebuild and reload HTML files in your browser"
+ @echo " clean to remove the venv and build files"
@echo " check to run a check for frequent markup errors"
- @echo " serve to serve devguide on the localhost (8000)"
+ @echo " lint to lint all the files"
-clean:
+.PHONY: clean
+clean: clean-venv
-rm -rf $(BUILDDIR)/*
+ -rm -rf $(_RELEASE_CYCLE)
+
+.PHONY: clean-venv
+clean-venv:
+ rm -rf $(VENVDIR)
+.PHONY: venv
venv:
- $(PYTHON) -m venv venv
- ./venv/bin/python3 -m pip install --upgrade pip
- ./venv/bin/python3 -m pip install -r requirements.txt
-
-html: venv
- $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-
-dirhtml: venv
- $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
-
-singlehtml: venv
- $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
- @echo
- @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
-
-pickle: venv
- $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
- @echo
- @echo "Build finished; now you can process the pickle files."
-
-json: venv
- $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
- @echo
- @echo "Build finished; now you can process the JSON files."
-
-htmlhelp: venv
- $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
- @echo
- @echo "Build finished; now you can run HTML Help Workshop with the" \
- ".hhp project file in $(BUILDDIR)/htmlhelp."
-
-qthelp: venv
- $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
- @echo
- @echo "Build finished; now you can run "qcollectiongenerator" with the" \
- ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
- @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/PythonDevelopersGuide.qhcp"
- @echo "To view the help file:"
- @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/PythonDevelopersGuide.qhc"
-
-devhelp: venv
- $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
- @echo
- @echo "Build finished."
- @echo "To view the help file:"
- @echo "# mkdir -p $$HOME/.local/share/devhelp/PythonDevelopersGuide"
- @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/PythonDevelopersGuide"
- @echo "# devhelp"
-
-epub: venv
- $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
- @echo
- @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
-
-latex: venv
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo
- @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
- @echo "Run \`make' in that directory to run these through (pdf)latex" \
- "(use \`make latexpdf' here to do that automatically)."
-
-latexpdf: venv
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo "Running LaTeX files through pdflatex..."
- make -C $(BUILDDIR)/latex all-pdf
- @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-text: venv
- $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
- @echo
- @echo "Build finished. The text files are in $(BUILDDIR)/text."
-
-man: venv
- $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
- @echo
- @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
-
-changes: venv
- $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
- @echo
- @echo "The overview file is in $(BUILDDIR)/changes."
-
-linkcheck: venv
- $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
- @echo
- @echo "Link check complete; look for any errors in the above output " \
- "or in $(BUILDDIR)/linkcheck/output.txt."
-
-doctest: venv
- $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
- @echo "Testing of doctests in the sources finished, look at the " \
- "results in $(BUILDDIR)/doctest/output.txt."
-
-check:
- $(PYTHON) tools/rstlint.py -i tools -i venv
-
-serve: html
- tools/serve.py _build/html
+ @if [ -d $(VENVDIR) ] ; then \
+ echo "venv already exists."; \
+ echo "To recreate it, remove it first with \`make clean-venv'."; \
+ else \
+ $(MAKE) ensure-venv; \
+ fi
+
+.PHONY: ensure-venv
+ensure-venv:
+ @if [ ! -d $(VENVDIR) ] ; then \
+ set -e; \
+ echo "Creating venv in $(VENVDIR)"; \
+ if $(UV) --version >/dev/null 2>&1; then \
+ $(UV) venv --python=$(PYTHON) $(VENVDIR); \
+ VIRTUAL_ENV=$(VENVDIR) $(UV) pip install -r $(REQUIREMENTS); \
+ else \
+ $(PYTHON) -m venv $(VENVDIR); \
+ $(VENVDIR)/bin/python3 -m pip install --upgrade pip; \
+ $(VENVDIR)/bin/python3 -m pip install -r $(REQUIREMENTS); \
+ fi; \
+ echo "The venv has been created in the $(VENVDIR) directory"; \
+ fi
+
+.PHONY: htmlview
+htmlview: html
+ $(PYTHON) -c "import os, webbrowser; webbrowser.open('file://' + os.path.realpath('_build/html/index.html'))"
+
+.PHONY: htmllive
+htmllive: SPHINXBUILD = $(VENVDIR)/bin/sphinx-autobuild
+# Arbitrarily selected ephemeral port between 49152–65535
+# to avoid conflicts with other processes:
+htmllive: SPHINXOPTS = --open-browser --delay 0 --port 55301
+htmllive: html
+
+.PHONY: check
+check: ensure-venv
+ # Ignore the tools and venv dirs and check that the default role is not used.
+ $(SPHINXLINT) -i tools -i $(VENVDIR) --enable default-role
+
+.PHONY: _ensure-package
+_ensure-package: venv
+ if $(UV) --version >/dev/null 2>&1; then \
+ VIRTUAL_ENV=$(VENVDIR) $(UV) pip install $(PACKAGE); \
+ else \
+ $(VENVDIR)/bin/python3 -m pip install $(PACKAGE); \
+ fi
+
+.PHONY: _ensure-pre-commit
+_ensure-pre-commit:
+ make _ensure-package PACKAGE=pre-commit
+
+.PHONY: lint
+lint: _ensure-pre-commit
+ $(VENVDIR)/bin/python3 -m pre_commit run --all-files
+
+# Defined so that "include/release-cycle.json"
+# doesn't fall through to the catch-all target.
+include/release-cycle.json:
+ @exit
+
+$(_RELEASE_CYCLE): include/release-cycle.json
+ $(VENVDIR)/bin/python3 _tools/generate_release_cycle.py
+ @echo Release cycle data generated.
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option.
+.PHONY: Makefile
+%: Makefile ensure-venv $(_RELEASE_CYCLE)
+ $(SPHINXBUILD) -M $@ "." "$(BUILDDIR)" $(_ALL_SPHINX_OPTS)
diff --git a/README.rst b/README.rst
index f083d9d0f..e2f0c5617 100644
--- a/README.rst
+++ b/README.rst
@@ -17,15 +17,21 @@ The CPython Developer's Guide
This guide covers how to contribute to CPython. It is known by the
-nickname of "the devguide" by the Python core developers.
+nickname of "the devguide" by the Python core team.
The official home of this guide is https://devguide.python.org.
-Compilation
+Render HTML
-----------
-For the compilation of the devguide, you need to use a version of Python which
-supports the ``venv`` module, because the ``make html`` command will create a
-virtual environment and will install the ``Sphinx`` package::
+To render the devguide to HTML under ``_build/html``, run::
make html
+
+To render the devguide to HTML, and open the result in a browser, run::
+
+ make htmlview
+
+To maintain a live view of edits as they are saved, run::
+
+ make htmllive
diff --git a/_static/activate_tab.js b/_static/activate_tab.js
new file mode 100644
index 000000000..8b5fcbabd
--- /dev/null
+++ b/_static/activate_tab.js
@@ -0,0 +1,42 @@
+// Based on https://stackoverflow.com/a/38241481/724176
+function getOS() {
+ const userAgent = window.navigator.userAgent,
+ platform =
+ window.navigator?.userAgentData?.platform || window.navigator.platform,
+ macosPlatforms = ["macOS", "Macintosh", "MacIntel", "MacPPC", "Mac68K"],
+ windowsPlatforms = ["Win32", "Win64", "Windows", "WinCE"],
+ iosPlatforms = ["iPhone", "iPad", "iPod"];
+
+ if (macosPlatforms.includes(platform)) {
+ return "macOS";
+ } else if (iosPlatforms.includes(platform)) {
+ return "iOS";
+ } else if (windowsPlatforms.includes(platform)) {
+ return "Windows";
+ } else if (/Android/.test(userAgent)) {
+ return "Android";
+ } else if (/Linux/.test(platform)) {
+ return "Unix";
+ }
+
+ return "unknown";
+}
+
+function activateTab(tabName) {
+ // Find all label elements containing the specified tab name
+ const labels = document.querySelectorAll(".tab-label");
+
+ labels.forEach((label) => {
+ if (label.textContent.includes(tabName)) {
+ // Find the associated input element using the 'for' attribute
+ const tabInputId = label.getAttribute("for");
+ const tabInput = document.getElementById(tabInputId);
+
+ // Check if the input element exists before attempting to set the "checked" attribute
+ if (tabInput) {
+ // Activate the tab by setting its "checked" attribute to true
+ tabInput.checked = true;
+ }
+ }
+ });
+}
diff --git a/_static/devguide_overrides.css b/_static/devguide_overrides.css
new file mode 100644
index 000000000..5b6d67b09
--- /dev/null
+++ b/_static/devguide_overrides.css
@@ -0,0 +1,125 @@
+/* Style overrides for the devguide */
+
+/* Make the site logo smaller */
+.sidebar-logo {
+ width: 111px;
+ height: 110px;
+}
+
+/* Release cycle chart */
+
+.release-cycle-chart {
+ width: 100%;
+}
+
+.release-cycle-chart .release-cycle-year-line {
+ stroke: var(--color-foreground-primary);
+ stroke-width: 0.8px;
+ opacity: 75%;
+}
+
+.release-cycle-chart .release-cycle-year-text {
+ fill: var(--color-foreground-primary);
+}
+
+.release-cycle-chart .release-cycle-today-line {
+ stroke: var(--color-brand-primary);
+ stroke-width: 1.6px;
+}
+
+.release-cycle-chart .release-cycle-row-shade {
+ fill: var(--color-background-item);
+ opacity: 50%;
+}
+
+.release-cycle-chart .release-cycle-version-label {
+ fill: var(--color-foreground-primary);
+}
+
+.release-cycle-chart .release-cycle-blob {
+ stroke-width: 1.6px;
+ /* default colours, overridden below for individual statuses */
+ fill: var(--color-background-primary);
+ stroke: var(--color-foreground-primary);
+}
+
+.release-cycle-chart .release-cycle-blob-label {
+ /* white looks good on both light & dark */
+ fill: white;
+}
+
+.release-cycle-chart .release-cycle-blob-label.release-cycle-status-security,
+.release-cycle-chart .release-cycle-blob-label.release-cycle-status-bugfix {
+ /* but use black to improve contrast for lighter backgrounds */
+ fill: black;
+}
+
+.release-cycle-chart .release-cycle-blob-label.release-cycle-status-end-of-life,
+.release-cycle-chart .release-cycle-blob-label.release-cycle-status-prerelease,
+.release-cycle-chart .release-cycle-blob-label.release-cycle-status-feature {
+ /* and FG when it's not in a blob */
+ fill: var(--color-foreground-primary);
+}
+
+.release-cycle-chart .release-cycle-status-end-of-life {
+ --status-bg-color: #DD2200;
+ --status-border-color: #FF8888;
+}
+
+.release-cycle-chart .release-cycle-status-security {
+ --status-bg-color: #FFDD44;
+ --status-border-color: #FF8800;
+}
+
+.release-cycle-chart .release-cycle-status-bugfix {
+ --status-bg-color: #00DD22;
+ --status-border-color: #008844;
+}
+
+.release-cycle-chart .release-cycle-status-prerelease {
+ --status-bg-color: teal;
+ --status-border-color: darkgreen;
+}
+
+.release-cycle-chart .release-cycle-status-feature {
+ --status-bg-color: #2222EE;
+ --status-border-color: #008888;
+}
+
+.release-cycle-chart .release-cycle-blob {
+ fill: var(--status-bg-color);
+ stroke: transparent;
+}
+
+.release-cycle-chart .release-cycle-blob-full {
+ fill: var(--status-bg-color);
+ stroke: var(--status-border-color);
+}
+
+.release-cycle-chart .release-cycle-border {
+ fill: transparent;
+ stroke: var(--status-border-color);
+ stroke-width: 1.6px;
+}
+
+.good pre {
+ border-left: 3px solid rgba(74, 182, 93, 1);
+}
+.bad pre {
+ border-left: 3px solid rgb(244, 76, 78);
+}
+
+.extlink-cpy-file,
+.extlink-gh-label {
+ border: 1px solid var(--color-background-border);
+ border-radius: .2em;
+ font-family: var(--font-stack--monospace);
+ font-size: var(--font-size--small--2);
+ padding: .1em .2em;
+}
+
+/* Table cells should always top-align */
+
+table.docutils td {
+ vertical-align: top;
+}
diff --git a/_static/favicon.png b/_static/favicon.png
new file mode 100644
index 000000000..462cfedd1
Binary files /dev/null and b/_static/favicon.png differ
diff --git a/_static/og-image-200x200.png b/_static/og-image-200x200.png
new file mode 100644
index 000000000..0e80751e7
Binary files /dev/null and b/_static/og-image-200x200.png differ
diff --git a/images/python-cyclic-gc-1-new-page.png b/_static/python-cyclic-gc-1-new-page.png
similarity index 100%
rename from images/python-cyclic-gc-1-new-page.png
rename to _static/python-cyclic-gc-1-new-page.png
diff --git a/images/python-cyclic-gc-2-new-page.png b/_static/python-cyclic-gc-2-new-page.png
similarity index 100%
rename from images/python-cyclic-gc-2-new-page.png
rename to _static/python-cyclic-gc-2-new-page.png
diff --git a/images/python-cyclic-gc-3-new-page.png b/_static/python-cyclic-gc-3-new-page.png
similarity index 100%
rename from images/python-cyclic-gc-3-new-page.png
rename to _static/python-cyclic-gc-3-new-page.png
diff --git a/images/python-cyclic-gc-4-new-page.png b/_static/python-cyclic-gc-4-new-page.png
similarity index 100%
rename from images/python-cyclic-gc-4-new-page.png
rename to _static/python-cyclic-gc-4-new-page.png
diff --git a/images/python-cyclic-gc-5-new-page.png b/_static/python-cyclic-gc-5-new-page.png
similarity index 100%
rename from images/python-cyclic-gc-5-new-page.png
rename to _static/python-cyclic-gc-5-new-page.png
diff --git a/_static/python-logo.svg b/_static/python-logo.svg
new file mode 100644
index 000000000..f69d24a74
--- /dev/null
+++ b/_static/python-logo.svg
@@ -0,0 +1,18 @@
+
diff --git a/_tools/generate_release_cycle.py b/_tools/generate_release_cycle.py
new file mode 100644
index 000000000..63d98cfce
--- /dev/null
+++ b/_tools/generate_release_cycle.py
@@ -0,0 +1,200 @@
+"""Read in a JSON and generate two CSVs and an SVG file."""
+
+from __future__ import annotations
+
+import argparse
+import csv
+import datetime as dt
+import json
+
+import jinja2
+
+
+def csv_date(date_str: str, now_str: str) -> str:
+ """Format a date for CSV."""
+ if date_str > now_str:
+ # Future, add italics
+ return f"*{date_str}*"
+ return date_str
+
+
+def parse_date(date_str: str) -> dt.date:
+ if len(date_str) == len("yyyy-mm"):
+ # We need a full yyyy-mm-dd, so let's approximate
+ return dt.date.fromisoformat(date_str + "-01")
+ return dt.date.fromisoformat(date_str)
+
+
+def parse_version(ver: str) -> list[int]:
+ return [int(i) for i in ver["key"].split(".")]
+
+
+class Versions:
+ """For converting JSON to CSV and SVG."""
+
+ def __init__(self, *, limit_to_active=False, special_py27=False) -> None:
+ with open("include/release-cycle.json", encoding="UTF-8") as in_file:
+ self.versions = json.load(in_file)
+
+ # Generate a few additional fields
+ for key, version in self.versions.items():
+ version["key"] = key
+ ver_info = parse_version(version)
+ if ver_info >= [3, 13]:
+ full_years = 2
+ else:
+ full_years = 1.5
+ version["first_release_date"] = r1 = parse_date(version["first_release"])
+ version["start_security_date"] = r1 + dt.timedelta(days=full_years * 365)
+ version["end_of_life_date"] = parse_date(version["end_of_life"])
+
+ self.cutoff = min(ver["first_release_date"] for ver in self.versions.values())
+
+ if limit_to_active:
+ self.cutoff = min(
+ version["first_release_date"]
+ for version in self.versions.values()
+ if version["status"] != "end-of-life"
+ )
+ self.versions = {
+ key: version
+ for key, version in self.versions.items()
+ if version["end_of_life_date"] >= self.cutoff
+ or (special_py27 and key == "2.7")
+ }
+ if special_py27:
+ self.cutoff = min(self.cutoff, dt.date(2019, 8, 1))
+ self.id_key = "active"
+ else:
+ self.id_key = "all"
+
+ self.sorted_versions = sorted(
+ self.versions.values(),
+ key=parse_version,
+ reverse=True,
+ )
+
+ # Set the row (Y coordinate) for the chart, to allow a gap between 2.7
+ # and the rest
+ y = len(self.sorted_versions) + (1 if special_py27 else 0)
+ for version in self.sorted_versions:
+ if special_py27 and version["key"] == "2.7":
+ y -= 1
+ version["y"] = y
+ y -= 1
+
+ def write_csv(self) -> None:
+ """Output CSV files."""
+ now_str = str(dt.datetime.now(dt.timezone.utc))
+
+ versions_by_category = {"branches": {}, "end-of-life": {}}
+ headers = None
+ for details in self.sorted_versions:
+ row = {
+ "Branch": details["branch"],
+ "Schedule": f":pep:`{details['pep']}`",
+ "Status": details["status"],
+ "First release": csv_date(details["first_release"], now_str),
+ "End of life": csv_date(details["end_of_life"], now_str),
+ "Release manager": details["release_manager"],
+ }
+ headers = row.keys()
+ cat = "end-of-life" if details["status"] == "end-of-life" else "branches"
+ versions_by_category[cat][details["key"]] = row
+
+ for cat, versions in versions_by_category.items():
+ with open(f"include/{cat}.csv", "w", encoding="UTF-8", newline="") as file:
+ csv_file = csv.DictWriter(file, fieldnames=headers, lineterminator="\n")
+ csv_file.writeheader()
+ csv_file.writerows(versions.values())
+
+ def write_svg(self, today: str, out_path: str) -> None:
+ """Output SVG file."""
+ env = jinja2.Environment(
+ loader=jinja2.FileSystemLoader("_tools/"),
+ autoescape=True,
+ lstrip_blocks=True,
+ trim_blocks=True,
+ undefined=jinja2.StrictUndefined,
+ )
+ template = env.get_template("release_cycle_template.svg.jinja")
+
+ # Scale. Should be roughly the pixel size of the font.
+ # All later sizes are multiplied by this, so you can think of all other
+ # numbers being multiples of the font size, like using `em` units in
+ # CSS.
+ # (Ideally we'd actually use `em` units, but SVG viewBox doesn't take
+ # those.)
+
+ # Uppercase sizes are un-scaled
+ SCALE = 18
+
+ # Width of the drawing and main parts
+ DIAGRAM_WIDTH = 46
+ LEGEND_WIDTH = 7
+ RIGHT_MARGIN = 0.5
+
+ # Height of one line. If you change this you'll need to tweak
+ # some positioning numbers in the template as well.
+ LINE_HEIGHT = 1.5
+
+ first_date = self.cutoff
+ last_date = max(ver["end_of_life_date"] for ver in self.sorted_versions)
+
+ def date_to_x(date: dt.date) -> float:
+ """Convert datetime.date to an SVG X coordinate"""
+ num_days = (date - first_date).days
+ total_days = (last_date - first_date).days
+ ratio = num_days / total_days
+ x = ratio * (DIAGRAM_WIDTH - LEGEND_WIDTH - RIGHT_MARGIN)
+ return (x + LEGEND_WIDTH) * SCALE
+
+ def year_to_x(year: int) -> float:
+ """Convert year number to an SVG X coordinate of 1st January"""
+ return date_to_x(dt.date(year, 1, 1))
+
+ def format_year(year: int) -> str:
+ """Format year number for display"""
+ return f"'{year % 100:02}"
+
+ with open(out_path, "w", encoding="UTF-8", newline="\n") as f:
+ template.stream(
+ SCALE=SCALE,
+ diagram_width=DIAGRAM_WIDTH * SCALE,
+ diagram_height=(self.sorted_versions[0]["y"] + 2) * LINE_HEIGHT * SCALE,
+ years=range(first_date.year, last_date.year + 1),
+ line_height=LINE_HEIGHT * SCALE,
+ legend_width=LEGEND_WIDTH * SCALE,
+ right_margin=RIGHT_MARGIN * SCALE,
+ versions=list(reversed(self.sorted_versions)),
+ today=dt.datetime.strptime(today, "%Y-%m-%d").date(),
+ year_to_x=year_to_x,
+ date_to_x=date_to_x,
+ format_year=format_year,
+ id_key=self.id_key,
+ ).dump(f)
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser(
+ description=__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter
+ )
+ parser.add_argument(
+ "--today",
+ default=str(dt.date.today()),
+ metavar=" YYYY-MM-DD",
+ help="Override today for testing",
+ )
+ args = parser.parse_args()
+
+ versions = Versions()
+ assert len(versions.versions) > 10
+ versions.write_csv()
+ versions.write_svg(args.today, "include/release-cycle-all.svg")
+
+ versions = Versions(limit_to_active=True, special_py27=True)
+ versions.write_svg(args.today, "include/release-cycle.svg")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/_tools/release_cycle_template.svg.jinja b/_tools/release_cycle_template.svg.jinja
new file mode 100644
index 000000000..d3d5866a0
--- /dev/null
+++ b/_tools/release_cycle_template.svg.jinja
@@ -0,0 +1,197 @@
+
+
diff --git a/appendix.rst b/appendix.rst
deleted file mode 100644
index 793f615c8..000000000
--- a/appendix.rst
+++ /dev/null
@@ -1,68 +0,0 @@
-Appendix: Topics
-================
-
-Basics for contributors
------------------------
-
-.. note:: **Recommended reading**
-
- - :doc:`setup`
- - :doc:`pullrequest`
-
-* :doc:`help`
-* :doc:`communication`
-
-Core developers
----------------
-
-.. note:: **Recommended reading**
-
- * :doc:`setup`
- * :doc:`pullrequest`
- * :doc:`committing`
-
-* :doc:`coredev`
-* :doc:`developers`
-* :doc:`motivations`
-* :doc:`experts`
-
-Development workflow for contributors
--------------------------------------
-
-* :doc:`devcycle`
-* :doc:`pullrequest`
-* :doc:`fixingissues`
-
-Documenting Python and style guide
-----------------------------------
-
-* :doc:`docquality`
-* :doc:`documenting`
-
-Issue tracking and triaging
----------------------------
-
-* :doc:`tracker`
-* :doc:`triaging`
-
-Language development in depth
------------------------------
-
-* :doc:`exploring`
-* :doc:`grammar`
-* :doc:`compiler`
-* :doc:`garbage_collector`
-* :doc:`stdlibchanges`
-* :doc:`langchanges`
-* :doc:`porting`
-
-Testing and continuous integration
-----------------------------------
-
-* :doc:`runtests`
-* :doc:`coverage`
-* :doc:`silencewarnings`
-* :doc:`buildbots`
-* :doc:`buildworker`
-* :doc:`coverity`
-
diff --git a/c-api.rst b/c-api.rst
deleted file mode 100644
index 9198c80cb..000000000
--- a/c-api.rst
+++ /dev/null
@@ -1,194 +0,0 @@
-=======================
-Changing Python's C API
-=======================
-
-The C API is divided into three sections:
-
-1. The internal, private API, available with ``Py_BUILD_CORE`` defined.
- Ideally declared in ``Include/internal/``. Any API named with a leading
- underscore is also considered private.
-2. The public C API, available when ``Python.h`` is included normally.
- Ideally declared in ``Include/cpython/``.
-3. The Limited API, available with ``Py_LIMITED_API`` defined.
- Ideally declared directly under ``Include/``.
-
-Each section has higher stability & maintenance requirements, and you will
-need to think about more issues when you add or change definitions in it.
-
-The compatibility guarantees for public C API are explained in the
-user documentation, ``Doc/c-api/stable.rst`` (:ref:`python:stable`).
-
-
-The internal API
-================
-
-Internal API is defined in ``Include/internal/`` and is only available
-for building CPython itself, as indicated by a macro like ``Py_BUILD_CORE``.
-
-While internal API can be changed at any time, it's still good to keep it
-stable: other API or other CPython developers may depend on it.
-
-With PyAPI_FUNC or PyAPI_DATA
------------------------------
-
-Functions or structures in ``Include/internal/`` defined with
-``PyAPI_FUNC`` or ``PyAPI_DATA`` are internal functions which are
-exposed only for specific use cases like debuggers and profilers.
-
-
-With the extern keyword
------------------------
-
-Functions in ``Include/internal/`` defined with the ``extern`` keyword
-*must not and can not* be used outside the CPython code base. Only
-built-in stdlib extensions (built with the ``Py_BUILD_CORE_BUILTIN``
-macro defined) can use such functions.
-
-When in doubt, new internal C functions should be defined in
-``Include/internal`` using the ``extern`` keyword.
-
-Private names
---------------
-
-Any API named with a leading underscore is also considered internal.
-There are two main use cases for using such names rather than putting the
-definition in ``Include/internal/`` (or directly in a ``.c`` file):
-
-* Internal helpers for other public API; users should not use these directly;
-* “Provisional” API, included in a Python release to test real-world usage
- of new API. Such names should be renamed when stabilized; preferably with
- a macro aliasing the old name to the new one.
- See `"Finalizing the API" in PEP 590`_ for an example.
-
-.. _"Finalizing the API" in PEP 590: https://www.python.org/dev/peps/pep-0590/#finalizing-the-api
-
-
-.. _public-capi:
-
-Public C API
-============
-
-CPython's public C API is available when ``Python.h`` is included normally
-(that is, without defining macros to select the other variants).
-
-It should be defined in ``Include/cpython/`` (unless part of the Limited API,
-see below).
-
-Guidelines for expanding/changing the public API:
-
-- Make sure the new API follows reference counting conventions.
- (Following them makes the API easier to reason about, and easier use
- in other Python implementations.)
-
- - Functions *must not* steal references
- - Functions *must not* return borrowed references
- - Functions returning references *must* return a strong reference
-
-- Make sure the ownership rules and lifetimes of all applicable struct
- fields, arguments and return values are well defined.
-
-
-Limited API
-===========
-
-The Limited API is a subset of the C API designed to guarantee ABI
-stability across Python 3 versions.
-Defining the macro ``Py_LIMITED_API`` will limit the exposed API to
-this subset.
-
-No changes that break the Stable ABI are allowed.
-
-The Limited API should be defined in ``Include/``, excluding the
-``cpython`` and ``internal`` subdirectories.
-
-Guidelines for changing the Limited API
----------------------------------------
-
-- Guidelines for the general :ref:`public-capi` apply.
-
-- New Limited API should only be defined if ``Py_LIMITED_API`` is set
- to the version the API was added in or higher.
- (See below for the proper ``#if`` guard.)
-
-- All parameter types, return values, struct members, etc. need to be part
- of the Limited API.
-
- - Functions that deal with ``FILE*`` (or other types with ABI portability
- issues) should not be added.
-
-- Think twice when defining macros.
-
- - Macros should not expose implementation details
- - Functions must be exported as actual functions, not (only)
- as functions-like macros.
- - If possible, avoid macros. This makes the Limited API more usable in
- languages that don't use the C preprocessor.
-
-- Please start a public discussion before expanding the Limited API
-
-- The Limited API and must follow standard C, not just features of currently
- supported platforms. The exact C dialect is described in :pep:`7`.
-
- - Documentation examples (and more generally: the intended use of the API)
- should also follow standard C.
- - In particular, do not cast a function pointer to ``void*`` (a data pointer)
- or vice versa.
-
-- Think about ease of use for the user.
-
- - In C, ease of use itself is not very important; what is useful is
- reducing boilerplate code needed to use the API. Bugs like to hide in
- boiler plates.
-
- - If a function will be often called with specific value for an argument,
- consider making it default (used when ``NULL`` is passed in).
- - The Limited API needs to be well documented.
-
-- Think about future extensions
-
- - If it's possible that future Python versions will need to add a new
- field to your struct, make sure it can be done.
- - Make as few assumptions as possible about implementation details that
- might change in future CPython versions or differ across C API
- implementations. The most important CPython-specific implementation
- details involve:
-
- - The GIL
- - :ref:`Garbage collection `
- - Memory layout of PyObject, lists/tuples and other structures
-
-If following these guidelines would hurt performance, add a fast function
-(or macro) to the non-limited API and a stable equivalent to the Limited
-API.
-
-If anything is unclear, or you have a good reason to break the guidelines,
-consider discussing the change at the `capi-sig`_ mailing list.
-
-.. _capi-sig: https://mail.python.org/mailman3/lists/capi-sig.python.org/
-
-Adding a new definition to the Limited API
-------------------------------------------
-
-- Add the declaration to a header file directly under ``Include/``, into a
- block guarded with the following:
-
- .. code-block:: c
-
- #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03yy0000
-
- with the ``yy`` corresponding to the target CPython version, e.g.
- ``0x030A0000`` for Python 3.10.
-- Append an entry to the Stable ABI manifest, ``Misc/stable_abi.txt``.
-- Regenerate the autogenerated files using ``make regen-limited-abi``.
- On platforms without ``make``, run this command directly:
-
- .. code-block:: shell
-
- ./python ./Tools/scripts/stable_abi.py --generate-all ./Misc/stable_abi.txt
-
-- Build Python and check the using ``make check-limited-abi``.
- On platforms without ``make``, run this command directly:
-
- .. code-block:: shell
-
- ./python ./Tools/scripts/stable_abi.py --all ./Misc/stable_abi.txt
diff --git a/communication.rst b/communication.rst
deleted file mode 100644
index 90e278e65..000000000
--- a/communication.rst
+++ /dev/null
@@ -1,138 +0,0 @@
-.. _communication:
-
-Following Python's Development
-==============================
-
-Python's development is communicated through a myriad of ways, mostly through
-mailing lists, but also other forms.
-
-.. _mailinglists:
-
-Mailing Lists
--------------
-
-python-dev_ is the primary mailing list for discussions about Python's
-development. The list is open to the public and is subscribed to by all core
-developers plus many people simply interested in following Python's
-development. Discussion is focused on issues related to Python's development,
-such as how to handle a specific issue, a PEP, etc.
-
-- Ideas about new functionality should **not** start here and instead
- should be sent to python-ideas_.
-- Technical support questions should also not be asked here and instead
- should go to python-list_ or python-help_.
-
-Python-ideas_ is a mailing list open to the public to discuss ideas on changing
-Python. If a new idea does not start here (or python-list_, discussed below),
-it will get redirected here.
-
-Sometimes people post new ideas to python-list_ to gather community opinion
-before heading to python-ideas_. The list is also sometimes known as
-comp.lang.python, the name of the newsgroup it mirrors (it is also known by
-the abbreviation c.l.py).
-
-The python-committers_ mailing list is a private mailing list for core
-developers (the archives are publicly available).
-If something only affects core developers (e.g., the
-tree is frozen for commits, etc.), it is discussed here instead of python-dev
-to keep traffic down on the latter.
-
-Python-checkins_ sends out an email for every commit to Python's various
-repositories from https://github.com/python/cpython. All core developers
-subscribe to this list and are known to reply to these emails to make comments
-about various issues they catch in the commit. Replies get redirected to
-python-dev.
-
-There are two mailing lists related to issues on the `issue tracker`_. If you
-only want an email for when a new issue is open, subscribe to
-new-bugs-announce_. If you would rather receive an email for all changes made
-to any issue, subscribe to python-bugs-list_.
-
-General Python questions should go to `python-list`_ or `tutor`_
-or similar resources, such as StackOverflow_ or the ``#python`` IRC channel
-on Libera.Chat_.
-
-`Core-Workflow `_
-mailing list is the place to discuss and work on improvements to the CPython
-core development workflow.
-
-A complete list of Python mailing lists can be found at https://mail.python.org/mailman/listinfo.
-Most lists are also mirrored at `GMANE `_ and can be read and
-posted to in various ways, including via web browsers, NNTP newsreaders, and
-RSS feed readers.
-
-.. _issue tracker: https://bugs.python.org
-.. _new-bugs-announce: https://mail.python.org/mailman/listinfo/new-bugs-announce
-.. _python-bugs-list: https://mail.python.org/mailman/listinfo/python-bugs-list
-.. _python-checkins: https://mail.python.org/mailman/listinfo/python-checkins
-.. _python-committers: https://mail.python.org/mailman/listinfo/python-committers
-.. _python-dev: https://mail.python.org/mailman/listinfo/python-dev
-.. _python-help: https://mail.python.org/mailman/listinfo/python-help
-.. _python-ideas: https://mail.python.org/mailman/listinfo/python-ideas
-.. _python-list: https://mail.python.org/mailman/listinfo/python-list
-.. _tutor: https://mail.python.org/mailman/listinfo/tutor
-.. _StackOverflow: https://stackoverflow.com/
-.. _Libera.Chat: https://libera.chat/
-
-
-Discourse
----------
-
-We have our own `Discourse`_ forum for both developers and users. This forum
-complements the `python-dev`_, `python-ideas`_, `python-help`_, and
-`python-list`_ mailing lists. Also, voting for new core developers takes place
-at `Discourse`_.
-
-.. _Discourse: https://discuss.python.org/
-
-
-IRC
----
-
-Some core developers enjoy spending time on IRC discussing various issues
-regarding Python's development in the ``#python-dev`` channel on
-``irc.libera.chat``. This is not a place to ask for help with Python, but to
-discuss issues related to Python's own development. See also the
-``#python-dev-notifs`` channel for bots notifications.
-
-
-Blogs
------
-
-Several core developers are active bloggers and discuss Python's development
-that way. You can find their blogs (and various other developers who use Python)
-at http://planetpython.org/.
-
-
-Standards of behaviour in these communication channels
-------------------------------------------------------
-We try to foster environments of mutual respect, tolerance and encouragement,
-as described in the PSF's `Diversity Statement`_. Abiding by the guidelines
-in this document and asking questions or posting suggestions in the
-appropriate channels are an excellent way to get started on the mutual respect
-part, greatly increasing the chances of receiving tolerance and encouragement
-in return.
-
-.. _Diversity Statement: https://www.python.org/psf/diversity/
-
-Setting Expectations for Open Source Participation
---------------------------------------------------
-
-Burn-out is common in open source due to a misunderstanding of what users, contributors,
-and maintainers should expect from each other. Brett Cannon gave a `talk `_
-about this topic that sets out to help everyone set reasonable expectations of each other in
-order to make open source pleasant for everyone involved.
-
-Additional Repositories
------------------------
-
-`Python Core Workflow`_ hosts the codebase for tools such as `cherry_picker`_
-and `blurb`_.
-
-Python `Performance Benchmark`_ project is intended to be an authoritative
-source of benchmarks for all Python implementations.
-
-.. _Python Core Workflow: https://github.com/python/core-workflow
-.. _cherry_picker: https://pypi.org/project/cherry-picker/
-.. _blurb: https://pypi.org/project/blurb
-.. _Performance Benchmark: https://github.com/python/pyperformance
diff --git a/compiler.rst b/compiler.rst
deleted file mode 100644
index baa0ae825..000000000
--- a/compiler.rst
+++ /dev/null
@@ -1,678 +0,0 @@
-.. _compiler:
-
-Design of CPython's Compiler
-============================
-
-.. highlight:: none
-
-Abstract
---------
-
-In CPython, the compilation from source code to bytecode involves several steps:
-
-1. Tokenize the source code (:file:`Parser/tokenizer.c`)
-2. Parse the stream of tokens into an Abstract Syntax Tree (:file:`Parser/parser.c`)
-3. Transform AST into a Control Flow Graph (:file:`Python/compile.c`)
-4. Emit bytecode based on the Control Flow Graph (:file:`Python/compile.c`)
-
-The purpose of this document is to outline how these steps of the process work.
-
-This document does not touch on how parsing works beyond what is needed
-to explain what is needed for compilation. It is also not exhaustive
-in terms of the how the entire system works. You will most likely need
-to read some source to have an exact understanding of all details.
-
-
-Parsing
--------
-
-As of Python 3.9, Python's parser is a PEG parser of a somewhat
-unusual design (since its input is a stream of tokens rather than a
-stream of characters as is more common with PEG parsers).
-
-The grammar file for Python can be found in
-:file:`Grammar/python.gram`. The definitions for literal tokens
-(such as ``:``, numbers, etc.) can be found in :file:`Grammar/Tokens`.
-Various C files, including :file:`Parser/parser.c` are generated from
-these (see :doc:`grammar`).
-
-
-Abstract Syntax Trees (AST)
----------------------------
-
-
-.. sidebar:: Green Tree Snakes
-
- See also `Green Tree Snakes - the missing Python AST docs
- `_ by Thomas Kluyver.
-
-The abstract syntax tree (AST) is a high-level representation of the
-program structure without the necessity of containing the source code;
-it can be thought of as an abstract representation of the source code. The
-specification of the AST nodes is specified using the Zephyr Abstract
-Syntax Definition Language (ASDL) [Wang97]_.
-
-The definition of the AST nodes for Python is found in the file
-:file:`Parser/Python.asdl`.
-
-Each AST node (representing statements, expressions, and several
-specialized types, like list comprehensions and exception handlers) is
-defined by the ASDL. Most definitions in the AST correspond to a
-particular source construct, such as an 'if' statement or an attribute
-lookup. The definition is independent of its realization in any
-particular programming language.
-
-The following fragment of the Python ASDL construct demonstrates the
-approach and syntax::
-
- module Python
- {
- stmt = FunctionDef(identifier name, arguments args, stmt* body,
- expr* decorators)
- | Return(expr? value) | Yield(expr? value)
- attributes (int lineno)
- }
-
-The preceding example describes two different kinds of statements and an
-expression: function definitions, return statements, and yield expressions.
-All three kinds are considered of type ``stmt`` as shown by ``|`` separating
-the various kinds. They all take arguments of various kinds and amounts.
-
-Modifiers on the argument type specify the number of values needed; ``?``
-means it is optional, ``*`` means 0 or more, while no modifier means only one
-value for the argument and it is required. ``FunctionDef``, for instance,
-takes an ``identifier`` for the *name*, ``arguments`` for *args*, zero or more
-``stmt`` arguments for *body*, and zero or more ``expr`` arguments for
-*decorators*.
-
-Do notice that something like 'arguments', which is a node type, is
-represented as a single AST node and not as a sequence of nodes as with
-stmt as one might expect.
-
-All three kinds also have an 'attributes' argument; this is shown by the
-fact that 'attributes' lacks a '|' before it.
-
-The statement definitions above generate the following C structure type:
-
-.. code-block:: c
-
- typedef struct _stmt *stmt_ty;
-
- struct _stmt {
- enum { FunctionDef_kind=1, Return_kind=2, Yield_kind=3 } kind;
- union {
- struct {
- identifier name;
- arguments_ty args;
- asdl_seq *body;
- } FunctionDef;
-
- struct {
- expr_ty value;
- } Return;
-
- struct {
- expr_ty value;
- } Yield;
- } v;
- int lineno;
- }
-
-Also generated are a series of constructor functions that allocate (in
-this case) a ``stmt_ty`` struct with the appropriate initialization. The
-``kind`` field specifies which component of the union is initialized. The
-``FunctionDef()`` constructor function sets 'kind' to ``FunctionDef_kind`` and
-initializes the *name*, *args*, *body*, and *attributes* fields.
-
-
-Memory Management
------------------
-
-Before discussing the actual implementation of the compiler, a discussion of
-how memory is handled is in order. To make memory management simple, an arena
-is used. This means that a memory is pooled in a single location for easy
-allocation and removal. What this gives us is the removal of explicit memory
-deallocation. Because memory allocation for all needed memory in the compiler
-registers that memory with the arena, a single call to free the arena is all
-that is needed to completely free all memory used by the compiler.
-
-In general, unless you are working on the critical core of the compiler, memory
-management can be completely ignored. But if you are working at either the
-very beginning of the compiler or the end, you need to care about how the arena
-works. All code relating to the arena is in either
-:file:`Include/Internal/pycore_pyarena.h` or :file:`Python/pyarena.c`.
-
-``PyArena_New()`` will create a new arena. The returned ``PyArena`` structure
-will store pointers to all memory given to it. This does the bookkeeping of
-what memory needs to be freed when the compiler is finished with the memory it
-used. That freeing is done with ``PyArena_Free()``. This only needs to be
-called in strategic areas where the compiler exits.
-
-As stated above, in general you should not have to worry about memory
-management when working on the compiler. The technical details have been
-designed to be hidden from you for most cases.
-
-The only exception comes about when managing a PyObject. Since the rest
-of Python uses reference counting, there is extra support added
-to the arena to cleanup each PyObject that was allocated. These cases
-are very rare. However, if you've allocated a PyObject, you must tell
-the arena about it by calling ``PyArena_AddPyObject()``.
-
-
-Source Code to AST
-------------------
-
-The AST is generated from source code using the function
-``_PyParser_ASTFromString()`` or ``_PyParser_ASTFromFile()``
-(from :file:`Parser/peg_api.c`) depending on the input type.
-
-After some checks, a helper function in :file:`Parser/parser.c` begins applying
-production rules on the source code it receives; converting source code to
-tokens and matching these tokens recursively to their corresponding rule. The
-rule's corresponding rule function is called on every match. These rule
-functions follow the format :samp:`xx_rule`. Where *xx* is the grammar rule
-that the function handles and is automatically derived from
-:file:`Grammar/python.gram` by :file:`Tools/peg_generator/pegen/c_generator.py`.
-
-Each rule function in turn creates an AST node as it goes along. It does this
-by allocating all the new nodes it needs, calling the proper AST node creation
-functions for any required supporting functions and connecting them as needed.
-This continues until all nonterminal symbols are replaced with terminals. If an
-error occurs, the rule functions backtrack and try another rule function. If
-there are no more rules, an error is set and the parsing ends.
-
-The AST node creation helper functions have the name :samp:`_PyAST_{xx}`
-where *xx* is the AST node that the function creates. These are defined by the
-ASDL grammar and contained in :file:`Python/Python-ast.c` (which is generated by
-:file:`Parser/asdl_c.py` from :file:`Parser/Python.asdl`). This all leads to a
-sequence of AST nodes stored in ``asdl_seq`` structs.
-
-To demonstrate everything explained so far, here's the
-rule function responsible for a simple named import statement such as
-``import sys``. Note that error-checking and debugging code has been
-omitted. Removed parts are represented by ``...``.
-Furthermore, some comments have been added for explanation. These comments
-may not be present in the actual code.
-
-.. code-block:: c
-
- // This is the production rule (from python.gram) the rule function
- // corresponds to:
- // import_name: 'import' dotted_as_names
- static stmt_ty
- import_name_rule(Parser *p)
- {
- ...
- stmt_ty _res = NULL;
- { // 'import' dotted_as_names
- ...
- Token * _keyword;
- asdl_alias_seq* a;
- // The tokenizing steps.
- if (
- (_keyword = _PyPegen_expect_token(p, 513)) // token='import'
- &&
- (a = dotted_as_names_rule(p)) // dotted_as_names
- )
- {
- ...
- // Generate an AST for the import statement.
- _res = _PyAST_Import ( a , ...);
- ...
- goto done;
- }
- ...
- }
- _res = NULL;
- done:
- ...
- return _res;
- }
-
-
-To improve backtracking performance, some rules (chosen by applying a
-``(memo)`` flag in the grammar file) are memoized. Each rule function checks if
-a memoized version exists and returns that if so, else it continues in the
-manner stated in the previous paragraphs.
-
-There are macros for creating and using ``asdl_xx_seq *`` types, where *xx* is
-a type of the ASDL sequence. Three main types are defined
-manually -- ``generic``, ``identifier`` and ``int``. These types are found in
-:file:`Python/asdl.c` and its corresponding header file
-:file:`Include/Internal/pycore_asdl.h`. Functions and macros
-for creating ``asdl_xx_seq *`` types are as follows:
-
-``_Py_asdl_generic_seq_new(Py_ssize_t, PyArena *)``
- Allocate memory for an ``asdl_int_seq`` of the specified length
-``_Py_asdl_identifier_seq_new(Py_ssize_t, PyArena *)``
- Allocate memory for an ``asdl_identifier_seq`` of the specified length
-``_Py_asdl_int_seq_new(Py_ssize_t, PyArena *)``
- Allocate memory for an ``asdl_generic_seq`` of the specified length
-
-In addition to the three types mentioned above, some ASDL sequence types are
-automatically generated by :file:`Parser/asdl_c.py` and found in
-:file:`Include/Internal/pycore_ast.h`. Macros for using both manually defined
-and automatically generated ASDL sequence types are as follows:
-
-``asdl_seq_GET(asdl_xx_seq *, int)``
- Get item held at a specific position in an ``asdl_xx_seq``
-``asdl_seq_SET(asdl_xx_seq *, int, stmt_ty)``
- Set a specific index in an ``asdl_xx_seq`` to the specified value
-
-Untyped counterparts exist for some of the typed macros. These are useful
-when a function needs to manipulate a generic ASDL sequence:
-
-``asdl_seq_GET_UNTYPED(asdl_seq *, int)``
- Get item held at a specific position in an ``asdl_seq``
-``asdl_seq_SET_UNTYPED(asdl_seq *, int, stmt_ty)``
- Set a specific index in an ``asdl_seq`` to the specified value
-``asdl_seq_LEN(asdl_seq *)``
- Return the length of an ``asdl_seq`` or ``asdl_xx_seq``
-
-Note that typed macros and functions are recommended over their untyped
-counterparts. Typed macros carry out checks in debug mode and aid
-debugging errors caused by incorrectly casting from ``void *``.
-
-If you are working with statements, you must also worry about keeping
-track of what line number generated the statement. Currently the line
-number is passed as the last parameter to each ``stmt_ty`` function.
-
-.. versionchanged:: 3.9
- The new PEG parser generates an AST directly without creating a
- parse tree. ``Python/ast.c`` is now only used to validate the AST for
- debugging purposes.
-
-.. seealso:: :pep:`617` (PEP 617 -- New PEG parser for CPython)
-
-
-Control Flow Graphs
--------------------
-
-A control flow graph (often referenced by its acronym, CFG) is a
-directed graph that models the flow of a program using basic blocks that
-contain the intermediate representation (abbreviated "IR", and in this
-case is Python bytecode) within the blocks. Basic blocks themselves are
-a block of IR that has a single entry point but possibly multiple exit
-points. The single entry point is the key to basic blocks; it all has
-to do with jumps. An entry point is the target of something that
-changes control flow (such as a function call or a jump) while exit
-points are instructions that would change the flow of the program (such
-as jumps and 'return' statements). What this means is that a basic
-block is a chunk of code that starts at the entry point and runs to an
-exit point or the end of the block.
-
-As an example, consider an 'if' statement with an 'else' block. The
-guard on the 'if' is a basic block which is pointed to by the basic
-block containing the code leading to the 'if' statement. The 'if'
-statement block contains jumps (which are exit points) to the true body
-of the 'if' and the 'else' body (which may be ``NULL``), each of which are
-their own basic blocks. Both of those blocks in turn point to the
-basic block representing the code following the entire 'if' statement.
-
-CFGs are usually one step away from final code output. Code is directly
-generated from the basic blocks (with jump targets adjusted based on the
-output order) by doing a post-order depth-first search on the CFG
-following the edges.
-
-
-AST to CFG to Bytecode
-----------------------
-
-With the AST created, the next step is to create the CFG. The first step
-is to convert the AST to Python bytecode without having jump targets
-resolved to specific offsets (this is calculated when the CFG goes to
-final bytecode). Essentially, this transforms the AST into Python
-bytecode with control flow represented by the edges of the CFG.
-
-Conversion is done in two passes. The first creates the namespace
-(variables can be classified as local, free/cell for closures, or
-global). With that done, the second pass essentially flattens the CFG
-into a list and calculates jump offsets for final output of bytecode.
-
-The conversion process is initiated by a call to the function
-``_PyAST_Compile()`` in :file:`Python/compile.c`. This function does both the
-conversion of the AST to a CFG and outputting final bytecode from the CFG.
-The AST to CFG step is handled mostly by two functions called by
-``_PyAST_Compile()``; ``_PySymtable_Build()`` and ``compiler_mod()``. The former
-is in :file:`Python/symtable.c` while the latter is in :file:`Python/compile.c`.
-
-``_PySymtable_Build()`` begins by entering the starting code block for the
-AST (passed-in) and then calling the proper :samp:`symtable_visit_{xx}` function
-(with *xx* being the AST node type). Next, the AST tree is walked with
-the various code blocks that delineate the reach of a local variable
-as blocks are entered and exited using ``symtable_enter_block()`` and
-``symtable_exit_block()``, respectively.
-
-Once the symbol table is created, it is time for CFG creation, whose
-code is in :file:`Python/compile.c`. This is handled by several functions
-that break the task down by various AST node types. The functions are
-all named :samp:`compiler_visit_{xx}` where *xx* is the name of the node type (such
-as ``stmt``, ``expr``, etc.). Each function receives a ``struct compiler *``
-and :samp:`{xx}_ty` where *xx* is the AST node type. Typically these functions
-consist of a large 'switch' statement, branching based on the kind of
-node type passed to it. Simple things are handled inline in the
-'switch' statement with more complex transformations farmed out to other
-functions named :samp:`compiler_{xx}` with *xx* being a descriptive name of what is
-being handled.
-
-When transforming an arbitrary AST node, use the ``VISIT()`` macro.
-The appropriate :samp:`compiler_visit_{xx}` function is called, based on the value
-passed in for (so :samp:`VISIT({c}, expr, {node})` calls
-:samp:`compiler_visit_expr({c}, {node})`). The ``VISIT_SEQ()`` macro is very similar,
-but is called on AST node sequences (those values that were created as
-arguments to a node that used the '*' modifier). There is also
-``VISIT_SLICE()`` just for handling slices.
-
-Emission of bytecode is handled by the following macros:
-
-``ADDOP(struct compiler *, int)``
- add a specified opcode
-``ADDOP_NOLINE(struct compiler *, int)``
- like ``ADDOP`` without a line number; used for artificial opcodes without
- no corresponding token in the source code
-``ADDOP_IN_SCOPE(struct compiler *, int)``
- like ``ADDOP``, but also exits current scope; used for adding return value
- opcodes in lambdas and closures
-``ADDOP_I(struct compiler *, int, Py_ssize_t)``
- add an opcode that takes an integer argument
-``ADDOP_O(struct compiler *, int, PyObject *, TYPE)``
- add an opcode with the proper argument based on the position of the
- specified PyObject in PyObject sequence object, but with no handling of
- mangled names; used for when you
- need to do named lookups of objects such as globals, consts, or
- parameters where name mangling is not possible and the scope of the
- name is known; *TYPE* is the name of PyObject sequence
- (``names`` or ``varnames``)
-``ADDOP_N(struct compiler *, int, PyObject *, TYPE)``
- just like ``ADDOP_O``, but steals a reference to PyObject
-``ADDOP_NAME(struct compiler *, int, PyObject *, TYPE)``
- just like ``ADDOP_O``, but name mangling is also handled; used for
- attribute loading or importing based on name
-``ADDOP_LOAD_CONST(struct compiler *, PyObject *)``
- add the `LOAD_CONST` opcode with the proper argument based on the
- position of the specified PyObject in the consts table.
-``ADDOP_LOAD_CONST_NEW(struct compiler *, PyObject *)``
- just like ``ADDOP_LOAD_CONST_NEW``, but steals a reference to PyObject
-``ADDOP_JUMP(struct compiler *, int, basicblock *)``
- create a jump to a basic block
-``ADDOP_JUMP_NOLINE(struct compiler *, int, basicblock *)``
- like ``ADDOP_JUMP`` without a line number; used for artificial jumps
- without no corresponding token in the source code.
-``ADDOP_JUMP_COMPARE(struct compiler *, cmpop_ty)``
- depending on the second argument, add an ``ADDOP_I`` with either an
- ``IS_OP``, ``CONTAINS_OP``, or ``COMPARE_OP`` opcode.
-
-Several helper functions that will emit bytecode and are named
-:samp:`compiler_{xx}()` where *xx* is what the function helps with (``list``,
-``boolop``, etc.). A rather useful one is ``compiler_nameop()``.
-This function looks up the scope of a variable and, based on the
-expression context, emits the proper opcode to load, store, or delete
-the variable.
-
-As for handling the line number on which a statement is defined, this is
-handled by ``compiler_visit_stmt()`` and thus is not a worry.
-
-In addition to emitting bytecode based on the AST node, handling the
-creation of basic blocks must be done. Below are the macros and
-functions used for managing basic blocks:
-
-``NEXT_BLOCK(struct compiler *)``
- create an implicit jump from the current block
- to the new block
-``compiler_new_block(struct compiler *)``
- create a block but don't use it (used for generating jumps)
-``compiler_use_next_block(struct compiler *, basicblock *block)``
- set a previously created block as a current block
-
-Once the CFG is created, it must be flattened and then final emission of
-bytecode occurs. Flattening is handled using a post-order depth-first
-search. Once flattened, jump offsets are backpatched based on the
-flattening and then a ``PyCodeObject`` is created. All of this is
-handled by calling ``assemble()``.
-
-
-Introducing New Bytecode
-------------------------
-
-Sometimes a new feature requires a new opcode. But adding new bytecode is
-not as simple as just suddenly introducing new bytecode in the AST ->
-bytecode step of the compiler. Several pieces of code throughout Python depend
-on having correct information about what bytecode exists.
-
-First, you must choose a name and a unique identifier number. The official
-list of bytecode can be found in :file:`Lib/opcode.py`. If the opcode is to
-take an argument, it must be given a unique number greater than that assigned to
-``HAVE_ARGUMENT`` (as found in :file:`Lib/opcode.py`).
-
-Once the name/number pair has been chosen and entered in :file:`Lib/opcode.py`,
-you must also enter it into :file:`Doc/library/dis.rst`, and regenerate
-:file:`Include/opcode.h` and :file:`Python/opcode_targets.h` by running
-``make regen-opcode regen-opcode-targets``.
-
-With a new bytecode you must also change what is called the magic number for
-.pyc files. The variable ``MAGIC_NUMBER`` in
-:file:`Lib/importlib/_bootstrap_external.py` contains the number.
-Changing this number will lead to all .pyc files with the old ``MAGIC_NUMBER``
-to be recompiled by the interpreter on import. Whenever ``MAGIC_NUMBER`` is
-changed, the ranges in the ``magic_values`` array in :file:`PC/launcher.c`
-must also be updated. Changes to :file:`Lib/importlib/_bootstrap_external.py`
-will take effect only after running ``make regen-importlib``. Running this
-command before adding the new bytecode target to :file:`Python/ceval.c` will
-result in an error. You should only run ``make regen-importlib`` after the new
-bytecode target has been added.
-
-.. note:: On Windows, running the ``./build.bat`` script will automatically
- regenerate the required files without requiring additional arguments.
-
-Finally, you need to introduce the use of the new bytecode. Altering
-:file:`Python/compile.c` and :file:`Python/ceval.c` will be the primary places
-to change. You must add the case for a new opcode into the 'switch'
-statement in the ``stack_effect()`` function in :file:`Python/compile.c`.
-If the new opcode has a jump target, you will need to update macros and
-'switch' statements in :file:`Python/peephole.c`. If it affects a control
-flow or the block stack, you may have to update the ``frame_setlineno()``
-function in :file:`Objects/frameobject.c`. :file:`Lib/dis.py` may need
-an update if the new opcode interprets its argument in a special way (like
-``FORMAT_VALUE`` or ``MAKE_FUNCTION``).
-
-If you make a change here that can affect the output of bytecode that
-is already in existence and you do not change the magic number constantly, make
-sure to delete your old .py(c|o) files! Even though you will end up changing
-the magic number if you change the bytecode, while you are debugging your work
-you will be changing the bytecode output without constantly bumping up the
-magic number. This means you end up with stale .pyc files that will not be
-recreated.
-Running ``find . -name '*.py[co]' -exec rm -f '{}' +`` should delete all .pyc
-files you have, forcing new ones to be created and thus allow you test out your
-new bytecode properly. Run ``make regen-importlib`` for updating the
-bytecode of frozen importlib files. You have to run ``make`` again after this
-for recompiling generated C files.
-
-
-Code Objects
-------------
-
-The result of ``PyAST_CompileObject()`` is a ``PyCodeObject`` which is defined in
-:file:`Include/code.h`. And with that you now have executable Python bytecode!
-
-The code objects (byte code) are executed in :file:`Python/ceval.c`. This file
-will also need a new case statement for the new opcode in the big switch
-statement in ``_PyEval_EvalFrameDefault()``.
-
-
-Important Files
----------------
-
-+ Parser/
-
- Python.asdl
- ASDL syntax file
-
- asdl.py
- Parser for ASDL definition files. Reads in an ASDL description
- and parses it into an AST that describes it.
-
- asdl_c.py
- "Generate C code from an ASDL description." Generates
- :file:`Python/Python-ast.c` and :file:`Include/Internal/pycore_ast.h`.
-
- parser.c
- The new PEG parser introduced in Python 3.9.
- Generated by :file:`Tools/peg_generator/pegen/c_generator.py`
- from the grammar :file:`Grammar/python.gram`. Creates the AST from
- source code. Rule functions for their corresponding production rules
- are found here.
-
- peg_api.c
- Contains high-level functions which are used by the interpreter to
- create an AST from source code .
-
- pegen.c
- Contains helper functions which are used by functions in
- :file:`Parser/parser.c` to construct the AST. Also contains helper
- functions which help raise better error messages when parsing source
- code.
-
- pegen.h
- Header file for the corresponding :file:`Parser/pegen.c`. Also contains
- definitions of the ``Parser`` and ``Token`` structs.
-
-+ Python/
-
- Python-ast.c
- Creates C structs corresponding to the ASDL types. Also
- contains code for marshalling AST nodes (core ASDL types have
- marshalling code in :file:`asdl.c`). "File automatically generated by
- :file:`Parser/asdl_c.py`". This file must be committed separately
- after every grammar change is committed since the ``__version__``
- value is set to the latest grammar change revision number.
-
- asdl.c
- Contains code to handle the ASDL sequence type. Also has code
- to handle marshalling the core ASDL types, such as number and
- identifier. Used by :file:`Python-ast.c` for marshalling AST nodes.
-
- ast.c
- Used for validating the AST.
-
- ast_opt.c
- Optimizes the AST.
-
- ast_unparse.c
- Converts the AST expression node back into a string
- (for string annotations).
-
- ceval.c
- Executes byte code (aka, eval loop).
-
- compile.c
- Emits bytecode based on the AST.
-
- symtable.c
- Generates a symbol table from AST.
-
- peephole.c
- Optimizes the bytecode.
-
- pyarena.c
- Implementation of the arena memory manager.
-
- wordcode_helpers.h
- Helpers for generating bytecode.
-
- opcode_targets.h
- One of the files that must be modified if :file:`Lib/opcode.py` is.
-
-+ Include/
-
- code.h
- Header file for :file:`Objects/codeobject.c`; contains definition of
- ``PyCodeObject``.
-
- opcode.h
- One of the files that must be modified if :file:`Lib/opcode.py` is.
-
- + Internal/
-
- pycore_ast.h
- Contains the actual definitions of the C structs as generated by
- :file:`Python/Python-ast.c`.
- "Automatically generated by :file:`Parser/asdl_c.py`".
-
- pycore_asdl.h
- Header for the corresponding :file:`Python/ast.c`
-
- pycore_ast.h
- Declares ``_PyAST_Validate()`` external (from :file:`Python/ast.c`).
-
- pycore_symtable.h
- Header for :file:`Python/symtable.c`. ``struct symtable`` and
- ``PySTEntryObject`` are defined here.
-
- pycore_parser.h
- Header for the corresponding :file:`Parser/peg_api.c`.
-
- pycore_pyarena.h
- Header file for the corresponding :file:`Python/pyarena.c`.
-
-
-+ Objects/
-
- codeobject.c
- Contains PyCodeObject-related code (originally in
- :file:`Python/compile.c`).
-
- frameobject.c
- Contains the ``frame_setlineno()`` function which should determine
- whether it is allowed to make a jump between two points in a bytecode.
-
-+ Lib/
-
- opcode.py
- Master list of bytecode; if this file is modified you must modify
- several other files accordingly (see "`Introducing New Bytecode`_")
-
- importlib/_bootstrap_external.py
- Home of the magic number (named ``MAGIC_NUMBER``) for bytecode
- versioning.
-
-
-Known Compiler-related Experiments
-----------------------------------
-
-This section lists known experiments involving the compiler (including
-bytecode).
-
-Skip Montanaro presented a paper at a Python workshop on a peephole optimizer
-[#skip-peephole]_.
-
-Michael Hudson has a non-active SourceForge project named Bytecodehacks
-[#Bytecodehacks]_ that provides functionality for playing with bytecode
-directly.
-
-An opcode to combine the functionality of ``LOAD_ATTR``/``CALL_FUNCTION`` was
-created named ``CALL_ATTR`` [#CALL_ATTR]_. Currently only works for classic
-classes and for new-style classes rough benchmarking showed an actual slowdown
-thanks to having to support both classic and new-style classes.
-
-
-
-References
-----------
-
-.. [Wang97] Daniel C. Wang, Andrew W. Appel, Jeff L. Korn, and Chris
- S. Serra. `The Zephyr Abstract Syntax Description Language.`_
- In Proceedings of the Conference on Domain-Specific Languages, pp.
- 213--227, 1997.
-
-.. _The Zephyr Abstract Syntax Description Language.:
- https://www.cs.princeton.edu/research/techreps/TR-554-97
-
-.. [#skip-peephole] Skip Montanaro's Peephole Optimizer Paper
- (https://drive.google.com/open?id=0B2InO7qBBGRXQXlDM3FVdWZxQWc)
-
-.. [#Bytecodehacks] Bytecodehacks Project
- (http://bytecodehacks.sourceforge.net/bch-docs/bch/index.html)
-
-.. [#CALL_ATTR] CALL_ATTR opcode
- (https://bugs.python.org/issue709744)
diff --git a/conf.py b/conf.py
index 468fe1f17..5050f5c45 100644
--- a/conf.py
+++ b/conf.py
@@ -1,234 +1,238 @@
-# -*- coding: utf-8 -*-
-#
-# Python Developer's Guide documentation build configuration file, created by
-# sphinx-quickstart on Tue Jan 4 10:34:03 2011.
-#
-# This file is execfile()d with the current directory set to its containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-import os
-import sys
-import time
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.insert(0, os.path.abspath('.'))
-
-sys.path.append(os.path.abspath('tools'))
-
-# -- General configuration -----------------------------------------------------
-
-# If your documentation needs a minimal Sphinx version, state it here.
-#needs_sphinx = '1.0'
-
-# Add any Sphinx extension module names here, as strings. They can be extensions
-# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx_copybutton']
-intersphinx_mapping = {'python': ('https://docs.python.org/3', None)}
-todo_include_todos = True
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The encoding of source files.
-#source_encoding = 'utf-8-sig'
+import json
+
+extensions = [
+ 'notfound.extension',
+ 'sphinx.ext.extlinks',
+ 'sphinx.ext.intersphinx',
+ 'sphinx.ext.todo',
+ 'sphinx_copybutton',
+ 'sphinx_inline_tabs',
+ 'sphinxext.opengraph',
+ 'sphinxext.rediraffe',
+]
# The master toctree document.
master_doc = 'index'
# General information about the project.
-project = 'Python Developer\'s Guide'
-copyright = '2011-%s, Python Software Foundation' % time.strftime('%Y')
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-version = ''
-# The full version, including alpha/beta/rc tags.
-release = ''
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
+project = "Python Developer's Guide"
+copyright = '2011 Python Software Foundation'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
-exclude_patterns = ['_build', 'venv*', 'env*', 'README.rst', '.github']
-
-# The reST default role (used for this markup: `text`) to use for all documents.
-#default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
+exclude_patterns = [
+ '_build',
+ 'venv*',
+ 'env*',
+ 'README.rst',
+ '.github',
+]
+nitpicky = True
-# -- Options for HTML output ---------------------------------------------------
-# Use the upstream python-docs-theme
html_theme = 'furo'
-html_theme_options = {}
-
-
-# The name for this set of Sphinx documents. If None, it defaults to
-# " v documentation".
-html_title = "%s %s" % (project, release)
-
-# Path to find HTML templates.
-templates_path = ['tools/templates']
-
-# Additional static files.
-html_static_path = ['tools/static']
-
-# A shorter title for the navigation bar. Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-html_logo = "python-logo.png"
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#html_use_smartypants = True
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-#html_domain_indices = True
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
-
-# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
-
-# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#html_show_copyright = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a tag referring to it. The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'PythonDevelopersGuidedoc'
-
-
-# -- Options for LaTeX output --------------------------------------------------
-
-# The paper size ('letter' or 'a4').
-#latex_paper_size = 'letter'
-
-# The font size ('10pt', '11pt' or '12pt').
-#latex_font_size = '10pt'
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, documentclass [howto/manual]).
-latex_documents = [
- (
- 'index',
- 'PythonDevelopersGuide.tex',
- 'Python Developer\'s Guide Documentation',
- 'Brett Cannon',
- 'manual',
- ),
+html_theme_options = {
+ "source_repository": "https://github.com/python/devguide",
+ "source_branch": "main",
+}
+html_static_path = ['_static']
+html_css_files = [
+ 'devguide_overrides.css',
]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# If true, show page references after internal links.
-#latex_show_pagerefs = False
-
-# If true, show URL addresses after external links.
-#latex_show_urls = False
-
-# Additional stuff for the LaTeX preamble.
-#latex_preamble = ''
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-#latex_domain_indices = True
-
-
-# -- Options for manual page output --------------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [
- (
- 'index',
- 'pythondevelopersguide',
- "Python Developer's Guide Documentation",
- ['Brett Cannon'],
- 1,
- ),
+html_js_files = [
+ "activate_tab.js",
]
+html_logo = "_static/python-logo.svg"
+html_favicon = "_static/favicon.png"
+
+# Set to '' to prevent appending "documentation" to the site title
+html_title = ""
+
+linkcheck_allowed_redirects = {
+ # Edit page
+ r"https://docs.google.com/document/d/.*/": r"https://docs.google.com/document/d/.*/edit", # noqa: E501
+ # Canonical
+ r"https://docs.python.org/": r"https://docs.python.org/3/",
+ # Translations with country codes
+ r"https://docs.python.org/[a-z-]+/": r"https://docs.python.org/[a-z-]+/3/",
+ # Personal /my/ links redirect to login page
+ r"https://discuss.python.org/my/.*": r"https://discuss.python.org/login-preferences", # noqa: E501
+ # Category number URL to full slug
+ r"https://discuss.python.org/c/\d+": r"https://discuss.python.org/c/.*",
+ # Login page
+ r"https://github.com/python/buildmaster-config/issues/new.*": r"https://github.com/login.*", # noqa: E501
+ r"https://github.com/python/core-workflow/issues/new.*": r"https://github.com/login.*", # noqa: E501
+ r"https://github.com/orgs/python/teams.*": r"https://github.com/login.*", # noqa: E501
+ # Archive redirect
+ r"https://github.com/python/cpython/archive/main.zip": r"https://codeload.github.com/python/cpython/zip/refs/heads/main", # noqa: E501
+ # Blob to tree
+ r"https://github.com/python/cpython/blob/.*": r"https://github.com/python/cpython/tree/.*", # noqa: E501
+ # HackMD shortcuts
+ r"https://hackmd.io/s/.*": r"https://hackmd.io/@.*",
+ # Read the Docs
+ r"https://python-docs-tr.readthedocs.io/": r"https://python-docs-tr.readthedocs.io/tr/.*", # noqa: E501
+ r"https://virtualenv.pypa.io/": r"https://virtualenv.pypa.io/en/latest/",
+ r"https://www.sphinx-doc.org/": r"https://www.sphinx-doc.org/en/master/",
+ # Cookie consent
+ r"https://www.youtube.com/playlist.*": r"https://consent.youtube.com/.*",
+}
# ignore linkcheck anchors for /#/$ANCHOR since it is used for
# dynamic pages such as http://buildbot.python.org/all/#/console
# http://www.sphinx-doc.org/en/stable/config.html?highlight=linkcheck#confval-linkcheck_anchors_ignore
linkcheck_anchors_ignore = [
# match any anchor that starts with a '/' since this is an invalid HTML anchor
- '\/.*',
+ r'\/.*',
]
+linkcheck_ignore = [
+ # Checks fail due to rate limits
+ r'https://github.com/.*',
+ r'https://www.gnu.org/software/autoconf/',
+ # The Discourse groups are private unless you are logged in
+ 'https://discuss.python.org/groups/staff',
+ 'https://discuss.python.org/groups/moderators',
+ 'https://discuss.python.org/groups/admins',
+ # "Anchor not found":
+ r'https://packaging.python.org/.*#',
+ # "-rate limited-", causing a timeout
+ r'https://stackoverflow.com/.*',
+ # Discord doesn't allow robot crawlers: "403 Client Error: Forbidden"
+ r'https://support.discord.com/hc/en-us/articles/219070107-Server-Nicknames',
+ # Patreon also gives 403 to the GHA linkcheck runner
+ r'https://www.patreon.com/.*',
+]
+
+rediraffe_redirects = {
+ # Development Tools
+ "clang.rst": "development-tools/clang.rst",
+ "gdb.rst": "development-tools/gdb.rst",
+ # Advanced Tools was renamed Development Tools in gh-1149
+ "advanced-tools/clang.rst": "development-tools/clang.rst",
+ "advanced-tools/gdb.rst": "development-tools/gdb.rst",
+ # Core team
+ "coredev.rst": "core-team/join-team.rst",
+ "committing.rst": "core-team/committing.rst",
+ "developers.rst": "core-team/team-log.rst",
+ "experts.rst": "core-team/experts.rst",
+ "motivations.rst": "core-team/motivations.rst",
+ # core-developers/ -> core-team/
+ "core-developers/become-core-developer.rst": "core-team/join-team.rst",
+ "core-developers/committing.rst": "core-team/committing.rst",
+ "core-developers/developer-log.rst": "core-team/team-log.rst",
+ "core-developers/experts.rst": "core-team/experts.rst",
+ "core-developers/index.rst": "core-team/index.rst",
+ "core-developers/memorialization.rst": "core-team/memorialization.rst",
+ "core-developers/motivations.rst": "core-team/motivations.rst",
+ "core-developers/responsibilities.rst": "core-team/responsibilities.rst",
+ # Developer Workflow
+ "c-api.rst": "developer-workflow/c-api.rst",
+ "communication.rst": "developer-workflow/communication-channels.rst",
+ "devcycle.rst": "developer-workflow/development-cycle.rst",
+ "extensions.rst": "developer-workflow/extension-modules.rst",
+ "grammar.rst": "developer-workflow/grammar.rst",
+ "langchanges.rst": "developer-workflow/lang-changes.rst",
+ "porting.rst": "developer-workflow/porting.rst",
+ "stdlibchanges.rst": "developer-workflow/stdlib.rst",
+ # Documentation
+ "docquality.rst": "documentation/help-documenting.rst",
+ "documenting.rst": "documentation/start-documenting.rst",
+ # Translating
+ "documentation/translating.rst": "documentation/translations/translating.rst",
+ "translating.rst": "documentation/translations/translating.rst",
+ "coordinating.rst": "documentation/translations/coordinating.rst",
+ # Getting Started
+ "fixingissues.rst": "getting-started/fixing-issues.rst",
+ "help.rst": "getting-started/getting-help.rst",
+ "gitbootcamp.rst": "getting-started/git-boot-camp.rst",
+ "pullrequest.rst": "getting-started/pull-request-lifecycle.rst",
+ "setup.rst": "getting-started/setup-building.rst",
+ # CPython Internals
+ "compiler.rst": "internals/compiler.rst",
+ "exploring.rst": "internals/exploring.rst",
+ "garbage_collector.rst": "internals/garbage-collector.rst",
+ "parser.rst": "internals/parser.rst",
+ # Testing and Buildbots
+ "buildbots.rst": "testing/buildbots.rst",
+ "coverage.rst": "testing/coverage.rst",
+ "buildworker.rst": "testing/new-buildbot-worker.rst",
+ "runtests.rst": "testing/run-write-tests.rst",
+ "silencewarnings.rst": "testing/silence-warnings.rst",
+ # Issues and Triaging
+ "gh-faq.rst": "triage/github-bpo-faq.rst",
+ "tracker.rst": "triage/issue-tracker.rst",
+ "gh-labels.rst": "triage/labels.rst",
+ "triaging.rst": "triage/triaging.rst",
+}
+
+intersphinx_mapping = {
+ 'python': ('https://docs.python.org/3', None),
+ 'diataxis': ('https://diataxis.fr/', None),
+}
+
+todo_include_todos = True
+
+# sphinx-notfound-page
+notfound_urls_prefix = "/"
+
+# Dynamically expose the Python version associated with the "main" branch.
+# Exactly one entry in ``release-cycle.json`` should have ``"branch": "main"``.
+with open("include/release-cycle.json", encoding="UTF-8") as _f:
+ _cycle = json.load(_f)
+
+_main_version = next(
+ version for version, data in _cycle.items() if data.get("branch") == "main"
+)
+
+# prolog and epilogs
+rst_prolog = f"""
+.. |draft| replace::
+ This is part of a **Draft** of the Python Contributor's Guide.
+ Text in square brackets are notes about content to fill in.
+ Currently, the devguide and this new Contributor's Guide co-exist in the
+ repo. We are using Sphinx include directives to demonstrate the re-organization.
+ The final Contributor's Guide will replace the devguide with content in only one
+ place.
+ We welcome help with this!
+
+.. |purpose| replace::
+ The :ref:`contrib-plan` page has more details about the current state of this draft
+ and **how you can help**. See more info about the Contributor Guide in the
+ discussion forum: `Refactoring the DevGuide`_.
+
+.. _Refactoring the DevGuide: https://discuss.python.org/t/refactoring-the-devguide-into-a-contribution-guide/63409
+
+.. |main_version| replace:: {_main_version}
+
+"""
+
+# sphinx.ext.extlinks
+# This config is a dictionary of external sites,
+# mapping unique short aliases to a base URL and a prefix.
+# https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html
+_repo = "https://github.com/python/cpython"
+extlinks = {
+ "cpy-file": (f"{_repo}/blob/main/%s", "%s"),
+ "gh-label": (f"{_repo}/labels/%s", "%s"),
+ "github": ("https://github.com/%s", "%s"),
+ "github-user": ("https://github.com/%s", "@%s"),
+ "pypi": ("https://pypi.org/project/%s/", "%s"),
+ "pypi-org": ("https://pypi.org/org/%s/", "%s"),
+}
+
+# sphinxext-opengraph config
+ogp_site_url = "https://devguide.python.org/"
+ogp_site_name = "Python Developer's Guide"
+ogp_image = "_static/og-image-200x200.png"
+ogp_custom_meta_tags = [
+ '',
+ '',
+ '',
+]
-# Use our custom CSS stylesheet to differentiate us from the official python
-# docs.
-def setup(app):
- app.add_css_file('custom.css')
+# Strip the dollar prompt when copying code
+# https://sphinx-copybutton.readthedocs.io/en/latest/use.html#strip-and-configure-input-prompts-for-code-cells
+copybutton_prompt_text = "$ "
+# https://sphinx-copybutton.readthedocs.io/en/latest/use.html#honor-line-continuation-characters-when-copying-multline-snippets
+copybutton_line_continuation_character = "\\"
diff --git a/contrib/code/developer-workflow.rst b/contrib/code/developer-workflow.rst
new file mode 100644
index 000000000..416ca2c02
--- /dev/null
+++ b/contrib/code/developer-workflow.rst
@@ -0,0 +1,25 @@
+====================
+Development workflow
+====================
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+[This is the existing :ref:`dev-workflow` page from the devguide]
+
+.. toctree::
+ :maxdepth: 5
+
+ ../../developer-workflow/communication-channels
+ ../../developer-workflow/development-cycle
+ ../../developer-workflow/stdlib
+ ../../developer-workflow/extension-modules
+ ../../developer-workflow/c-api
+ ../../developer-workflow/lang-changes
+ ../../developer-workflow/grammar
+ ../../developer-workflow/porting
+ ../../developer-workflow/sbom
+ ../../developer-workflow/psrt
diff --git a/contrib/code/development-tools.rst b/contrib/code/development-tools.rst
new file mode 100644
index 000000000..348ceb95a
--- /dev/null
+++ b/contrib/code/development-tools.rst
@@ -0,0 +1,19 @@
+=================
+Development tools
+=================
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+[This is the existing :ref:`development-tools` page from the devguide.]
+
+.. toctree::
+ :maxdepth: 5
+
+ ../../development-tools/clinic
+ ../../development-tools/gdb
+ ../../development-tools/clang
+ ../../development-tools/warnings
diff --git a/contrib/code/git.rst b/contrib/code/git.rst
new file mode 100644
index 000000000..7c7aaa57b
--- /dev/null
+++ b/contrib/code/git.rst
@@ -0,0 +1,11 @@
+========
+Git tips
+========
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+[More git help for advanced things needed by code contributors.]
diff --git a/contrib/code/index.rst b/contrib/code/index.rst
new file mode 100644
index 000000000..768095066
--- /dev/null
+++ b/contrib/code/index.rst
@@ -0,0 +1,30 @@
+.. _c_code:
+
+==================
+Code contributions
+==================
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+[The main page for code contributors.]
+
+[We'll include code-focused content from the :ref:`main devguide page `: Quick
+reference, Quick links, Proposing changes, and so on.]
+
+[The existing :ref:`internals` section of the devguide will be fully
+migrated into the Python repo.]
+
+
+.. toctree::
+ :maxdepth: 5
+
+ setup
+ git
+ pull-request-lifecycle
+ developer-workflow
+ testing
+ development-tools
diff --git a/contrib/code/pull-request-lifecycle.rst b/contrib/code/pull-request-lifecycle.rst
new file mode 100644
index 000000000..30c0fd590
--- /dev/null
+++ b/contrib/code/pull-request-lifecycle.rst
@@ -0,0 +1,21 @@
+.. _code-pull-request-lifecycle:
+
+======================
+Pull request lifecycle
+======================
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+[Details of pull requests for code contributions. The existing
+:ref:`pull-request-lifecycle` page is long and includes many details.
+Some only apply to code contributions, but many are common to all
+contributions. Should we keep a common page, with extra steps here, or
+should this page have all of the details even if they are duplicated
+elsewhere?]
+
+[See :ref:`docs-pull-request-lifecycle` for the documentation half of this conundrum.]
diff --git a/contrib/code/setup.rst b/contrib/code/setup.rst
new file mode 100644
index 000000000..2d14bb0d9
--- /dev/null
+++ b/contrib/code/setup.rst
@@ -0,0 +1,12 @@
+==================
+Setup and building
+==================
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+[More setup and build instructions specifically for code contributors, building
+on the basics from the :ref:`Getting Started ` section.]
diff --git a/contrib/code/testing.rst b/contrib/code/testing.rst
new file mode 100644
index 000000000..575d1477a
--- /dev/null
+++ b/contrib/code/testing.rst
@@ -0,0 +1,20 @@
+=====================
+Testing and buildbots
+=====================
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+[This is the existing :ref:`testing` page from the devguide.]
+
+.. toctree::
+ :maxdepth: 5
+
+ ../../testing/run-write-tests
+ ../../testing/silence-warnings
+ ../../testing/coverage
+ ../../testing/buildbots
+ ../../testing/new-buildbot-worker
diff --git a/contrib/contrib-plan.rst b/contrib/contrib-plan.rst
new file mode 100644
index 000000000..65e386e2b
--- /dev/null
+++ b/contrib/contrib-plan.rst
@@ -0,0 +1,47 @@
+.. _contrib-plan:
+
+==================================
+[Plan for the Contributor's Guide]
+==================================
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+We are in the process of updating and refactoring the devguide to be a
+Contributor's Guide. It will highlight the different kinds of contribution
+possible, and how to succeed at each kind.
+
+Currently, the Contibutor's Guide is a draft in this new last section of the
+devguide. We welcome feedback, but please understand that some of the current
+content is moving or skeletal.
+
+Repo structure
+==============
+
+While the reorganization is happening, we are keeping the old devguide as it
+is. The new Contributor's Guide is represented in this last section, but will
+eventually be the only content in the guide. To avoid copying content, we're
+using Sphinx include directives to display existing devguide content in its new
+Contributor's Guide location. That is not how the eventual Guide will be
+built. Once we are ready to make the Contributor's Guide real, we will
+rearrange content into its new location.
+
+How to help
+===========
+
+To help, you can:
+
+- `Write an issue`_ detailing a change you'd like to see here.
+- `Make a pull request`_ in this repo to add content.
+- Join us in the `Python Docs Discord`_ to collaborate with other docs-minded
+ community members.
+- Get in touch with the `Docs Editorial Board`_ to discuss larger documentation
+ concerns.
+
+.. _Write an issue: https://github.com/python/devguide/issues
+.. _Make a pull request: https://github.com/python/devguide/pulls
+.. _Python Docs Discord: https://discord.gg/qcfPbnM2zH
+.. _Docs Editorial Board: https://python.github.io/editorial-board/
diff --git a/contrib/core-team/committing.rst b/contrib/core-team/committing.rst
new file mode 100644
index 000000000..5b639cd5a
--- /dev/null
+++ b/contrib/core-team/committing.rst
@@ -0,0 +1,11 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+[This is the existing core developers :ref:`committing` page from the devguide. We'll
+adjust "core developer" to "core team" where appropriate.]
+
+.. include:: ../../core-team/committing.rst
diff --git a/contrib/core-team/experts.rst b/contrib/core-team/experts.rst
new file mode 100644
index 000000000..aa16f10bd
--- /dev/null
+++ b/contrib/core-team/experts.rst
@@ -0,0 +1,10 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+[This is the existing core team :ref:`experts` page from the devguide.]
+
+.. include:: ../../core-team/experts.rst
diff --git a/contrib/core-team/index.rst b/contrib/core-team/index.rst
new file mode 100644
index 000000000..2ca21344b
--- /dev/null
+++ b/contrib/core-team/index.rst
@@ -0,0 +1,24 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+.. _c_core-team:
+
+=========
+Core team
+=========
+
+[This is mostly re-organized from the :ref:`core-team` section of the devguide]
+
+.. toctree::
+ :maxdepth: 5
+
+ responsibilities
+ committing
+ experts
+ team-log
+ motivations
+ join-team
diff --git a/contrib/core-team/join-team.rst b/contrib/core-team/join-team.rst
new file mode 100644
index 000000000..932216f7c
--- /dev/null
+++ b/contrib/core-team/join-team.rst
@@ -0,0 +1,10 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+[This is the existing core team :ref:`join-core-team` page from the devguide.]
+
+.. include:: ../../core-team/join-team.rst
diff --git a/contrib/core-team/motivations.rst b/contrib/core-team/motivations.rst
new file mode 100644
index 000000000..38ba31023
--- /dev/null
+++ b/contrib/core-team/motivations.rst
@@ -0,0 +1,10 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+[This is the existing core team :ref:`motivations` page from the devguide.]
+
+.. include:: ../../core-team/motivations.rst
diff --git a/contrib/core-team/responsibilities.rst b/contrib/core-team/responsibilities.rst
new file mode 100644
index 000000000..d6902bd78
--- /dev/null
+++ b/contrib/core-team/responsibilities.rst
@@ -0,0 +1,10 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+[This is the existing core team :ref:`responsibilities` page from the devguide.]
+
+.. include:: ../../core-team/responsibilities.rst
diff --git a/contrib/core-team/team-log.rst b/contrib/core-team/team-log.rst
new file mode 100644
index 000000000..ecfe856a4
--- /dev/null
+++ b/contrib/core-team/team-log.rst
@@ -0,0 +1,10 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+[This is the existing core team :ref:`team-log` page from the devguide.]
+
+.. include:: ../../core-team/team-log.rst
diff --git a/contrib/doc/devguide.rst b/contrib/doc/devguide.rst
new file mode 100644
index 000000000..2c83e5200
--- /dev/null
+++ b/contrib/doc/devguide.rst
@@ -0,0 +1,12 @@
+==================================
+Helping with the Developer's Guide
+==================================
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+[This is the existing :ref:`devguide` page from the devguide.]
diff --git a/contrib/doc/help-documenting.rst b/contrib/doc/help-documenting.rst
new file mode 100644
index 000000000..befb4b246
--- /dev/null
+++ b/contrib/doc/help-documenting.rst
@@ -0,0 +1,12 @@
+==========================
+Helping with documentation
+==========================
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+[This is the existing :ref:`help-documenting` page from the devguide.]
diff --git a/contrib/doc/index.rst b/contrib/doc/index.rst
new file mode 100644
index 000000000..dc8ec9307
--- /dev/null
+++ b/contrib/doc/index.rst
@@ -0,0 +1,29 @@
+.. _c_docs:
+
+===========================
+Documentation contributions
+===========================
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+[The main page for documentation contributors.]
+
+[We'll include docs-focused content from the :ref:`main devguide page `: Quick
+reference, Quick links, and so on.]
+
+
+.. toctree::
+ :maxdepth: 5
+
+ start-documenting
+ help-documenting
+ style-guide
+ markup
+ pull-request-lifecycle
+ translating
+ devguide
diff --git a/contrib/doc/markup.rst b/contrib/doc/markup.rst
new file mode 100644
index 000000000..96b9faad5
--- /dev/null
+++ b/contrib/doc/markup.rst
@@ -0,0 +1,12 @@
+=======================
+reStructuredText markup
+=======================
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+[This is the existing :ref:`markup` page from the devguide.]
diff --git a/contrib/doc/pull-request-lifecycle.rst b/contrib/doc/pull-request-lifecycle.rst
new file mode 100644
index 000000000..a62e63728
--- /dev/null
+++ b/contrib/doc/pull-request-lifecycle.rst
@@ -0,0 +1,21 @@
+.. _docs-pull-request-lifecycle:
+
+======================
+Pull request lifecycle
+======================
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+[Details of pull requests for documentation contributions. The existing
+:ref:`pull-request-lifecycle` page is long and includes many details.
+Some only apply to code contributions, but many are common to all
+contributions. Should we keep a common page, with documentation tweaks here, or
+should this page have only the documentation details even if they are duplicated
+elsewhere?]
+
+[See :ref:`code-pull-request-lifecycle` for the code half of this conundrum.]
diff --git a/contrib/doc/start-documenting.rst b/contrib/doc/start-documenting.rst
new file mode 100644
index 000000000..c5cf96161
--- /dev/null
+++ b/contrib/doc/start-documenting.rst
@@ -0,0 +1,12 @@
+===============
+Getting started
+===============
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+[This is the existing documentation :ref:`start-documenting` page from the devguide.]
diff --git a/contrib/doc/style-guide.rst b/contrib/doc/style-guide.rst
new file mode 100644
index 000000000..87762f3e0
--- /dev/null
+++ b/contrib/doc/style-guide.rst
@@ -0,0 +1,12 @@
+===========
+Style guide
+===========
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+[This is the existing documentation :ref:`style-guide` page from the devguide.]
diff --git a/contrib/doc/translating.rst b/contrib/doc/translating.rst
new file mode 100644
index 000000000..baface2f0
--- /dev/null
+++ b/contrib/doc/translating.rst
@@ -0,0 +1,12 @@
+===========
+Translating
+===========
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+[This is the existing :ref:`translating` page from the devguide.]
diff --git a/contrib/index.rst b/contrib/index.rst
new file mode 100644
index 000000000..0b5a3edc6
--- /dev/null
+++ b/contrib/index.rst
@@ -0,0 +1,119 @@
+.. _c_root:
+
+==================================
+Python Contributor's Guide (draft)
+==================================
+
+.. raw:: html
+
+
+
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+[Open question: how to divide content between this Introduction and the
+:ref:`introduction `?]
+
+This guide is a comprehensive resource for :ref:`contributing `
+to Python_ -- for both new and experienced contributors. It is :ref:`maintained
+` by the same community that maintains Python. We welcome your
+contributions to Python!
+
+We encourage everyone to contribute to Python. This guide should have
+everything you need to get started and be productive. If you still have
+questions after reviewing the material in this guide, the `Core Python
+Mentorship`_ group is available to help you through the process.
+
+There are a number of ways to contribute including code, documentation, and
+triaging issues. We've organized this guide to provide specifics based on the
+type of activity you'll be engaged in.
+
+
+Using this guide
+================
+
+We recommend reading this guide as needed. You can stop where you feel
+comfortable and begin contributing immediately without reading and
+understanding everything. If you do choose to skip around this guide, be aware
+that it is written assuming preceding sections have been read so you may need
+to backtrack to fill in missing concepts and terminology.
+
+No matter what kind of contribution you'll be making, you should start with
+these common sections:
+
+* :ref:`c_intro`
+* :ref:`c_project`
+
+Then choose a path based on your type of activity:
+
+*[The original table on the devguide home had a fourth column for Core
+Developers. That made the table wider and more confusing. I don't think core
+team members need a quick intro path since they will have been through the
+devguide before.]*
+
+*[I haven't adjusted the links in the table yet other than to add a link to the
+major section at the top of each column.]*
+
+.. list-table::
+ :widths: 10 10 10
+ :header-rows: 1
+
+ * - :ref:`Documentation `
+ - :ref:`Code `
+ - :ref:`Triaging `
+ * -
+ * :ref:`docquality`
+ * :ref:`documenting`
+ * :ref:`style-guide`
+ * :ref:`rst-primer`
+ * :doc:`documentation/translations`
+ * :ref:`devguide`
+ -
+ * :ref:`setup`
+ * :ref:`help`
+ * :ref:`pullrequest`
+ * :ref:`runtests`
+ * :ref:`fixingissues`
+ * :ref:`communication`
+ * :ref:`gitbootcamp`
+ * :ref:`devcycle`
+ -
+ * :ref:`tracker`
+ * :ref:`triaging`
+ * :ref:`helptriage`
+ * :ref:`experts`
+ * :ref:`labels`
+ * :ref:`gh-faq`
+ * :ref:`triage-team`
+
+Core team members will find guidance in the :ref:`c_core-team` section.
+
+Contents
+========
+
+.. toctree::
+ :maxdepth: 3
+
+ contrib-plan
+ intro/index
+ project/index
+ triage/index
+ doc/index
+ code/index
+ core-team/index
+ user-success
+ security
+ workflows/index
+
+
+.. _Python: https://www.python.org/
+.. _Core Python Mentorship: https://www.python.org/dev/core-mentorship/
diff --git a/contrib/intro/index.rst b/contrib/intro/index.rst
new file mode 100644
index 000000000..c5ba303df
--- /dev/null
+++ b/contrib/intro/index.rst
@@ -0,0 +1,53 @@
+.. _c_intro:
+
+============
+Introduction
+============
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+
+[Open question: how to divide content between this Introduction and the
+:ref:`home page `?]
+
+Welcome!
+
+New to open source?
+===================
+
+Python is an open source project, with culture and techniques from the broader
+open source world. You might find it helpful to read about open source in
+general. A number of individuals from the Python community have contributed to
+a series of excellent guides at `Open Source Guides
+`_.
+
+Anyone will find the following guides useful:
+
+* `How to Contribute to Open Source `_
+* `Building Welcoming Communities `_
+
+
+Healthy collaboration
+=====================
+
+[Importance of healthy inclusive collaboration]
+
+[While code is a large part of the project's success, project management, documentation, governance, sprint outreach, etc. matter.]
+
+[We respect the individual skills people bring to the project and strive to create and maintain a culture of inclusion.]
+
+About this guide
+================
+
+Types of contribution
+=====================
+
+[Pathways for contributors]
+
+Helping with this guide
+=======================
diff --git a/contrib/project/channels.rst b/contrib/project/channels.rst
new file mode 100644
index 000000000..711dbe587
--- /dev/null
+++ b/contrib/project/channels.rst
@@ -0,0 +1,16 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+======================
+Communication channels
+======================
+
+* Repos
+* Discourse
+* Discord
+* Mailing lists (deprioritize)
+* Where to get help
diff --git a/contrib/project/conduct.rst b/contrib/project/conduct.rst
new file mode 100644
index 000000000..37fe3bbfa
--- /dev/null
+++ b/contrib/project/conduct.rst
@@ -0,0 +1,16 @@
+===============
+Code of Conduct
+===============
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+[Brief summary of the code of conduct, with links to official source.]
+
+* Standard for communication
+* How to report
+* Enforcement details
diff --git a/contrib/project/directory-structure.rst b/contrib/project/directory-structure.rst
new file mode 100644
index 000000000..0cebb25f7
--- /dev/null
+++ b/contrib/project/directory-structure.rst
@@ -0,0 +1,17 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+.. _c_directory_structure:
+
+===================
+Directory structure
+===================
+
+[This is the :ref:`build_directory_structure` section from the devguide.]
+
+.. include:: ../../getting-started/setup-building.rst
+ :start-after: c_directory_structure_start
+ :end-before: c_directory_structure_end
diff --git a/contrib/project/generative-ai.rst b/contrib/project/generative-ai.rst
new file mode 100644
index 000000000..6cb5b62ff
--- /dev/null
+++ b/contrib/project/generative-ai.rst
@@ -0,0 +1,10 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+[This is the existing :ref:`generative-ai` page from the devguide.]
+
+.. include:: ../../getting-started/generative-ai.rst
diff --git a/contrib/project/github.rst b/contrib/project/github.rst
new file mode 100644
index 000000000..fe45c6b8b
--- /dev/null
+++ b/contrib/project/github.rst
@@ -0,0 +1,15 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+======
+GitHub
+======
+
+[Where are the actual artifacts?]
+
+* Main CPython repos
+* Core workflow repos
+* Infrastructure repos
diff --git a/contrib/project/governance.rst b/contrib/project/governance.rst
new file mode 100644
index 000000000..a4bc66ff1
--- /dev/null
+++ b/contrib/project/governance.rst
@@ -0,0 +1,25 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+==========
+Governance
+==========
+
+[How decisions are made, who is involved, how to participate.]
+
+Steering Council
+================
+
+Documentation Editorial Board
+=============================
+
+Typing Council
+==============
+
+
+Others?
+=======
diff --git a/contrib/project/index.rst b/contrib/project/index.rst
new file mode 100644
index 000000000..9d3c89b9a
--- /dev/null
+++ b/contrib/project/index.rst
@@ -0,0 +1,29 @@
+.. _c_project:
+
+===================
+The CPython project
+===================
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+[Give the reader an understanding of the project as a whole. What are the
+moving parts, who is involved, how do they interact?]
+
+* Structure
+
+.. toctree::
+ :maxdepth: 5
+
+ conduct
+ roles
+ governance
+ generative-ai.rst
+ github
+ directory-structure.rst
+ channels
+ outreach
diff --git a/contrib/project/outreach.rst b/contrib/project/outreach.rst
new file mode 100644
index 000000000..d43aa8e9d
--- /dev/null
+++ b/contrib/project/outreach.rst
@@ -0,0 +1,12 @@
+========
+Outreach
+========
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+* Sprints
diff --git a/contrib/project/roles.rst b/contrib/project/roles.rst
new file mode 100644
index 000000000..8336fe465
--- /dev/null
+++ b/contrib/project/roles.rst
@@ -0,0 +1,17 @@
+=====
+Roles
+=====
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+[Quick overview of the roles people play. Core team has its own section.]
+
+* Core team
+* Triager
+* Contributors
+ * types of contributions
diff --git a/contrib/security.rst b/contrib/security.rst
new file mode 100644
index 000000000..db40b4a16
--- /dev/null
+++ b/contrib/security.rst
@@ -0,0 +1,13 @@
+=========================================
+Security and infrastructure contributions
+=========================================
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+* Security
+* Infrastructure
+* Core workflow
diff --git a/contrib/triage/index.rst b/contrib/triage/index.rst
new file mode 100644
index 000000000..0a547d9d7
--- /dev/null
+++ b/contrib/triage/index.rst
@@ -0,0 +1,14 @@
+.. _c_triage:
+
+===================
+Issues and triaging
+===================
+
+.. toctree::
+ :maxdepth: 5
+
+ issue-tracker
+ triaging
+ labels
+ reviewing
+ triage-team
diff --git a/contrib/triage/issue-tracker.rst b/contrib/triage/issue-tracker.rst
new file mode 100644
index 000000000..a5777bc81
--- /dev/null
+++ b/contrib/triage/issue-tracker.rst
@@ -0,0 +1,9 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+[This is the existing :ref:`issue-tracker` page from the devguide]
+
+.. include:: ../../triage/issue-tracker.rst
diff --git a/contrib/triage/labels.rst b/contrib/triage/labels.rst
new file mode 100644
index 000000000..c36481733
--- /dev/null
+++ b/contrib/triage/labels.rst
@@ -0,0 +1,9 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+[This is the existing :ref:`labels` page from the devguide]
+
+.. include:: ../../triage/labels.rst
diff --git a/contrib/triage/reviewing.rst b/contrib/triage/reviewing.rst
new file mode 100644
index 000000000..060f6b78d
--- /dev/null
+++ b/contrib/triage/reviewing.rst
@@ -0,0 +1,13 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+=========
+Reviewing
+=========
+
+* How? Etiquette?
+* How to request a review?
diff --git a/contrib/triage/triage-team.rst b/contrib/triage/triage-team.rst
new file mode 100644
index 000000000..a9b59056a
--- /dev/null
+++ b/contrib/triage/triage-team.rst
@@ -0,0 +1,9 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+[This is the existing :ref:`triage-team` page from the devguide]
+
+.. include:: ../../triage/triage-team.rst
diff --git a/contrib/triage/triaging.rst b/contrib/triage/triaging.rst
new file mode 100644
index 000000000..22e1ccc65
--- /dev/null
+++ b/contrib/triage/triaging.rst
@@ -0,0 +1,9 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+[This is the existing :ref:`triaging` page from the devguide]
+
+.. include:: ../../triage/triaging.rst
diff --git a/contrib/user-success.rst b/contrib/user-success.rst
new file mode 100644
index 000000000..2a9ef5d4e
--- /dev/null
+++ b/contrib/user-success.rst
@@ -0,0 +1,14 @@
+=======================================
+Accessibility, design, and user success
+=======================================
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+* Accessibility
+* Design
+* User success
diff --git a/contrib/workflows/codespaces.rst b/contrib/workflows/codespaces.rst
new file mode 100644
index 000000000..eb97ef7c2
--- /dev/null
+++ b/contrib/workflows/codespaces.rst
@@ -0,0 +1,17 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+.. _c_using_codespaces:
+
+=======================
+Using GitHub Codespaces
+=======================
+
+[This is the :ref:`using-codespaces` section from the devguide.]
+
+.. include:: ../../getting-started/setup-building.rst
+ :start-after: c_codespaces_start
+ :end-before: c_codespaces_end
diff --git a/contrib/workflows/compile.rst b/contrib/workflows/compile.rst
new file mode 100644
index 000000000..18157b717
--- /dev/null
+++ b/contrib/workflows/compile.rst
@@ -0,0 +1,22 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+.. _c_compiling:
+
+=================
+Compile and build
+=================
+
+.. note::
+ [This is the :ref:`compiling` section from the devguide. I think this page
+ is too long and could be split by build target, but we can leave that for a
+ later time.]
+
+.. include:: ../../getting-started/setup-building.rst
+ :start-after: c_compile_and_build_start
+ :end-before: c_compile_and_build_end
+
+.. include:: ../../links.rst
diff --git a/contrib/workflows/get-source.rst b/contrib/workflows/get-source.rst
new file mode 100644
index 000000000..ed56fe4e1
--- /dev/null
+++ b/contrib/workflows/get-source.rst
@@ -0,0 +1,19 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+.. _c_checkout:
+
+===================
+Get the source code
+===================
+
+.. note::
+ [This is the :ref:`checkout` section from the devguide. We might need to edit
+ it to clarify that some steps are only needed for code contribution.]
+
+.. include:: ../../getting-started/setup-building.rst
+ :start-after: c_get_source_code_start
+ :end-before: c_get_source_code_end
diff --git a/contrib/workflows/index.rst b/contrib/workflows/index.rst
new file mode 100644
index 000000000..2c6ccf2bc
--- /dev/null
+++ b/contrib/workflows/index.rst
@@ -0,0 +1,25 @@
+.. _c_workflows:
+
+=========
+Workflows
+=========
+
+.. important::
+
+ |draft|
+
+ |purpose|
+
+
+This section contains details of workflows needed for all kinds of
+contribution.
+
+.. toctree::
+
+ install-git.rst
+ get-source.rst
+ install-dependencies.rst
+ compile.rst
+ regenerate.rst
+ troubleshooting.rst
+ codespaces.rst
diff --git a/contrib/workflows/install-dependencies.rst b/contrib/workflows/install-dependencies.rst
new file mode 100644
index 000000000..9a511c6da
--- /dev/null
+++ b/contrib/workflows/install-dependencies.rst
@@ -0,0 +1,17 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+.. _c_build-dependencies:
+
+====================
+Install Dependencies
+====================
+
+[This is the :ref:`build-dependencies` section from the devguide.]
+
+.. include:: ../../getting-started/setup-building.rst
+ :start-after: c_install_dependencies_start
+ :end-before: c_install_dependencies_end
diff --git a/contrib/workflows/install-git.rst b/contrib/workflows/install-git.rst
new file mode 100644
index 000000000..e3d738b2a
--- /dev/null
+++ b/contrib/workflows/install-git.rst
@@ -0,0 +1,17 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+.. _c_vcsetup:
+
+===========
+Install Git
+===========
+
+[This is the :ref:`vcsetup` section from the devguide.]
+
+.. include:: ../../getting-started/setup-building.rst
+ :start-after: c_install_git_start
+ :end-before: c_install_git_end
diff --git a/contrib/workflows/regenerate.rst b/contrib/workflows/regenerate.rst
new file mode 100644
index 000000000..b5bca7dca
--- /dev/null
+++ b/contrib/workflows/regenerate.rst
@@ -0,0 +1,28 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+.. _c_regenerating:
+
+===============================
+Regenerating auto-created files
+===============================
+
+.. note::
+ [These are two similar sections from the is the :ref:`setup-building` section from the devguide.]
+
+Regenerate ``configure``
+========================
+
+.. include:: ../../getting-started/setup-building.rst
+ :start-after: c_regenerate_configure_start
+ :end-before: c_regenerate_configure_end
+
+Regenerate the ABI dump
+=======================
+
+.. include:: ../../getting-started/setup-building.rst
+ :start-after: c_regenerate_abi_start
+ :end-before: c_regenerate_abi_end
diff --git a/contrib/workflows/troubleshooting.rst b/contrib/workflows/troubleshooting.rst
new file mode 100644
index 000000000..68aa80158
--- /dev/null
+++ b/contrib/workflows/troubleshooting.rst
@@ -0,0 +1,17 @@
+.. important::
+
+ |draft|
+
+ |purpose|
+
+.. _c_build_troubleshooting:
+
+===========
+Install Git
+===========
+
+[This is the :ref:`build_troubleshooting` section from the devguide.]
+
+.. include:: ../../getting-started/setup-building.rst
+ :start-after: c_build_troubleshooting_start
+ :end-before: c_build_troubleshooting_end
diff --git a/committing.rst b/core-team/committing.rst
similarity index 59%
rename from committing.rst
rename to core-team/committing.rst
index 213a2292e..41cf67254 100644
--- a/committing.rst
+++ b/core-team/committing.rst
@@ -1,11 +1,11 @@
.. _committing:
-Accepting Pull Requests
+Accepting pull requests
=======================
.. highlight:: none
-This page is a step-by-step guide for core developers who need to assess,
+This page is a step-by-step guide for the core team to assess,
merge, and possibly backport a pull request on the main repository.
Assessing a pull request
@@ -14,38 +14,39 @@ Assessing a pull request
Before you can accept a pull request, you need to make sure that it is ready
to enter the public source tree. Ask yourself the following questions:
-* **Are there ongoing discussions at** ``bugs.python.org`` **(b.p.o.)?**
- Read the linked b.p.o. issue. If there are ongoing discussions, then
+* **Are there ongoing discussions at the issue tracker?**
+ Read the linked issue. If there are ongoing discussions, then
we need to have a resolution there before we can merge the pull request.
-* **Was the pull request first made against the appropriate branch?**
+* **Was the pull request first made against the appropriate branch?**
The only branch that receives new features is ``main``, the
in-development branch. Pull requests should only target bug-fix branches
if an issue appears in only that version and possibly older versions.
-* **Are the changes acceptable?**
- If you want to share your work-in-progress code on a feature or bugfix,
- then you can open a ``WIP``-prefixed pull request, publish patches on
- the `issue tracker `_, or create a public
- fork of the repository.
+* **Are the changes acceptable?**
+ If you want to share your work-in-progress code on a feature or bugfix,
+ then you can open a ``WIP``-prefixed pull request, publish patches on
+ the `issue tracker`_, or create a public fork of the repository.
-* **Do the checks on the pull request show that the test suite passes?**
+* **Do the checks on the pull request show that the test suite passes?**
Make sure that all of the status checks are passing.
-* **Is the patch in a good state?**
- Check :ref:`patch` and :ref:`helptriage` to review what is expected of
- a patch.
+* **Is the pull request in a good state?**
+ Check :ref:`pull-request-lifecycle` and :ref:`helptriage` to review what
+ is expected of a pull request.
+
+* **Does the change break backwards-compatibility without a strong reason?**
+ :ref:`Run the entire test suite ` to make sure that everything
+ still passes. If there is a change to the semantics, then there needs to
+ be a strong reason, because it will cause some peoples' code to break.
+ If you are unsure if the breakage is worth it, then ask
+ on the `Core Development Discourse category
+ `__.
-* **Does the patch break backwards-compatibility without a strong reason?**
- :ref:`Run the entire test suite ` to make sure that everything
- still passes. If there is a change to the semantics, then there needs to
- be a strong reason, because it will cause some peoples' code to break.
- If you are unsure if the breakage is worth it, then ask on python-dev.
-
* **Does documentation need to be updated?**
- If the pull request introduces backwards-incompatible changes (e.g.
- deprecating or removing a feature), then make sure that those changes
- are reflected in the documentation before you merge the pull request.
+ If the pull request introduces backwards-incompatible changes (for example,
+ deprecating or removing a feature), then make sure that those changes
+ are reflected in the documentation before you merge the pull request.
* **Were appropriate labels added to signify necessary backporting of the pull request?**
If it is determined that a pull request needs to be
@@ -53,99 +54,124 @@ to enter the public source tree. Ask yourself the following questions:
developer can apply the label ``needs backport to X.Y`` to the pull
request. Once the backport pull request has been created, remove the
``needs backport to X.Y`` label from the original pull request. (Only
- core developers and members of the `Python Triage Team`_ can apply
- labels to GitHub pull requests).
+ the core team and members of the :ref:`Python Triage Team `
+ can apply labels to GitHub pull requests).
-* **Does the pull request have a label indicating that the submitter has signed the CLA?**
+* **Does the pull request pass a check indicating that the submitter has signed the CLA?**
Make sure that the contributor has signed a `Contributor
- Licensing Agreement `_
- (CLA), unless their change has no possible intellectual property
- associated with it (e.g. fixing a spelling mistake in documentation).
- To check if a contributor’s CLA has been received, go
- to `Check Python CLA `_ and
- put in their GitHub username. For further questions about the CLA
+ Licensing Agreement `_
+ (CLA), unless their change has no possible intellectual property
+ associated with it (for example, fixing a spelling mistake in documentation).
+ The `Python Software Foundation Contributor License Agreement Management Bot
+ `_
+ checks whether the author has signed the CLA, and replies in the PR
+ if they haven't. For further questions about the CLA
process, write to contributors@python.org.
-* **Were** ``What's New in Python`` **and** ``Misc/NEWS.d/next`` **updated?**
- If the change is particularly interesting for end users (e.g. new features,
- significant improvements, or backwards-incompatible changes), then an
- entry in the ``What's New in Python`` document (in ``Doc/whatsnew/``) should
- be added as well. Changes that affect only documentation generally do not
+* **Were** ``What's New in Python`` **and** ``Misc/NEWS.d/next`` **updated?**
+ If the change is particularly interesting for end users (for example, new features,
+ significant improvements, or backwards-incompatible changes), then an
+ entry in the ``What's New in Python`` document (in ``Doc/whatsnew/``) should
+ be added as well. Changes that affect only documentation generally do not
require a ``NEWS`` entry. (See the following section for more information.)
+.. _news-entry:
+.. _what-s-new-and-news-entries:
Updating NEWS and What's New in Python
--------------------------------------
-Almost all changes made to the code base deserve an entry in ``Misc/NEWS.d``.
-If the change is particularly interesting for end users (e.g. new features,
-significant improvements, or backwards-incompatible changes), then an entry in
-the ``What's New in Python`` document (in ``Doc/whatsnew/``) should be added
-as well. Changes that affect documentation only generally do not require
-a ``NEWS`` entry.
+Changes that require NEWS entries
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-There are two notable exceptions to this general principle, and they
-both relate to changes that:
+Most changes made to the codebase deserve an entry in :cpy-file:`Misc/NEWS.d`,
+except for the following:
-* Already have a ``NEWS`` entry
-* Have not yet been included in any formal release (including alpha
- and beta releases)
+* documentation changes
+* test changes
+* strictly internal changes with no user-visible effects
+* changes that already have a ``NEWS`` entry
+* reverts that have not yet been included in any formal release
+ (including alpha and beta releases)
-These are the two exceptions:
+For the last two, note the following:
#. **If a change is reverted prior to release**, then the corresponding
entry is simply removed. Otherwise, a new entry must be added noting
- that the change has been reverted (e.g. when a feature is released in
+ that the change has been reverted (for example, when a feature is released in
an alpha and then cut prior to the first beta).
#. **If a change is a fix (or other adjustment) to an earlier unreleased
change and the original** ``NEWS`` **entry remains valid**, then no additional
entry is needed.
-If a change needs an entry in ``What's New in Python``, then it very
-likely not suitable for including in a maintenance release.
+Changes that require "What's New in Python" entries
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If a change is particularly interesting for end users (for example, new features,
+significant improvements, or backwards-incompatible changes), add an entry in
+the "What's New in Python" document (in :cpy-file:`Doc/whatsnew/`)
+in addition to the ``NEWS`` entry.
+
+In most cases, it is sufficient to reuse the wording from the ``NEWS`` entry
+in the "What's New in Python" entry.
+
+.. note::
+
+ A change that needs an entry in "What's New in Python",
+ is very likely not suitable for inclusion in a maintenance release.
+
+How to add a NEWS entry
+^^^^^^^^^^^^^^^^^^^^^^^
``NEWS`` entries go into the ``Misc/NEWS.d`` directory as individual files. The
``NEWS`` entry can be created by using `blurb-it `_,
-or the `blurb `_ tool and its ``blurb add``
-command.
+or the :pypi:`blurb` tool and its ``blurb add`` command.
If you are unable to use the tool, then you can create the ``NEWS`` entry file
manually. The ``Misc/NEWS.d`` directory contains a sub-directory named
``next``, which contains various sub-directories representing classifications
-for what was affected (e.g. ``Misc/NEWS.d/next/Library`` for changes relating
+for what was affected (for example, ``Misc/NEWS.d/next/Library`` for changes relating
to the standard library). The file name itself should be in the format
-``.bpo-..rst``:
+``.gh-issue-..rst``:
-* ```` is today's date joined with a hyphen (``-``) to the current
- time, in the ``YYYY-MM-DD-hh-mm-ss`` format (e.g. ``2017-05-27-16-46-23``).
-* ```` is the issue number the change is for (e.g. ``12345``
- for ``bpo-12345``).
+* ```` is today's date joined with a hyphen (``-``) to your current
+ local time, in the ``YYYY-MM-DD-hh-mm-ss`` format (for example, ``2017-05-27-16-46-23``).
+* ```` is the issue number the change is for (for example, ``12345``
+ for ``gh-issue-12345``).
* ```` is a unique string to guarantee that the file name is
- unique across branches (e.g. ``Yl4gI2``). It is typically six characters
+ unique across branches (for example, ``Yl4gI2``). It is typically six characters
long, but it can be any length of letters and numbers. Its uniqueness
can be satisfied by typing random characters on your keyboard.
As a result, a file name can look something like
-``Misc/NEWS.d/next/Library/2017-05-27-16-46-23.bpo-12345.Yl4gI2.rst``.
+``Misc/NEWS.d/next/Library/2017-05-27-16-46-23.gh-issue-12345.Yl4gI2.rst``.
+
+How to write a NEWS entry
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+All ``NEWS`` entries end up being part of the changelog.
+The changelog contains *a lot* of entries,
+and its intended audience is mainly users, not the core team and contributors.
+Take this into consideration when wording your ``NEWS`` entry.
+Describe the user-visible effects of your change succinctly and accurately;
+avoid long technical elaborations, digressions, and do not expect or require
+the reader to have read the actual diff for the change.
The contents of a ``NEWS`` file should be valid reStructuredText. An 80 character
column width should be used. There is no indentation or leading marker in the
-file (e.g. ``-``). There is also no need to start the entry with the issue
+file (for example, ``-``). There is also no need to start the entry with the issue
number since it is part of the file name. You can use
:ref:`inline markups ` too. Here is an example of a ``NEWS``
entry::
Fix warning message when :func:`os.chdir` fails inside
- :func:`test.support.temp_cwd`. Patch by Chris Jerdonek.
+ :func:`test.support.temp_cwd`. Contributed by Chris Jerdonek.
The inline Sphinx roles like ``:func:`` can be used help readers
find more information. You can build HTML and verify that the
link target is appropriate by using :ref:`make html `.
-While Sphinx roles can be beneficial to readers, they are not required.
-Inline ````code blocks```` can be used instead.
-
Working with Git_
-----------------
@@ -153,16 +179,16 @@ Working with Git_
.. seealso::
:ref:`gitbootcamp`
-As a core developer, you have the ability to push changes to the official
+As a core team member, you have the ability to push changes to the official
Python repositories, so you need to be careful with your workflow:
* **You should not push new branches to the main repository.** You can
- still use them in the fork that you use for the development of patches.
+ still use them in the fork that you use for your own development.
You can also push these branches to a separate public repository
for maintenance work before it is integrated into the main repository.
* **You should not commit directly into the** ``main`` **branch, or any of the maintenance branches.**
- You should commit against your own feature branch, and then create a
+ You should commit against your own feature branch, and then create a
pull request.
* **For a small change, you can make a quick edit through the GitHub web UI.**
@@ -183,26 +209,27 @@ clone.
.. _committing-active-branches:
Seeing active branches
-''''''''''''''''''''''
+^^^^^^^^^^^^^^^^^^^^^^
If you use ``git branch``, then you will see a :ref:`list of branches
`. The only branch that receives new features is
``main``, the in-development branch. The other branches receive only
-bug fixes or security fixes.
+bug fixes or security fixes. In almost all cases the fixes should first
+originate on ``main`` and then be ported back to older branches.
.. _branch-merge:
Backporting changes to an older version
-'''''''''''''''''''''''''''''''''''''''
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If it is determined that a pull request needs to be backported into one or
-more of the maintenance branches, then a core developer can apply the label
+more of the maintenance branches, then a core team member can apply the label
``needs backport to X.Y`` to the pull request.
After the pull request has been merged, miss-islington (bot) will first try to
do the backport automatically. If miss-islington is unable to do it,
-then the pull request author or the core developer who merged it should look into
+then the pull request author or the core team member who merged it should look into
backporting it themselves, using the backport generated by cherry_picker.py_
as a starting point.
@@ -217,23 +244,24 @@ hashes and their first line of the commit, use the following command::
You can prefix the backport pull request with the branch, and reference
the pull request number from ``main``. Here is an example::
- [3.9] bpo-12345: Fix the Spam Module (GH-NNNN)
+ [3.9] gh-12345: Fix the Spam Module (GH-NNNN)
+Here "gh-12345" is the GitHub *issue* number, and "GH-NNNN" is the
+number of the original *pull request*.
Note that cherry_picker.py_ adds the branch prefix automatically.
Once the backport pull request has been created, remove the
``needs backport to X.Y`` label from the original pull request. (Only
-core developers and members of the `Python Triage Team`_ can apply
-labels to GitHub pull requests).
+members of the core team and :ref:`Python Triage Team `
+can apply labels to GitHub pull requests).
.. _cherry_picker.py: https://github.com/python/cherry-picker
-.. _`Python Triage Team`: https://devguide.python.org/triaging/#python-triage-team
Reverting a merged pull request
-'''''''''''''''''''''''''''''''
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-To revert a merged pull request, press the ``Revert`` button at the
+To revert a merged pull request, press the :guilabel:`Revert` button at the
bottom of the pull request. That will bring up the page to create a
new pull request where the commit can be reverted. It will also create
a new branch on the main CPython repository. Delete the branch once
@@ -243,7 +271,9 @@ Always include the reason for reverting the commit to help others
understand why it was done. The reason should be included as part of
the commit message. Here is an example::
- Revert bpo-NNNN: Fix Spam Module (GH-111)
+ Revert gh-NNNN: Fix Spam Module (GH-111)
Reverts python/cpython#111.
Reason: This commit broke the buildbot.
+
+.. _issue tracker: https://github.com/python/cpython/issues
diff --git a/developers.csv b/core-team/core-team.csv
similarity index 74%
rename from developers.csv
rename to core-team/core-team.csv
index b37e5a15e..ab87c50fa 100644
--- a/developers.csv
+++ b/core-team/core-team.csv
@@ -1,12 +1,41 @@
+Emma Smith,emmatyping,2025-07-31,,
+Tomas Roun,tomasr8,2025-06-16,,
+Peter Bierma,ZeroIntensity,2025-06-16,,
+Diego Russo,diegorusso,2025-05-13,,
+Bénédikt Tran,picnixz,2025-01-10,,
+Savannah Bailey,savannahostrowski,2024-11-13,,
+Matt Page,mpage,2024-10-10,,
+Kirill Podoprigora,Eclips4,2024-09-20,,
+Ned Batchelder,nedbat,2024-07-16,,
+Tian Gao,gaogaotiantian,2024-06-06,,
+Michael Droettboom,mdboom,2024-06-06,,
+Russell Keith-Magee,freakboy3742,2024-05-30,,
+Sam Gross,colesbury,2024-02-06,,
+Nikita Sobolev,sobolevn,2024-02-06,,
+Adam Turner,AA-Turner,2023-10-10,,
+C.A.M. Gerlach,CAM-Gerlach,2023-04-19,,
+Barney Gale,barneygale,2023-03-21,,
+Carl Meyer,carljm,2023-02-28,,
+Pradyun Gedam,pradyunsg,2023-01-30,,
+Shantanu Jain,hauntsaninja,2022-12-19,,
+Kumar Aditya,kumaraditya303,2022-11-21,,
+Hugo van Kemenade,hugovk,2022-11-21,,
+Alex Waygood,AlexWaygood,2022-10-18,,
+Filipe Laíns,FFY00,2022-10-17,,
+Erlend Egeberg Aasland,erlend-aasland,2022-05-05,,
+Jelle Zijlstra,JelleZijlstra,2022-02-15,,
+Dennis Sweeney,sweeneyde,2022-02-02,,
+Ken Jin,Fidget-Spinner,2021-08-26,,
+Ammar Askar,ammaraskar,2021-07-30,,
Irit Katriel,iritkatriel,2021-05-10,,
Batuhan Taskaya,isidentical,2020-11-08,,
Brandt Bucher,brandtbucher,2020-09-14,,
Lysandros Nikolaou,lysnikolaou,2020-06-29,,
Kyle Stanley,aeros,2020-04-14,,
-Dong-hee Na,corona10,2020-04-08,,
+Donghee Na,corona10,2020-04-08,,
Karthikeyan Singaravelan,tirkarthi,2019-12-31,,
Joannah Nanjekye,nanjekyejoannah,2019-09-23,,
-Abhilash Raj,maxking,2019-08-06,,
+Abhilash Raj,maxking,2019-08-06,2022-11-30,Privileges relinquished on 2022-11-30
Paul Ganssle,pganssle,2019-06-15,,
Stéphane Wirtel,matrixise,2019-04-08,,
Stefan Behnel,scoder,2019-04-08,,
@@ -27,7 +56,7 @@ Xavier de Gaye,xdegaye,2016-06-03,2018-01-25,Privileges relinquished on 2018-01-
Davin Potts,applio,2016-03-06,,
Martin Panter,vadmium,2015-08-10,2020-11-26,
Paul Moore,pfmoore,2015-03-15,,
-Robert Collins,rbtcollins,2014-10-16,,To work on unittest
+Robert Collins,rbtcollins,2014-10-16,2021-11-30,To work on unittest; privileges relinquished on 2021-11-30
Berker Peksağ,berkerpeksag,2014-06-26,,
Steve Dower,zooba,2014-05-10,,
Kushal Das,kushaldas,2014-04-14,,
@@ -44,18 +73,19 @@ Hynek Schlawack,hynek,2012-05-14,,
Richard Oudkerk,,2012-04-29,2017-02-10,For multiprocessing module; did not make GitHub transition
Andrew Svetlov,asvetlov,2012-03-13,,At PyCon sprint
Petri Lehtinen,akheron,2011-10-22,2020-11-12,
-Meador Inge,meadori,2011-09-19,2020-11-26,
+Meador Inge,meadori,2011-09-19,,
Jeremy Kloth,jkloth,2011-09-12,,
Sandro Tosi,sandrotosi,2011-08-01,,
Alex Gaynor,alex,2011-07-18,,For PyPy compatibility (since expanded scope)
Charles-François Natali,,2011-05-19,2017-02-10,Did not make GitHub transition
Nadeem Vawda,,2011-04-10,2017-02-10,Did not make GitHub transition
+CF Bolz-Tereick,cfbolz,2011-03-21,,for stdlib compatibility work for PyPy
Jason R. Coombs,jaraco,2011-03-14,,For sprinting on distutils2
Ross Lagerwall,,2011-03-13,2017-02-10,Did not make GitHub transition
-Eli Bendersky,eliben,2011-01-11,2020-11-26,
+Eli Bendersky,eliben,2011-01-11,2020-11-26,Relinquished privileges on 2020-11-26
Ned Deily,ned-deily,2011-01-09,,
David Malcolm,davidmalcolm,2010-10-27,2020-11-12,relinquished privileges on 2020-11-12
-Tal Einat,taleinat,2010-10-04,,For IDLE
+Tal Einat,taleinat,2010-10-04,,Initially for IDLE
Łukasz Langa,ambv,2010-09-08,,
Daniel Stutzbach,,2010-08-22,2017-02-10,Did not make GitHub transition
Éric Araujo,merwok,2010-08-10,,
@@ -74,23 +104,23 @@ Doug Hellmann,dhellmann,2009-09-20,2020-11-11,For documentation; relinquished pr
Frank Wierzbicki,,2009-08-02,2017-02-10,For Jython compatibility; did not make GitHub transition
Ezio Melotti,ezio-melotti,2009-06-07,,For documentation
Philip Jenvey,pjenvey,2009-05-07,2020-11-26,For Jython compatibility
-Michael Foord,voidspace,2009-04-01,,For IronPython compatibility
+Michael Foord,voidspace,2009-04-01,2025-01-24,For IronPython compatibility; deceased
R\. David Murray,bitdancer,2009-03-30,,
Chris Withers,cjw296,2009-03-08,,
-Tarek Ziadé,,2008-12-21,2017-02-10,For distutils module; did not make GitHub transition
+Tarek Ziadé,tarekziade,2008-12-21,2017-02-10,For distutils module
Hirokazu Yamamoto,,2008-08-12,2017-02-10,For Windows build; did not make GitHub transition
-Armin Ronacher,mitsuhiko,2008-07-23,2020-11-26,For documentation toolset and ast module
+Armin Ronacher,mitsuhiko,2008-07-23,,For documentation toolset and ast module
Antoine Pitrou,pitrou,2008-07-16,,
-Senthil Kumaran,orsenthil,2008-06-16,,For GSoC
+Senthil Kumaran,orsenthil,2008-06-16,,
Jesse Noller,,2008-06-16,2017-02-10,For multiprocessing module; did not make GitHub transition
Jesús Cea,jcea,2008-05-13,,For bsddb module
Guilherme Polo,,2008-04-24,2017-02-10,Did not make GitHub transition
Jeroen Ruigrok van der Werven,,2008-04-12,2017-02-10,For documentation; did not make GitHub transition
Benjamin Peterson,benjaminp,2008-03-25,,For bug triage
David Wolever,wolever,2008-03-17,2020-11-21,For 2to3 module
-Trent Nelson,tpn,2008-03-17,2020-11-26,
-Mark Dickinson,mdickinson,2008-01-06,,For maths-related work
-Amaury Forgeot d'Arc,amauryfa,2007-11-09,2020-11-26,
+Trent Nelson,tpn,2008-03-17,,
+Mark Dickinson,mdickinson,2008-01-06,2024-08-13,For maths-related work
+Amaury Forgeot d'Arc,amauryfa,2007-11-09,2020-11-26,Relinquished privileges on 2020-11-26
Christian Heimes,tiran,2007-10-31,,
Bill Janssen,,2007-08-28,2017-02-10,For ssl module; did not make GitHub transition
Jeffrey Yasskin,,2007-08-09,2017-02-10,Did not make GitHub transition
@@ -98,7 +128,7 @@ Mark Summerfield,,2007-08-01,2017-02-10,For documentation; did not make GitHub t
Alexandre Vassalotti,avassalotti,2007-05-21,2020-11-12,For GSoC
Travis E. Oliphant,,2007-04-17,2017-02-10,Did not make GitHub transition
Eric V. Smith,ericvsmith,2007-02-28,,For PEP 3101 in a sandbox
-Josiah Carlson,,2007-01-06,2017-02-10,For asyncore and asynchat modules; did not make GitHub transition
+Josiah Carlson,josiahcarlson,2007-01-06,2017-02-10,For asyncore and asynchat modules
Collin Winter,,2007-01-05,2017-02-10,For PEP access; did not make GitHub transition
Richard Jones,,2006-05-23,2017-02-10,For Need for Speed sprint; did not make GitHub transition
Kristján Valur Jónsson,,2006-05-17,2017-02-10,For Need for Speed sprint; did not make GitHub transition
@@ -107,18 +137,18 @@ Steven Bethard,,2006-04-27,2017-02-10,For PEP access and SourceForge maintenance
Gerhard Häring,,2006-04-23,2017-02-10,Did not make the GitHub transition
George Yoshida,,2006-04-17,2017-02-10,For tracker administration; did not make GitHub transition
Ronald Oussoren,ronaldoussoren,2006-03-03,,For Mac-related work
-Nick Coghlan,ncoghlan,2005-10-16,,
+Alyssa Coghlan,ncoghlan,2005-10-16,,Also contributed as Nick Coghlan (prior to 2023-08-04)
Georg Brandl,birkenfeld,2005-05-28,,
Terry Jan Reedy,terryjreedy,2005-04-07,,
-Bob Ippolito,,2005-03-02,2017-02-10,For Mac-related work; did not make GitHub transition
+Bob Ippolito,etrepum,2005-03-02,2017-02-10,For Mac-related work
Peter Astrand,,2004-10-21,2017-02-10,Did not make GitHub transition
Facundo Batista,facundobatista,2004-10-16,,
Sean Reifschneider,,2004-09-17,2017-02-10,Did not make GitHub transition
Johannes Gijsbers,,2004-08-14,2005-07-27,Privileges relinquished on 2005-07-27
Matthias Klose,doko42,2004-08-04,,
-PJ Eby,pjeby,2004-03-24,2020-11-26,
+PJ Eby,pjeby,2004-03-24,2020-11-26,Relinquished privileges on 2020-11-26
Vinay Sajip,vsajip,2004-02-20,,
-Hye-Shik Chang,,2003-12-10,2017-02-10,Did not make GitHub transition
+Hye-Shik Chang,hyeshik,2003-12-10,2025-02-28,Privileges relinquished on 2025-02-28
Armin Rigo,,2003-10-24,2012-06-01,Privileges relinquished in 2012
Andrew McNamara,,2003-06-09,2017-02-10,Did not make GitHub transition
Samuele Pedroni,,2003-05-16,2017-02-10,Did not make GitHub transition
@@ -127,11 +157,11 @@ Brett Cannon,brettcannon,2003-04-18,,
David Goodger,,2003-01-02,2017-02-10,Did not make GitHub transition
Gustavo Niemeyer,,2002-11-05,2017-02-10,Did not make GitHub transition
Tony Lownds,,2002-09-22,2017-02-10,Did not make GitHub transition
-Steve Holden,,2002-06-14,2017-02-10,"Relinquished privileges on 2005-04-07,
+Steve Holden,holdenweb,2002-06-14,2017-02-10,"Relinquished privileges on 2005-04-07,
but granted again for Need for Speed sprint; did not make GitHub transition"
Christian Tismer,ctismer,2002-05-17,,For Need for Speed sprint
Jason Tishler,,2002-05-15,2017-02-10,Did not make GitHub transition
-Walter Dörwald,doerwalter,2002-03-21,,
+Walter Dörwald,doerwalter,2002-03-21,2021-11-16,Relinquished privileges on 2021-11-16
Andrew MacIntyre,,2002-02-17,2016-01-02,Privileges relinquished 2016-01-02
Gregory P. Smith,gpshead,2002-01-08,,
Anthony Baxter,,2001-12-21,2017-02-10,Did not make GitHub transition
@@ -164,9 +194,9 @@ Eric S. Raymond,,2000-06-02,2017-02-10,Did not make GitHub transition
Greg Stein,,1999-11-07,2017-02-10,Did not make GitHub transition
Just van Rossum,,1999-01-22,2017-02-10,Did not make GitHub transition
Greg Ward,,1998-12-18,2017-02-10,Did not make GitHub transition
-Andrew Kuchling,akuchling,1998-04-09,,
+Andrew Kuchling,akuchling,1998-04-09,2022-11-09,Privileges relinquished 2022-11-09
Ken Manheimer,,1998-03-03,2005-04-08,Privileges relinquished on 2005-04-08
-Jeremy Hylton,jeremyhylton,1997-08-13,2020-11-26,
+Jeremy Hylton,jeremyhylton,1997-08-13,,
Roger E. Masse,,1996-12-09,2017-02-10,Did not make GitHub transition
Fred Drake,freddrake,1996-07-23,,
Barry Warsaw,warsaw,1994-07-25,,
diff --git a/core-team/experts.rst b/core-team/experts.rst
new file mode 100644
index 000000000..5791ff408
--- /dev/null
+++ b/core-team/experts.rst
@@ -0,0 +1,369 @@
+.. _experts:
+
+=============
+Experts index
+=============
+
+This document has tables that list Python Modules, Tools, Platforms and
+Interest Areas and GitHub names for each item that indicate a maintainer or
+an expert in the field. This list is intended to be used by issue submitters,
+issue triage people, and other issue participants to find people to @mention
+or add as reviewers to issues and pull requests. People on this list may be
+asked to render final judgment on a feature or bug. If no active maintainer
+is listed for a given module, then questionable changes should be discussed
+on the `Core Development Discourse category
+`__,
+while any other issues can and should be decided by any committer.
+
+Developers can choose to follow labels, so if a label that they are
+following is added to an issue or pull request, they will be notified
+automatically. The :cpy-file:`.github/CODEOWNERS` file is also used to indicate
+maintainers that will be automatically added as reviewers to pull requests.
+
+Unless a name is followed by a '*', you should never assign an issue to
+that person. Names followed by a '*' may be assigned issues involving the
+module or topic.
+
+Names followed by a '^' indicate old bugs.python.org usernames, for people
+that did not transition to GitHub.
+
+The Platform and Interest Area tables list broader fields in which various
+people have expertise. These people can also be contacted for help,
+opinions, and decisions when issues involve their areas.
+
+If a listed maintainer does not respond to requests for comment for an
+extended period (three weeks or more), they should be marked as inactive
+in this list by placing the word 'inactive' in parenthesis behind their
+tracker id. They are of course free to remove that inactive mark at
+any time.
+
+Committers should update these tables as their areas of expertise widen.
+New topics may be added to the Interest Area table at will.
+
+The existence of this list is not meant to indicate that these people
+*must* be contacted for decisions; it is, rather, a resource to be used
+by non-committers to find responsible parties, and by committers who do
+not feel qualified to make a decision in a particular context.
+
+
+Stdlib
+======
+
+==================== =============================================
+Module Maintainers
+==================== =============================================
+__future__
+__main__ gvanrossum, ncoghlan
+_thread
+abc
+annotationlib JelleZijlstra*
+argparse savannahostrowski*, serhiy-storchaka*
+array
+ast benjaminp, pablogsal, isidentical, JelleZijlstra, eclips4
+asyncio 1st1, asvetlov, gvanrossum, graingert, kumaraditya303, willingc
+atexit
+base64
+bdb
+binascii
+bisect rhettinger*
+builtins
+calendar
+cmath
+cmd
+code
+codecs malemburg, doerwalter
+codeop
+collections rhettinger*
+collections.abc rhettinger*, stutzbach^
+colorsys
+compileall carljm
+compression.bz2
+compression.gzip
+compression.lzma
+compression.zlib Yhg1s, gpshead*
+compression.zstd
+concurrent.futures pitrou, brianquinlan, gpshead*
+configparser ambv*
+contextlib ncoghlan, 1st1
+contextvars
+copy avassalotti, serhiy-storchaka*
+copyreg avassalotti, serhiy-storchaka*
+cProfile
+csv smontanaro (inactive), serhiy-storchaka*
+ctypes theller (inactive), abalkin, amauryfa, meadori
+curses Yhg1s
+dataclasses ericvsmith*, carljm
+datetime abalkin, pganssle
+dbm
+decimal facundobatista, rhettinger
+difflib tim-one (inactive)
+dis 1st1
+doctest tim-one (inactive)
+email warsaw, bitdancer*, maxking
+encodings malemburg
+ensurepip ncoghlan, dstufft, pradyunsg, pfmoore
+enum eliben*, warsaw, ethanfurman*
+errno Yhg1s
+faulthandler vstinner, gpshead, ZeroIntensity*
+fcntl Yhg1s
+filecmp
+fileinput
+fnmatch serhiy-storchaka*
+fractions
+ftplib giampaolo*
+functools rhettinger*
+gc pitrou, pablogsal, nascheme
+getopt serhiy-storchaka*
+getpath FFY00
+getpass
+gettext tomasr8
+glob serhiy-storchaka*
+grp
+hashlib tiran, gpshead*, picnixz
+heapq rhettinger*, stutzbach^
+hmac tiran, gpshead*, picnixz
+html ezio-melotti*
+http
+idlelib kbkaiser (inactive), terryjreedy*, serwy (inactive),
+ taleinat
+imaplib
+importlib brettcannon
+inspect 1st1
+io benjaminp, stutzbach^
+ipaddress pmoody^
+itertools rhettinger*
+json etrepum (inactive), ezio-melotti, rhettinger,
+ serhiy-storchaka*
+keyword
+libmpdec
+linecache
+locale malemburg
+logging vsajip
+mailbox
+marshal
+math rhettinger, stutzbach^
+mimetypes
+mmap Yhg1s
+modulefinder theller (inactive), jvr^
+msvcrt
+multiprocessing applio*, pitrou, jnoller^ (inactive), sbt^ (inactive), gpshead*
+netrc
+numbers
+operator
+optparse mitsuhiko, serhiy-storchaka*
+os
+os.path serhiy-storchaka*
+parser pablogsal
+pathlib barneygale*
+pdb gaogaotiantian
+pickle avassalotti, serhiy-storchaka*
+pickletools avassalotti, serhiy-storchaka*
+pkgutil
+platform malemburg
+plistlib
+poplib
+posix larryhastings, gpshead
+pprint freddrake
+profile
+pstats
+pty Yhg1s*
+pwd
+py_compile carljm
+pyclbr isidentical
+pydoc AA-Turner, serhiy-storchaka*
+queue rhettinger*
+quopri
+random rhettinger
+re ezio-melotti, serhiy-storchaka*
+readline Yhg1s
+reprlib
+resource Yhg1s
+rlcompleter
+runpy ncoghlan
+sched
+secrets
+select
+selectors neologix^, giampaolo
+shelve
+shlex
+shutil tarekziade, giampaolo
+signal gpshead
+site
+smtplib
+socket gpshead
+socketserver
+sqlite3 ghaering^, erlend-aasland*
+ssl jackjansen, tiran, dstufft, alex
+stat tiran
+statistics stevendaprano, rhettinger
+string
+stringprep
+struct meadori
+subprocess astrand^ (inactive), giampaolo, gpshead*
+symtable benjaminp
+sys
+sysconfig FFY00
+syslog jafo^*
+tabnanny tim-one (inactive)
+tarfile gustaebel
+tempfile serhiy-storchaka*
+termios Yhg1s
+test ezio-melotti, serhiy-storchaka*
+textwrap
+threading pitrou, gpshead
+time abalkin, pganssle
+timeit
+tkinter gpolo^, serhiy-storchaka*
+token
+tokenize meadori
+tomllib hauntsaninja*
+trace abalkin
+traceback iritkatriel
+tracemalloc vstinner
+tty Yhg1s*
+turtle gregorlingl^, willingc
+turtledemo terryjreedy*
+types 1st1
+typing gvanrossum, JelleZijlstra*, AlexWaygood*, carljm, sobolevn*
+unicodedata malemburg, ezio-melotti
+unittest ezio-melotti, rbtcollins, gpshead, serhiy-storchaka*
+unittest.mock
+urllib orsenthil
+uuid
+venv vsajip, FFY00
+warnings
+wave
+weakref freddrake, nascheme
+webbrowser
+winreg stutzbach^
+winsound
+wsgiref pjenvey
+xml.dom
+xml.dom.minidom
+xml.dom.pulldom
+xml.etree eliben*, scoder
+xml.parsers.expat
+xml.sax
+xml.sax.handler
+xml.sax.saxutils
+xml.sax.xmlreader
+xmlrpc
+zipapp pfmoore
+zipfile alanmcintyre^, serhiy-storchaka, Yhg1s, gpshead
+zipimport Yhg1s*
+==================== =============================================
+
+
+Tools
+=====
+
+================== ===========
+Tool Maintainers
+================== ===========
+Argument Clinic larryhastings, AlexWaygood*, erlend-aasland,
+ serhiy-storchaka*
+Deepfreeze gvanrossum, kumaraditya303
+PEG Generator gvanrossum, pablogsal, lysnikolaou
+================== ===========
+
+
+.. _platform-experts:
+
+Platforms
+=========
+
+For official contacts for supported platforms, see :pep:`11`.
+
+Platforms listed here are not necessarily supported by CPython.
+Some of the experts listed here maintain and distribute Python
+for “their” platform as a third-party project.
+
+=================== ===========
+Platform Maintainers
+=================== ===========
+AIX edelsohn, ayappanec
+Android mhsmith
+Cygwin jlt63^, stutzbach^
+Emscripten hoodmane, pmp-p, rdb, rth, ryanking13
+FreeBSD
+HP-UX
+iOS freakboy3742, ned-deily
+JVM/Java frank.wierzbicki^
+Linux
+macOS ronaldoussoren, ned-deily, freakboy3742
+NetBSD1
+OS2/EMX aimacintyre^
+Solaris/OpenIndiana jcea, kulikjak
+Windows tjguk, zooba, pfmoore
+=================== ===========
+
+
+Miscellaneous
+=============
+
+================== ==========================================================
+Interest Area Maintainers
+================== ==========================================================
+algorithms rhettinger*, serhiy-storchaka
+argument clinic larryhastings, AlexWaygood*, erlend-aasland,
+ serhiy-storchaka*
+AST/compiler benjaminp, 1st1, pablogsal, markshannon, isidentical, brandtbucher, carljm, iritkatriel
+autoconf/makefiles Yhg1s*
+issue tracker ezio-melotti
+buildbots zware, pablogsal
+bytecode benjaminp, 1st1, markshannon, brandtbucher, carljm, iritkatriel
+context managers ncoghlan
+core workflow Mariatta, ezio-melotti, hugovk, AA-Turner
+cryptography gpshead, dstufft, picnixz
+data formats
+database malemburg
+devguide merwok, ezio-melotti, willingc, Mariatta, hugovk,
+ AA-Turner
+documentation ezio-melotti, merwok, JulienPalard, willingc, hugovk,
+ AA-Turner, AlexWaygood*
+emoji Mariatta
+extension modules encukou, ncoghlan
+filesystem giampaolo
+frozen modules ericsnowcurrently, gvanrossum, kumaraditya303
+f-strings ericvsmith*
+GUI
+i18n malemburg, merwok, tomasr8
+import machinery brettcannon, ncoghlan, ericsnowcurrently, FFY00
+initialization FFY00
+io benjaminp, stutzbach^, gpshead
+JIT brandtbucher*, savannahostrowski*
+locale malemburg
+mathematics malemburg, stutzbach^, rhettinger, serhiy-storchaka
+memory management tim-one, malemburg, Yhg1s, nascheme
+memoryview
+networking giampaolo, gpshead
+object model benjaminp, Yhg1s
+packaging tarekziade, malemburg, alexis^, merwok, dstufft, pfmoore
+pattern matching brandtbucher*
+PEG parser gvanrossum, pablogsal, lysnikolaou
+performance vstinner, serhiy-storchaka*, 1st1, rhettinger, markshannon,
+ brandtbucher, carljm, Fidget-Spinner, AlexWaygood*, nascheme
+pip ncoghlan, dstufft, pfmoore, Marcus.Smith^, pradyunsg
+release management tarekziade, malemburg, benjaminp, warsaw,
+ gvanrossum, anthonybaxter^, merwok, ned-deily,
+ birkenfeld, JulienPalard, hugovk
+runtime lifecycle ericsnowcurrently, kumaraditya303, zooba, ZeroIntensity, nascheme
+str.format ericvsmith*
+subinterpreters ericsnowcurrently, kumaraditya303, ZeroIntensity*
+symbol table JelleZijlstra, carljm
+testing ezio-melotti
+test coverage
+threads gpshead
+time and dates malemburg, abalkin, pganssle
+Unicode malemburg, ezio-melotti, benjaminp
+version control merwok, ezio-melotti
+================== ==========================================================
+
+
+Documentation translations
+==========================
+
+Translations are within the charter of
+`Editorial Board `_.
+For a list of translations and their coordinators, see
+:ref:`this table of translations `.
diff --git a/core-team/index.rst b/core-team/index.rst
new file mode 100644
index 000000000..f8dafe05e
--- /dev/null
+++ b/core-team/index.rst
@@ -0,0 +1,17 @@
+.. _core-dev:
+.. _core-team:
+
+=========
+Core team
+=========
+
+.. toctree::
+ :maxdepth: 5
+
+ responsibilities
+ committing
+ experts
+ team-log
+ motivations
+ join-team
+ memorialization
diff --git a/core-team/join-team.rst b/core-team/join-team.rst
new file mode 100644
index 000000000..eb0f56e09
--- /dev/null
+++ b/core-team/join-team.rst
@@ -0,0 +1,115 @@
+.. _become-core-developer:
+.. _coredev:
+.. _join-core-team:
+
+=========================
+How to join the core team
+=========================
+
+What it takes
+=============
+
+When you have consistently made contributions which meet quality standards
+without requiring extensive rewrites prior to being committed,
+you may qualify for commit privileges and join the core team of Python.
+You must also work well with other core team members (and people in general)
+as you become an ambassador for the Python project.
+
+Typically a core team member will offer you the chance to gain commit privilege.
+The person making the offer will become your mentor and watch your commits for
+a while to make sure you understand the development process. If other core
+developers agree that you should gain commit privileges you are then extended
+an official offer. How core team members come to that agreement are outlined in
+:pep:`13`.
+
+
+Gaining commit privileges
+=========================
+
+After a candidate has demonstrated consistent contributions, commit privileges
+are granted through these steps:
+
+#. A core team member (submitter, usually the mentor) starts a poll
+ (see the :ref:`template ` below) in
+ the `Committers category`_ on the `Python Discourse`_.
+
+ - open for 7 days
+ - results shown only upon closing
+
+#. If the candidate receives at least two-thirds positive votes when the poll closes
+ (as per :pep:`13`), the submitter `emails the steering council
+ `_ with the candidate's email address
+ requesting that the council either accept or reject the proposed membership. Technically, the
+ council may only `veto a positive vote `_.
+
+#. Assuming the steering council does not veto the positive vote, a member of the council or its
+ delegate (approver, usually in practice a :ref:`Developer-in-Residence `) will
+ email the candidate:
+
+ - A request for account details as required by
+ `🔒 python/voters `_.
+ - A reminder about the `Code of Conduct`_ and guidance on reporting issues
+ to the PSF Conduct WG.
+
+#. Once the candidate has provided the pertinent details, the approver will:
+
+ - Enable the various new privileges.
+ - Remove the new committer from the triage team, if applicable.
+ - Add their details to `🔒 python/voters `_.
+ - Update the devguide to publicly list their team membership
+ at :ref:`developers`.
+ - Post an announcement in the `Committers Discourse category
+ `_. The past few announcements
+ were in the form of a separate post on the already open topic with
+ the poll.
+
+Getting a python.org email address
+----------------------------------
+
+Members of the core team can get an email address on the python.org domain.
+For more details refer to the `python.org email policy
+`_.
+
+
+Poll template
+=============
+
+.. _coredev-template:
+
+While Discourse uses Markdown for formatting, the poll functionality is
+custom and somewhat resembles BBcode. There's a creator for polls in the
+UI (click the cog icon in the edit box toolbar and choose "Build Poll").
+Here's what it outputs, you can copy and paste it for your poll:
+
+.. code-block:: bbcode
+
+ [poll type=regular results=on_close public=false chartType=bar groups=committers close=2024-07-15T21:15:00.000Z]
+ * Promote Basil Fawlty
+ * Do not promote
+ [/poll]
+
+The important options in the poll builder set to get this result:
+
+- Show who voted: **disabled** (``public=false``)
+- Limit voting to these groups: **committers** (``groups=committers``)
+- Automatically close poll: **in 7 days** (``close=...``)
+- Show results: **When poll is closed** (``results=on_close``)
+
+.. raw:: html
+
+
+
+.. _Code of Conduct: https://policies.python.org/python.org/code-of-conduct/
+.. _Committers category: https://discuss.python.org/c/committers/5
+.. _Python Discourse: https://discuss.python.org
diff --git a/core-team/memorialization.rst b/core-team/memorialization.rst
new file mode 100644
index 000000000..7ab0fab02
--- /dev/null
+++ b/core-team/memorialization.rst
@@ -0,0 +1,159 @@
+.. _memorialize-core-developer:
+.. _memorialize-core-team-member:
+
+===============
+Memorialization
+===============
+
+Rationale
+=========
+
+When a core team member passes away, memorializing accounts helps create
+a space for remembering the contributor and protects against attempted
+logins and fraudulent activity.
+
+The process
+===========
+
+The memorialization process is performed by a member of the PSF staff
+with administrative access to current and historical systems where
+the core team has access.
+
+After the status of the core team member in question is confirmed,
+access to the systems listed below is revoked and some changes are
+made to how the user displays to others.
+
+To respect the choices that someone made while alive, we aim to preserve
+content of their accounts without changes after they've passed away.
+To support the bereaved, in some instances, we may remove or change
+certain content when the legacy contact or family members request it.
+
+GitHub
+------
+
+* The user is removed from the `python/ `_
+ organization on GitHub;
+* The user is removed from the `psf/ `_
+ organization on GitHub;
+* The user is removed from the `pypa/ `_
+ organization on GitHub.
+
+The PSF staff does not follow up with GitHub with regards to GitHub account
+cancellation as this action is reserved for next-of-kin or designated by
+the deceased GitHub user to act as an account successor.
+
+The general policy regarding deceased users on GitHub is described on their
+`Deceased User Policy `_
+page.
+
+Repositories in the organization
+--------------------------------
+
+* The user's GitHub handle is removed from ``/.github/CODEOWNERS``.
+ To see all that need action, perform
+ `this query `_.
+* The user is marked as deceased in the private
+ `voters/python-core.toml `_
+ file with the ``left=`` field set to the day of passing, if known.
+
+discuss.python.org
+------------------
+
+* The user's "custom status" is set to 🕊 ``in memoriam``;
+* The user's "about me" is amended with ``$firstname passed away on $date. [In memoriam.]($in_memoriam_post_url)``;
+* In the user's security "recently used devices" the staff member
+ chooses "Log out all";
+* In the user's permissions the staff member chooses "Deactivate account";
+* The user's trust level is reset to ``1: basic user`` (trust level 0
+ doesn't allow links in "About Me");
+* The user's "associated accounts" (like GitHub) that provide an
+ alternative login method, are all disconnected;
+* The user's API keys are revoked;
+* The user's admin or moderator right is revoked;
+* The user's primary email address is reset to
+ ``USERNAME@in-memoriam.invalid`` and secondary email addresses are
+ removed (this step requires the administrator to contact Discourse.org
+ staff via ``team@discourse.org``).
+
+The "in memoriam" Discourse topic mentioned above is best created by
+a community member close to the deceased.
+
+The general best practice for deceased community members on
+Discourse-powered forums is described on their
+`Best practices for deceased community members `_
+page.
+
+python.org email account
+------------------------
+
+The PSF staff member emails ``postmaster@python.org`` to ask the email
+administrator to:
+
+* remove SMTP access from ``USERNAME@python.org``;
+* reset the password to POP3/IMAP for ``USERNAME@python.org``;
+* disable email forwarding, if set up, for ``USERNAME@python.org`` and
+ leave a record permanently as "in memoriam" to avoid future account
+ name reuse;
+* remove this email from all mailing lists under ``@python.org``;
+* remove any known alternate emails for the same user from all mailing
+ lists under ``@python.org``.
+
+In case the email shutdown causes issues for the estate executors, the
+PSF will reasonably try to help if contacted directly.
+
+python.org admin
+----------------
+
+* The user's account (``/admin/users/user``) is deactivated (NOT deleted)
+ and their staff and superuser status is unchecked;
+* The user's password is reset to a long random string;
+* The user's primary email address is set to
+ ``USERNAME@in-memoriam.invalid`` and set as unverified;
+* The user's secondary email addresses are deleted;
+* The user's API keys (both on the account and ``tastypie``) are deleted;
+* The user's "I would like to be a PSF Voting Member" field is cleared.
+
+devguide.python.org
+-------------------
+
+* The user is marked as deceased in `core-team.csv `_;
+* The user is removed from the `experts index `_.
+
+bugs.python.org
+---------------
+
+While the issue tracker was migrated to GitHub, the Roundup instance
+is still up for historical purposes.
+
+* the PSF staff member logs into ``bugs.nyc1.psf.io``;
+* the PSF staff member runs ``roundup-admin`` to set the user's email
+ address to ``USERNAME@in-memoriam.invalid``;
+* the user's alternate emails are removed;
+* the user's password is reset to a long random string;
+* the PSF staff member removes any active login sessions from Postgres.
+
+Other PSF-related infrastructure
+--------------------------------
+
+* The PSF staff member notifies administrators of the Python Core Devs
+ Discord server to remove the user from the server. The PSF staff
+ does not follow up with Discord with regards to Discord account
+ cancellation. The general policy regarding deceased users on Discord
+ is available on their `Deceased or Incapacitated Users `_
+ page.
+
+* The user is removed from Salt configuration for the PSF infrastructure
+ in `/pillar/base/users `_
+ that allows SSH access to PSF-controlled servers.
+
+* The user might have ran a buildbot worker. The PSF staff member will
+ look for that in the
+ `buildmaster-config `_
+ repository.
+
+PyPI
+----
+
+* The PSF staff member notifies PyPI admins by emailing them at
+ ``admin@pypi.org`` to mark the user as inactive, remove their email
+ addresses, prohibit their password resets, and revoke all API keys.
diff --git a/motivations.rst b/core-team/motivations.rst
similarity index 69%
rename from motivations.rst
rename to core-team/motivations.rst
index f1a1a41cc..d5a87e22c 100644
--- a/motivations.rst
+++ b/core-team/motivations.rst
@@ -1,24 +1,25 @@
.. _motivations:
-Core Developer Motivations and Affiliations
-===========================================
+============================
+Motivations and affiliations
+============================
-CPython core developers participate in the core development process for a
-variety of reasons. Being accepted as a core developer indicates that
+CPython core team members participate in the core development process for a
+variety of reasons. Being accepted as a core team member indicates that
an individual is interested in acquiring those responsibilities, has the
-ability to collaborate effectively with existing core developers, and has had
+ability to collaborate effectively with existing core team members, and has had
the time available to demonstrate both that interest and that ability.
-This page allows core developers that choose to do so to provide more
+This page allows core team members that choose to do so to provide more
information to the rest of the Python community regarding their personal
situation (such as their general location and professional affiliations), as
well as any personal motivations that they consider particularly relevant.
-Core developers that wish to provide this additional information add a new
+Core team members that wish to provide this additional information add a new
entry to the :ref:`published-motivations` section below. Guidelines relating
to content and layout are included as comments in the source code for this page.
-Core developers that are available for training, consulting, contract, or
+Core team members who are available for training, consulting, contract, or
full-time work, or are seeking crowdfunding support for their community
contributions, may also choose to provide that information here (including
linking out to commercial sites with the relevant details).
@@ -29,9 +30,9 @@ For more information on the origins and purpose of this page, see
.. _published-motivations:
Published entries
------------------
+=================
-The following core developers have chosen to provide additional details
+The following core team members have chosen to provide additional details
regarding their professional affiliations and (optionally) other reasons for
participating in the CPython core development process:
@@ -42,7 +43,7 @@ participating in the CPython core development process:
Topic headings should be in the form of "Name (Country)" or
"Name (Continent)" to help give some indication as to the geographic
- distribution of core developers.
+ distribution of core team members.
NOTE: The rest of these guidelines are highly provisional - we can evolve
them as people add entries, and we decide on the style we like. The
@@ -79,7 +80,7 @@ participating in the CPython core development process:
country of residence.
Include a "Crowdfunding" bullet point with a link if you'd like to highlight
- crowdfunding services (e.g. Patreon) that folks can use to support your core
+ crowdfunding services (for example, Patreon) that folks can use to support your core
development work.
Include additional bullet points (without links) for any other affiliations
@@ -87,46 +88,51 @@ participating in the CPython core development process:
If there's a kind of link you'd like to include in your entry that isn't
already covered by the categories mentioned above, please start a discussion
- about that on the python-committers mailing list.
+ about that on the Committers category on the Python Discourse
+ (discuss.python.org).
- python-committers is also the appropriate point of contact for any other
+ The Committers Discourse category
+ is also the appropriate point of contact for any other
questions or suggestions relating to this page.
.. topic:: Brett Cannon (Canada)
* Personal site: `snarky.ca `_
- * `Extended bio `__
* Microsoft (Software Developer)
* Python Software Foundation (Fellow)
-.. topic:: Nick Coghlan (Australia)
+.. topic:: Alyssa Coghlan (Australia)
* Personal site: `Curious Efficiency `_
* `Extended bio `__
- * `Tritium `__ (Software Developer)
* Python Software Foundation (Fellow, Packaging Working Group)
+ * Element Labs/LM Studio (Python deployment engineer)
- Nick began using Python as a testing and prototyping language while working
- for Boeing Defence Australia, and continues to use it for that purpose today.
+ Alyssa began using Python as a testing and prototyping language while working
+ for Boeing Defence Australia. She now primarily uses it as the lead project
+ maintainer for the open source ``venvstacks`` Python deployment utility.
- As a core developer, he is primarily interested in helping to ensure Python's
+ As a core team member, she is primarily interested in helping to ensure Python's
continued suitability for educational, testing and data analysis use cases,
as well as in encouraging good architectural practices when assembling Python
applications and test harnesses from open source components.
+ Note: prior to August 2023, Alyssa used her birth name (Nick Coghlan). Some records
+ (for example, mailing list archives, version control history) will still reference that name.
+
.. topic:: Steve Dower (United States/Australia)
* Microsoft (Software Developer)
* Personal site: `stevedower.id.au `_
* Speaking: `stevedower.id.au/speaking `_
- * Work blog: `aka.ms/pythonblog `_
+ * Work blog: `devblogs.microsoft.com/python/ `_
* Email address: steve.dower@python.org
Steve started with Python while automating a test harness for medical
devices, and now works for Microsoft on anything that makes Python more
accessible to developers on any platform.
- As a core developer, his focus is on maintaining the already excellent
+ As a core team member, his focus is on maintaining the already excellent
Windows support and improving Python's ability to be embedded in other
applications.
@@ -137,25 +143,25 @@ participating in the CPython core development process:
.. topic:: Mariatta (Canada)
- * Personal site: `mariatta.ca `_
+ * Personal site: `mariatta.ca `_
* Works as a `Software Engineer `_
in Vancouver, helps organize `Vancouver PyLadies
`_ meetup on the side, and
- sometimes `speaks `_
+ sometimes `speaks `_
at conferences.
* Email address: mariatta@python.org
- * `Sponsor Mariatta on GitHub `_
+ * `Sponsor Mariatta on GitHub `_
* `Patreon `_
- Support Mariatta by `becoming a sponsor `_,
+ Support Mariatta by `becoming a sponsor `_,
sending her a `happiness packet `_,
- or `paypal `_.
+ or `paypal `_.
.. topic:: R. David Murray (United States)
- * Personal site: `bitdance.com `_
+ * Personal site: `bitdance.com `_
* Available for `Python and Internet Services Consulting
- and Python contract programming `_
+ and Python contract programming `_
David has been involved in the Internet since the days when the old IBM
BITNET and the ARPANet got cross connected, and in Python programming since
@@ -164,16 +170,16 @@ participating in the CPython core development process:
business started declining) to being a full time independent consultant,
David started contributing directly to CPython development. He became a
committer in 2009. He subsequently took over primary maintenance of the
- email package from Barry Warsaw, and contributed the unicode oriented API.
+ email package from Barry Warsaw, and contributed the Unicode oriented API.
David is also active in mentoring new contributors and, when time is
available, working on the infrastructure that supports CPython development,
specifically the Roundup-based bug tracker and the buildbot system.
David currently does both proprietary and open source development work,
primarily in Python, through the company in which he is a partner, `Murray &
- Walker, Inc `_. He has done contract work
+ Walker, Inc `_. He has done contract work
focused specifically on CPython development both through the PSF (the
- kickstart of the email unicode API development) and directly funded by
+ kickstart of the email Unicode API development) and directly funded by
interested corporations (additional development work on email funded by
QNX, and work on CPython ICC support funded by Intel). He would like to
spend more of his (and his company's) time on open source work, and so is
@@ -182,23 +188,23 @@ participating in the CPython core development process:
.. topic:: Antoine Pitrou (France)
* LinkedIn: ``_ (Senior Software Engineer)
- * Independent (currently Ursa Labs / R Studio)
+ * QuantStack
* Python Software Foundation (Fellow)
- * Available for open source contract work
* Email address: antoine@python.org
Antoine started working with Python in 2005 in order to implement a
decentralized virtual world protocol. He started contributing to CPython
- in 2007 and became a core developer in 2008. His motivations have been
+ in 2007 and became a core team member in 2008. His motivations have been
driven both by the abstract desire to make Python better for the whole
world, and by the concrete roadblocks he was hitting in professional
settings. Topics of choice have included interpreter optimizations,
garbage collection, network programming, system programming and
- concurrent programming (such as maintaining ``multiprocessing``).
+ concurrent programming.
As a professional, Antoine has been first specializing in network
- programming, and more lately in open source data science infrastructure
- such as Dask, Numba, Apache Arrow.
+ programming, and more lately in open source data science infrastructure.
+ He has made numerous contributions to Numba, Dask and is currently working
+ full time on Apache Arrow as a technical leader at QuantStack.
.. topic:: Victor Stinner (France)
@@ -207,7 +213,7 @@ participating in the CPython core development process:
Victor is paid by Red Hat to maintain Python upstream and downstream (RHEL,
CentOS, Fedora & Software collections). See `Victor's contributions to
- Python `_.
+ Python `_.
.. topic:: Kushal Das (India)
@@ -217,25 +223,23 @@ participating in the CPython core development process:
.. topic:: Barry Warsaw (United States)
- * `LinkedIn: `_ (Senior Staff
- Software Engineer - Python Foundation team)
+ * NVIDIA, Principal System Software Engineer, Open Source Python Ecosystem
* Personal site: `barry.warsaw.us `_
* Blog: `We Fear Change `_
+ * `LinkedIn `_
+ * `Bluesky `_
* Email address: barry@python.org
* Python Software Foundation (Fellow)
Barry has been working in, with, and on Python since 1994. He attended the
- first Python workshop at NBS (now `NIST `_) in
- Gaithersburg, MD in 1994, where he met Guido and several other early Python
- adopters. Barry subsequently worked with Guido for 8 years while at `CNRI
- `_. From 2007 until 2017, Barry worked for
- `Canonical `_, corporate sponsor of `Ubuntu
- `_ Linux, primarily on the Python ecosystem, and
- is both an Ubuntu and a `Debian `_ uploading
- developer. Barry has served as Python's postmaster, webmaster, release
- manager, Language Summit co-chair, `Jython `_
- project leader, `GNU Mailman `_ project leader, and
- probably lots of other things he shouldn't admit to.
+ first Python workshop at `NIST `_ in Gaithersburg,
+ MD in 1994, where he met Guido and several other early Python adopters.
+ Barry subsequently worked with Guido for 8 years while at `CNRI
+ `_. Barry has served as Python's postmaster,
+ webmaster, release manager, Language Summit co-chair, `Jython
+ `_ project leader, `GNU Mailman
+ `_ project leader, and Python Steering Council
+ member in 2019, 2020, 2021, 2024, and 2025.
.. topic:: Eric Snow (United States)
@@ -244,43 +248,43 @@ participating in the CPython core development process:
.. topic:: Dino Viehland (United States)
- * Microsoft: ``_ (Software Engineer)
- * Email address: dinov@microsoft.com
+ * Meta (Software Engineer)
+ * Email address: dinoviehland@gmail.com
Dino started working with Python in 2005 by working on IronPython, an
implementation of Python running on .NET. He was one of the primary
developers on the project for 6 years. After that he started the Python
Tools for Visual Studio project focusing on providing advanced code completion
and debugging features for Python. Today he works on
- `Azure Notebooks `_ bringing the Python based
- Jupyter notebook as a hosted on-line service.
+ `Cinder `_ improving Python
+ performance for Instagram.
.. topic:: Carol Willing (United States)
- * Noteable: ``__ (Technical Evangelist)
+ * Noteable (VP Engineering)
* Personal site: `Willing Consulting `_
* `Extended bio `__
- * Project Jupyter (Steering Council, Core Team for JupyterHub/Binder)
+ * Project Jupyter (Software Council, Core Team for JupyterHub/Binder)
* Python Software Foundation (Fellow)
Carol is focused on Python's usage in education and scientific research.
- She is interested in organizational development, operational workflows,
- and sustainability of open source projects.
+ She is interested in distributed computing, organizational development,
+ operational workflows, and sustainability of open source projects.
.. _goals-of-the-motivations-page:
Goals of this page
-------------------
+==================
The `issue metrics`_ automatically collected by the CPython issue tracker
strongly suggest that the current core development process is bottlenecked on
-core developer time - this is most clearly indicated in the first metrics graph,
-which shows both the number of open issues and the number of patches awaiting
+core team time. This is most clearly indicated in the first metrics graph,
+which shows both the number of open issues and the number of pull requests awaiting
review growing steadily over time, despite CPython being one of the most
active open source projects in the world. This bottleneck then impacts not only
-resolving open issues and applying submitted patches, but also the process of
-identifying, nominating and mentoring new core developers.
+resolving open issues and accepting submitted pull requests, but also the process of
+identifying, nominating and mentoring new core team members.
The core commit statistics monitored by sites like `OpenHub`_ provide a good
record as to *who* is currently handling the bulk of the review and maintenance
@@ -289,13 +293,13 @@ people's ability to spend time on reviewing proposed changes, or mentoring new
contributors.
This page aims to provide at least some of that missing data by encouraging
-core developers to highlight professional affiliations in the following two
+core team members to highlight professional affiliations in the following two
cases (even if not currently paid for time spent participating in the core
development process):
-* developers working for vendors that distribute a commercially supported
+* members working for vendors that distribute a commercially supported
Python runtime
-* developers working for Sponsor Members of the Python Software Foundation
+* members working for Sponsor Members of the Python Software Foundation
These are cases where documenting our affiliations helps to improve the
overall transparency of the core development process, as well as making it
@@ -303,44 +307,44 @@ easier for staff at these organisations to locate colleagues that can help
them to participate in and contribute effectively to supporting the core
development process.
-Core developers working for organisations with a vested interest in the
+Core team members working for organisations with a vested interest in the
sustainability of the CPython core development process are also encouraged to
seek opportunities to spend work time on mentoring potential new core
developers, whether through the general `core mentorship program`_, through
mentoring colleagues, or through more targeted efforts like Outreachy's paid
`internships`_ and Google's `Summer of Code`_.
-Core developers that are available for consulting or contract work on behalf of
+Core team members who are available for consulting or contract work on behalf of
the Python Software Foundation or other organisations are also encouraged
to provide that information here, as this will help the PSF to better
facilitate funding of core development work by organisations that don't
-directly employ any core developers themselves.
+directly employ any core team members themselves.
-Finally, some core developers seeking to increase the time they have available
+Finally, some core team members seeking to increase the time they have available
to contribute to CPython may wish to pursue crowdfunding efforts that allow
their contributions to be funded directly by the community, rather than relying
on institutional sponsors allowing them to spend some or all of their work
time contributing to CPython development.
.. _issue metrics: https://bugs.python.org/issue?@template=stats
-.. _OpenHub: https://www.openhub.net/p/python/contributors
+.. _OpenHub: https://openhub.net/p/python/contributors
.. _core mentorship program: https://www.python.org/dev/core-mentorship/
-.. _internships: https://www.gnome.org/outreachy/
+.. _internships: https://www.outreachy.org/
.. _Summer of Code: https://wiki.python.org/moin/SummerOfCode/2016
Limitations on scope
---------------------
+====================
-* Specific technical areas of interest for core developers should be captured in
+* Specific technical areas of interest for core team members should be captured in
the :ref:`Experts Index `.
-* This specific listing is limited to CPython core developers (since it's
- focused on the specific constraint that is core developer time), but it
+* This specific listing is limited to CPython core team members (since it's
+ focused on the specific constraint that is core team member time), but it
would be possible to create a more expansive listing on the Python wiki that
- also covers issue triagers, and folks seeking to become core developers.
+ also covers issue triagers, and folks seeking to join the core team.
-* Changes to the software and documentation maintained by core developers,
+* Changes to the software and documentation maintained by the core team,
together with related design discussions, all take place in public venues, and
hence are inherently subject to full public review. Accordingly, core
developers are NOT required to publish their motivations and affiliations if
diff --git a/core-team/responsibilities.rst b/core-team/responsibilities.rst
new file mode 100644
index 000000000..3b2137d6b
--- /dev/null
+++ b/core-team/responsibilities.rst
@@ -0,0 +1,130 @@
+.. _responsibilities:
+
+================
+Responsibilities
+================
+
+As contributors to the CPython project, our shared responsibility is to
+collaborate constructively with other contributors, including core team members.
+This responsibility covers all forms of contribution, whether that's submitting
+pull requests to the implementation or documentation, reviewing other peoples'
+pull requests, triaging issues on the issue tracker, or discussing design and
+development ideas on the core
+:ref:`communication channels `.
+
+Core team members accept key additional responsibilities around the ongoing
+management of the project:
+
+* core team members bear the additional responsibility of handling the
+ consequences of accepting a change into the code base or documentation.
+ That includes reverting or fixing it if it causes problems in the
+ Buildbot fleet or someone spots a problem in post-commit review, as well
+ as helping out the release manager in resolving any problems found during
+ the pre-release testing cycle. While all contributors are free to help out
+ with this part of the process, and it is most welcome when they do, the
+ actual responsibility rests with the core team member that merged the change
+* core team members also bear the primary responsibility for deciding when
+ changes proposed on the issue tracker should be escalated to
+ the appropriate :ref:`Discourse ` category
+ for wider discussion, as well as suggesting the use of the
+ Python Enhancement Proposal process to manage the design and justification
+ of complex changes, or changes with a potentially significant impact on
+ end users
+
+As a result of the additional responsibilities they accept, core team members
+gain the privilege of being able to approve proposed changes, as well as being
+able to reject them as inappropriate. Core team members are also able to request
+that even already merged changes be escalated to
+:ref:`Discourse ` for further discussion,
+and potentially even reverted prior to release.
+
+Joining the core team isn't a binary "all-or-nothing" status - CPython
+is a large project, and different core team members accept responsibility for
+making design and development decisions in different areas (as documented
+in the :ref:`experts` and :ref:`developers`).
+
+
+Communication channels and bug notifications
+============================================
+
+Mailing lists have generally been replaced by the
+`Discourse forum `_ (``discuss.python.org``).
+Refer to the :ref:`mailinglists` and :ref:`communication-discourse` sections
+for more information.
+
+If you want notification of new issues, you can use the appropriate GitHub notification
+settings for the `python/cpython `_ repository —
+follow the link and click on the :guilabel:`Watch` button to set your notification options.
+
+
+.. _contributor_agreement:
+
+Sign a contributor agreement
+============================
+
+Submitting a `contributor form for Python`_ licenses any code you contribute to
+the Python Software Foundation. While you retain the copyright, giving the PSF
+the ability to license your code means it can be put under the PSF license so
+it can be legally distributed with Python.
+
+This is a very important step! Hopefully you have already submitted a
+contributor agreement if you have been submitting pull requests. But if you have not
+done this yet, it is best to do this ASAP, probably before you even do your
+first commit so as to not forget. Also do not forget to enter your GitHub
+username into your details on the issue tracker.
+
+
+.. _contributor form for Python: https://www.python.org/psf/contrib/
+
+
+Pull request merging
+====================
+
+Once you have your commit privileges on GitHub you will be able to accept
+pull requests on GitHub. You should plan to continue to submit your own
+changes through pull requests as if you weren't a core team member to benefit
+from various things such as automatic integration testing, but you
+can accept your own pull requests if you feel comfortable doing so.
+
+
+Expectations
+============
+
+As a core team member, there are certain things that are expected of you.
+
+First and foremost, be a good person. This might sound melodramatic, but you
+are now a member of the Python project and thus represent the project and your
+fellow core team members whenever you discuss Python with anyone. We have a
+reputation for being a very nice group of people and we would like to keep it
+that way. Core team responsibilities include following the `PSF Code of
+Conduct`_.
+
+Second, please be prompt in responding to questions. Many contributors to Python
+are volunteers so what little free time they can dedicate to Python should be
+spent being productive. If you have been asked to respond to an issue or answer
+a question and you put it off it ends up stalling other people's work. It is
+completely acceptable to say you are too busy, but you need to say that instead
+of leaving people waiting for an answer. This also applies to anything you
+do on the issue tracker.
+
+Third, please list what areas you want to be considered an expert in the
+:ref:`experts`. This allows triagers to direct issues to you which involve
+an area you are an expert in. But, as stated in the second point above, if you
+do not have the time to answer questions promptly then please remove yourself as
+needed from the file so that you will not be bothered in the future. Once again,
+we all understand how life gets in the way, so no one will be insulted if you
+remove yourself from the list.
+
+Fourth, please consider whether or not you wish to add your name to the
+:ref:`motivations` list. Core contributor participation in the list helps the
+wider Python community to better appreciate the perspectives currently
+represented amongst the core team, the Python Software Foundation
+to better assess the sustainability of current contributions to CPython core
+development, and also serves as a referral list for organisations seeking
+commercial Python support from the core development community.
+
+And finally, enjoy yourself! Contributing to open source software should be fun
+(overall). If you find yourself no longer enjoying the work then either take a
+break or figure out what you need to do to make it enjoyable again.
+
+.. _PSF Code of Conduct: https://policies.python.org/python.org/code-of-conduct/
diff --git a/developers.rst b/core-team/team-log.rst
similarity index 79%
rename from developers.rst
rename to core-team/team-log.rst
index 160b7060e..77639ebf1 100644
--- a/developers.rst
+++ b/core-team/team-log.rst
@@ -1,18 +1,20 @@
+.. _developer-log:
.. _developers:
+.. _team-log:
-Developer Log
-=============
+Team log
+========
-This page lists the historical members of the Python development team. (The
+This page lists the historical members of the Python core team. (The
master list is kept in a private repository due to containing sensitive contact
information.)
.. csv-table::
:header: "Name", "GitHub username", "Joined", "Left", "Notes"
- :file: developers.csv
+ :file: core-team.csv
:encoding: "utf-8"
-Procedure for Granting or Dropping Access
+Procedure for granting or dropping access
-----------------------------------------
To be granted the ability to manage who is a committer, you must be a
diff --git a/coredev.rst b/coredev.rst
deleted file mode 100644
index 195b5f559..000000000
--- a/coredev.rst
+++ /dev/null
@@ -1,178 +0,0 @@
-.. _coredev:
-
-How to Become a Core Developer
-==============================
-
-What it Takes
--------------
-
-When you have consistently contributed patches which meet quality standards
-without requiring extensive rewrites prior to being committed,
-you may qualify for commit privileges and become a core developer of Python.
-You must also work well with other core developers (and people in general)
-as you become an ambassador for the Python project.
-
-Typically a core developer will offer you the chance to gain commit privilege.
-The person making the offer will become your mentor and watch your commits for
-a while to make sure you understand the development process. If other core
-developers agree that you should gain commit privileges you are then extended
-an official offer. How core developers come to that agreement are outlined in
-:pep:`13`.
-
-What it Means
--------------
-
-As contributors to the CPython project, our shared responsibility is to
-collaborate constructively with other contributors, including core developers.
-This responsibility covers all forms of contribution, whether that's submitting
-patches to the implementation or documentation, reviewing other peoples'
-patches, triaging issues on the issue tracker, or discussing design and
-development ideas on the core mailing lists.
-
-Core developers accept key additional responsibilities around the ongoing
-management of the project:
-
-* core developers bear the additional responsibility of handling the
- consequences of accepting a change into the code base or documentation.
- That includes reverting or fixing it if it causes problems in the
- Buildbot fleet or someone spots a problem in post-commit review, as well
- as helping out the release manager in resolving any problems found during
- the pre-release testing cycle. While all contributors are free to help out
- with this part of the process, and it is most welcome when they do, the
- actual responsibility rests with the core developer that merged the change
-* core developers also bear the primary responsibility for deciding when
- changes proposed on the issue tracker should be escalated to python-ideas
- or python-dev for wider discussion, as well as suggesting the use of the
- Python Enhancement Proposal process to manage the design and justification
- of complex changes, or changes with a potentially significant impact on
- end users
-
-As a result of the additional responsibilities they accept, core developers
-gain the privilege of being able to approve proposed changes, as well as being
-able to reject them as inappropriate. Core developers are also able to request
-that even already merged changes be escalated to python-dev for further
-discussion, and potentially even reverted prior to release.
-
-Becoming a core developer isn't a binary "all-or-nothing" status - CPython
-is a large project, and different core developers accept responsibility for
-making design and development decisions in different areas (as documented
-in the :ref:`experts` and :ref:`developers`).
-
-Gaining Commit Privileges
--------------------------
-
-The steps to gaining commit privileges are:
-
-1. A core developer starts a poll at https://discuss.python.org/c/committers/
-
- - Open for 7 days
- - Results shown upon close
-
-2. The poll is announced on python-committers
-3. Wait for the poll to close and see if the results confirm your membership
- as per the voting results requied by PEP 13
-4. The person who nominated you emails the steering council with your email
- address and a request that the council either accept or reject the proposed
- membership
-5. Assuming the steering council does not object, a member of the council will
- email you asking for:
-
- - Account details as required by
- https://github.com/python/voters/
- - Your preferred email address to
- subscribe to python-committers with
- - A reminder about the `Code of Conduct`_ and to report issues to the PSF
- Conduct WG
-
-6. Once you have provided the pertinent details, your various new privileges
- will be turned on
-7. Your details will be added to https://github.com/python/voters/
-8. They will update the devguide to publicly list your team membership at
- :ref:`developers`
-9. An announcement email by the steering council member handling your new
- membership will be sent to python-committers
-
-.. _Code of Conduct: https://www.python.org/psf/conduct/
-
-
-Mailing Lists
-'''''''''''''
-
-You are expected to subscribe to python-committers, python-dev,
-python-checkins, and one of new-bugs-announce or python-bugs-list. See
-:ref:`communication` for links to these mailing lists.
-
-
-.. _contributor_agreement:
-
-Sign a Contributor Agreement
-''''''''''''''''''''''''''''
-
-Submitting a `contributor form for Python`_ licenses any code you contribute to
-the Python Software Foundation. While you retain the copyright, giving the PSF
-the ability to license your code means it can be put under the PSF license so
-it can be legally distributed with Python.
-
-This is a very important step! Hopefully you have already submitted a
-contributor agreement if you have been submitting patches. But if you have not
-done this yet, it is best to do this ASAP, probably before you even do your
-first commit so as to not forget. Also do not forget to enter your GitHub
-username into your details on the issue tracker.
-
-
-.. _contributor form for Python: https://www.python.org/psf/contrib/
-
-
-
-Pull Request merging
-''''''''''''''''''''
-
-Once you have your commit privileges on GitHub you will be able to accept
-pull requests on GitHub. You should plan to continue to submit your own
-changes through pull requests as if you weren't a core developer to benefit
-from various things such as automatic integration testing, but you
-can accept your own pull requests if you feel comfortable doing so.
-
-
-Responsibilities
-----------------
-
-As a core developer, there are certain things that are expected of you.
-
-First and foremost, be a good person. This might sound melodramatic, but you
-are now a member of the Python project and thus represent the project and your
-fellow core developers whenever you discuss Python with anyone. We have a
-reputation for being a very nice group of people and we would like to keep it
-that way. Core developers responsibilities include following the `PSF Code of
-Conduct`_.
-
-Second, please be prompt in responding to questions. Many contributors to Python
-are volunteers so what little free time they can dedicate to Python should be
-spent being productive. If you have been asked to respond to an issue or answer
-a question and you put it off it ends up stalling other people's work. It is
-completely acceptable to say you are too busy, but you need to say that instead
-of leaving people waiting for an answer. This also applies to anything you
-do on the issue tracker.
-
-Third, please list what areas you want to be considered an expert in the
-:ref:`experts`. This allows triagers to direct issues to you which involve
-an area you are an expert in. But, as stated in the second point above, if you
-do not have the time to answer questions promptly then please remove yourself as
-needed from the file so that you will not be bothered in the future. Once again,
-we all understand how life gets in the way, so no one will be insulted if you
-remove yourself from the list.
-
-Fourth, please consider whether or not you wish to add your name to the
-:ref:`motivations` list. Core contributor participation in the list helps the
-wider Python community to better appreciate the perspectives currently
-represented amongst the core development team, the Python Software Foundation
-to better assess the sustainability of current contributions to CPython core
-development, and also serves as a referral list for organisations seeking
-commercial Python support from the core development community.
-
-And finally, enjoy yourself! Contributing to open source software should be fun
-(overall). If you find yourself no longer enjoying the work then either take a
-break or figure out what you need to do to make it enjoyable again.
-
-
-.. _PSF Code of Conduct: https://www.python.org/psf/codeofconduct/
diff --git a/coverity.rst b/coverity.rst
deleted file mode 100644
index 2a9359715..000000000
--- a/coverity.rst
+++ /dev/null
@@ -1,153 +0,0 @@
-=============
-Coverity Scan
-=============
-
-.. _coverity:
-
-Coverity Scan is a free service for static code analysis of Open Source
-projects. It is based on Coverity's commercial product and is able to analyze
-C, C++ and Java code.
-
-Coverity's static code analysis doesn't run the code. Instead of that it uses
-abstract interpretation to gain information about the code's control flow and
-data flow. It's able to follow all possible code paths that a program may
-take. For example the analyzer understands that ``malloc()`` returns a memory
-that must be freed with ``free()`` later. It follows all branches and function
-calls to see if all possible combinations free the memory. The analyzer is
-able to detect all sorts of issues like resource leaks (memory, file
-descriptors), NULL dereferencing, use after free, unchecked return values,
-dead code, buffer overflows, integer overflows, uninitialized variables, and
-many more.
-
-
-Access to analysis reports
-==========================
-
-The results are available on the `Coverity Scan`_ website. In order to
-access the results you have to create an account yourself. Then go to
-*Projects using Scan* and add yourself to the Python project. New members must
-be approved by an admin (see `Contact`_).
-
-Access is restricted to Python core developers only. Other individuals may be
-given access at our own discretion, too. Every now and then Coverity detects a
-critical issue in Python's code -- new analyzers may even find new bugs in
-mature code. We don't want to disclose issues prematurely.
-
-
-Building and uploading analysis
-===============================
-
-The process is automated. A script checks out the code, runs
-``cov-build`` and uploads the latest analysis to Coverity. Since Coverity has
-limited the maximum number of builds per week Python is analyzed every second
-day. The build runs on a dedicated virtual machine on PSF's infrastructure at
-OSU Open Source Labs. The process is maintained by Christian Heimes (see
-`Contact`_). At present only the tip is analyzed with the 64bit Linux tools.
-
-
-Known limitations
-=================
-
-Some aspects of Python's C code are not yet understood by Coverity.
-
-False positives
----------------
-
-``Py_BuildValue("N", PyObject*)``
- Coverity doesn't understand that ``N`` format char passes the object along
- without touching its reference count. On this ground the analyzer detects
- a resource leak. CID 719685
-
-``PyLong_FromLong()`` for negative values
- Coverity claims that ``PyLong_FromLong()`` and other ``PyLong_From*()``
- functions cannot handle a negative value because the value might be used as
- an array index in ``get_small_int()``. CID 486783
-
-``PyLong_FromLong()`` for n in [-5 ... +255]
- For integers in the range of Python's small int cache the ``PyLong_From*()``
- function can never fail and never returns NULL. CID 1058291
-
-``PyArg_ParseTupleAndKeywords(args, kwargs, "s#", &data, &length)``
- Some functions use the format char combination such as ``s#``, ``u#`` or
- ``z#`` to get data and length of a character array. Coverity doesn't
- recognize the relation between data and length. Sometimes it detects a buffer
- overflow if data is written to a fixed size buffer although
- ``length <= sizeof(buffer)``. CID 486613
-
-``path_converter()`` dereferencing after null check
- The ``path_converter()`` function in ``posixmodule.c`` makes sure that
- either ``path_t.narrow`` or ``path_t.wide`` is filled unless
- ``path_t.nullable`` is explicitly enabled. CID 719648
-
-
-Intentionally
--------------
-
-``Py_VA_COPY()``
- Python is written in C89 (ANSI C), therefore it can't use C99 features such
- as ``va_copy()``. Python's own variant ``Py_VA_COPY()`` uses ``memcpy()``
- to make a copy of a ``va_list`` variable. Coverity detects two issues in
- this approach: "Passing argument "lva" of type "va_list" and sizeof(va_list)
- to function memcpy() is suspicious." CID 486405 and "Uninitialized pointer
- read" CID 486630.
-
-
-Modeling
-========
-
-Modeling is explained in the *Coverity Help Center* which is available in
-the help menu of `Coverity Connect`_. `coverity_model.c`_ contains a copy of
-Python's modeling file for Coverity. Please keep the copy in sync with the
-model file in *Analysis Settings* of `Coverity Scan`_.
-
-
-Workflow
-========
-
-False positive and intentional issues
--------------------------------------
-
-If the problem is listed under `Known limitations`_ then please set the
-classification to either "False positive" or "Intentional", the action to
-"Ignore", owner to your own account and add a comment why the issue
-is considered false positive or intentional.
-
-If you think it's a new false positive or intentional then please contact an
-admin. The first step should be an updated to Python's `Modeling`_ file.
-
-
-Positive issues
----------------
-
-You should always create an issue unless it's really a trivial case. Please
-add the full url to the ticket under *Ext. Reference* and add the CID
-(Coverity ID) to both the ticket and the checkin message. It makes it much
-easier to understand the relation between tickets, fixes and Coverity issues.
-
-
-Contact
-=======
-
-Please include both Brett and Christian in any mail regarding Coverity. Mails
-to Coverity should go through Brett or Christian, too.
-
-Christian Heimes
- admin, maintainer of build machine, intermediary between Python and Coverity
-
-Brett Cannon
- co-admin
-
-Dakshesh Vyas
- Technical Manager - Coverity Scan
-
-
-.. seealso::
-
- `Coverity Scan FAQ `_
-
-
-.. _Coverity Scan: https://scan.coverity.com/
-
-.. _Coverity Connect: https://scan.coverity.com/projects/python
-
-.. _coverity_model.c: https://github.com/python/cpython/blob/main/Misc/coverity_model.c
diff --git a/developer-workflow/c-api.rst b/developer-workflow/c-api.rst
new file mode 100644
index 000000000..90c1d12e4
--- /dev/null
+++ b/developer-workflow/c-api.rst
@@ -0,0 +1,454 @@
+.. _c-api:
+
+=======================
+Changing Python's C API
+=======================
+
+The C API is divided into these tiers:
+
+1. The internal, private API, available with ``Py_BUILD_CORE`` defined.
+ Ideally declared in ``Include/internal/``. Any API named with a leading
+ underscore is also considered private.
+2. The Unstable C API, identified by the ``PyUnstable_`` name prefix.
+ Ideally declared in :cpy-file:`Include/cpython/` along with the general public API.
+3. The “general” public C API, available when :cpy-file:`Include/Python.h` is included normally.
+ Ideally declared in ``Include/cpython/``.
+4. The Limited C API, available with :c:macro:`Py_LIMITED_API` defined.
+ Ideally declared directly under ``Include/``.
+
+Each tier has different stability and maintenance requirements to consider
+when you add or change definitions in it.
+
+The public backwards compatibility guarantees for public C API are explained
+in the user documentation, ``Doc/c-api/stable.rst`` (:ref:`python:stable`).
+C language compatibility guarantees are in ``Doc/c-api/intro.rst``
+(:ref:`python:api-intro`).
+
+As core developers, we need to be more careful about compatibility than what
+we promise publicly. See :ref:`public-capi` for details.
+
+
+The internal API
+================
+
+Internal API is defined in ``Include/internal/`` and is only available
+for building CPython itself, as indicated by a macro like ``Py_BUILD_CORE``.
+
+While internal API can be changed at any time, it's still good to keep it
+stable: other API or other CPython developers may depend on it.
+For users, internal API is sometimes the best workaround for a thorny problem
+--- though those use cases should be discussed on the
+`C API Discourse category `_
+or an issue so we can try to find a supported way to serve them.
+
+
+With PyAPI_FUNC or PyAPI_DATA
+-----------------------------
+
+Functions or structures in ``Include/internal/`` defined with
+``PyAPI_FUNC`` or ``PyAPI_DATA`` are internal functions which are
+exposed only for specific use cases like debuggers and profilers.
+Ideally, these should be migrated to the :ref:`unstable-capi`.
+
+
+With the extern keyword
+-----------------------
+
+Functions in ``Include/internal/`` defined with the ``extern`` keyword
+*must not and can not* be used outside the CPython code base. Only
+built-in stdlib extensions (built with the ``Py_BUILD_CORE_BUILTIN``
+macro defined) can use such functions.
+
+When in doubt, new internal C functions should be defined in
+``Include/internal`` using the ``extern`` keyword.
+
+Private names
+-------------
+
+Any API named with a leading underscore is also considered internal.
+There is currently only one main use case for using such names rather than
+putting the definition in :cpy-file:`Include/internal/` (or directly in a ``.c`` file):
+
+* Internal helpers for other public APIs, which users should not call directly.
+
+Note that historically, underscores were used for APIs that are better served by
+the :ref:`unstable-capi`:
+
+* “provisional” APIs, included in a Python release to test real-world
+ usage of new APIs;
+* APIs for very specialized uses like JIT compilers.
+
+
+Internal API tests
+------------------
+
+C tests for the internal C API live in ``Modules/_testinternalcapi.c``.
+Functions named ``test_*`` are used as tests directly.
+Python parts of the tests live in various places in ``Lib/test``.
+
+
+.. _public-capi:
+
+Public C API
+============
+
+CPython's public C API is available when ``Python.h`` is included normally
+(that is, without defining macros to select the other variants).
+
+It should be defined in ``Include/cpython/`` (unless part of the Limited API,
+see below).
+
+Before adding new public API, please ask in the `decisions repo`_ of
+the :pep:`C API workgroup <731>`.
+This helps us ensure *newly added* API is consistent and maintainable.
+
+Also check with the C API WG before requiring a C feature not present in C99.
+While the *public* docs only promise compatibility with C11, in practice
+we only intruduce C11 features individually as needed.
+
+.. _decisions repo: https://github.com/capi-workgroup/decisions/issues
+
+
+.. _public-api-guidelines:
+
+Guidelines for expanding/changing the public API
+------------------------------------------------
+
+- Make sure the new API follows reference counting conventions.
+ (Following them makes the API easier to reason about, and easier use
+ in other Python implementations.)
+
+ - Functions *must not* steal references
+ - Functions *must not* return borrowed references
+ - Functions returning references *must* return a strong reference
+
+- Make sure the ownership rules and lifetimes of all applicable struct
+ fields, arguments and return values are well defined.
+
+- Functions returning ``PyObject *`` must return a valid pointer on success,
+ and ``NULL`` with an exception raised on error.
+ Most other API must return ``-1`` with an exception raised on error,
+ and ``0`` on success.
+
+- APIs with lesser and greater results must return ``0`` for the lesser result,
+ and ``1`` for the greater result.
+ Consider a lookup function with a three-way return:
+
+ - ``return -1``: internal error or API misuse; exception raised
+ - ``return 0``: lookup succeeded; no item was found
+ - ``return 1``: lookup succeeded; item was found
+
+Please start a public discussion if these guidelines won't work for your API.
+
+.. note::
+
+ By *return value*, we mean the value returned by the *C return statement*.
+
+C API tests
+-----------
+
+Tests for the public C API live in the ``_testcapi`` module.
+Functions named ``test_*`` are used as tests directly.
+Tests that need Python code (or are just easier to partially write in Python)
+live in ``Lib/test``, mainly in :cpy-file:`Lib/test/test_capi`.
+
+Due to its size, the ``_testcapi`` module is defined in several source
+files.
+To add a new set of tests (or extract a set out of the monolithic
+:cpy-file:`Modules/_testcapimodule.c`):
+
+- Create a C file named ``Modules/_testcapi/yourfeature.c``
+
+- The file should define a module as usual, except:
+
+ - Instead of ````, include ``"parts.h"``.
+ - Instead of ``PyInit_modname``, define a ``_PyTestCapi_Init_yourfeature``
+ function that *takes* the ``_testcapi`` module and adds functions/classes
+ to it. (You can use ``PyModule_AddFunctions`` to add functions.)
+
+- Add the ``_PyTestCapi_Init_*`` function to ``Modules/_testcapi/parts.h``
+
+- Call the ``_PyTestCapi_Init_*`` from ``PyInit__testcapi`` in
+ ``Modules/_testcapimodule.c``.
+
+- Add the new C file to :cpy-file:`Modules/Setup.stdlib.in`,
+ :cpy-file:`PCbuild/_testcapi.vcxproj` and
+ :cpy-file:`PCbuild/_testcapi.vcxproj.filters`,
+ alongside the other ``_testcapi/*.c`` entries.
+
+Note that all ``Modules/_testcapi/*.c`` sources initialize the same module,
+so be careful about name collisions.
+
+When moving existing tests, feel free to replace ``TestError`` with
+``PyExc_AssertionError`` unless actually testing custom exceptions.
+
+
+.. _unstable-capi:
+
+Unstable C API
+==============
+
+The unstable C API tier is meant for extensions that need tight integration
+with the interpreter, like debuggers and JIT compilers.
+Users of this tier may need to change their code with every feature release.
+
+In many ways, this tier is like the general C API:
+
+- it's available when ``Python.h`` is included normally,
+- it should be defined in :cpy-file:`Include/cpython/`,
+- it requires tests, so we don't break it unintentionally
+- it requires docs, so both we and the users,
+ can agree on the expected behavior,
+- it is tested and documented in the same way.
+
+The differences are:
+
+- Names of functions structs, macros, etc. start with the ``PyUnstable_``
+ prefix. This defines what's in the unstable tier.
+- The unstable API can change in feature releases, without any deprecation
+ period.
+- A stability note appears in the docs.
+ This happens automatically, based on the name
+ (via :cpy-file:`Doc/tools/extensions/c_annotations.py`).
+
+Despite being “unstable”, there are rules to make sure third-party code can
+use this API reliably:
+
+* Changes and removals can be done in feature releases
+ (:samp:`3.{x}.0`, including Alphas and Betas for :samp:`3.{x}.0`).
+* Adding a new unstable API *for an existing feature* is allowed even after
+ Beta feature freeze, up until the first Release Candidate.
+ Consensus on the `Core Development Discourse `_
+ is needed in the Beta period.
+* Backwards-incompatible changes should make existing C callers fail to compile.
+ For example, arguments should be added/removed, or a function should be
+ renamed.
+* When moving an API into or out of the Unstable tier, the old name
+ should continue to be available (but deprecated) until an incompatible
+ change is made. In other words, while we're allowed to break calling code,
+ we shouldn't break it *unnecessarily*.
+
+
+Moving an API from the public tier to Unstable
+----------------------------------------------
+
+* Expose the API under its new name, with the ``PyUnstable_`` prefix.
+ The ``PyUnstable_`` prefix must be used for all symbols (functions, macros,
+ variables, etc.).
+* Make the old name an alias (for example, a ``static inline`` function calling the
+ new function).
+* Deprecate the old name, typically using :c:macro:`Py_DEPRECATED`.
+* Announce the change in the "What's New".
+
+The old name should continue to be available until an incompatible change is
+made. Per Python’s backwards compatibility policy (:pep:`387`),
+this deprecation needs to last at least two releases
+(modulo Steering Council exceptions).
+
+The rules are relaxed for APIs that were introduced in Python versions
+before 3.12, when the official Unstable tier was added.
+You can make an incompatible change (and remove the old name)
+as if the function was already part of the Unstable tier
+for APIs introduced before Python 3.12 that are either:
+
+* Documented to be less stable than default.
+* Named with a leading underscore.
+
+Moving an API from the private tier to unstable
+-----------------------------------------------
+
+* Expose the API under its new name, with the ``PyUnstable_`` prefix.
+* If the old name is documented, or widely used externally,
+ make it an alias and deprecate it (typically with :c:macro:`Py_DEPRECATED`).
+ It should continue to be available until an incompatible change is made,
+ as if it was previously public.
+
+ This applies even to underscored names. Python wasn't always strict with
+ the leading underscore.
+* Announce the change in What's New.
+
+Moving an API from unstable to public
+-------------------------------------
+
+* Expose the API under its new name, without the ``PyUnstable_`` prefix.
+* Make the old ``PyUnstable_*`` name be an alias (for example, a ``static inline``
+ function calling the new function).
+* Announce the change in What's New.
+
+The old name should remain available until the
+new public name is deprecated or removed.
+There's no need to deprecate the old name (it was unstable to begin with),
+but there's also no need to break working code just because some function
+is now ready for a wider audience.
+
+
+Limited API
+===========
+
+The Limited API is a subset of the C API designed to guarantee ABI
+stability across Python 3 versions.
+Defining the macro ``Py_LIMITED_API`` will limit the exposed API to
+this subset.
+
+No changes that break the Stable ABI are allowed.
+
+The Limited API should be defined in ``Include/``, excluding the
+``cpython`` and ``internal`` subdirectories.
+
+
+Guidelines for changing the Limited API, and removing items from it
+-------------------------------------------------------------------
+
+While the *Stable ABI* must not be broken, the existing Limited API can be
+changed, and items can be removed from it, if:
+
+- the Backwards Compatibility Policy (:pep:`387`) is followed, and
+- the Stable ABI is not broken -- that is, extensions compiled with
+ Limited API of older versions of Python continue to work on
+ newer versions of Python.
+
+This is tricky to do and requires careful thought.
+Some examples:
+
+- Functions, structs etc. accessed by macros in *any version* of the
+ Limited API are part of the Stable ABI, even if they are named with
+ an underscore. They must not be removed and their signature must not change.
+ (Their implementation may change, though.)
+- Structs members cannot be rearranged if they were part of any version of
+ the Limited API.
+- If the Limited API allows users to allocate a struct directly,
+ its size must not change.
+- Exported symbols (functions and data) must continue to be available
+ as exported symbols. Specifically, a function can only be converted
+ to a ``static inline`` function (or macro) if Python also continues to
+ provide the actual function.
+ For an example, see the ``Py_NewRef`` `macro`_ and `redefinition`_ in 3.10.
+
+.. _macro: https://github.com/python/cpython/blob/2cd268a3a9340346dd86b66db2e9b428b3f878fc/Include/object.h#L592-L596
+.. _redefinition: https://github.com/python/cpython/blob/2cd268a3a9340346dd86b66db2e9b428b3f878fc/Objects/object.c#L2303-L2313
+
+It is possible to remove items marked as part of the Stable ABI, but only
+if there was no way to use them in any past version of the Limited API.
+
+
+.. _limited-api-guidelines:
+
+Guidelines for adding to the Limited API
+----------------------------------------
+
+- Guidelines for the general :ref:`public-capi` apply.
+ See :ref:`public-api-guidelines`.
+
+- New Limited API should only be defined if ``Py_LIMITED_API`` is set
+ to the version the API was added in or higher.
+ (See below for the proper ``#if`` guard.)
+
+- All parameter types, return values, struct members, etc. need to be part
+ of the Limited API.
+
+ - Functions that deal with ``FILE*`` (or other types with ABI portability
+ issues) should not be added.
+
+- Think twice when defining macros.
+
+ - Macros should not expose implementation details
+ - Functions must be exported as actual functions, not (only)
+ as functions-like macros.
+ - If possible, avoid macros. This makes the Limited API more usable in
+ languages that don't use the C preprocessor.
+
+- Please start a public discussion before expanding the Limited API
+
+- The Limited API and must follow standard C, not just features of currently
+ supported platforms. The exact C dialect is described in :pep:`7`.
+
+ - Documentation examples (and more generally: the intended use of the API)
+ should also follow standard C.
+ - In particular, do not cast a function pointer to ``void*`` (a data pointer)
+ or vice versa.
+
+- Think about ease of use for the user.
+
+ - In C, ease of use itself is not very important; what is useful is
+ reducing boilerplate code needed to use the API. Bugs like to hide in
+ boiler plates.
+
+ - If a function will be often called with specific value for an argument,
+ consider making it default (used when ``NULL`` is passed in).
+ - The Limited API needs to be well documented.
+
+- Think about future extensions
+
+ - If it's possible that future Python versions will need to add a new
+ field to your struct, make sure it can be done.
+ - Make as few assumptions as possible about implementation details that
+ might change in future CPython versions or differ across C API
+ implementations. The most important CPython-specific implementation
+ details involve:
+
+ - The GIL
+ - :ref:`Garbage collection `
+ - Memory layout of PyObject, lists/tuples and other structures
+
+If following these guidelines would hurt performance, add a fast function
+(or macro) to the non-limited API and a stable equivalent to the Limited
+API.
+
+If anything is unclear, or you have a good reason to break the guidelines,
+consider discussing the change at the `capi-sig`_ mailing list.
+
+.. _capi-sig: https://mail.python.org/mailman3/lists/capi-sig.python.org/
+
+Adding a new definition to the Limited API
+------------------------------------------
+
+- Add the declaration to a header file directly under ``Include/``, into a
+ block guarded with the following:
+
+ .. code-block:: c
+
+ #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03yy0000
+
+ with the ``yy`` corresponding to the target CPython version, for example,
+ ``0x030A0000`` for Python 3.10.
+- Append an entry to the Stable ABI manifest, ``Misc/stable_abi.toml``
+- Regenerate the autogenerated files using ``make regen-limited-abi``.
+ On platforms without ``make``, run this command directly:
+
+ .. code-block:: shell
+
+ ./python ./Tools/build/stable_abi.py --generate-all ./Misc/stable_abi.toml
+
+- Build Python and check the using ``make check-limited-abi``.
+ On platforms without ``make``, run this command directly:
+
+ .. code-block:: shell
+
+ ./python ./Tools/build/stable_abi.py --all ./Misc/stable_abi.toml
+
+- Add tests -- see below.
+
+
+Limited API tests
+-----------------
+
+Since Limited API is a subset of the C API, there's no need to test the
+behavior of individual functions. Rather, the tests could verify that some
+task is possible using the exposed subset, or exercise a feature that was
+removed from the current Limited API but still needs to be supported for
+older Limited API/Stable ABI versions.
+
+To add a test file:
+
+- Add a C file ``Modules/_testcapi/yourfeature_limited.c``. If that file
+ already exists but its ``Py_LIMITED_API`` version is too low, add a version
+ postfix, for example, ``yourfeature_limited_3_12.c`` for Python 3.12+.
+- ``#define Py_LIMITED_API`` to the minimum limited API version needed.
+- ``#include "parts.h"`` after the ``Py_LIMITED_API`` definition
+- Enclose the entire rest of the file in ``#ifdef LIMITED_API_AVAILABLE``,
+ so it's skipped on incompatible builds.
+- Follow the general instructions for `C API tests`_. All additions go in the
+ sections guarded by ``#ifdef LIMITED_API_AVAILABLE``.
+
+Use the ``test.support.requires_limited_api`` decorator for Python tests
+in ``Lib/test``, so they're skipped on incompatible builds.
diff --git a/developer-workflow/communication-channels.rst b/developer-workflow/communication-channels.rst
new file mode 100644
index 000000000..9b088b350
--- /dev/null
+++ b/developer-workflow/communication-channels.rst
@@ -0,0 +1,276 @@
+.. _communication-channels:
+.. _communication:
+
+==============================
+Following Python's development
+==============================
+
+Python's development is communicated through a myriad of ways,
+primarily :ref:`Discourse ` along with other platforms.
+
+
+Standards of behaviour in these communication channels
+======================================================
+
+We try to foster environments of mutual respect, tolerance and encouragement,
+as described in the PSF's `Diversity Statement`_. Abiding by the guidelines
+in this document and asking questions or posting suggestions in the
+appropriate channels are an excellent way to get started on the mutual respect
+part, greatly increasing the chances of receiving tolerance and encouragement
+in return.
+
+.. _Diversity Statement: https://www.python.org/psf/diversity/
+
+
+.. _mailinglists:
+
+Mailing lists
+=============
+
+.. note::
+
+ Mailing lists have generally been replaced by the `Discourse`_ forum.
+ Specifically,
+
+ * The python-dev list is superseded by the `Core Development`_
+ and `PEPs`_ categories on Discourse.
+ * The python-ideas list is superseded by posts in the `Ideas`_
+ category on Discourse.
+
+ Discussion in :guilabel:`Core Development` is focused on issues related to Python's
+ own development, such as how to handle a specific issue, a PEP, etc.
+
+ - Ideas about new functionality should **not** start here, and instead
+ should be discussed in `Ideas`_.
+ - Technical support questions should also not be asked here, and instead
+ should go to the `Python Help`_ category on Discourse or the python-list_.
+
+ Previous threads on the python-dev_, python-committers_, and python-ideas_
+ mailing lists can be accessed through the `online archive
+ `__.
+
+ .. _python-committers: https://mail.python.org/mailman3/lists/python-committers.python.org/
+ .. _python-dev: https://mail.python.org/mailman3/lists/python-dev.python.org/
+ .. _python-ideas: https://mail.python.org/mailman3/lists/python-ideas.python.org
+
+General Python questions should go to `python-list`_ or `tutor`_
+or similar resources, such as `Stack Overflow`_ or the ``#python`` IRC channel
+on Libera.Chat_.
+
+The `core-workflow `__
+issue tracker is the place to discuss and work on improvements to the CPython
+core development workflow.
+
+A complete list of Python mailing lists can be found at
+https://mail.python.org/mailman/listinfo (older lists, using Mailman2) or
+https://mail.python.org/mailman3/ (newer lists, using Mailman3). Some lists may also
+be mirrored at `GMANE `_ and can be read and posted to in various
+ways, including via web browsers, NNTP newsreaders, and RSS feed readers.
+
+.. _python-list: https://mail.python.org/mailman/listinfo/python-list
+.. _tutor: https://mail.python.org/mailman/listinfo/tutor
+.. _Stack Overflow: https://stackoverflow.com/
+.. _Libera.Chat: https://libera.chat/
+
+
+.. _communication-discourse:
+
+Discourse (discuss.python.org web forum)
+========================================
+
+We have our own `Discourse`_ forum for both developers and users.
+It has different categories and most core development discussions
+take place in the open forum categories for `PEPs`_ and `Core Development`_
+(these are the Discourse equivalents to the python-dev mailing list).
+All categories are open for users to read and post with the exception of
+the `Committers`_ category, where posting is restricted to the `CPython
+`_ core team.
+
+The Committers category is often used for announcements and notifications.
+It is also the designated venue for the core team promotion votes.
+
+Tutorials for new users
+-----------------------
+
+To start a topic or participate in any discussions in the forum, sign up and
+create an account using an email address or GitHub account. You can do so by
+clicking the :guilabel:`Sign Up` button on the top right hand corner of the
+`Discourse`_ main page.
+
+The Python Discourse `Quick Start `_
+compiled by `Carol Willing `_ gives you
+a quick overview on how to kick off Python Discourse.
+
+We recommend new users getting familiarised with the forum by going through Discobot tutorials.
+These tutorials can be activated by replying to a welcome message from "discourse
+Greetings!" received under Notifications and Messages in your user account.
+
+* Click on your personal account found on the top right hand corner of the page.
+* The dropdown menu will show four different icons:
+ :guilabel:`🔔` (Notifications),
+ :guilabel:`🔖` (Bookmarks),
+ :guilabel:`✉️` (Messages), and
+ :guilabel:`👤` (Preferences).
+* Select either Notifications or Messages.
+* Open the "Greetings!" message sent by Discobot to start the tutorial.
+
+Ensure that you read through the `Python Code of Conduct `_.
+We are to be open, considerate and respectful to all users in the community.
+You can report messages that don't respect the CoC by clicking on the three
+dots under the message and then on the :guilabel:`⚐` icon. You can also mention the
+`@staff `_,
+`@moderators `_, or
+`@admins `_ groups in a message.
+
+
+
+Reading topics
+--------------
+
+Click a topic title and read down the list of replies in chronological order,
+following links or previewing replies and quotes as you go. Use your mouse to
+scroll the screen, or use the timeline scroll bar on the right which also shows
+you how far through the conversation you've read. On smaller screens, select the
+bottom progress bar to expand it.
+
+
+Notifications
+-------------
+
+Following categories (category notifications)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Notifications can be set for individual categories and topics. To change any of these
+defaults, you can either go to your user preferences, or visit the category
+page, and use the notification button :guilabel:`🔔` above the topic list,
+on the top right hand corner of the category page beside the
+:guilabel:`+ New Topic` button.
+
+Clicking on the notification control :guilabel:`🔔` will show a drop-down panel with 5
+different options: Watching, Tracking, Watching First Post, Normal, and Muted.
+All categories are set by default in Normal mode where you will only be notified
+if someone mentions your @name or replies to you.
+
+Following individual threads (topic notifications)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To follow any individual topics or threads, you can adjust your notifications
+through the notification button :guilabel:`🔔` found on the right of the topic at the end
+of the timeline. You can also do so at the bottom of each topic.
+Select "Watching" and you will be notified when there is any new updated reply
+from that particular thread.
+
+Customising notifications on user preference
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To get a bird's eye view of all your customised notifications, you can
+go to `Preferences of your account `_.
+This allows you to make adjustments according to categories, users, and tags.
+
+Enabling mailing list mode
+--------------------------
+
+In mailing list mode, you will receive one email per post, as happens with
+traditional mailing lists. This is desirable if you prefer to interact via email,
+without visiting the forum website.
+To activate the mailing list mode, go to the `email preferences
+`_, check "Enable
+mailing list mode" and save changes.
+
+.. _Discourse: https://discuss.python.org/
+.. _PEPs: https://discuss.python.org/c/peps/19
+.. _Core Development: https://discuss.python.org/c/core-dev/23
+.. _Committers: https://discuss.python.org/c/committers/5
+.. _Ideas: https://discuss.python.org/c/ideas/6
+.. _Python Help: https://discuss.python.org/c/help/7
+
+
+Discord (private chat server)
+=============================
+
+For more real-time discussions, the core development team have a private Discord
+server available. Core team members, Steering Council members, triagers, and
+documentarians on the project are eligible to join the server. Joining the
+Discord server is entirely optional, as all essential communications occur on
+the mailing lists and Discourse forums.
+
+For core team members, a long-lived multiple-use invitation link for this server
+can be found in the private core team only section of the Discourse forum.
+
+For triagers and documentarians joining the Discord server, a single use invitation
+link should be generated and sent to them directly.
+
+When first joining the server, new users will only have access to the ``#welcome``
+and ``#rules-and-info`` channels. To link their Discord ID with their project
+role, core team members may update their Steering Council 🔒 `voter record`_ with
+their Discord ID before posting in the ``#welcome`` channel to request access
+to the rest of the server channels. Triagers, documentarians, and core team members
+that would prefer not to add their Discord ID to their Steering Council voter
+record may instead be vouched for by an existing member of the Discord server.
+
+As a private, non-archived, forum, final decisions on design and development
+questions should not be made on Discord. Any conclusions from Discord discussions
+should be summarised and posted to the issue tracker, Discourse forum, or
+mailing list (the appropriate venue for sharing conclusions will depend on the
+specific discussion).
+
+Note: existing Discord users may want to right click on their username in the
+automatic Discord welcome message and choose "Edit Server Profile" in order to
+set a specific `Server Nickname`_
+
+.. _voter record: https://github.com/python/voters/blob/main/python-core.toml
+.. _Server Nickname: https://support.discord.com/hc/en-us/articles/219070107-Server-Nicknames
+
+
+IRC
+===
+
+Some core team members still participate in the ``#python-dev`` IRC channel on
+``irc.libera.chat``. This is not a place to ask for help with Python, but to
+discuss issues related to Python's own development. See also the
+``#python-dev-notifs`` channel for bots notifications.
+
+
+Blogs
+=====
+
+Several core team members are active bloggers and discuss Python's development
+that way. You can find their blogs (and various other developers who use Python)
+at `Planet Python `__.
+
+
+Setting expectations for open source participation
+==================================================
+
+Burn-out is common in open source due to a misunderstanding of what users, contributors,
+and maintainers should expect from each other. Brett Cannon gave a `talk `_
+about this topic that sets out to help everyone set reasonable expectations of each other in
+order to make open source pleasant for everyone involved.
+
+Additional repositories
+=======================
+
+`Python Core Workflow`_ hosts an issue tracker for workflow discussions.
+
+Some core workflow tools are:
+
+* `cherry_picker`_ (:pypi:`PyPI `)
+* `bedevere`_
+* `blurb`_ (:pypi:`PyPI `)
+* `blurb_it`_
+* `miss-islington`_
+* `clabot`_
+* `webhook-mailer`_
+
+Python `Performance Benchmark`_ project is intended to be an authoritative
+source of benchmarks for all Python implementations.
+
+.. _Python Core Workflow: https://github.com/python/core-workflow
+.. _cherry_picker: https://github.com/python/cherry-picker
+.. _bedevere: https://github.com/python/bedevere
+.. _blurb: https://github.com/python/blurb
+.. _blurb_it: https://github.com/python/blurb_it
+.. _miss-islington: https://github.com/python/miss-islington
+.. _clabot: https://github.com/psf/clabot
+.. _webhook-mailer: https://github.com/python/webhook-mailer
+.. _Performance Benchmark: https://github.com/python/pyperformance
diff --git a/devcycle.rst b/developer-workflow/development-cycle.rst
similarity index 54%
rename from devcycle.rst
rename to developer-workflow/development-cycle.rst
index e8bb60934..c8b2d5ebf 100644
--- a/devcycle.rst
+++ b/developer-workflow/development-cycle.rst
@@ -1,9 +1,10 @@
+.. _development-cycle:
.. _devcycle:
-Development Cycle
+Development cycle
=================
-The responsibilities of a core developer shift based on what kind of branch of
+The responsibilities of a core team member shift based on what kind of branch of
Python a developer is working on and what stage the branch is in.
To clarify terminology, Python uses a ``major.minor.micro`` nomenclature
@@ -33,16 +34,16 @@ and *null* for final releases), and ``N`` is the release serial number.
Some examples of release tags: ``v3.7.0a1``, ``v3.6.3``, ``v2.7.14rc1``.
Branches
-''''''''
+--------
-There is a branch for each *feature version*, whether released or not (e.g.
-3.7, 3.8).
+There is a branch for each *feature version*, whether released or not (for
+example, 3.12, 3.13).
.. _indevbranch:
In-development (main) branch
-----------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The ``main`` branch is the branch for the next feature release; it is
under active development for all kinds of changes: new features, semantic
@@ -50,13 +51,11 @@ changes, performance improvements, bug fixes.
At some point during the life-cycle of a release, a
new :ref:`maintenance branch ` is created to host all bug fixing
-activity for further micro versions in a feature version (3.8.1, 3.8.2, etc.).
+activity for further micro versions in a feature version (3.12.1, 3.12.2, and so
+on).
-For versions 3.4 and before, this was conventionally done when the final
-release was cut (for example, 3.4.0 final).
-
-Starting with the 3.5 release, we create the release maintenance branch
-(e.g. 3.5) at the time we enter beta (3.5.0 beta 1). This allows
+We create the release maintenance branch
+(``3.14``) at the time we enter beta (3.14.0 beta 1). This allows
feature development for the release 3.n+1 to occur within the main
branch alongside the beta and release candidate stabilization periods
for release 3.n.
@@ -64,7 +63,7 @@ for release 3.n.
.. _maintbranch:
Maintenance branches
---------------------
+^^^^^^^^^^^^^^^^^^^^
A branch for a previous feature release, currently being maintained for bug
fixes, or for the next feature release in its
@@ -76,13 +75,19 @@ releases; the terms are used interchangeably. These releases have a
**micro version** number greater than zero.
The only changes allowed to occur in a maintenance branch without debate are
-bug fixes. Also, a general rule for maintenance branches is that compatibility
-must not be broken at any point between sibling micro releases (3.5.1, 3.5.2,
+bug fixes, test improvements, and edits to the documentation.
+Also, a general rule for maintenance branches is that compatibility
+must not be broken at any point between sibling micro releases (3.12.1, 3.12.2,
etc.). For both rules, only rare exceptions are accepted and **must** be
discussed first.
+Backporting changes reduces the risk of future conflicts.
+For documentation, it increases the visibility of improvements,
+since most readers access the `stable documentation `__
+rather than the `development documentation `__.
+
A new maintenance branch is normally created when the next feature release
-cycle reaches feature freeze, i.e. at its first beta pre-release.
+cycle reaches feature freeze, that is, at its first beta pre-release.
From that point on, changes intended for remaining pre-releases, the final
release (3.x.0), and subsequent bugfix releases are merged to
that maintenance branch.
@@ -90,14 +95,14 @@ that maintenance branch.
Sometime following the final release (3.x.0), the maintenance branch for
the previous minor version will go into :ref:`security mode `,
usually after at least one more bugfix release at the discretion of the
-release manager. For example, the 3.4 maintenance branch was put into
-:ref:`security mode ` after the 3.4.4 bugfix release
-which followed the release of 3.5.1.
+release manager. For example, the 3.11 maintenance branch was put into
+:ref:`security mode ` after the 3.11.9 bugfix release
+which followed the release of 3.12.2.
.. _secbranch:
Security branches
------------------
+^^^^^^^^^^^^^^^^^
A branch less than 5 years old but no longer in bugfix mode is a security
branch.
@@ -113,40 +118,20 @@ Commits to security branches are to be coordinated with the release manager
for the corresponding feature version, as listed in the :ref:`branchstatus`.
Merging of pull requests to security branches is restricted to release managers.
Any release made from a security branch is source-only and done only when actual
-security patches have been applied to the branch. These releases have a
+security fixes have been applied to the branch. These releases have a
**micro version** number greater than the last **bugfix** release.
.. _eolbranch:
End-of-life branches
---------------------
+^^^^^^^^^^^^^^^^^^^^
The code base for a release cycle which has reached end-of-life status
is frozen and no longer has a branch in the repo. The final state of
the end-of-lifed branch is recorded as a tag with the same name as the
-former branch, e.g. ``3.3`` or ``2.6``.
-
-For reference, here are the Python versions that most recently reached their end-of-life:
-
-+------------------+--------------+----------------+----------------+----------------------------------+
-| Branch | Schedule | First release | End-of-life | Release manager |
-+==================+==============+================+================+==================================+
-| 3.5 | :pep:`478` | 2015-09-13 | 2020-09-30 | Larry Hastings |
-+------------------+--------------+----------------+----------------+----------------------------------+
-| 3.4 | :pep:`429` | 2014-03-16 | 2019-03-18 | Larry Hastings |
-+------------------+--------------+----------------+----------------+----------------------------------+
-| 3.3 | :pep:`398` | 2012-09-29 | 2017-09-29 | Georg Brandl, Ned Deily (3.3.7+) |
-+------------------+--------------+----------------+----------------+----------------------------------+
-| 3.2 | :pep:`392` | 2011-02-20 | 2016-02-20 | Georg Brandl |
-+------------------+--------------+----------------+----------------+----------------------------------+
-| 3.1 | :pep:`375` | 2009-06-27 | 2012-04-09 | Benjamin Peterson |
-+------------------+--------------+----------------+----------------+----------------------------------+
-| 3.0 | :pep:`361` | 2008-12-03 | 2009-06-27 | Barry Warsaw |
-+------------------+--------------+----------------+----------------+----------------------------------+
-| 2.7 | :pep:`373` | 2010-07-03 | 2020-01-01 | Benjamin Peterson |
-+------------------+--------------+----------------+----------------+----------------------------------+
-| 2.6 | :pep:`361` | 2008-10-01 | 2013-10-29 | Barry Warsaw |
-+------------------+--------------+----------------+----------------+----------------------------------+
+former branch, for example, ``3.8`` or ``2.7``.
+
+The :ref:`versions` page contains list of active and end-of-life branches.
The latest release for each Python version can be found on the `download page
`_.
@@ -154,27 +139,27 @@ The latest release for each Python version can be found on the `download page
.. _stages:
Stages
-''''''
+------
Based on what stage the :ref:`in-development ` version of Python
-is in, the responsibilities of a core developer change in regards to commits
+is in, the responsibilities of a core team member change in regards to commits
to the :abbr:`VCS (version control system)`.
Pre-alpha
----------
+^^^^^^^^^
The branch is in this stage when no official release has been done since
the latest final release. There are no special restrictions placed on
-commits, although the usual advice applies (getting patches reviewed, avoiding
-breaking the buildbots).
+commits, although the usual advice applies (getting pull requests reviewed,
+avoiding breaking the buildbots).
.. _alpha:
Alpha
------
+^^^^^
-Alpha releases typically serve as a reminder to core developers that they
+Alpha releases typically serve as a reminder to the core team that they
need to start getting in changes that change semantics or add something to
Python as such things should not be added during a Beta_. Otherwise no new
restrictions are in place while in alpha.
@@ -182,29 +167,26 @@ restrictions are in place while in alpha.
.. _beta:
Beta
-----
+^^^^
After a first beta release is published, no new features are accepted. Only
bug fixes and improvements to documentation and tests can now be committed.
-This is when core developers should concentrate on the task of fixing
+This is when the core team should concentrate on the task of fixing
regressions and other new issues filed by users who have downloaded the alpha
and beta releases.
Being in beta can be viewed much like being in RC_ but without the extra
overhead of needing commit reviews.
-Please see the note in the `In-development (main) branch`_ section above for
-new information about the creation of the 3.5 maintenance branch during beta.
-
.. _rc:
Release Candidate (RC)
-----------------------
+^^^^^^^^^^^^^^^^^^^^^^
A branch preparing for an RC release can only have bugfixes applied that have
-been reviewed by other core developers. Generally, these issues must be
-severe enough (e.g. crashes) that they deserve fixing before the final release.
+been reviewed by other core team members. Generally, these issues must be
+severe enough (for example, crashes) that they deserve fixing before the final release.
All other issues should be deferred to the next development cycle, since
stability is the strongest concern at this point.
@@ -214,40 +196,67 @@ changes should be discussed first with the release manager.
You **cannot** skip the peer review during an RC, no matter how small! Even if
it is a simple copy-and-paste change, **everything** requires peer review from
-a core developer.
+a core team member.
.. _final:
Final
------
+^^^^^
When a final release is being cut, only the release manager (RM) can make
changes to the branch. After the final release is published, the full
:ref:`development cycle ` starts again for the next minor version.
-Repository Administration
-'''''''''''''''''''''''''
+Repository administration
+-------------------------
The source code is currently hosted on `GitHub
`_ in the `Python organization `_.
-Organization Repository Policy
-------------------------------
-
-Within the `Python organization `_, repositories are expected to fall within these general categories:
-
-1. The reference implementation of Python and related repositories (i.e. `CPython `_)
-2. Reference implementations of PEPs (e.g. `mypy `_)
-3. Tooling and support around CPython and the language (e.g. `python.org repository `_)
-4. PSF-related repositories (e.g. the `Code of Conduct `_)
-5. PSF Infrastructure repositories (e.g. the `PSF Infrastructure Salt configurations `_)
-
-For any repository which does not explicitly and clearly fall under one of these categories, permission should be sought
-from the `Python steering council `_.
-
-Organization Owner Policy
--------------------------
+Organization repository policy
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Within the `GitHub Python organization `_,
+repositories are expected to relate to the Python language, the CPython
+reference implementation, their documentation and their development workflow.
+This includes, for example:
+
+* The reference implementation of Python and related repositories: `CPython `_.
+* Tooling and support around CPython development: `pyperformance `_, `Bedevere `_.
+* Helpers and backports for Python/CPython features: `typing_extensions `_, `typeshed `_, `tzdata `_, `pythoncapi-compat `_.
+* Organization-related repositories: the `Code of Conduct `_, `.github `_.
+* Documentation and websites for all the above: `python.org repository `_, `PEPs `_, `Devguide `_, docs translations.
+* Infrastructure for all the above: `docsbuild-scripts `_, `buildmaster-config `_.
+* Discussions and notes around official development-related processes and events: `steering-council `_, `core-sprint `_.
+
+Before adding a new repository to the organization, open a discussion to seek consensus
+in the `Committers Discourse category `_.
+Once people are satisfied with that, ask the `Python steering council `_
+to grant permission.
+
+Note that several repositories remain in the organization for historic reasons,
+and would probably not be appropriate to add today.
+
+Generally, new repositories should start their life under personal GitHub
+accounts or other GitHub orgs. It is relatively easy to move a repository to
+the organization once it is mature. For example, this would now apply to
+experimental features like `asyncio `_,
+`exceptiongroups `_,
+and drafts of new guides and other documentation (for example, `redistributor-guide
+`_).
+
+General-use tools and libraries (for example, `mypy `_
+or `Black `_) should also be developed outside
+the ``python`` organization, unless core devs (as represented by the SC)
+specifically want to “bless” one implementation (as with
+`typeshed `_,
+`tzdata `_, or
+`pythoncapi-compat `_).
+
+
+Organization owner policy
+^^^^^^^^^^^^^^^^^^^^^^^^^
The GitHub Organization Owner role allows for full management of all aspects of
the Python organization. Allowing for visibility and management of all aspects
@@ -255,12 +264,12 @@ at all levels including organization membership, team membership, access
control, and merge privileges on all repositories. For full details of the
permission levels see `GitHub's documentation on Organization permission
levels
-`_.
+`_.
This role is paramount to the security of the Python Language, Community, and
Infrastructure.
The Executive Director of the Python Software Foundation delegates authority on
-GitHub Organization Owner Status to Ee W. Durbin III - Python Software
+GitHub Organization Owner Status to Ee Durbin - Python Software
Foundation Director of Infrastructure. Common reasons for this role are:
Infrastructure Staff Membership, Python Software Foundation General Counsel,
and Python Software Foundation Staff as fallback.
@@ -271,8 +280,10 @@ who no longer necessitate this level of access will be removed with notice.
Multi-Factor Authentication must be enabled by the user in order to remain an
Owner of the Python Organization.
-Current Owners
---------------
+.. _current owners:
+
+Current owners
+^^^^^^^^^^^^^^
+----------------------+--------------------------------+-----------------+
| Name | Role | GitHub Username |
@@ -283,27 +294,34 @@ Current Owners
+----------------------+--------------------------------+-----------------+
| Donald Stufft | Infrastructure Staff | dstufft |
+----------------------+--------------------------------+-----------------+
-| Ewa Jodlowska | PSF Executive Director | ejodlowska |
+| Ee Durbin | PSF Director of Infrastructure | ewdurbin |
+----------------------+--------------------------------+-----------------+
-| Ee W. Durbin III | PSF Director of Infrastructure | ewdurbin |
+| Jacob Coffee | PSF Infrastructure Engineer | JacobCoffee |
+----------------------+--------------------------------+-----------------+
-| Van Lindberg | PSF General Counsel | VanL |
+| Łukasz Langa | CPython Developer in Residence | ambv |
+----------------------+--------------------------------+-----------------+
-Repository Administrator Role Policy
-------------------------------------
+Certain actions (blocking spam accounts, inviting new users, adjusting
+organization-level settings) can only `be performed`_ by owners of the Python
+organization on GitHub. The ``@python/organization-owners`` team can be
+mentioned to request assistance from an organization owner.
+
+.. _be performed: https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization#permissions-for-organization-roles
+
+Repository administrator role policy
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The Administrator role on the repository allows for managing all aspects
including collaborators, access control, integrations, webhooks, and branch
protection. For full details of the permission levels see `GitHub's
-documentation on Repository permission levels
-`_.
-Common reasons for this role are: maintenance of Core Developer
-Workflow tooling, Release Managers for all :ref:`in-development `,
+documentation on repository permission levels
+`_.
+Common reasons for this role are: maintenance of core
+workflow tooling, Release Managers for all :ref:`in-development `,
:ref:`maintenance `, and :ref:`security mode `
-releases, and additional Python Core Developers as necessary for redundancy.
-Occasional temporary administrator access is acceptable as necessary for Core
-Developer workflow projects.
+releases, and additional Python core team members as necessary for redundancy.
+Occasional temporary administrator access is acceptable as necessary for core
+workflow projects.
Inactive or unreachable members may be removed with or without notice. Members
who no longer necessitate this level of access will be removed with notice.
@@ -311,39 +329,96 @@ who no longer necessitate this level of access will be removed with notice.
Multi-Factor Authentication must be enabled by the user in order to remain an
Administrator of the repository.
-Current Administrators
-----------------------
+Current administrators
+^^^^^^^^^^^^^^^^^^^^^^
+-------------------+----------------------------------------------------------+-----------------+
| Name | Role | GitHub Username |
+===================+==========================================================+=================+
-| Pablo Galindo | Python 3.10 and 3.11 Release Manager, | pablogsal |
-| | Maintainer of buildbot.python.org | |
+| Hugo van Kemenade | Python 3.14 and 3.15 Release Manager | hugovk |
+-------------------+----------------------------------------------------------+-----------------+
-| Łukasz Langa | Python 3.8 and 3.9 Release Manager | ambv |
+| Thomas Wouters | Python 3.12 and 3.13 Release Manager | Yhg1s |
+-------------------+----------------------------------------------------------+-----------------+
-| Ned Deily | Python 3.6 and 3.7 Release Manager | ned-deily |
-+-------------------+----------------------------------------------------------+-----------------+
-| Lary Hastings | Retired Release Manager (for Python 3.4 and 3.5) | larryhastings |
+| Pablo Galindo | Python 3.10 and 3.11 Release Manager, | pablogsal |
+| | Maintainer of buildbot.python.org | |
+-------------------+----------------------------------------------------------+-----------------+
-| Berker Peksag | Maintainer of bpo-linkify and cpython-emailer-webhook | berkerpeksag |
+| Łukasz Langa | Python 3.9 Release Manager, | ambv |
+| | PSF CPython Developer in Residence 2021-present | |
+-------------------+----------------------------------------------------------+-----------------+
-| Brett Cannon | Maintainer of bedevere and the-knights-who-say-ni | brettcannon |
+| Brett Cannon | | brettcannon |
+-------------------+----------------------------------------------------------+-----------------+
| Ezio Melotti | Maintainer of bugs.python.org GitHub webhook integration | ezio-melotti |
+-------------------+----------------------------------------------------------+-----------------+
-| Mariatta Wijaya | Maintainer of blurb_it and miss-islington | Mariatta |
+| Mariatta Wijaya | Maintainer of bedevere, blurb_it and miss-islington | Mariatta |
++-------------------+----------------------------------------------------------+-----------------+
+| Seth Larson | PSF Security Developer-in-Residence | sethmlarson |
+-------------------+----------------------------------------------------------+-----------------+
-Repository Release Manager Role Policy
---------------------------------------
+Repository release manager role policy
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Release Managers for :ref:`in-development `, :ref:`maintenance
`, and :ref:`security mode ` Python releases are
granted Administrator privileges on the repository. Once a release branch has
-entered :ref:`end-of-life `, the Release Manager for that branch is
-removed as an Administrator and granted sole privileges (out side of repository
-administrators) to merge changes to that branch.
+entered :ref:`end-of-life `, the Release Manager for that branch
+creates a final tag and deletes the branch. After this, they are
+removed as an Administrator.
Multi-Factor Authentication must be enabled by the user in order to retain
access as a Release Manager of the branch.
+
+PyPI organization policy
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+The Python core team owns the :pypi-org:`cpython` and :pypi-org:`python`
+organizations on PyPI for publishing packages.
+The main benefits of adding packages to these organizations:
+
+* Visibility: we can see our packages under a PyPI org page
+* Maintainability: we can share granular PyPI access to improve the bus factor
+
+The general policy on which organization to use:
+
+* :pypi-org:`cpython`:
+ for development tools that are tied fairly closely to CPython development.
+ For example, :pypi:`blurb` and :pypi:`cherry-picker`.
+ Users generally shouldn’t have to care except for developing CPython itself
+ (although that doesn’t mean the tools necessarily have to be unusable for
+ anyone else).
+* :pypi-org:`python`:
+ for general-audience projects that are maintained by the Python core team.
+ For example, :pypi:`pyperformance`, :pypi:`python-docs-theme` and
+ :pypi:`tzdata`.
+
+
+Governance
+----------
+
+The Python Steering Council has overall authority over Python and has delegated
+some of its responsibilities to other groups.
+
+This table lists the PEPs defining each group's responsibilities,
+and the repository where you can open an issue to ask for a decision.
+
+.. list-table::
+ :header-rows: 1
+
+ * - Name
+ - PEP
+ - Contact repo
+ * - Steering Council
+ - :pep:`13`
+ - :github:`python/steering-council`
+ * - C API Working Group
+ - :pep:`731`
+ - :github:`capi-workgroup/decisions`
+ * - Documentation Editorial Board
+ - :pep:`732`
+ - :github:`python/editorial-board`
+ * - Typing Council
+ - :pep:`729`
+ - :github:`python/typing-council`
+
+.. seealso::
+
+ All governance PEPs: https://peps.python.org/topic/governance/
diff --git a/developer-workflow/extension-modules.rst b/developer-workflow/extension-modules.rst
new file mode 100644
index 000000000..7131cfdf8
--- /dev/null
+++ b/developer-workflow/extension-modules.rst
@@ -0,0 +1,669 @@
+.. _extension-modules:
+.. _extensions:
+
+==================================
+Standard library extension modules
+==================================
+
+In this section, we explain how to configure and compile the CPython project
+with a C :term:`extension module`. We will not explain how to write a C
+extension module and prefer to give you some links where you can read good
+documentation:
+
+* https://docs.python.org/dev/c-api/
+* https://docs.python.org/dev/extending/
+* :pep:`399`
+* https://pythonextensionpatterns.readthedocs.io/en/latest/
+
+Some modules in the standard library, such as :mod:`datetime` or :mod:`pickle`,
+have identical implementations in C and Python; the C implementation, when
+available, is expected to improve performance (such extension modules are
+commonly referred to as *accelerator modules*).
+
+Other modules mainly implemented in Python may import a C helper extension
+providing implementation details (for instance, the :mod:`csv` module uses
+the internal :mod:`!_csv` module defined in :cpy-file:`Modules/_csv.c`).
+
+Classifying extension modules
+=============================
+
+Extension modules can be classified into two categories:
+
+* A *built-in* extension module is a module built and shipped with
+ the Python interpreter. A built-in module is *statically* linked
+ into the interpreter, thereby lacking a :attr:`!__file__` attribute.
+
+ .. seealso:: :data:`sys.builtin_module_names` --- names of built-in modules.
+
+ Built-in modules are built with the :c:macro:`!Py_BUILD_CORE_BUILTIN`
+ macro defined.
+
+* A *shared* (or *dynamic*) extension module is built as a shared library
+ (``.so`` or ``.dll`` file) and is *dynamically* linked into the interpreter.
+
+ In particular, the module's :attr:`!__file__` attribute contains the path
+ to the ``.so`` or ``.dll`` file.
+
+ Shared modules are built with the :c:macro:`!Py_BUILD_CORE_MODULE`
+ macro defined. Using the :c:macro:`!Py_BUILD_CORE_BUILTIN` macro
+ instead causes an :exc:`ImportError` when importing the module.
+
+.. note::
+
+ Informally, built-in extension modules can be regarded as *required*
+ while shared extension modules are *optional* in the sense that they
+ might be supplied, overridden or disabled externally.
+
+ Usually, accelerator modules are built as *shared* extension modules,
+ especially if they already have a pure Python implementation.
+
+According to :pep:`399`, *new* extension modules MUST provide a working and
+tested pure Python implementation, unless a special dispensation from
+the :github:`Steering Council ` is given.
+
+Adding an extension module to CPython
+=====================================
+
+Assume that the standard library contains a pure Python module :mod:`!foo`
+with the following :func:`!foo.greet` function:
+
+.. code-block:: python
+ :caption: Lib/foo.py
+
+ def greet():
+ return "Hello World!"
+
+Instead of using the Python implementation of :func:`!foo.greet`, we want to
+use its corresponding C extension implementation exposed in the :mod:`!_foo`
+module. Ideally, we want to modify ``Lib/foo.py`` as follows:
+
+.. code-block:: python
+ :caption: Lib/foo.py
+
+ try:
+ # use the C implementation if possible
+ from _foo import greet
+ except ImportError:
+ # fallback to the pure Python implementation
+ def greet():
+ return "Hello World!"
+
+.. note::
+
+ Accelerator modules should *never* be imported directly. The convention is
+ to mark them as private implementation details with the underscore prefix
+ (namely, :mod:`!_foo` in this example).
+
+In order to incorporate the accelerator module, we need to determine:
+
+- where to update the CPython project tree with the extension module source code,
+- which files to modify to configure and compile the CPython project, and
+- which ``Makefile`` rules to invoke at the end.
+
+Updating the CPython project tree
+---------------------------------
+
+Usually, accelerator modules are added in the :cpy-file:`Modules` directory of
+the CPython project. If more than one file is needed for the extension module,
+it is more convenient to create a sub-directory in :cpy-file:`Modules`.
+
+In the simplest example where the extension module consists of one file, it may
+be placed in :cpy-file:`Modules` as ``Modules/_foomodule.c``. For a non-trivial
+example of the extension module :mod:`!_foo`, we consider the following working
+tree:
+
+- :ref:`Modules/_foo/_foomodule.c` --- the extension module implementation.
+- :ref:`Modules/_foo/helper.h` --- the extension helpers declarations.
+- :ref:`Modules/_foo/helper.c` --- the extension helpers implementations.
+
+By convention, the source file containing the extension module implementation
+is called ``module.c``, where ```` is the name of the module that
+will be later imported (in our case :mod:`!_foo`). In addition, the directory
+containing the implementation should also be named similarly.
+
+.. code-block:: c
+ :caption: Modules/_foo/helper.h
+ :name: Modules/_foo/helper.h
+
+ #ifndef _FOO_HELPER_H
+ #define _FOO_HELPER_H
+
+ #include "Python.h"
+
+ typedef struct {
+ /* ... */
+ } foomodule_state;
+
+ static inline foomodule_state *
+ get_foomodule_state(PyObject *module)
+ {
+ void *state = PyModule_GetState(module);
+ assert(state != NULL);
+ return (foomodule_state *)state;
+ }
+
+ /* Helper used in Modules/_foo/_foomodule.c
+ * but implemented in Modules/_foo/helper.c.
+ */
+ extern PyObject *
+ _Py_greet_fast(void);
+
+ #endif // _FOO_HELPER_H
+
+.. tip::
+
+ Functions or data that do not need to be shared across different C source
+ files should be declared ``static`` to avoid exporting their symbols from
+ ``libpython``.
+
+ If symbols need to be exported, their names must start with ``Py`` or
+ ``_Py``. This can be verified by ``make smelly``. For more details,
+ please refer to the section on :ref:`Changing Python's C API `.
+
+.. code-block:: c
+ :caption: Modules/_foo/helper.c
+ :name: Modules/_foo/helper.c
+
+ #include "_foomodule.h"
+
+ PyObject *_Py_greet_fast(void) {
+ return PyUnicode_FromString("Hello World!");
+ }
+
+.. code-block:: c
+ :caption: Modules/_foo/_foomodule.c
+ :name: Modules/_foo/_foomodule.c
+
+ #include "helper.h"
+ #include "clinic/_foomodule.c.h"
+
+ /* Functions for the extension module's state */
+ static int
+ foomodule_exec(PyObject *module)
+ {
+ // imports, static attributes, exported classes, etc
+ return 0;
+ }
+
+ static int
+ foomodule_traverse(PyObject *m, visitproc visit, void *arg)
+ {
+ foomodule_state *st = get_foomodule_state(m);
+ // call Py_VISIT() on the state attributes
+ return 0;
+ }
+
+ static int
+ foomodule_clear(PyObject *m)
+ {
+ foomodule_state *st = get_foomodule_state(m);
+ // call Py_CLEAR() on the state attributes
+ return 0;
+ }
+
+ static void
+ foomodule_free(void *m) {
+ (void)foomodule_clear((PyObject *)m);
+ }
+
+ /* Implementation of publicly exported functions. */
+
+ /*[clinic input]
+ module foo
+ [clinic start generated code]*/
+ /*[clinic end generated code: output=... input=...]*/
+
+ /*[clinic input]
+ foo.greet -> object
+
+ [clinic start generated code]*/
+
+ static PyObject *
+ foo_greet_impl(PyObject *module)
+ /*[clinic end generated code: output=... input=...]*/
+ {
+ return _Py_greet_fast();
+ }
+
+ /* Exported module's data */
+
+ static PyMethodDef foomodule_methods[] = {
+ // macro in 'clinic/_foomodule.c.h' after running 'make clinic'
+ FOO_GREET_METHODDEF
+ {NULL, NULL}
+ };
+
+ static struct PyModuleDef_Slot foomodule_slots[] = {
+ // 'foomodule_exec' may be NULL if the state is trivial
+ {Py_mod_exec, foomodule_exec},
+ {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
+ {Py_mod_gil, Py_MOD_GIL_NOT_USED},
+ {0, NULL},
+ };
+
+ static struct PyModuleDef foomodule = {
+ PyModuleDef_HEAD_INIT,
+ .m_name = "_foo",
+ .m_doc = "some doc", // or NULL if not needed
+ .m_size = sizeof(foomodule_state),
+ .m_methods = foomodule_methods,
+ .m_slots = foomodule_slots,
+ .m_traverse = foomodule_traverse, // or NULL if the state is trivial
+ .m_clear = foomodule_clear, // or NULL if the state is trivial
+ .m_free = foomodule_free, // or NULL if the state is trivial
+ };
+
+ PyMODINIT_FUNC
+ PyInit__foo(void)
+ {
+ return PyModuleDef_Init(&foomodule);
+ }
+
+.. tip::
+
+ Recall that the ``PyInit_`` function must be suffixed by the
+ module name ```` used in import statements (here ``_foo``),
+ and which usually coincides with :c:member:`PyModuleDef.m_name`.
+
+ Other identifiers such as those used in :ref:`Argument Clinic `
+ inputs do not have such naming requirements.
+
+Configuring the CPython project
+-------------------------------
+
+Now that we have added our extension module to the CPython source tree,
+we need to update some configuration files in order to compile the CPython
+project on different platforms.
+
+Updating ``Modules/Setup.{bootstrap,stdlib}.in``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Depending on whether the extension module is required to get a functioning
+interpreter or not, we update :cpy-file:`Modules/Setup.bootstrap.in` or
+:cpy-file:`Modules/Setup.stdlib.in`. In the former case, the extension
+module is necessarily built as a built-in extension module.
+
+.. tip::
+
+ For accelerator modules, :cpy-file:`Modules/Setup.stdlib.in` should be
+ preferred over :cpy-file:`Modules/Setup.bootstrap.in`.
+
+For built-in extension modules, update :cpy-file:`Modules/Setup.bootstrap.in`
+by adding the following line after the ``*static*`` marker:
+
+.. code-block:: text
+ :caption: :cpy-file:`Modules/Setup.bootstrap.in`
+ :emphasize-lines: 3
+
+ *static*
+ ...
+ _foo _foo/_foomodule.c _foo/helper.c
+ ...
+
+The syntax is ```` where ```` is the name of the
+module used in :keyword:`import` statements and ```` is the list
+of space-separated source files.
+
+For other extension modules, update :cpy-file:`Modules/Setup.stdlib.in`
+by adding the following line after the ``*@MODULE_BUILDTYPE@*`` marker
+but before the ``*shared*`` marker:
+
+.. code-block:: text
+ :caption: :cpy-file:`Modules/Setup.stdlib.in`
+ :emphasize-lines: 3
+
+ *@MODULE_BUILDTYPE@*
+ ...
+ @MODULE__FOO_TRUE@_foo _foo/_foomodule.c _foo/helper.c
+ ...
+ *shared*
+
+The ``@MODULE__TRUE@`` marker expects ```` to
+be the upper-cased form of ````, where ```` has the same meaning
+as before (in our case, ```` and ```` are ``_FOO`` and
+``_foo`` respectively). The marker is followed by the list of source files.
+
+If the extension module must be built as a *shared* module, put the
+``@MODULE__FOO_TRUE@_foo`` line after the ``*shared*`` marker:
+
+.. code-block:: text
+ :caption: :cpy-file:`Modules/Setup.stdlib.in`
+ :emphasize-lines: 4
+
+ ...
+ *shared*
+ ...
+ @MODULE__FOO_TRUE@_foo _foo/_foomodule.c _foo/helper.c
+
+Updating :cpy-file:`configure.ac`
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. add section about configuration variable afterwards
+
+* Locate the ``SRCDIRS`` variable and add the following line:
+
+ .. code-block:: text
+ :caption: :cpy-file:`configure.ac`
+ :emphasize-lines: 4
+
+ AC_SUBST([SRCDIRS])
+ SRCDIRS="\
+ ...
+ Modules/_foo \
+ ..."
+
+ .. note::
+
+ This step is only needed when adding new source directories to
+ the CPython project.
+
+* Find the section containing ``PY_STDLIB_MOD`` and ``PY_STDLIB_MOD_SIMPLE``
+ usages and add the following line:
+
+ .. code-block:: text
+ :caption: :cpy-file:`configure.ac`
+ :emphasize-lines: 3
+
+ dnl always enabled extension modules
+ ...
+ PY_STDLIB_MOD_SIMPLE([_foo], [-I\$(srcdir)/Modules/_foo], [])
+ ...
+
+ The ``PY_STDLIB_MOD_SIMPLE`` macro takes as arguments:
+
+ * the module name ```` used in :keyword:`import` statements,
+ * the compiler flags (CFLAGS), and
+ * the linker flags (LDFLAGS).
+
+ If the extension module may not be enabled or supported depending on the
+ host configuration, use the ``PY_STDLIB_MOD`` macro instead, which takes
+ as arguments:
+
+ * the module name ```` used in :keyword:`import` statements,
+ * a boolean indicating whether the extension is **enabled** or not,
+ * a boolean indicating whether the extension is **supported** or not,
+ * the compiler flags (CFLAGS), and
+ * the linker flags (LDFLAGS).
+
+ For instance, enabling the :mod:`!_foo` extension on Linux platforms, but
+ only providing support for 32-bit architecture, is achieved as follows:
+
+ .. code-block:: text
+ :caption: :cpy-file:`configure.ac`
+ :emphasize-lines: 2, 3
+
+ PY_STDLIB_MOD([_foo],
+ [test "$ac_sys_system" = "Linux"],
+ [test "$ARCH_RUN_32BIT" = "true"],
+ [-I\$(srcdir)/Modules/_foo], [])
+
+ More generally, the host's configuration status of the extension is
+ determined as follows:
+
+ +-----------+-----------------+----------+
+ | Enabled | Supported | Status |
+ +===========+=================+==========+
+ | true | true | yes |
+ +-----------+-----------------+----------+
+ | true | false | missing |
+ +-----------+-----------------+----------+
+ | false | true or false | disabled |
+ +-----------+-----------------+----------+
+
+ The extension status is ``n/a`` if the extension is marked unavailable
+ by the ``PY_STDLIB_MOD_SET_NA`` macro. To mark an extension as unavailable,
+ find the usages of ``PY_STDLIB_MOD_SET_NA`` in :cpy-file:`configure.ac` and
+ add the following line:
+
+ .. code-block:: text
+ :caption: :cpy-file:`configure.ac`
+ :emphasize-lines: 4
+
+ dnl Modules that are not available on some platforms
+ AS_CASE([$ac_sys_system],
+ ...
+ [PLATFORM_NAME], [PY_STDLIB_MOD_SET_NA([_foo])],
+ ...
+ )
+
+.. tip::
+
+ Consider reading the comments and configurations for existing modules
+ in :cpy-file:`configure.ac` for guidance on adding new external build
+ dependencies for extension modules that need them.
+
+Updating :cpy-file:`Makefile.pre.in`
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If needed, add the following line to the section for module dependencies:
+
+.. code-block:: text
+ :caption: :cpy-file:`Makefile.pre.in`
+ :emphasize-lines: 4
+
+ ##########################################################################
+ # Module dependencies and platform-specific files
+ ...
+ MODULE__FOO_DEPS=$(srcdir)/Modules/_foo/helper.h
+ ...
+
+The ``MODULE__DEPS`` variable follows the same naming
+requirements as the ``@MODULE__TRUE@`` marker.
+
+Updating MSVC project files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+We describe the minimal steps for compiling on Windows using MSVC.
+
+* Update :cpy-file:`PC/config.c`:
+
+ .. code-block:: c
+ :caption: :cpy-file:`PC/config.c`
+ :emphasize-lines: 3, 8
+
+ ...
+ // add the entry point prototype
+ extern PyObject* PyInit__foo(void);
+ ...
+ // update the entry points table
+ struct _inittab _PyImport_Inittab[] = {
+ ...
+ {"_foo", PyInit__foo},
+ ...
+ {0, 0}
+ };
+ ...
+
+ Each item in ``_PyImport_Inittab`` consists of the module name to import,
+ here :mod:`!_foo`, with the corresponding ``PyInit_*`` function correctly
+ suffixed.
+
+* Update :cpy-file:`PCbuild/pythoncore.vcxproj`:
+
+ .. code-block:: xml
+ :caption: :cpy-file:`PCbuild/pythoncore.vcxproj`
+ :emphasize-lines: 4, 11-12
+
+
+
+ ...
+
+ ...
+
+
+
+
+ ...
+
+
+ ...
+
+
+* Update :cpy-file:`PCbuild/pythoncore.vcxproj.filters`:
+
+ .. code-block:: xml
+ :caption: :cpy-file:`PCbuild/pythoncore.vcxproj.filters`
+ :emphasize-lines: 4-6, 13-18
+
+
+
+ ...
+
+ Modules\_foo
+
+ ...
+
+
+
+
+ ...
+
+ Modules\_foo
+
+
+ Modules\_foo
+
+ ...
+
+
+.. tip::
+
+ Header files use ```` tags, whereas
+ source files use ```` tags.
+
+
+Compiling the CPython project
+-----------------------------
+
+Now that the configuration is in place, it remains to compile the project:
+
+.. code-block:: shell
+
+ make regen-configure
+ ./configure
+ make regen-all
+ make regen-stdlib-module-names
+ make
+
+.. tip::
+
+ Use ``make -jN`` to speed-up compilation by utilizing as many CPU cores
+ as possible, where *N* is as many CPU cores you want to spare (and have
+ memory for). Be careful using ``make -j`` with no argument, as this puts
+ no limit on the number of jobs, and compilation can sometimes use up a
+ lot of memory (like when building with LTO).
+
+* ``make regen-configure`` updates the :cpy-file:`configure` script.
+
+ The :cpy-file:`configure` script must be generated using a specific version
+ of ``autoconf``. To that end, the :cpy-file:`Tools/build/regen-configure.sh`
+ script which the ``regen-configure`` rule is based on either requires Docker
+ or Podman, the latter being assumed by default.
+
+ .. tip::
+
+ We recommend installing `Podman `_
+ instead of Docker since the former does not require a background service
+ and avoids creating files owned by the ``root`` user in some cases.
+
+* ``make regen-all`` is responsible for regenerating header files and
+ invoking other scripts, such as :ref:`Argument Clinic `.
+ Execute this rule if you do not know which files should be updated.
+
+* ``make regen-stdlib-module-names`` updates the standard module names, making
+ :mod:`!_foo` discoverable and importable via ``import _foo``.
+
+* The final ``make`` step is generally not needed since the previous ``make``
+ invokations may completely rebuild the project, but it could be needed in
+ some specific cases.
+
+Troubleshooting
+---------------
+
+This section addresses common issues that you may face when following
+this example of adding an extension module.
+
+No rule to make target ``regen-configure``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This usually happens after running ``make distclean`` (which removes
+the ``Makefile``). The solution is to regenerate the :cpy-file:`configure`
+script as follows:
+
+.. code-block:: shell
+
+ ./configure # for creating the 'Makefile' file
+ make regen-configure # for updating the 'configure' script
+ ./configure # for updating the 'Makefile' file
+
+If missing, the :cpy-file:`configure` script can be regenerated
+by executing :cpy-file:`Tools/build/regen-configure.sh`:
+
+.. code-block:: shell
+
+ ./Tools/build/regen-configure.sh # create an up-to-date 'configure'
+ ./configure # create an up-to-date 'Makefile'
+
+``make regen-configure`` and missing permissions with Docker
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If Docker complains about missing permissions, this Stack Overflow post
+could be useful in solving the issue: `How to fix docker: permission denied
+`_. Alternatively, you may try
+using `Podman `_.
+
+Missing ``Py_BUILD_CORE`` define when using internal headers
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+By default, the CPython :ref:`Stable ABI ` is exposed via
+:code:`#include "Python.h"`. In some cases, this may be insufficient
+and internal headers from :cpy-file:`Include/internal` are needed;
+in particular, those headers require the :c:macro:`!Py_BUILD_CORE`
+macro to be defined.
+
+To that end, one should define the :c:macro:`!Py_BUILD_CORE_BUILTIN`
+or the :c:macro:`!Py_BUILD_CORE_MODULE` macro depending on whether the
+extension module is built-in or shared. Using either of the two macros
+implies :c:macro:`!Py_BUILD_CORE` and gives access to CPython internals:
+
+.. code-block:: c
+ :caption: Definition of :c:macro:`!Py_BUILD_CORE_BUILTIN`
+
+ #ifndef Py_BUILD_CORE_MODULE
+ # define Py_BUILD_CORE_BUILTIN 1
+ #endif
+
+.. code-block:: c
+ :caption: Definition of :c:macro:`!Py_BUILD_CORE_MODULE`
+
+ #ifndef Py_BUILD_CORE_BUILTIN
+ # define Py_BUILD_CORE_MODULE 1
+ #endif
+
+Tips
+----
+
+In this section, we give some tips for improving the quality of
+extension modules meant to be included in the standard library.
+
+Restricting to the Limited API
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In order for non-CPython implementations to benefit from new extension modules,
+it is recommended to use the :ref:`Limited API `. Instead of
+exposing the entire Stable ABI, define the :c:macro:`Py_LIMITED_API` macro
+*before* the :code:`#include "Python.h"` directive:
+
+.. code-block:: c
+ :caption: Using the 3.13 Limited API.
+ :emphasize-lines: 3, 6
+
+ #include "pyconfig.h" // Py_GIL_DISABLED
+ #ifndef Py_GIL_DISABLED
+ # define Py_LIMITED_API 0x030d0000
+ #endif
+
+ #include "Python.h"
+
+This makes the extension module non-CPython implementation-friendly by
+removing the dependencies to CPython internals.
diff --git a/developer-workflow/grammar.rst b/developer-workflow/grammar.rst
new file mode 100644
index 000000000..d574dfed7
--- /dev/null
+++ b/developer-workflow/grammar.rst
@@ -0,0 +1,8 @@
+.. _grammar:
+
+==========================
+Changing CPython's grammar
+==========================
+
+This document is now part of the
+`CPython Internals Docs `_.
diff --git a/developer-workflow/index.rst b/developer-workflow/index.rst
new file mode 100644
index 000000000..e73927f1d
--- /dev/null
+++ b/developer-workflow/index.rst
@@ -0,0 +1,19 @@
+.. _dev-workflow:
+
+====================
+Development workflow
+====================
+
+.. toctree::
+ :maxdepth: 5
+
+ communication-channels
+ development-cycle
+ stdlib
+ extension-modules
+ c-api
+ lang-changes
+ grammar
+ porting
+ sbom
+ psrt
diff --git a/developer-workflow/lang-changes.rst b/developer-workflow/lang-changes.rst
new file mode 100644
index 000000000..52aabb15d
--- /dev/null
+++ b/developer-workflow/lang-changes.rst
@@ -0,0 +1,88 @@
+.. _lang-changes:
+.. _langchanges:
+
+Changing the Python language
+============================
+On occasion people come up with an idea on how to change or improve Python as a
+programming language. This document is meant to explain exactly what changes
+have a reasonable chance of being considered and what the process is to propose
+changes to the language.
+
+
+What qualifies
+--------------
+First and foremost, it must be understood that changes to the Python
+programming language are difficult to make. When the language changes,
+**every** Python programmer already in existence and all Python programmers to
+come will end up eventually learning about the change you want to propose.
+Books will need updating, code will be changed, and a new way to do things will
+need to be learned. Changes to the Python programming language are never taken
+lightly.
+
+Because of the seriousness that language changes carry, any change must be
+beneficial to a large proportion of Python users. If the change only benefits a
+small percentage of Python developers then the change will not be made. A good
+way to see if your idea would work for a large portion of the Python community
+is to ask in the `Ideas Discourse category`_. You can also
+go through Python's stdlib and find examples of code which would benefit from
+your proposed change (which helps communicate the usefulness of your change to
+others). For further guidance, see :ref:`suggesting-changes`.
+
+Your proposed change also needs to be *Pythonic*. While only the Steering
+Council can truly classify something as Pythonic, you can read the
+:pep:`Zen of Python <20>` for guidance.
+
+
+.. index::
+ single: PEP process
+
+.. _suggesting-changes:
+
+Suggesting new features and language changes
+--------------------------------------------
+
+The `Ideas Discourse category`_
+is specifically intended for discussion of new features and language changes.
+Please don't be disappointed if your idea isn't met with universal approval:
+as the :pep:`long list of Withdrawn and Rejected PEPs
+<0#rejected-superseded-and-withdrawn-peps>`
+in the :pep:`PEP Index <0>` attests,
+and as befits a reasonably mature programming language,
+getting significant changes into Python isn't a simple task.
+
+If the idea is reasonable, someone will suggest posting it as a feature
+request on the `issue tracker`_, or, for larger changes,
+writing it up as PEP following the :ref:`lang-changes-pep-process`.
+
+Sometimes core developers will differ in opinion,
+or merely be collectively unconvinced.
+When there isn't an obvious victor, then the `Status Quo Wins a Stalemate`_.
+
+For some examples on language changes that were accepted,
+see `Justifying Python Language Changes`_.
+
+
+.. index:: PEP process
+
+.. _lang-changes-pep-process:
+
+PEP process
+-----------
+
+Once you are certain you have a language change proposal
+which will appeal to the general Python community,
+you can begin the :abbr:`PEP (Python enhancement proposal)` process
+to officially propose the change.
+See :pep:`1` for information on PEPs and the PEP process,
+and the :pep:`PEP Index <0>` for examples.
+
+If the PEP is accepted, then your proposed language change will be introduced
+in the next release of Python.
+Otherwise, your PEP will be recorded as rejected along with an explanation,
+to inform others who may propose a similar language change in the future.
+
+
+.. _issue tracker: https://github.com/python/cpython/issues
+.. _Ideas Discourse category: https://discuss.python.org/c/ideas/6
+.. _Status Quo Wins a Stalemate: https://www.curiousefficiency.org/posts/2011/02/status-quo-wins-stalemate.html
+.. _Justifying Python Language Changes: https://www.curiousefficiency.org/posts/2011/02/justifying-python-language-changes.html
diff --git a/porting.rst b/developer-workflow/porting.rst
similarity index 81%
rename from porting.rst
rename to developer-workflow/porting.rst
index fdf01eef9..f308e6c14 100644
--- a/porting.rst
+++ b/developer-workflow/porting.rst
@@ -1,7 +1,8 @@
.. _porting:
-Porting Python to a new platform
---------------------------------
+=========================
+Porting to a new platform
+=========================
The first step is to familiarize yourself with the development toolchain on
the platform in question, notably the C compiler. Make sure you can compile and
@@ -11,12 +12,12 @@ Next, learn how to compile and run the Python interpreter on a platform to
which it has already been ported; preferably Unix, but Windows will
do, too. The build process for Python, in particular the ``Makefile`` in the
source distribution, will give you a hint on which files to compile
-for Python. Not all source files are relevant: some are platform
-specific, others are only used in emergencies (e.g. ``getopt.c``).
+for Python. Not all source files are relevant: some are platform-specific,
+and others are only used in emergencies (for example, ``getopt.c``).
-It is not recommended to start porting Python without at least medium-level
-understanding of your target platform; i.e. how it is generally used, how to
-write platform specific apps, etc. Also, some Python knowledge is required, or
+It is not recommended to start porting Python without at least a medium-level
+understanding of your target platform; how it is generally used, how to
+write platform-specific apps, and so on. Also, some Python knowledge is required, or
you will be unable to verify that your port is working correctly.
You will need a ``pyconfig.h`` file tailored for your platform. You can
diff --git a/developer-workflow/psrt.rst b/developer-workflow/psrt.rst
new file mode 100644
index 000000000..9d9019dbf
--- /dev/null
+++ b/developer-workflow/psrt.rst
@@ -0,0 +1,160 @@
+Python Security Response Team (PSRT)
+====================================
+
+The Python Security Response Team (PSRT) is responsible for handling
+vulnerability reports for CPython and pip.
+
+Vulnerability report triage
+---------------------------
+
+Vulnerability reports are sent to one of two locations,
+the long-standing ``security@python.org`` mailing list
+or using the private vulnerability reporting feature
+of GitHub Security Advisories (GHSA).
+
+For reports sent to ``security@python.org``, a PSRT admin
+will triage the report and if the report seems plausible
+(that is, not spam and for the correct project) will reply with
+instructions on how to report the vulnerability on GitHub.
+
+If the reporter doesn't want to use GitHub's Security Advisories feature
+then the PSRT admins can create a draft report on behalf of the reporter.
+
+Coordinating a vulnerability report
+-----------------------------------
+
+Each report will have a member of the PSRT assigned as the "coordinator".
+The coordinator will be responsible for following the below process and
+will be publicly credited on vulnerability records post-publication.
+
+If a coordinator can't complete the process for any reason (time obligation,
+vacation, etc.) they must find a replacement coordinator in the PSRT
+and reassign the vulnerability report appropriately.
+
+Coordinators are expected to collaborate with other PSRT and core team members
+when needed for guidance on whether the report is an actual vulnerability,
+severity, advisory text, and fixes.
+
+**The vulnerability coordination process is:**
+
+* Coordinator will determine whether the report constitutes a vulnerability. If the report isn't a vulnerability,
+ the reporter should be notified appropriately. Close the GHSA report, the report can be reopened if
+ sufficient evidence is later obtained that the report is a vulnerability.
+
+* After a vulnerability report is accepted, a Common Vulnerabilities and Exposures (CVE) ID must be assigned. If this is not done
+ automatically, then a CVE ID can be obtained by the coordinator sending an email to ``cna@python.org``.
+ No details about the vulnerability report need to be shared with the PSF CVE Numbering Authority (CNA) for a CVE ID to be reserved.
+
+* If the report is a vulnerability, the coordinator will determine the severity of the vulnerability. Severity is one of:
+ **Low**, **Medium**, **High**, and **Critical**. Coordinators can use their knowledge of the code, how the code is likely used,
+ or another mechanism like Common Vulnerability Scoring System (CVSS) for determining a severity. Add this information to the GitHub Security Advisory.
+
+* Once a CVE ID is assigned, the coordinator will share the acceptance and CVE ID with the reporter.
+ Use this CVE ID for referencing the vulnerability. The coordinator will ask the reporter
+ if the reporter would like to be credited publicly for the report and if so, how they would like to be credited.
+ Add this information to the GitHub Security Advisory.
+
+* The coordinator authors the vulnerability advisory text. The advisory must include the following information:
+
+ * Title should be a brief description of the vulnerability and affected component
+ (for example, "Buffer over-read in SSLContext.set_npn_protocols()")
+
+ * Short description of the vulnerability, impact, and the conditions where the affected component is vulnerable, if applicable.
+
+ * Affected versions. This could be "all versions", but if the vulnerability exists in a new feature
+ or removed feature then this could be different. Include versions that are end-of-life in this calculation
+ (for example, "Python 3.9 and earlier", "Python 3.10 and later", "all versions of Python").
+
+ * Affected components and APIs. The module, function, class, or method must be specified so users can
+ search their codebase for usage. For issues affecting the entire project, this can be omitted.
+
+ * Mitigations for the vulnerability beyond upgrading to a fixed version, if applicable.
+
+ This can all be done within the GitHub Security Advisory UI for easier collaboration between reporter and coordinator.
+
+* The coordinator determines the fix approach and who will provide a fix.
+ Some reporters are willing to provide or collaborate to create a fix,
+ otherwise relevant core team members can be invited to collaborate by
+ the coordinator.
+
+ * For **Low** and **Medium** severity vulnerabilities it is acceptable
+ to develop a fix in public.
+ The pull request must be marked with the ``security`` and ``release-blocker``
+ labels so that a release is not created without including the fix.
+
+ * For **High** and **Critical** severity vulnerabilities the fix must be
+ developed privately using GitHub Security Advisories' "Private Forks" feature.
+ Core team members can be added to the GitHub Security Advisory via "collaborators"
+ to work on the fix together. Once a fix is approved privately and tested,
+ a public issue and pull request can be created with
+ the ``security`` and ``release-blocker`` labels.
+
+* Once the pull request is merged the advisory can be published. The coordinator will send the advisory by email
+ to ``security-announce@python.org`` using the below template. Backport labels must be added as appropriate.
+ After the advisory is published a CVE record can be created.
+
+Template responses
+------------------
+
+These template responses should be used as guidance for messaging
+in various points in the process above. They are not required to be sent as-is,
+please feel free to adapt them as needed for the current context.
+
+**Directing to GitHub Security Advisories:**
+
+.. highlight:: none
+
+::
+
+ Thanks for submitting this report.
+ We use GitHub Security Advisories for triaging vulnerability reports,
+ are you able to submit your report directly to GitHub?
+
+ https://github.com/python/cpython/security/advisories/new
+
+ If you're unable to submit a report to GitHub (due to not having a GitHub
+ account or something else) let me know and I will create a GitHub Security
+ Advisory on your behalf, although you won't be able to participate directly
+ in discussions.
+
+**Rejecting a vulnerability report:**
+
+::
+
+ Thanks for your report. We've determined that the report doesn't constitute
+ a vulnerability. Let us know if you disagree with this determination.
+ If you are interested in working on this further, you can optionally open a
+ public issue on GitHub.
+
+**Accepting a vulnerability report:**
+
+::
+
+ Thanks for your report. We've determined that the report
+ is a vulnerability. We've assigned {CVE-YYYY-XXXX} and determined
+ a severity of {Low,Medium,High,Critical}. Let us know if you disagree
+ with the determined severity.
+
+ If you would like to be publicly credited for this vulnerability as the
+ reporter, please indicate that, along with how you would like to be
+ credited (name or organization).
+
+ Please keep this vulnerability report private until we've published
+ an advisory to ``security-announce@python.org``.
+
+**Advisory email:**
+
+::
+
+ Title: [{CVE-YYYY-XXXX}] {title}
+
+ There is a {LOW, MEDIUM, HIGH, CRITICAL} severity vulnerability
+ affecting {project}.
+
+ {description}
+
+ Please see the linked CVE ID for the latest information on
+ affected versions:
+
+ * https://www.cve.org/CVERecord?id={CVE-YYYY-XXXX}
+ * {pull request URL}
diff --git a/developer-workflow/sbom.rst b/developer-workflow/sbom.rst
new file mode 100644
index 000000000..756c17570
--- /dev/null
+++ b/developer-workflow/sbom.rst
@@ -0,0 +1,109 @@
+Software Bill-of-Materials (SBOM)
+=================================
+
+Software Bill-of-Materials (abbreviated as "SBOM") is a document for sharing
+information about software and how it's been composed. This format is used
+most often in the security space for checking software and its dependencies
+for vulnerabilities using vulnerability databases like
+`CVE `_ and `OSV `_. The SBOM format
+that the CPython project uses is `SPDX `_
+which can be transformed into other formats if necessary by consumers.
+
+There are multiple sources of third-party dependencies for CPython.
+Some are vendored into the source code of CPython itself (like ``mpdecimal``
+vendored at :cpy-file:`Modules/_decimal/libmpdec`) or they could be optionally pulled
+in during builds like Windows using dependencies from the
+`python/cpython-source-deps `_
+repository.
+
+Whenever adding or updating a third-party dependency, an update will likely
+need to be done to the SBOM in order to track the version and software identifiers.
+
+Updating a dependency
+---------------------
+
+The SBOM for CPython's bundled dependencies is kept at
+:cpy-file:`Misc/sbom.spdx.json`. When updating a dependency to a new version
+you'll need to edit the version and other metadata about this dependency in
+the SBOM.
+
+The recommended workflow is:
+
+1. Download the new dependency as an archive. Take note of the new version, download
+ URL, and checksum of the downloaded archive.
+2. Update the vendored code in the CPython source tree.
+3. Edit :cpy-file:`Misc/sbom.spdx.json` to add the new ``versionInfo``,
+ ``downloadLocation``, ``checksums``, and ``externalReferences`` for the
+ corresponding ``package``. For most of these updates all that's needed is to
+ update the embedded version within URLs and project identifiers.
+ Don't update any information in ``files`` and ``relationships`` as this will
+ be generated automatically by the SBOM tool.
+4. Run ``make regen-sbom`` or ``python Tools/build/generate_sbom.py``.
+ Ensure that this doesn't fail with validation errors.
+5. Run ``git diff Misc/sbom.spdx.json`` and check the diff matches the
+ expected changes.
+6. Commit the changes to :cpy-file:`Misc/sbom.spdx.json` along with the
+ update to the dependency code.
+
+Adding a new dependency
+-----------------------
+
+When adding a dependency it's important to have the following information:
+
+* Name, version, and download URL of the project
+* License of the project as an `SPDX License Expression `_
+* Software identifiers that match values in vulnerability databases
+ (`CPE `_ and
+ `Package URLs `_
+ or "PURLs")
+* Paths to include and exclude in the CPython source tree corresponding to this dependency
+
+After gathering this information:
+
+1. Add the information into a new entry in ``packages`` in the file
+ :cpy-file:`Misc/sbom.spdx.json`. Don't worry about formatting, the tool will
+ auto-format your manually written JSON. The fields to fill out include:
+
+ * ``name`` for the project name.
+ * ``SPDXID`` which will be ``"SPDXRef-PACKAGE-{name}"``.
+ * ``licenseConcluded`` for the SPDX license identifier of the project license.
+ * ``versionInfo`` for the version of the project.
+ * ``downloadLocation`` should be an HTTPS URL for the project download as an archive.
+ * ``checksums[0].checksumValue`` and ``.algorithm`` will be the SHA-256
+ checksum of the downloaded archive.
+ * ``originator`` for the original author information, prefix with either an
+ ``Organization:`` or ``Person:`` depending on the author/maintenance situation.
+ * ``primaryPackagePurpose`` will likely be ``"SOURCE"``.
+ * ``externalReferences`` is a list of one or more project identifiers,
+ either CPE or Package URL. The value for ``referenceLocator`` must include
+ the value in ``versionInfo`` to ensure the identifier
+ corresponds to the correct release of the software. You can read more about
+ external references in the `SPDX SBOM specification`_.
+2. If a new license ID is to be used, add the license expression to
+ ``ALLOWED_LICENSE_EXPRESSIONS`` in the :cpy-file:`Tools/build/generate_sbom.py`.
+3. Add the paths to include and exclude into a ``PackageFiles`` instance
+ with a key corresponding to the SBOM ID for the package (``SPDXID`` without the
+ ``SPDXRef-PACKAGE-*`` prefix) in :cpy-file:`Tools/build/generate_sbom.py`.
+4. Run the tool with ``make regen-sbom`` or ``python Tools/build/generate_sbom.py``.
+ Ensure that the tool doesn't fail with any validation errors.
+5. Compare the changes to :cpy-file:`Misc/sbom.spdx.json` with ``git diff``, check
+ that all information appears correct.
+6. Commit the changes to :cpy-file:`Misc/sbom.spdx.json` and
+ :cpy-file:`Tools/build/generate_sbom.py`.
+
+.. _SPDX SBOM specification: https://spdx.github.io/spdx-spec/v2-draft/external-repository-identifiers/
+
+Removing a dependency
+---------------------
+
+When removing a dependency:
+
+1. Remove the entry from the :cpy-file:`Misc/sbom.spdx.json`
+ under the ``packages`` field.
+2. Remove the corresponding ``PackageFiles`` entry in :cpy-file:`Tools/build/generate_sbom.py`
+3. Run the tool with ``make regen-sbom`` or ``python Tools/build/generate_sbom.py``.
+ Ensure that the tool doesn't fail with any validation errors.
+4. Compare the changes to :cpy-file:`Misc/sbom.spdx.json` with ``git diff``, check
+ that correct package is removed from the SBOM.
+5. Commit the changes to :cpy-file:`Misc/sbom.spdx.json` and
+ :cpy-file:`Tools/build/generate_sbom.py`.
diff --git a/stdlibchanges.rst b/developer-workflow/stdlib.rst
similarity index 55%
rename from stdlibchanges.rst
rename to developer-workflow/stdlib.rst
index 970843bd8..b683e55e9 100644
--- a/stdlibchanges.rst
+++ b/developer-workflow/stdlib.rst
@@ -1,6 +1,7 @@
+.. _stdlib:
.. _stdlibchanges:
-Adding to the Stdlib
+Adding to the stdlib
====================
While the stdlib contains a great amount of useful code, sometimes you want
@@ -11,8 +12,6 @@ module.
Changes to pre-existing code is not covered as that is considered a bugfix and
thus is treated as a bug that should be filed on the `issue tracker`_.
-.. _issue tracker: https://bugs.python.org/
-
Adding to a pre-existing module
-------------------------------
@@ -21,48 +20,47 @@ If you have found that a function, method, or class is useful and you believe
it would be useful to the general Python community, there are some steps to go
through in order to see it added to the stdlib.
-First is you should gauge the usefulness of the code. Typically this is done
-by sharing the code publicly. You have a couple of options for this. One is to
-post it online at the `Python Cookbook`_. Based on feedback or reviews of the
-recipe you can see if others find the functionality as useful as you do.
-A search of the issue tracker for previous suggestions related to the proposed
-addition may turn up a rejected issue that explains why the suggestion will not
-be accepted.
-Another is to do a blog post about the code and see what kind of responses you
-receive. Posting to python-list (see :ref:`communication` for where to find the
-list and other mailing lists) to discuss your code also works. Finally, asking
-on a specific :abbr:`SIG (special interest group)` from mail.python.org or
-python-ideas is also acceptable. This is not a required step but it is
-suggested.
+First, you should gauge the usefulness of the code,
+which is typically done by sharing the code publicly.
+This is not a required step, but it is suggested.
+You have a several options for this:
+
+* Search the `issue tracker`_ for discussion related to the proposed addition.
+ This may turn up an issue that explains why the suggestion wasn't accepted.
+* Open a new thread in the `Ideas Discourse category`_
+ to gather feedback directly from the Python core team and community.
+* Write a blog post about the code, which may also help gather useful feedback.
If you have found general acceptance and usefulness for your code from people,
you can open an issue on the `issue tracker`_ with the code attached as a
-:ref:`patch `. If possible, also submit a
+:ref:`pull request `. If possible, also submit a
:ref:`contributor agreement `.
-If a core developer decides that your code would be useful to the general
+If a core team member decides that your code would be useful to the general
Python community, they will then commit your code. If your code is not picked
-up by a core developer and committed then please do not take this personally.
+up by a core team and committed then please do not take this personally.
Through your public sharing of your code in order to gauge community support
for it you at least can know that others will come across it who may find it
useful.
-.. _Python Cookbook: https://code.activestate.com/recipes/langs/python/
+.. _Ideas Discourse category: https://discuss.python.org/c/ideas/6
Adding a new module
-------------------
+
It must be stated upfront that getting a new module into the stdlib is very
difficult. Adding any significant amount of code to the stdlib increases the
-burden placed upon core developers. It also means that the module somewhat
-becomes "sanctioned" by the core developers as a good way to do something,
+burden placed upon the core team. It also means that the module somewhat
+becomes "sanctioned" by the core team as a good way to do something,
typically leading to the rest of the Python community to using the new module
over other available solutions. All of this means that additions to the stdlib
are not taken lightly.
-Acceptable Types of Modules
-'''''''''''''''''''''''''''
+Acceptable types of modules
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
Typically two types of modules get added to the stdlib. One type is a module
which implements something that is difficult to get right. A good example of
this is the :py:mod:`multiprocessing` package. Working out the various OS
@@ -78,17 +76,18 @@ that the stdlib consists of.
While a new stdlib module does not need to appeal to all users of Python, it
should be something that a large portion of the community will find useful.
-This makes sure that the developer burden placed upon core developers is worth
+This makes sure that the developer burden placed upon the core team is worth
it.
Requirements
-''''''''''''
+^^^^^^^^^^^^
+
In order for a module to even be considered for inclusion into the stdlib, a
couple of requirements must be met.
The most basic is that the code must meet
-:ref:`standard patch requirements `. For code that has
+:ref:`standard pull request requirements `. For code that has
been developed outside the stdlib typically this means making sure the coding
style guides are followed and that the proper tests have been written.
@@ -105,46 +104,47 @@ year, a module needs to have established itself as (one of) the top choices by
the community for solving the problem the module is intended for.
The development of the module must move into Python's
-infrastructure (i.e., the module is no longer directly maintained outside of
+infrastructure (that is, the module is no longer directly maintained outside of
Python). This prevents a divergence between the code that is included in the
stdlib and that which is released outside the stdlib (typically done to provide
the module to older versions of Python). It also removes the burden of forcing
-core developers to have to redirect bug reports or patches to an external issue
+the core team to have to redirect bug reports or changes to an external issue
tracker and :abbr:`VCS (version control system)`.
Someone involved with the development of the
module must promise to help maintain the module in the stdlib for two years.
-This not only helps out other core developers by alleviating workload from bug
+This not only helps out other core team members by alleviating workload from bug
reports that arrive from the first Python release containing the module, but
also helps to make sure that the overall design of the module continues to be
uniform.
-Proposal Process
-''''''''''''''''
-If the module you want to propose adding to the stdlib meets the proper
-requirements, you may propose its inclusion. To start, you should email
-python-list or python-ideas to make sure the community in general would support
-the inclusion of the module (see :ref:`communication`).
-
-If the feedback from the community is positive overall, you will need to write
-a :abbr:`PEP (Python enhancement proposal)` for the module's inclusion. It
-should outline what the module's overall goal is, why it should be included in
-the stdlib, and specify the API of the module. See the `PEP index`_ for PEPs
-that have been accepted before that proposed a module for inclusion.
-
-Once your PEP is written, send it to python-ideas for basic vetting. Be
-prepared for extensive feedback and lots of discussion (not all of it
-positive). This will help make the PEP be of good quality and properly
-formatted.
-
-When you have listened to, responded, and integrated as appropriate the
-feedback from python-ideas into your PEP, you may send it to python-dev. You
-will once again receive a large amount of feedback and discussion. A PEP
-dictator will be assigned who makes the final call on whether the PEP will be
-accepted or not. If the PEP dictator agrees to accept your PEP (which typically
-means that the core developers end up agreeing in general to accepting
-your PEP) then the module will be added to the stdlib once the creators of the
-module sign :ref:`contributor agreements `.
-
-.. _PEP index: https://www.python.org/dev/peps/
+Proposal process
+^^^^^^^^^^^^^^^^
+
+If the module you want to propose adding to the stdlib meets the requirements,
+you may propose its inclusion
+by following the :abbr:`PEP (Python Enhancement Proposal)` process.
+See :pep:`1` for details,
+and the :pep:`PEP index <0>` for previously-accepted PEPs
+that have proposed a module for inclusion.
+
+If the PEP is accepted, then the module will be added to the stdlib
+once the authors of the module sign
+:ref:`contributor agreements `.
+
+.. _issue tracker: https://github.com/python/cpython/issues
+
+Adding a new environment variable
+---------------------------------
+
+Names of environment variables should be uppercase and, from Python 3.13
+onwards, use underscores for readability and accessibility.
+
+For example, use ``PYTHON_CPU_COUNT`` instead of ``PYTHONCPUCOUNT``.
+
+See also:
+
+* :ref:`python:using-on-envvars`
+* `"Change environment variable style" Discourse discussion
+ `__
diff --git a/clang.rst b/development-tools/clang.rst
similarity index 50%
rename from clang.rst
rename to development-tools/clang.rst
index 76afd4786..b353d82f0 100644
--- a/clang.rst
+++ b/development-tools/clang.rst
@@ -1,13 +1,13 @@
-***************************
-Dynamic Analysis with Clang
-***************************
+.. _clang:
+
+===========================
+Dynamic analysis with Clang
+===========================
.. highlight:: bash
This document describes how to use Clang to perform analysis on Python and its
-libraries. In addition to performing the analysis, the document will cover
-downloading, building and installing the latest Clang/LLVM combination (which
-is currently 3.4).
+libraries.
This document does not cover interpreting the findings. For a discussion of
interpreting results, see Marshall Clow's `Testing libc++ with
@@ -15,6 +15,13 @@ interpreting results, see Marshall Clow's `Testing libc++ with
blog posting is a detailed examinations of issues uncovered by Clang in
``libc++``.
+The document focuses on Clang, although most techniques should generally apply
+to GCC's sanitizers as well.
+
+The instructions were tested on Linux, but they should work on macOS as well.
+Instructions for Windows are incomplete.
+
+
What is Clang?
==============
@@ -23,7 +30,7 @@ front-end provides access to LLVM's optimizer and code generator. The
sanitizers - or checkers - are hooks into the code generation phase to
instrument compiled code so suspicious behavior is flagged.
-What are Sanitizers?
+What are sanitizers?
====================
Clang sanitizers are runtime checkers used to identify suspicious and undefined
@@ -47,177 +54,99 @@ A complete list of sanitizers can be found at `Controlling Code Generation
Clang and its sanitizers have strengths (and weaknesses). Its just one tool in
the war chest to uncovering bugs and improving code quality. Clang should be
-used to compliment other methods, including Code Reviews, Valgrind, Coverity,
+used to complement other methods, including Code Reviews, `Valgrind`_,
etc.
-Clang/LLVM Setup
+Clang/LLVM setup
================
-This portion of the document covers downloading, building and installing Clang
-and LLVM. There are three components to download and build. They are the LLVM
-compiler, the compiler front end and the compiler runtime library.
-
-In preparation you should create a scratch directory. Also ensure you are using
-Python 2 and not Python 3. Python 3 will cause the build to fail.
-
-Download, Build and Install
----------------------------
-
-Perform the following to download, build and install the Clang/LLVM 3.4. ::
+Pre-built Clang builds are available for most platforms:
- # Download
- wget https://llvm.org/releases/3.4/llvm-3.4.src.tar.gz
- wget https://llvm.org/releases/3.4/clang-3.4.src.tar.gz
- wget https://llvm.org/releases/3.4/compiler-rt-3.4.src.tar.gz
+- On macOS, Clang is the default compiler.
+- For mainstream Linux distros, you can install a ``clang`` package.
+ In some cases, you also need to install ``llvm`` separately, otherwise
+ some tools are not available.
+- On Windows, the installer for Visual Studio (not Code)
+ includes the "C++ clang tools for windows" feature.
- # LLVM
- tar xvf llvm-3.4.src.tar.gz
- cd llvm-3.4/tools
+You can also build ``clang`` from source; refer to
+`the clang documentation `_ for details.
- # Clang Front End
- tar xvf ../../clang-3.4.src.tar.gz
- mv clang-3.4 clang
-
- # Compiler RT
- cd ../projects
- tar xvf ../../compiler-rt-3.4.src.tar.gz
- mv compiler-rt-3.4/ compiler-rt
-
- # Build
- cd ..
- ./configure --enable-optimized --prefix=/usr/local
- make -j4
- sudo make install
-
-.. note::
-
- If you receive an error ``'LibraryDependencies.inc' file not found``, then
- ensure you are utilizing Python 2 and not Python 3. If you encounter the
- error after switching to Python 2, then delete everything and start over.
-
-After ``make install`` executes, the compilers will be installed in
-``/usr/local/bin`` and the various libraries will be installed in
-``/usr/local/lib/clang/3.4/lib/linux/``:
+The installer does not install all the components needed on occasion. For
+example, you might want to run a ``scan-build`` or examine the results with
+``scan-view``. If this is your case, you can build Clang from source and
+copy tools from ``tools/clang/tools`` to a directory on your ``PATH``.
-.. code-block:: console
+Another reason to build from source is to get the latest version of Clang/LLVM,
+if your platform's channels don't provide it yet.
+Newer versions of Clang/LLVM introduce new sanitizer checks.
- $ ls /usr/local/lib/clang/3.4/lib/linux/
- libclang_rt.asan-x86_64.a libclang_rt.profile-x86_64.a
- libclang_rt.dfsan-x86_64.a libclang_rt.san-x86_64.a
- libclang_rt.full-x86_64.a libclang_rt.tsan-x86_64.a
- libclang_rt.lsan-x86_64.a libclang_rt.ubsan_cxx-x86_64.a
- libclang_rt.msan-x86_64.a libclang_rt.ubsan-x86_64.a
-On Mac OS X, the libraries are installed in
-``/usr/local/lib/clang/3.3/lib/darwin/``:
+Python build setup
+==================
-.. code-block:: console
+This portion of the document covers invoking Clang and LLVM with the options
+required so the sanitizers analyze Python with under its test suite.
- $ ls /usr/local/lib/clang/3.3/lib/darwin/
- libclang_rt.10.4.a libclang_rt.ios.a
- libclang_rt.asan_osx.a libclang_rt.osx.a
- libclang_rt.asan_osx_dynamic.dylib libclang_rt.profile_ios.a
- libclang_rt.cc_kext.a libclang_rt.profile_osx.a
- libclang_rt.cc_kext_ios5.a libclang_rt.ubsan_osx.a
- libclang_rt.eprintf.a
+Set the compiler to Clang, in case it's not the default::
-.. note::
+ export CC="clang"
- You should never have to add the libraries to a project. Clang will handle
- it for you. If you find you cannot pass the ``-fsanitize=XXX`` flag through
- ``make``'s implicit variables (``CFLAGS``, ``CXXFLAGS``, ``CC``,
- ``CXXFLAGS``, ``LDFLAGS``) during ``configure``, then you should modify the
- makefile after configuring to ensure the flag is passed through the
- compiler.
+If you want to use additional sanitizer options (found in Clang documentation),
+add them to the ``CFLAGS`` variable.
+For example, you may want the checked process to exit after the first failure::
-The installer does not install all the components needed on occasion. For
-example, you might want to run a ``scan-build`` or examine the results with
-``scan-view``. You can copy the components by hand with: ::
+ export CFLAGS="-fno-sanitize-recover"
- sudo mkdir /usr/local/bin/scan-build
- sudo cp -r llvm-3.4/tools/clang/tools/scan-build /usr/local/bin
- sudo mkdir /usr/local/bin/scan-view
- sudo cp -r llvm-3.4/tools/clang/tools/scan-view /usr/local/bin
+Then, run ``./configure`` with the relevant flags:
-.. note::
+* ASan: ``--with-address-sanitizer --without-pymalloc``
+* UBsan: ``--with-undefined-behavior-sanitizer``
- Because the installer does not install all the components needed on
- occasion, you should not delete the scratch directory until you are sure
- things work as expected. If a library is missing, then you should search for
- it in the Clang/LLVM build directory.
+The ``--without-pymalloc`` option is not necessary (tests should pass without it),
+but disabling pymalloc helps ASan uncover more bugs (ASan does not track
+individual allocations done by pymalloc).
-Python Build Setup
-==================
+It is OK to specify both sanitizers.
-This portion of the document covers invoking Clang and LLVM with the options
-required so the sanitizers analyze Python with under its test suite. Two
-checkers are used - ASan and UBSan.
+After that, run ``make`` and ``make test`` as usual.
+Note that ``make`` itself may fail with a sanitizer failure,
+since the just-compiled Python runs during later stages of the build.
-Because the sanitizers are runtime checkers, its best to have as many positive
-and negative self tests as possible. You can never have enough self tests.
-The general idea is to compile and link with the sanitizer flags. At link time,
-Clang will include the needed runtime libraries. However, you can't use
-``CFLAGS`` and ``CXXFLAGS`` to pass the options through the compiler to the
-linker because the makefile rules for ``BUILDPYTHON``, ``_testembed`` and
-``_freeze_importlib`` don't use the implicit variables.
+Build setup for enabling sanitizers for all code
+------------------------------------------------
-As a workaround to the absence of flags to the linker, you can pass the
-sanitizer options by way of the compilers - ``CC`` and ``CXX``. Passing the
-flags though the compiler is used below, but passing them through ``LDFLAGS`` is
-also reported to work.
+Some parts of Python (for example, ``_testembed``, ``_freeze_importlib``,
+``test_cppext``) may not use the variables set by ``configure``,
+and with the above settings they'll be compiled without sanitization.
-Building Python
----------------
+As a workaround, you can pass the sanitizer options by way of the *compilers*,
+``CC`` (for C) and ``CXX`` (for C++). This is used below.
+Passing the options through ``LDFLAGS`` is also reported to work.
-To begin, export the variables of interest with the desired sanitizers. Its OK
-to specify both sanitizers: ::
+For ASan, use::
# ASan
- export CC="/usr/local/bin/clang -fsanitize=address"
- export CXX="/usr/local/bin/clang++ -fsanitize=address -fno-sanitize=vptr"
+ export CC="clang -fsanitize=address"
+ export CXX="clang++ -fsanitize=address -fno-sanitize=vptr"
-Or: ::
+And for UBSan::
# UBSan
- export CC="/usr/local/bin/clang -fsanitize=undefined"
- export CXX="/usr/local/bin/clang++ -fsanitize=undefined -fno-sanitize=vptr"
-
-The ``-fno-sanitize=vptr`` removes vtable checks that are part of UBSan from C++
-projects due to noise. Its not needed with Python, but you will likely need it
-for other C++ projects.
-
-After exporting ``CC`` and ``CXX``, ``configure`` as normal:
-
-.. code-block:: console
-
- $ ./configure
- checking build system type... x86_64-unknown-linux-gnu
- checking host system type... x86_64-unknown-linux-gnu
- checking for --enable-universalsdk... no
- checking for --with-universal-archs... 32-bit
- checking MACHDEP... linux
- checking for --without-gcc... no
- checking for gcc... /usr/local/bin/clang -fsanitize=undefined
- checking whether the C compiler works... yes
- ...
+ export CC="clang -fsanitize=undefined"
+ export CXX="clang++ -fsanitize=undefined -fno-sanitize=vptr"
-Next is a standard ``make`` (formatting added for clarity):
+It's OK to specify both sanitizers.
-.. code-block:: console
+After this, run ``./configure``, ``make`` and ``make test`` as usual.
- $ make
- /usr/local/bin/clang -fsanitize=undefined -c -Wno-unused-result
- -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I.
- -IInclude -I./Include -DPy_BUILD_CORE -o Modules/python.o
- ./Modules/python.c
- /usr/local/bin/clang -fsanitize=undefined -c -Wno-unused-result
- -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I.
- -IInclude -I./Include -DPy_BUILD_CORE -o Parser/acceler.o
- Parser/acceler.c
- ...
-Finally is ``make test`` (formatting added for clarity):
+Analyzing the output
+====================
+
+Sanitizer failures will make the process fail and output a diagnostic,
+for example:
.. code-block:: none
@@ -231,8 +160,12 @@ Finally is ``make test`` (formatting added for clarity):
^
...
-If you are using the address sanitizer, its important to pipe the output through
-``asan_symbolize.py`` to get a good trace. For example, from Issue 20953 during
+If you are using the address sanitizer, an additional tool is needed to
+get good traces. Usually, this happens automatically through the
+``llvm-symbolizer`` tool. If this tool is not installed on your ``PATH``,
+you can set ``ASAN_SYMBOLIZER_PATH`` to the location of the tool,
+or pipe test output through ``asan_symbolize.py`` script from the
+Clang distribution. For example, from Issue 20953 during
compile (formatting added for clarity):
.. code-block:: none
@@ -300,25 +233,25 @@ compile (formatting added for clarity):
.. note::
- ``asan_symbolize.py`` is supposed to be installed during ``make install``.
- If its not installed, then look in the Clang/LLVM build directory for it and
- copy it to ``/usr/local/bin``.
+ If ``asan_symbolize.py`` is not installed, build Clang from source, then
+ look in the Clang/LLVM build directory for it and use it directly or copy
+ it to a directory on ``PATH``.
-Blacklisting (Ignoring) Findings
---------------------------------
+Ignoring findings
+-----------------
.. highlight:: none
Clang allows you to alter the behavior of sanitizer tools for certain
-source-level by providing a special blacklist file at compile-time. The
-blacklist is needed because it reports every instance of an issue, even if the
+source-level by providing a special ignorelist file at compile-time. The
+ignorelist is needed because it reports every instance of an issue, even if the
issue is reported 10's of thousands of time in un-managed library code.
-You specify the blacklist with ``-fsanitize-blacklist=XXX``. For example::
+You specify the ignorelist with ``-fsanitize-ignorelist=XXX``. For example::
- -fsanitize-blacklist=my_blacklist.txt
+ -fsanitize-ignorelist=my_ignorelist.txt
-``my_blacklist.txt`` would then contain entries such as the following. The entry
+``my_ignorelist.txt`` would then contain entries such as the following. The entry
will ignore a bug in ``libc++``'s ``ios`` formatting functions::
fun:_Ios_Fmtflags
@@ -340,7 +273,7 @@ findings::
...
One of the function of interest is ``audioop_getsample_impl`` (flagged at line
-422), and the blacklist entry would include::
+422), and the ignorelist entry would include::
fun:audioop_getsample_imp
@@ -348,7 +281,9 @@ Or, you could ignore the entire file with::
src:Modules/audioop.c
-Unfortunately, you won't know what to blacklist until you run the sanitizer.
+Unfortunately, you won't know what to ignorelist until you run the sanitizer.
The documentation is available at `Sanitizer special case list
`_.
+
+.. _Valgrind: https://github.com/python/cpython/blob/main/Misc/README.valgrind
diff --git a/development-tools/clinic.rst b/development-tools/clinic.rst
new file mode 100644
index 000000000..2f4677430
--- /dev/null
+++ b/development-tools/clinic.rst
@@ -0,0 +1,2215 @@
+.. highlight:: c
+
+.. _clinic:
+
+***************
+Argument Clinic
+***************
+
+:author: Larry Hastings
+
+**Source code:** :cpy-file:`Tools/clinic/clinic.py`.
+
+Argument Clinic is a preprocessor for CPython C files.
+It was introduced in Python 3.4 with :pep:`436`,
+in order to provide introspection signatures,
+and to generate performant and tailor-made boilerplate code
+for argument parsing in CPython builtins, module level functions, and class methods.
+This document is divided in four major sections:
+
+* :ref:`clinic-background` talks about the basic concepts and goals of Argument Clinic.
+* :ref:`clinic-reference` describes the command-line interface and Argument Clinic terminology.
+* :ref:`clinic-tutorial` guides you through all the steps required to adapt an existing C function to Argument Clinic.
+* :ref:`clinic-howtos` details how to handle specific tasks.
+
+
+.. note::
+
+ Argument Clinic is considered internal-only
+ for CPython. Its use is not supported for files outside
+ CPython, and no guarantees are made regarding backwards
+ compatibility for future versions. In other words: if you
+ maintain an external C extension for CPython, you're welcome
+ to experiment with Argument Clinic in your own code. But the
+ version of Argument Clinic that ships with the next version
+ of CPython *could* be totally incompatible and break all your code.
+
+
+.. _clinic-background:
+
+Background
+==========
+
+Basic concepts
+--------------
+
+When Argument Clinic is run on a file, either via the :ref:`clinic-cli`
+or via ``make clinic``, it will scan over the input files looking for
+:term:`start lines `:
+
+.. code-block:: none
+
+ /*[clinic input]
+
+When it finds one, it reads everything up to the :term:`end line`:
+
+.. code-block:: none
+
+ [clinic start generated code]*/
+
+Everything in between these two lines is Argument Clinic :term:`input`.
+When Argument Clinic parses input, it generates :term:`output`.
+The output is rewritten into the C file immediately after the input,
+followed by a :term:`checksum line`.
+All of these lines, including the :term:`start line` and :term:`checksum line`,
+are collectively called an Argument Clinic :term:`block`:
+
+.. code-block:: none
+
+ /*[clinic input]
+ ... clinic input goes here ...
+ [clinic start generated code]*/
+ ... clinic output goes here ...
+ /*[clinic end generated code: ...]*/
+
+If you run Argument Clinic on the same file a second time, Argument Clinic
+will discard the old :term:`output` and write out the new output with a fresh
+:term:`checksum line`.
+If the :term:`input` hasn't changed, the output won't change either.
+
+.. note::
+
+ You should never modify the output of an Argument Clinic block,
+ as any change will be lost in future Argument Clinic runs;
+ Argument Clinic will detect an output checksum mismatch and regenerate the
+ correct output.
+ If you are not happy with the generated output,
+ you should instead change the input until it produces the output you want.
+
+
+.. _clinic-reference:
+
+Reference
+=========
+
+
+.. _clinic-terminology:
+
+Terminology
+-----------
+
+.. glossary::
+
+ start line
+ The line ``/*[clinic input]``.
+ This line marks the beginning of Argument Clinic input.
+ Note that the *start line* opens a C block comment.
+
+ end line
+ The line ``[clinic start generated code]*/``.
+ The *end line* marks the *end* of Argument Clinic :term:`input`,
+ but at the same time marks the *start* of Argument Clinic :term:`output`,
+ thus the text *"clinic start start generated code"*
+ Note that the *end line* closes the C block comment opened
+ by the *start line*.
+
+ checksum
+ A hash to distinguish unique :term:`inputs `
+ and :term:`outputs