From 42e2aee7799228918dda2bbf3d95e94e4e4d9cdf Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Sun, 15 Jun 2025 01:14:24 +0100 Subject: [PATCH 001/103] Split `translating.rst` into pages for Translators and Coordinators (#1575) * Big Split * Move links * Fix link * Apply suggestions from willingc Co-authored-by: Carol Willing --------- Co-authored-by: Carol Willing --- conf.py | 4 + documentation/index.rst | 2 +- documentation/translations/coordinating.rst | 123 ++++++++++++++++++ documentation/translations/index.rst | 9 ++ .../{ => translations}/translating.rst | 116 ----------------- 5 files changed, 137 insertions(+), 117 deletions(-) create mode 100644 documentation/translations/coordinating.rst create mode 100644 documentation/translations/index.rst rename documentation/{ => translations}/translating.rst (55%) diff --git a/conf.py b/conf.py index ba7ee6040c..bedd99c42f 100644 --- a/conf.py +++ b/conf.py @@ -127,6 +127,10 @@ # 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", diff --git a/documentation/index.rst b/documentation/index.rst index 3f2512bcfb..eaa9e1a967 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -9,5 +9,5 @@ Documentation help-documenting style-guide markup - translating + translations/index devguide diff --git a/documentation/translations/coordinating.rst b/documentation/translations/coordinating.rst new file mode 100644 index 0000000000..3d64858ad8 --- /dev/null +++ b/documentation/translations/coordinating.rst @@ -0,0 +1,123 @@ +============ +Coordinating +============ + +Starting a new translation +========================== + +First subscribe to the `translation mailing list `_, +and introduce yourself and the translation you're starting. Translations +fall under the aegis of the `PSF Translation Workgroup `_ + +Then you can bootstrap your new translation by using `cookiecutter +`__ or +`bootstrapper `__. + +The important steps look like this: + +- Create the GitHub repo (any account) with the correct hierarchy by using one + of the bootstrappers. +- Gather people to help you translate. You can't do it alone. +- You can use any tool to translate, as long as you can synchronize with Git. + Some use Transifex, and some use only GitHub. You can choose another + way if you like; it's up to you. +- Update :doc:`this page ` to reflect your work and progress, either via a + PR or by asking on the `translation mailing list `_. +- When ``bugs``, ``tutorial``, and ``library/functions`` are 100% + completed, ask on the `translation mailing list `_ for + your language to be added in the language switcher on docs.python.org. + + +PEP 545 summary +=============== + +Here are the essential points of :PEP:`545`: + +- Each translation is assigned an appropriate lowercased language tag, + with an optional region subtag, and joined with a dash, like + ``pt-br`` or ``fr``. + +- Each translation is under CC0 and marked as such in the README (as in + the cookiecutter). + +- Translation files are hosted on + ``https://github.com/python/python-docs-{LANGUAGE_TAG}`` (not + mandatory to start a translation, but mandatory to land on + ``docs.python.org``). + +- Translations having completed ``tutorial/``, ``library/stdtypes`` + and ``library/functions`` are hosted on + ``https://docs.python.org/{LANGUAGE_TAG}/{VERSION_TAG}/``. + + +Coordinating FAQ +================ + +Are there tools to help in managing the repo? +--------------------------------------------- + +Here's what we're using: + +- :pypi:`pomerge` to propagate translations from one file to others. +- :pypi:`pospell` to check for typos in ``.po`` files. +- :pypi:`powrap` to rewrap the ``.po`` files + before committing. This helps keep Git diffs short. +- :pypi:`potodo` to list what needs to be translated. +- :pypi:`sphinx-lint` to validate reST syntax in translation files. + +More related tools and projects can be found in the +`python-docs-translations`__ organisation on GitHub. + +__ https://github.com/python-docs-translations + +How is a coordinator elected? +----------------------------- + +There is no election. Each translation will sort out the number of coordinators. We recommend 2 or 3 coordinators, though you may begin with one. Here are some general suggestions. + +- Coordinator requests are to be public on the `translation mailing list `_. +- If the given language has a native core dev, the core dev has input + on the coordinator request. +- Anyone who wants to become coordinator for their native language and shows + motivation by translating and building a community will be named + coordinator. +- We expect the local community to self-organize coordinators and contributors. + If you have questions, please ask on the mailing list or Discourse. +- If a coordinator becomes inactive or unreachable for a long + period of time, someone else can ask to be added as a primary coordinator on the `translation mailing list `_. + As a community resource, we aim to keep translations up to date with active contributors, including coordinators. + +I have a translation, but it's not in Git. What should I do? +------------------------------------------------------------ + +You can ask for help on the `translation mailing list `_, and +the team will help you create an appropriate repository. You can still use tools like transifex, +if you like. + + +My Git hierarchy does not match yours. Can I keep it? +----------------------------------------------------- + +No, inside the ``github.com/python`` organization we’ll all have the +exact same hierarchy so bots will be able to build all of our +translations. So you may have to convert from one hierarchy to another. +Ask for help on the `translation mailing list `_ if you’re +not sure on how to do it. + + +What hierarchy should I use in my GitHub repository? +---------------------------------------------------- + +As for every project, we have a *branch* per version. We store ``.po`` +files in the root of the repository using the ``gettext_compact=0`` +style. + + +The entry for my translation is missing/not up to date on this page +------------------------------------------------------------------- + +Ask on the `translation mailing list `_, or better, make a PR on the `devguide +`__. + +.. _translation_wg: https://wiki.python.org/psf/TranslationWG/Charter +.. _translation_ml: https://mail.python.org/mailman3/lists/translation.python.org/ diff --git a/documentation/translations/index.rst b/documentation/translations/index.rst new file mode 100644 index 0000000000..67ab049f99 --- /dev/null +++ b/documentation/translations/index.rst @@ -0,0 +1,9 @@ +============ +Translations +============ + +.. toctree:: + :maxdepth: 2 + + translating + coordinating diff --git a/documentation/translating.rst b/documentation/translations/translating.rst similarity index 55% rename from documentation/translating.rst rename to documentation/translations/translating.rst index abbd2c74f5..47f04cef89 100644 --- a/documentation/translating.rst +++ b/documentation/translations/translating.rst @@ -110,53 +110,6 @@ details. .. _tx: https://explore.transifex.com/python-doc/python-newest/ -Starting a new translation -========================== - -First subscribe to the `translation mailing list `_, -and introduce yourself and the translation you're starting. Translations -fall under the aegis of the `PSF Translation Workgroup `_ - -Then you can bootstrap your new translation by using `cookiecutter -`__ or -`bootstrapper `__. - -The important steps look like this: - -- Create the GitHub repo (anywhere) with the right hierarchy (using one - of the bootstrappers). -- Gather people to help you translate. You can't do it alone. -- You can use any tool to translate, as long as you can synchronize with Git. - Some use Transifex, and some use only GitHub. You can choose another - way if you like; it's up to you. -- Ensure we update this page to reflect your work and progress, either via a - PR or by asking on the `translation mailing list `_. -- When ``bugs``, ``tutorial``, and ``library/functions`` are 100% - completed, ask on the `translation mailing list `_ for - your language to be added in the language switcher on docs.python.org. - - -PEP 545 summary -=============== - -Here are the essential points of :PEP:`545`: - -- Each translation is assigned an appropriate lowercased language tag, - with an optional region subtag, and joined with a dash, like - ``pt-br`` or ``fr``. - -- Each translation is under CC0 and marked as such in the README (as in - the cookiecutter). - -- Translation files are hosted on - ``https://github.com/python/python-docs-{LANGUAGE_TAG}`` (not - mandatory to start a translation, but mandatory to land on - ``docs.python.org``). - -- Translations having completed ``tutorial/``, ``library/stdtypes`` - and ``library/functions`` are hosted on - ``https://docs.python.org/{LANGUAGE_TAG}/{VERSION_TAG}/``. - How to get help =============== @@ -177,74 +130,6 @@ Consensus is to work on the current stable version. You can then propagate your translation from one branch to another using :pypi:`pomerge`. -Are there tools to help in managing the repo? ---------------------------------------------- - -Here's what we're using: - -- :pypi:`pomerge` to propagate translations from one file to others. -- :pypi:`pospell` to check for typos in ``.po`` files. -- :pypi:`powrap` to rewrap the ``.po`` files - before committing. This helps keep Git diffs short. -- :pypi:`potodo` to list what needs to be translated. -- :pypi:`sphinx-lint` to validate reST syntax in translation files. - -More related tools and projects can be found in the -`python-docs-translations`__ organisation on GitHub. - -__ https://github.com/python-docs-translations - -How is a coordinator elected? ------------------------------ - -There is no election; each translation has to sort this out. Here are some suggestions. - -- Coordinator requests are to be public on the `translation mailing list `_. -- If the given language has a native core dev, the core dev has their - say on the choice. -- Anyone who wants to become coordinator for their native language and shows - motivation by translating and building a community will be named - coordinator. -- In case of concurrency between two persons, no one will sort this out - for you. It is up to you two to organize a local election or whatever is - needed to sort this out. -- If a coordinator becomes inactive or unreachable for a long - period of time, someone else can ask for a takeover on the `translation mailing list `_. - - -The entry for my translation is missing/not up to date on this page -------------------------------------------------------------------- - -Ask on the `translation mailing list `_, or better, make a PR on the `devguide -`__. - - -I have a translation, but it's not in Git. What should I do? ------------------------------------------------------------- - -You can ask for help on the `translation mailing list `_, and -the team will help you create an appropriate repository. You can still use tools like transifex, -if you like. - - -My Git hierarchy does not match yours. Can I keep it? ------------------------------------------------------ - -No, inside the ``github.com/python`` organization we’ll all have the -exact same hierarchy so bots will be able to build all of our -translations. So you may have to convert from one hierarchy to another. -Ask for help on the `translation mailing list `_ if you’re -not sure on how to do it. - - -What hierarchy should I use in my GitHub repository? ----------------------------------------------------- - -As for every project, we have a *branch* per version. We store ``.po`` -files in the root of the repository using the ``gettext_compact=0`` -style. - - How should I translate code examples? ------------------------------------- @@ -252,5 +137,4 @@ Translate values in code examples (i.e. string literals) and comments. Don't translate keywords or names, including variable, function, class, argument, and attribute names. -.. _translation_wg: https://wiki.python.org/psf/TranslationWG/Charter .. _translation_ml: https://mail.python.org/mailman3/lists/translation.python.org/ From b062cc9233194e6da21da8b0da0c8edcd605e937 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Sun, 15 Jun 2025 02:35:40 +0200 Subject: [PATCH 002/103] Switch to non-deprecated Tools/wasm/wasi (#1570) --- getting-started/setup-building.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index aa783f24eb..62da6b3fb2 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -411,7 +411,9 @@ Python you have installed on your machine): .. code-block:: shell - $ python3 Tools/wasm/wasi.py build --quiet -- --config-cache --with-pydebug + $ python3 Tools/wasm/wasi build --quiet -- --config-cache --with-pydebug + +For Python 3.14 and earlier, use ``Tools/wasm/wasi.py`` instead. That single command will configure and build both the build Python and the WASI build in ``cross-build/build`` and ``cross-build/wasm32-wasi``, @@ -422,10 +424,10 @@ is a convenience wrapper around the following commands: .. code-block:: shell - $ python Tools/wasm/wasi.py configure-build-python --quiet -- --config-cache --with-pydebug - $ python Tools/wasm/wasi.py make-build-python --quiet - $ python Tools/wasm/wasi.py configure-host --quiet -- --config-cache - $ python Tools/wasm/wasi.py make-host --quiet + $ python Tools/wasm/wasi configure-build-python --quiet -- --config-cache --with-pydebug + $ python Tools/wasm/wasi make-build-python --quiet + $ python Tools/wasm/wasi configure-host --quiet -- --config-cache + $ python Tools/wasm/wasi make-host --quiet .. note:: From 868d878eb19f964ad5415027f7ea810371e845a3 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 16 Jun 2025 02:11:06 +0100 Subject: [PATCH 003/103] Add python-docs-transifex-automations to translations page --- documentation/translations/coordinating.rst | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/documentation/translations/coordinating.rst b/documentation/translations/coordinating.rst index 3d64858ad8..7568116c84 100644 --- a/documentation/translations/coordinating.rst +++ b/documentation/translations/coordinating.rst @@ -12,11 +12,13 @@ fall under the aegis of the `PSF Translation Workgroup `_ Then you can bootstrap your new translation by using `cookiecutter `__ or `bootstrapper `__. +You can also start your translation using `Transifex `_ +following this `guide `_. The important steps look like this: - Create the GitHub repo (any account) with the correct hierarchy by using one - of the bootstrappers. + of the bootstrappers or Transifex. - Gather people to help you translate. You can't do it alone. - You can use any tool to translate, as long as you can synchronize with Git. Some use Transifex, and some use only GitHub. You can choose another @@ -58,11 +60,12 @@ Are there tools to help in managing the repo? Here's what we're using: -- :pypi:`pomerge` to propagate translations from one file to others. -- :pypi:`pospell` to check for typos in ``.po`` files. -- :pypi:`powrap` to rewrap the ``.po`` files - before committing. This helps keep Git diffs short. -- :pypi:`potodo` to list what needs to be translated. +- :pypi:`poutils` which includes: + - :pypi:`pomerge` to propagate translations from one file to others. + - :pypi:`pospell` to check for typos in ``.po`` files. + - :pypi:`powrap` to rewrap the ``.po`` files + before committing. This helps keep Git diffs short. + - :pypi:`potodo` to list what needs to be translated. - :pypi:`sphinx-lint` to validate reST syntax in translation files. More related tools and projects can be found in the From 00ca265bfe16d75e6946bc315abf957b4d7355cd Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 16 Jun 2025 02:12:16 +0100 Subject: [PATCH 004/103] Update translating with new Romanian translation location --- documentation/translations/translating.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/translations/translating.rst b/documentation/translations/translating.rst index 47f04cef89..d2cbe66214 100644 --- a/documentation/translations/translating.rst +++ b/documentation/translations/translating.rst @@ -82,7 +82,7 @@ details. `article `__ * - Romanian (ro) - Octavian Mustafa (:github-user:`octaG-M`, `email `__) - - :github:`GitHub ` + - :github:`GitHub ` * - Russian (ru) - Daniil Kolesnikov (:github-user:`MLGRussianXP`, `email `__) - :github:`GitHub `, From f9cb7e5b2c11b25c931c822b003d66b7fa80a60d Mon Sep 17 00:00:00 2001 From: Micha Albert Date: Sun, 15 Jun 2025 21:16:31 -0400 Subject: [PATCH 005/103] gh-1309: Document how to selectively build RST pages (#1562) --- documentation/start-documenting.rst | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/documentation/start-documenting.rst b/documentation/start-documenting.rst index 184cf54bfd..973b36b122 100644 --- a/documentation/start-documenting.rst +++ b/documentation/start-documenting.rst @@ -153,6 +153,25 @@ To build the docs as HTML, run: start a local server, and automatically reload the page in your browser when you make changes to reST files (Unix only). +It is also possible to build only certain pages of the documentation in order +to save time during the build process. Following is an example for building two +pages: + +.. tab:: Unix/macOS + + .. code-block:: shell + + make html SOURCES="tutorial/classes.rst tutorial/inputoutput.rst" + +.. tab:: Windows + + See :ref:`using-sphinx-build`. When invoking ``sphinx-build``, pass the + desired pages as the final parameter, like so: + + .. code-block:: dosbatch + + python -m sphinx -b html . build/html tutorial/classes.rst tutorial/inputoutput.rst + To check the docs for common errors with `Sphinx Lint`_ (which is run on all :ref:`pull requests `), use: From 2d657ff814d31b49d56633fbe42d75dd26b665d8 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Mon, 16 Jun 2025 14:50:30 -0400 Subject: [PATCH 006/103] Add Peter Bierma (#1577) --- core-developers/developers.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index aaa8d5d611..73e93ce465 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -1,3 +1,4 @@ +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,, From f1f5b8fb0cb3e008219cb4aa06edafb6eef1d625 Mon Sep 17 00:00:00 2001 From: "Tomas R." Date: Mon, 16 Jun 2025 21:41:54 +0200 Subject: [PATCH 007/103] Add Tomas Roun (#1578) --- core-developers/developers.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index 73e93ce465..b0ec464477 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -1,3 +1,4 @@ +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,, From 623218d403ed7a07ceec4fe9b88f5fecb1bdcef7 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 18 Jun 2025 13:55:37 +0200 Subject: [PATCH 008/103] Regenerate developers.csv (GH-1579) The CSV file should be generated from the voters repo (which is private to protect personal information). But, it was edited by hand recently. Regenerate to make future diffs smaller. The differences are CSV encoding details and one name variant. --- core-developers/developers.csv | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index b0ec464477..79f2e86f46 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -34,7 +34,7 @@ Kyle Stanley,aeros,2020-04-14,, Donghee Na,corona10,2020-04-08,, Karthikeyan Singaravelan,tirkarthi,2019-12-31,, Joannah Nanjekye,nanjekyejoannah,2019-09-23,, -Abhilash Raj,maxking,2019-08-06,2022-11-30,"Privileges relinquished on 2022-11-30" +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,, @@ -78,7 +78,7 @@ 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 -Carl Friedrich Bolz-Tereick,cfbolz,2011-03-21,,for stdlib compatibility work for PyPy +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,Relinquished privileges on 2020-11-26 @@ -119,7 +119,7 @@ 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,, 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" +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 @@ -145,9 +145,9 @@ 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,"Relinquished privileges on 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,hyeshik,2003-12-10,2025-02-28,"Relinquished privileges on 2025-02-28" +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 @@ -156,11 +156,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,holdenweb,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,2021-11-16,"Relinquished privileges on 2021-11-16" +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 From e5637b712f882608f36571f983fdb3a1357e72c1 Mon Sep 17 00:00:00 2001 From: "Tomas R." Date: Thu, 19 Jun 2025 21:49:40 +0200 Subject: [PATCH 009/103] Add tomasr8 to gettext & i18n (#1584) --- core-developers/experts.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 54f7fd3735..599d4d50e9 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -115,7 +115,7 @@ gc pitrou, pablogsal getopt serhiy-storchaka* getpath FFY00 getpass -gettext +gettext tomasr8 glob serhiy-storchaka* grp hashlib tiran, gpshead*, picnixz @@ -336,7 +336,7 @@ filesystem giampaolo frozen modules ericsnowcurrently, gvanrossum, kumaraditya303 f-strings ericvsmith* GUI -i18n malemburg, merwok +i18n malemburg, merwok, tomasr8 import machinery brettcannon, ncoghlan, ericsnowcurrently, FFY00 initialization FFY00 io benjaminp, stutzbach^, gpshead From 3a8b71e56390aab4914eea1ab773e1a2f3c87abd Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Fri, 20 Jun 2025 20:28:01 +0100 Subject: [PATCH 010/103] Update `translation/translators.rst` to add pages and detail for Coordinators and Translators (#1576) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial * Rafael's feedback * Further updates and amendments * Rafael's review * Carol’s suggestion Co-authored-by: Carol Willing * Maciek's review * Reviews * Maciek's review + comma * Hugo’s suggestions Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --------- Co-authored-by: Carol Willing Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- contrib/index.rst | 2 +- core-developers/experts.rst | 5 +- documentation/translations/coordinating.rst | 64 ++++- documentation/translations/index.rst | 2 +- documentation/translations/translating.rst | 246 ++++++++++++++++---- 5 files changed, 256 insertions(+), 63 deletions(-) diff --git a/contrib/index.rst b/contrib/index.rst index f9b54bc56a..b93d36504f 100644 --- a/contrib/index.rst +++ b/contrib/index.rst @@ -75,7 +75,7 @@ major section at the top of each column.]* * :ref:`documenting` * :ref:`style-guide` * :ref:`rst-primer` - * :ref:`translating` + * :doc:`documentation/translations` * :ref:`devguide` - * :ref:`setup` diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 599d4d50e9..76ea564c26 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -372,4 +372,7 @@ version control merwok, ezio-melotti Documentation translations ========================== -For a list of translators, see :ref:`this table about 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/documentation/translations/coordinating.rst b/documentation/translations/coordinating.rst index 7568116c84..4e78b92473 100644 --- a/documentation/translations/coordinating.rst +++ b/documentation/translations/coordinating.rst @@ -2,15 +2,21 @@ Coordinating ============ +Information about the Python documentation translation processes is +found in this devguide and :PEP:`545`. +Translations are built by `docsbuild-scripts +`__ and hosted on +docs.python.org. Translations +are overseen by the `Editorial Board `_ + Starting a new translation ========================== First subscribe to the `translation mailing list `_, -and introduce yourself and the translation you're starting. Translations -fall under the aegis of the `PSF Translation Workgroup `_ +and introduce yourself and the translation you're starting. -Then you can bootstrap your new translation by using `cookiecutter -`__ or +Then you can bootstrap your new translation by using the `cookiecutter +`__ or `bootstrapper `__. You can also start your translation using `Transifex `_ following this `guide `_. @@ -30,6 +36,16 @@ The important steps look like this: your language to be added in the language switcher on docs.python.org. +How to get help +=============== + +Discussions about translations occur on the Python Docs Discord +`#translations channel `_, `translation +mailing list `_, and the +`translations category `_ +of the Python Discourse. + + PEP 545 summary =============== @@ -52,6 +68,13 @@ Here are the essential points of :PEP:`545`: ``https://docs.python.org/{LANGUAGE_TAG}/{VERSION_TAG}/``. +Transifex +========= + +If you need help from a Transifex administrator, open an issue on the +`tracker `_. + + Coordinating FAQ ================ @@ -76,7 +99,9 @@ __ https://github.com/python-docs-translations How is a coordinator elected? ----------------------------- -There is no election. Each translation will sort out the number of coordinators. We recommend 2 or 3 coordinators, though you may begin with one. Here are some general suggestions. +Each translation team will decide on the number of coordinators. +We recommend two or three coordinators, though you may begin with one. +Here are some general suggestions. - Coordinator requests are to be public on the `translation mailing list `_. - If the given language has a native core dev, the core dev has input @@ -116,11 +141,30 @@ files in the root of the repository using the ``gettext_compact=0`` style. -The entry for my translation is missing/not up to date on this page -------------------------------------------------------------------- +.. XXX Explain necessary folder structure + + +Which version of the Python documentation should be translated? +--------------------------------------------------------------- + +It's best to work on Python's current stable or beta version. You can then +propagate your translation from one branch to another using :pypi:`pomerge`. + + +The entry for my translation is missing or not up to date +--------------------------------------------------------- + +Ask on the `translation mailing list `_, or better, make a PR +on the `devguide `__. + + +Is there a Weblate instance we can translate on? +------------------------------------------------ + +There is currently no Weblate instance for Python translations. +See this `Discourse thread `_ +for updates. -Ask on the `translation mailing list `_, or better, make a PR on the `devguide -`__. -.. _translation_wg: https://wiki.python.org/psf/TranslationWG/Charter +.. _EB: https://python.github.io/editorial-board/ .. _translation_ml: https://mail.python.org/mailman3/lists/translation.python.org/ diff --git a/documentation/translations/index.rst b/documentation/translations/index.rst index 67ab049f99..2f5cfe0f40 100644 --- a/documentation/translations/index.rst +++ b/documentation/translations/index.rst @@ -3,7 +3,7 @@ Translations ============ .. toctree:: - :maxdepth: 2 + :maxdepth: 3 translating coordinating diff --git a/documentation/translations/translating.rst b/documentation/translations/translating.rst index d2cbe66214..7d1e2f251e 100644 --- a/documentation/translations/translating.rst +++ b/documentation/translations/translating.rst @@ -1,40 +1,43 @@ -.. _translating: - =========== Translating =========== .. highlight:: rest -Python documentation translations are governed by :PEP:`545`. -They are built by `docsbuild-scripts -`__ and hosted on -docs.python.org. There are several documentation translations already -in production; others are works in progress. See `the dashboard -`__ for -details. +There are several documentation translations already +in production and can be found in the language switcher; others are works in +progress. To get started read your repository's contributing guide, which is +generally the ``README`` file, and this page. +If your language isn’t listed below, feel free to start the translation! +See :doc:`coordinating` guide to get started. + +For more details about translations and their progress, see `the dashboard +`__. + +.. _translation-coordinators: .. list-table:: :header-rows: 1 * - Language - - Contact + - Coordination team - Links * - Arabic (ar) - Abdur-Rahmaan Janhangeer (:github-user:`Abdur-rahmaanJ`) - :github:`GitHub ` - * - Bengali (bn_IN) + * - `Bengali (bn-IN) `__ - Kushal Das (:github-user:`kushaldas`) - :github:`GitHub ` * - `French (fr) `__ - Julien Palard (:github-user:`JulienPalard`) - - :github:`GitHub ` - * - Greek (gr) - - Lysandros Nikolaou (:github-user:`lysnikolaou`), - Fanis Petkos (:github-user:`thepetk`), - Panagiotis Skias (:github-user:`skpanagiotis`) - - :github:`GitHub ` - * - Hindi (hi_IN) + - `AFPy/python-docs-fr `_, + :github:`mirror ` + * - `Greek (el) `__ + - | Lysandros Nikolaou (:github-user:`lysnikolaou`), + | Fanis Petkos (:github-user:`thepetk`), + | Panagiotis Skias (:github-user:`skpanagiotis`) + - :github:`GitHub ` + * - Hindi (hi-IN) - Sanyam Khurana (:github-user:`CuriousLearner`) - :github:`GitHub ` * - Hungarian (hu) @@ -42,16 +45,16 @@ details. - :github:`GitHub `, `mailing list `__ * - `Indonesian (id) `__ - - Irvan Putra (:github-user:`irvan-putra`), - Jeff Jacobson (:github-user:`jwjacobson`) + - | Irvan Putra (:github-user:`irvan-putra`), + | Jeff Jacobson (:github-user:`jwjacobson`) - :github:`GitHub ` - * - Italian (it) + * - `Italian (it) `__ - Alessandro Cucci (`email `__) - :github:`GitHub `, - `original mail `__ + `original announcement `__ * - `Japanese (ja) `__ - - Kinebuchi Tomohiko (:github-user:`cocoatomo`), - Atsuo Ishimoto (:github-user:`atsuoishimoto`) + - | Kinebuchi Tomohiko (:github-user:`cocoatomo`), + | Atsuo Ishimoto (:github-user:`atsuoishimoto`) - :github:`GitHub ` * - `Korean (ko) `__ - 오동권 (:github-user:`flowdas`) @@ -61,43 +64,44 @@ details. - :github:`GitHub ` * - Lithuanian (lt) - Albertas Gimbutas (:github-user:`albertas`, `email `__) - - `Original mail `__ + - `original announcement `__ * - Persian (fa) - Alireza Shabani (:github-user:`revisto`) - :github:`GitHub ` * - `Polish (pl) `__ - - Maciej Olko (:github-user:`m-aciek`) + - | Maciej Olko (:github-user:`m-aciek`), + | Stan Ulbrych (:github-user:`StanFromIreland`) - :github:`GitHub `, `Transifex `_, - `original mail `__ + `original announcement `__ * - Portuguese (pt) - Gustavo Toffo - * - `Brazilian Portuguese (pt-br) `__ - - Rafael Fontenelle (:github-user:`rffontenelle`), - Marco Rougeth (:github-user:`rougeth`) + - | Rafael Fontenelle (:github-user:`rffontenelle`), + | Marco Rougeth (:github-user:`rougeth`) - :github:`GitHub `, - `wiki `__, + `guide `__, `Telegram `__, `article `__ - * - Romanian (ro) + * - `Romanian (ro) `__ - Octavian Mustafa (:github-user:`octaG-M`, `email `__) - :github:`GitHub ` * - Russian (ru) - Daniil Kolesnikov (:github-user:`MLGRussianXP`, `email `__) - :github:`GitHub `, - `mail `__ + `original announcement `__ * - `Simplified Chinese (zh-cn) `__ - - Shengjing Zhu (:github-user:`zhsj`), - Du, Meng (:github-user:`dumeng`) + - | Shengjing Zhu (:github-user:`zhsj`), + | Du, Meng (:github-user:`dumeng`) - :github:`GitHub `, `Transifex `_ * - `Spanish (es) `__ - Raúl Cumplido - :github:`GitHub ` * - `Traditional Chinese (zh-tw) `__ - - 王威翔 Matt Wang (:github-user:`mattwang44`), - Josix Wang + - | 王威翔 Matt Wang (:github-user:`mattwang44`), + | Josix Wang - :github:`GitHub ` * - `Turkish (tr) `__ - Ege Akman (:github-user:`egeakman`) @@ -108,33 +112,175 @@ details. - :github:`GitHub `, `Transifex `_ -.. _tx: https://explore.transifex.com/python-doc/python-newest/ - How to get help =============== -Discussions about translations occur on the Python Docs Discord +If there is already a repository for your language team (there may be links to +Telegrams/Discords in the ``README``), join and introduce +yourself. Your fellow translators will be more than happy to help! +General discussions about translations occur on the Python Docs Discord `#translations channel `_, `translation -mailing list `_, and there's a `Libera.Chat IRC -`_ channel, ``#python-doc``. +mailing list `_, and the `translations category <_discourse>`_ +of the Python Discourse. + + +Style guide +=========== + +Before translating, you should familiarize yourself with the general +documentation :doc:`style guide<../style-guide>`. Some translation-specific +guidelines are explained below. + + +Translate the meaning +--------------------- + +Try to stay as close as possible to the original text. Focus on translating its +meaning in the best possible way. + + +Gender neutrality +----------------- + +Many languages use grammatical gender. When possible and natural, prefer +gender-neutral or inclusive forms. Aim to reflect the inclusive tone of +the English documentation. + + +Roles and links +--------------- + +The Python docs contain many roles (``:role:`target```) that link to other parts +of the documentation. +Do not translate reStructuredText roles targets, such as ``:func:`print``` or +``:ref:`some-section``` because it will break the link. +If alternate text (``:role:`text ``` is provided, it generally +should be translated. You can also introduce alternate text for translation if +the target is not a name or term. + +Links (```text `_``) should be handled similarly. If possible, the target +should be updated to match the language. + +.. seealso:: + :doc:`../markup` + + +Translation quality +------------------- + +Translators should know both English and the language they are +translating to. Translators should aim for a similar level of quality as that +of the English documentation. + +Do not rely solely on machine translation. These tools can be useful to speed up +work, but often produce inaccurate or misleading results and should be reviewed +by a human. + + +Terminology +----------- + +The documentation is full of technical terms, some are common in general +programming and have translations, whereas others are specific to Python +and previous translations are not available. +Translation teams should keep the translations of these terms +consistent, which is done with glossaries. + +Some general guidelines for deciding on a translation: + +- Use existing community conventions over inventing new terms. +- You can use a hybrid English form if users are generally familiar + with the English word. +- For common terms, the English word may be best. +- Use other translations as a reference as to what they did for the word. +- Be careful to not translate names. +- Use your best judgment. +- When you translate a specific term, record it in your translations glossary to + help fellow translators and ensure consistency. + + +Dialects +-------- + +Some translation receive contributions from people of several different dialects, +understandably the language will differ. It is recommended however that +translators try to keep files and sections consistent. + + +Code examples +------------- + +Translate values in code examples, that is string literals, and comments. +Don't translate keywords or names, including variable, function, class, argument, +and attribute names. An example of a translated codeblock from the `tutorial `_ +is provided below: + +.. code-block:: python + + def cheeseshop(kind, *arguments, **keywords): + print("-- Czy jest może", kind, "?") + print("-- Przykro mi, nie mamy już sera", kind) + for arg in arguments: + print(arg) + print("-" * 40) + for kw in keywords: + print(kw, ":", keywords[kw]) + + +Transifex +========= + +.. important:: + + There are many translations in the `python-doc organization on Transifex `_, + some of which, however, are not used or do not have a coordination team. + Confirm this is not the case before you begin translating. + +Several language projects use Transifex as their translation interface. +Translations on Transifex are carried out via a web interface, similar to Weblate. +You should translate the `python-newest `_ project. +If you are new to Transifex, it is recommended that you take the time to read +through the following resources from the Transifex documentation: + +- `Getting started as a translator `__: + This covers signing up for an account and joining a translation team. +- `Translating with the Web Editor `__: + This covers getting to the editor, searching and filtering strings, and translating strings. +- `Other Tools in the Editor `__: + This covers the history, glossary, comments, keyboard shortcuts, and more. +- `Starting with the basics `__: + A group of documents with basic information. + +For further information about Transifex see our `documentation `_. + + +Pull requests +============= + +Several translations accept contributions by pull requests. Most have their +own guide for how to do this, and for general tips see our :ref:`git-boot-camp`. Translation FAQ =============== -Which version of the Python documentation should be translated? ---------------------------------------------------------------- +Which version of the Python documentation should I work on? +----------------------------------------------------------- + +You should work on the latest branch available to you for translation (this should +be the latest non-alpha branch), the translations should then be propagated by +your languages coordination team. -Consensus is to work on the current stable version. You can then propagate your -translation from one branch to another using :pypi:`pomerge`. +The coordination team for my language is inactive, what do I do? +---------------------------------------------------------------- -How should I translate code examples? -------------------------------------- +If you would like to coordinate, open a pull request in the +`devguide `_ adding yourself, and ping +``@python/editorial-board``. -Translate values in code examples (i.e. string literals) and comments. -Don't translate keywords or names, -including variable, function, class, argument, and attribute names. .. _translation_ml: https://mail.python.org/mailman3/lists/translation.python.org/ +.. _discourse: https://discuss.python.org/c/documentation/translations/ +.. _tx: https://explore.transifex.com/python-doc/python-newest/ From 470512685664d98e7d9b20f99cdf8dfb7ac1d030 Mon Sep 17 00:00:00 2001 From: Cornelius Roemer Date: Tue, 24 Jun 2025 09:21:06 +0200 Subject: [PATCH 011/103] Dynamically substitute main version in versions.rst from release-cycle.json (#1583) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Ezio Melotti --- conf.py | 15 ++++++++++++++- versions.rst | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/conf.py b/conf.py index bedd99c42f..9bfe2305cb 100644 --- a/conf.py +++ b/conf.py @@ -1,3 +1,5 @@ +import json + extensions = [ 'notfound.extension', 'sphinx.ext.extlinks', @@ -165,8 +167,17 @@ # 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 = """ +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. @@ -183,6 +194,8 @@ .. _Refactoring the DevGuide: https://discuss.python.org/t/refactoring-the-devguide-into-a-contribution-guide/63409 +.. |main_version| replace:: {_main_version} + """ # sphinx.ext.extlinks diff --git a/versions.rst b/versions.rst index 8cfd259f8a..0a52829c2f 100644 --- a/versions.rst +++ b/versions.rst @@ -5,7 +5,7 @@ Status of Python versions ========================= -The ``main`` branch is currently the future Python 3.14, and is the only +The ``main`` branch is currently the future Python |main_version|, and is the only branch that accepts new features. The latest release for each Python version can be found on the `download page `_. From 8b085665d9694d7ce4cf8ed0f231888fbf60dff8 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Thu, 26 Jun 2025 04:01:46 -0700 Subject: [PATCH 012/103] Add instructions on how to use the dev container image from GHCR (#1581) Co-authored-by: Petr Viktorin Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- getting-started/setup-building.rst | 57 +++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 62da6b3fb2..910808453a 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -1188,19 +1188,52 @@ select the option ``Open in VS Code``. You will still be working on the remote codespace instance, thus using the remote instance's compute power. The compute power may be a much higher spec than your local machine which can be helpful. +.. _devcontainer-directly: -Building the container locally ------------------------------- +Using the dev container directly +================================ If you want more control over the environment, or to work offline, -you can build the container locally. +you can use the same container used in +:ref:`GitHub Codespaces ` directly. This is meant for users who have (or want to get) some experience with containers. -The following instructions are a starting point for -your own customizations. -They assume a Unix-like environment, and Docker or Podman installed. +These instructions assume a Unix-like environment with +`Docker `__ or `Podman `__ +installed. -In a clone of the `cpython-devcontainers repo `_, +.. _devcontainer-image: + +Using the pre-built container image +----------------------------------- + +`Dev container images `__ +are available from the +`GitHub Container Registry (GHCR) account for the Python org `__. + +To run the container and launch a Bash shell, run one of the following commands +in a clone of the CPython repository. + +.. code-block:: bash + + docker run -it --rm --volume $PWD:/workspace --workdir /workspace ghcr.io/python/devcontainer:latest + +.. code-block:: bash + + podman run -it --rm --volume $PWD:/workspace:Z --workdir /workspace ghcr.io/python/devcontainer:latest + +Note that the container has read/write access to the working directory. +You may want to use a separate clone of CPython, or run ``make clean`` +to remove caches and build output generated for your host OS. + +.. _building-the-container-locally +.. _devcontainer-build: + +Building yourself +----------------- + +If you prefer, you can build the container image yourself. In a clone of the +`cpython-devcontainers repo `_, build the container and name it ``cpython-dev``: .. code-block:: bash @@ -1213,8 +1246,8 @@ The same command will update any existing ``cpython-dev`` container. Run it again from time to time -- especially if the container stops working for you. -To run the container, run one of the following commands in a clone of the -CPython repository. +To run the container and launch a Bash shell, run one of the following commands +in a clone of the CPython repository. .. code-block:: bash @@ -1224,12 +1257,10 @@ CPython repository. podman run -it --rm --volume $PWD:/workspace:Z --workdir /workspace cpython-dev -Note that the container has read/write access to the working directory. -You may want to use a separate clone of CPython, or run ``make clean`` -to remove caches and build output generated for your host OS. +The same caveats outlined above when running from a container image from GHCR +also apply here. .. c_codespaces_end - .. include:: ../links.rst From 7800083e2cf806fb75520d3f48233dea7e48c2c3 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Tue, 1 Jul 2025 11:26:58 -0400 Subject: [PATCH 013/103] Add Peter Bierma to the experts index (#1596) --- core-developers/experts.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 76ea564c26..6f40abe1d4 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -103,7 +103,7 @@ encodings malemburg ensurepip ncoghlan, dstufft, pradyunsg, pfmoore enum eliben*, warsaw, ethanfurman* errno Yhg1s -faulthandler vstinner, gpshead +faulthandler vstinner, gpshead, ZeroIntensity* fcntl Yhg1s filecmp fileinput @@ -356,9 +356,9 @@ 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 +runtime lifecycle ericsnowcurrently, kumaraditya303, zooba, ZeroIntensity str.format ericvsmith* -subinterpreters ericsnowcurrently, kumaraditya303 +subinterpreters ericsnowcurrently, kumaraditya303, ZeroIntensity* symbol table JelleZijlstra, carljm testing ezio-melotti test coverage From 99af371e5932270f114e4afe75caeee23d4e8167 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 3 Jul 2025 21:14:38 +0300 Subject: [PATCH 014/103] Reorder the list of argparse experts in alphabetical order. (#1599) --- core-developers/experts.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 6f40abe1d4..4237d8241b 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -56,7 +56,7 @@ __future__ __main__ gvanrossum, ncoghlan _thread abc -argparse serhiy-storchaka*, savannahostrowski* +argparse savannahostrowski*, serhiy-storchaka* array ast benjaminp, pablogsal, isidentical, JelleZijlstra, eclips4 asyncio 1st1, asvetlov, gvanrossum, graingert, kumaraditya303, willingc From 347a9b08cdff5a3bf9939619e4b5e4a38f12434d Mon Sep 17 00:00:00 2001 From: Neil Schemenauer Date: Thu, 3 Jul 2025 16:23:05 -0700 Subject: [PATCH 015/103] Add "nascheme" in a few places. (#1597) --- core-developers/experts.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 4237d8241b..0e54a339ff 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -111,7 +111,7 @@ fnmatch serhiy-storchaka* fractions ftplib giampaolo* functools rhettinger* -gc pitrou, pablogsal +gc pitrou, pablogsal, nascheme getopt serhiy-storchaka* getpath FFY00 getpass @@ -241,7 +241,7 @@ uuid venv vsajip, FFY00 warnings wave -weakref freddrake +weakref freddrake, nascheme webbrowser winreg stutzbach^ winsound @@ -343,7 +343,7 @@ io benjaminp, stutzbach^, gpshead JIT brandtbucher*, savannahostrowski* locale malemburg mathematics malemburg, stutzbach^, rhettinger, serhiy-storchaka -memory management tim-one, malemburg, Yhg1s +memory management tim-one, malemburg, Yhg1s, nascheme memoryview networking giampaolo, gpshead object model benjaminp, Yhg1s @@ -351,12 +351,12 @@ 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* + 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 +runtime lifecycle ericsnowcurrently, kumaraditya303, zooba, ZeroIntensity, nascheme str.format ericvsmith* subinterpreters ericsnowcurrently, kumaraditya303, ZeroIntensity* symbol table JelleZijlstra, carljm From 12c4b0e6355a313b476be4b7a0a835744cd0d431 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 5 Jul 2025 15:30:50 -0700 Subject: [PATCH 016/103] experts: add Jelle as expert for annotationlib (#1601) --- core-developers/experts.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 0e54a339ff..5731b0c92b 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -56,6 +56,7 @@ __future__ __main__ gvanrossum, ncoghlan _thread abc +annotationlib JelleZijlstra* argparse savannahostrowski*, serhiy-storchaka* array ast benjaminp, pablogsal, isidentical, JelleZijlstra, eclips4 From 9c94fdd285a23c032d9b471b80d0c90bbc38e360 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 6 Jul 2025 01:32:39 +0300 Subject: [PATCH 017/103] Move `core-developers/` to `core-team/` (#1593) --- conf.py | 21 +++++++++++++------ contrib/core-team/committing.rst | 2 +- contrib/core-team/developer-log.rst | 11 ---------- contrib/core-team/experts.rst | 2 +- contrib/core-team/index.rst | 6 +++--- contrib/core-team/join-team.rst | 9 ++------ contrib/core-team/motivations.rst | 2 +- contrib/core-team/responsibilities.rst | 2 +- contrib/core-team/team-log.rst | 11 ++++++++++ contrib/index.rst | 2 +- {core-developers => core-team}/committing.rst | 0 .../developers.csv => core-team/core-team.csv | 0 {core-developers => core-team}/experts.rst | 0 {core-developers => core-team}/index.rst | 11 +++++----- .../join-team.rst | 7 ++++--- .../memorialization.rst | 4 ++-- .../motivations.rst | 0 .../responsibilities.rst | 0 .../team-log.rst | 9 ++++---- index.rst | 4 ++-- 20 files changed, 55 insertions(+), 48 deletions(-) delete mode 100644 contrib/core-team/developer-log.rst create mode 100644 contrib/core-team/team-log.rst rename {core-developers => core-team}/committing.rst (100%) rename core-developers/developers.csv => core-team/core-team.csv (100%) rename {core-developers => core-team}/experts.rst (100%) rename {core-developers => core-team}/index.rst (58%) rename core-developers/become-core-developer.rst => core-team/join-team.rst (97%) rename {core-developers => core-team}/memorialization.rst (96%) rename {core-developers => core-team}/motivations.rst (100%) rename {core-developers => core-team}/responsibilities.rst (100%) rename core-developers/developer-log.rst => core-team/team-log.rst (85%) diff --git a/conf.py b/conf.py index 9bfe2305cb..5050f5c45c 100644 --- a/conf.py +++ b/conf.py @@ -111,12 +111,21 @@ # 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 Developers - "coredev.rst": "core-developers/become-core-developer.rst", - "committing.rst": "core-developers/committing.rst", - "developers.rst": "core-developers/developer-log.rst", - "experts.rst": "core-developers/experts.rst", - "motivations.rst": "core-developers/motivations.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", diff --git a/contrib/core-team/committing.rst b/contrib/core-team/committing.rst index 59cf7c1af2..5b639cd5a0 100644 --- a/contrib/core-team/committing.rst +++ b/contrib/core-team/committing.rst @@ -8,4 +8,4 @@ [This is the existing core developers :ref:`committing` page from the devguide. We'll adjust "core developer" to "core team" where appropriate.] -.. include:: ../../core-developers/committing.rst +.. include:: ../../core-team/committing.rst diff --git a/contrib/core-team/developer-log.rst b/contrib/core-team/developer-log.rst deleted file mode 100644 index 473cd3c6c6..0000000000 --- a/contrib/core-team/developer-log.rst +++ /dev/null @@ -1,11 +0,0 @@ -.. important:: - - |draft| - - |purpose| - - -[This is the existing core developers :ref:`developer-log` page from the devguide. We'll -adjust "core developer" to "core team" where appropriate.] - -.. include:: ../../core-developers/developer-log.rst diff --git a/contrib/core-team/experts.rst b/contrib/core-team/experts.rst index 7f2a103cd5..73a9431c0b 100644 --- a/contrib/core-team/experts.rst +++ b/contrib/core-team/experts.rst @@ -8,4 +8,4 @@ [This is the existing core developers :ref:`experts` page from the devguide. We'll adjust "core developer" to "core team" where appropriate.] -.. include:: ../../core-developers/experts.rst +.. include:: ../../core-team/experts.rst diff --git a/contrib/core-team/index.rst b/contrib/core-team/index.rst index a89d08affc..d51a8a4e83 100644 --- a/contrib/core-team/index.rst +++ b/contrib/core-team/index.rst @@ -5,13 +5,13 @@ |purpose| -.. _c_coreteam: +.. _c_core-team: ========= Core team ========= -[This is mostly re-organized from the :ref:`core-dev` section of the devguide, +[This is mostly re-organized from the :ref:`core-team` section of the devguide, but with "core developer" language changed to "core team" where possible.] .. toctree:: @@ -20,6 +20,6 @@ but with "core developer" language changed to "core team" where possible.] responsibilities committing experts - developer-log + team-log motivations join-team diff --git a/contrib/core-team/join-team.rst b/contrib/core-team/join-team.rst index 0c893ae08d..70557589da 100644 --- a/contrib/core-team/join-team.rst +++ b/contrib/core-team/join-team.rst @@ -5,12 +5,7 @@ |purpose| -[This is the existing core developers :ref:`become-core-developer` page from the devguide with the title changed. We'll +[This is the existing core developers :ref:`join-core-team` page from the devguide. We'll adjust "core developer" to "core team" where appropriate.] -========================= -How to join the core team -========================= - -.. include:: ../../core-developers/become-core-developer.rst - :start-line: 7 +.. include:: ../../core-team/join-team.rst diff --git a/contrib/core-team/motivations.rst b/contrib/core-team/motivations.rst index c9e0281b6f..8fc6f94dba 100644 --- a/contrib/core-team/motivations.rst +++ b/contrib/core-team/motivations.rst @@ -8,4 +8,4 @@ [This is the existing core developers :ref:`motivations` page from the devguide. We'll adjust "core developer" to "core team" where appropriate.] -.. include:: ../../core-developers/motivations.rst +.. include:: ../../core-team/motivations.rst diff --git a/contrib/core-team/responsibilities.rst b/contrib/core-team/responsibilities.rst index a3de329561..973385a157 100644 --- a/contrib/core-team/responsibilities.rst +++ b/contrib/core-team/responsibilities.rst @@ -8,4 +8,4 @@ [This is the existing core developers :ref:`responsibilities` page from the devguide. We'll adjust "core developer" to "core team" where appropriate.] -.. include:: ../../core-developers/responsibilities.rst +.. 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 0000000000..d6b480d25d --- /dev/null +++ b/contrib/core-team/team-log.rst @@ -0,0 +1,11 @@ +.. important:: + + |draft| + + |purpose| + + +[This is the existing core team :ref:`team-log` page from the devguide. We'll +adjust "core developer" to "core team" where appropriate.] + +.. include:: ../../core-team/team-log.rst diff --git a/contrib/index.rst b/contrib/index.rst index b93d36504f..0b5a3edc65 100644 --- a/contrib/index.rst +++ b/contrib/index.rst @@ -95,7 +95,7 @@ major section at the top of each column.]* * :ref:`gh-faq` * :ref:`triage-team` -Core team members will find guidance in the :ref:`c_coreteam` section. +Core team members will find guidance in the :ref:`c_core-team` section. Contents ======== diff --git a/core-developers/committing.rst b/core-team/committing.rst similarity index 100% rename from core-developers/committing.rst rename to core-team/committing.rst diff --git a/core-developers/developers.csv b/core-team/core-team.csv similarity index 100% rename from core-developers/developers.csv rename to core-team/core-team.csv diff --git a/core-developers/experts.rst b/core-team/experts.rst similarity index 100% rename from core-developers/experts.rst rename to core-team/experts.rst diff --git a/core-developers/index.rst b/core-team/index.rst similarity index 58% rename from core-developers/index.rst rename to core-team/index.rst index 2e6db104f4..f8dafe05ee 100644 --- a/core-developers/index.rst +++ b/core-team/index.rst @@ -1,8 +1,9 @@ .. _core-dev: +.. _core-team: -=============== -Core developers -=============== +========= +Core team +========= .. toctree:: :maxdepth: 5 @@ -10,7 +11,7 @@ Core developers responsibilities committing experts - developer-log + team-log motivations - become-core-developer + join-team memorialization diff --git a/core-developers/become-core-developer.rst b/core-team/join-team.rst similarity index 97% rename from core-developers/become-core-developer.rst rename to core-team/join-team.rst index 70b7e25af9..5735f72a13 100644 --- a/core-developers/become-core-developer.rst +++ b/core-team/join-team.rst @@ -1,9 +1,10 @@ .. _become-core-developer: .. _coredev: +.. _join-core-team: -============================== -How to become a core developer -============================== +========================= +How to join the core team +========================= What it takes ============= diff --git a/core-developers/memorialization.rst b/core-team/memorialization.rst similarity index 96% rename from core-developers/memorialization.rst rename to core-team/memorialization.rst index b1e51cea2c..2bcf24ae12 100644 --- a/core-developers/memorialization.rst +++ b/core-team/memorialization.rst @@ -115,8 +115,8 @@ python.org admin devguide.python.org ------------------- -* The user is marked as deceased in `developers.csv `_; -* The user is removed from the `Experts Index `_. +* The user is marked as deceased in `core-team.csv `_; +* The user is removed from the `experts index `_. bugs.python.org --------------- diff --git a/core-developers/motivations.rst b/core-team/motivations.rst similarity index 100% rename from core-developers/motivations.rst rename to core-team/motivations.rst diff --git a/core-developers/responsibilities.rst b/core-team/responsibilities.rst similarity index 100% rename from core-developers/responsibilities.rst rename to core-team/responsibilities.rst diff --git a/core-developers/developer-log.rst b/core-team/team-log.rst similarity index 85% rename from core-developers/developer-log.rst rename to core-team/team-log.rst index 665ef07003..77639ebf1d 100644 --- a/core-developers/developer-log.rst +++ b/core-team/team-log.rst @@ -1,16 +1,17 @@ .. _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 diff --git a/index.rst b/index.rst index b70461dc0d..4f62668ac0 100644 --- a/index.rst +++ b/index.rst @@ -169,7 +169,7 @@ Core developers and contributors alike will find the following guides useful: Guide for contributing to Python: ======================== =================== ======================= ======================= -Contributors Documentarians Triagers Core Developers +Contributors Documentarians Triagers Core team ======================== =================== ======================= ======================= :ref:`setup` :ref:`docquality` :ref:`tracker` :ref:`responsibilities` :ref:`help` :ref:`documenting` :ref:`triaging` :ref:`developers` @@ -314,7 +314,7 @@ Full table of contents documentation/index testing/index development-tools/index - core-developers/index + core-team/index internals/index versions contrib/index From 903e4d25210009122e0838515717aa7926a8f909 Mon Sep 17 00:00:00 2001 From: "W. H. Wang" Date: Tue, 8 Jul 2025 01:05:29 +0800 Subject: [PATCH 018/103] remove deleted modules (PEP 594) from experts index (#1600) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- core-team/experts.rst | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/core-team/experts.rst b/core-team/experts.rst index 5731b0c92b..5791ff4088 100644 --- a/core-team/experts.rst +++ b/core-team/experts.rst @@ -127,7 +127,6 @@ http idlelib kbkaiser (inactive), terryjreedy*, serwy (inactive), taleinat imaplib -imghdr importlib brettcannon inspect 1st1 io benjaminp, stutzbach^ @@ -146,24 +145,19 @@ math rhettinger, stutzbach^ mimetypes mmap Yhg1s modulefinder theller (inactive), jvr^ -msilib msvcrt multiprocessing applio*, pitrou, jnoller^ (inactive), sbt^ (inactive), gpshead* netrc -nis -nntplib numbers operator optparse mitsuhiko, serhiy-storchaka* os os.path serhiy-storchaka* -ossaudiodev parser pablogsal pathlib barneygale* pdb gaogaotiantian pickle avassalotti, serhiy-storchaka* pickletools avassalotti, serhiy-storchaka* -pipes pkgutil platform malemburg plistlib @@ -196,10 +190,8 @@ shutil tarekziade, giampaolo signal gpshead site smtplib -sndhdr socket gpshead socketserver -spwd sqlite3 ghaering^, erlend-aasland* ssl jackjansen, tiran, dstufft, alex stat tiran @@ -237,7 +229,6 @@ unicodedata malemburg, ezio-melotti unittest ezio-melotti, rbtcollins, gpshead, serhiy-storchaka* unittest.mock urllib orsenthil -uu uuid venv vsajip, FFY00 warnings @@ -247,7 +238,6 @@ webbrowser winreg stutzbach^ winsound wsgiref pjenvey -xdrlib xml.dom xml.dom.minidom xml.dom.pulldom From 1c3d689c0d77cb5f4deedf69d3bce0b3c01bbf79 Mon Sep 17 00:00:00 2001 From: Yuki Kobayashi Date: Wed, 9 Jul 2025 21:59:58 +0900 Subject: [PATCH 019/103] Fix some bullet lists in the documentation (GH-1602) Added newlines and fixed indentations so that the lists render correctly. --- core-team/join-team.rst | 9 +++++---- developer-workflow/extension-modules.rst | 16 ++++++++-------- development-tools/warnings.rst | 19 +++++++++++-------- documentation/translations/coordinating.rst | 12 +++++++----- 4 files changed, 31 insertions(+), 25 deletions(-) diff --git a/core-team/join-team.rst b/core-team/join-team.rst index 5735f72a13..1067696bbb 100644 --- a/core-team/join-team.rst +++ b/core-team/join-team.rst @@ -89,10 +89,11 @@ Here's what it outputs, you can copy and paste it for your poll: [/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``) + +- 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 diff --git a/developer-workflow/extension-modules.rst b/developer-workflow/extension-modules.rst index d6be888241..7131cfdf86 100644 --- a/developer-workflow/extension-modules.rst +++ b/developer-workflow/extension-modules.rst @@ -555,16 +555,16 @@ Now that the configuration is in place, it remains to compile the project: * ``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. + 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:: + .. 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. + 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 `. diff --git a/development-tools/warnings.rst b/development-tools/warnings.rst index b6448f3979..b30d811311 100644 --- a/development-tools/warnings.rst +++ b/development-tools/warnings.rst @@ -37,15 +37,18 @@ platform-specific warning ignore file. The warning ignore file is either If a warning check fails with: * Unexpected warnings - * Attempt to refactor the code to avoid the warning. - * If it is not possible to avoid the warning document in the PR why it is - reasonable to ignore and add the warning to the platform-specific - warning ignore file. If the file exists in the warning ignore file - increment the count by the number of newly introduced warnings. + + * Attempt to refactor the code to avoid the warning. + * If it is not possible to avoid the warning document in the PR why it is + reasonable to ignore and add the warning to the platform-specific + warning ignore file. If the file exists in the warning ignore file + increment the count by the number of newly introduced warnings. + * Unexpected improvements (less warnings) - * Document in the PR that the change reduces the number of compiler - warnings. Decrement the count in the platform-specific warning - ignore file or remove the file if the count is now zero. + + * Document in the PR that the change reduces the number of compiler + warnings. Decrement the count in the platform-specific warning + ignore file or remove the file if the count is now zero. .. _updating-warning-ignore-file: diff --git a/documentation/translations/coordinating.rst b/documentation/translations/coordinating.rst index 4e78b92473..d2878385ee 100644 --- a/documentation/translations/coordinating.rst +++ b/documentation/translations/coordinating.rst @@ -84,11 +84,13 @@ Are there tools to help in managing the repo? Here's what we're using: - :pypi:`poutils` which includes: - - :pypi:`pomerge` to propagate translations from one file to others. - - :pypi:`pospell` to check for typos in ``.po`` files. - - :pypi:`powrap` to rewrap the ``.po`` files - before committing. This helps keep Git diffs short. - - :pypi:`potodo` to list what needs to be translated. + + - :pypi:`pomerge` to propagate translations from one file to others. + - :pypi:`pospell` to check for typos in ``.po`` files. + - :pypi:`powrap` to rewrap the ``.po`` files + before committing. This helps keep Git diffs short. + - :pypi:`potodo` to list what needs to be translated. + - :pypi:`sphinx-lint` to validate reST syntax in translation files. More related tools and projects can be found in the From 33db444d69a58c18b5cca55244d0b8e233b5131e Mon Sep 17 00:00:00 2001 From: Yuki Kobayashi Date: Fri, 11 Jul 2025 02:34:50 +0900 Subject: [PATCH 020/103] Fix markup error in hyperlink target (#1604) Co-authored-by: Petr Viktorin --- getting-started/setup-building.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 910808453a..bd026ea714 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -1226,7 +1226,6 @@ Note that the container has read/write access to the working directory. You may want to use a separate clone of CPython, or run ``make clean`` to remove caches and build output generated for your host OS. -.. _building-the-container-locally .. _devcontainer-build: Building yourself From bdfc99f7b8e27c0b8bdff28669b5aeed42b8ee7e Mon Sep 17 00:00:00 2001 From: Yuki Kobayashi Date: Sat, 19 Jul 2025 19:46:09 +0900 Subject: [PATCH 021/103] Use correct emphasis markup (#1608) --- development-tools/clinic.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/development-tools/clinic.rst b/development-tools/clinic.rst index 642f40dce9..2f46774303 100644 --- a/development-tools/clinic.rst +++ b/development-tools/clinic.rst @@ -107,8 +107,8 @@ Terminology 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`, + 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*. From 96905b48ccf2bc8ee84312f6998305820635451c Mon Sep 17 00:00:00 2001 From: Disconnect3d Date: Sat, 19 Jul 2025 13:54:14 +0200 Subject: [PATCH 022/103] Update ASan information regarding --without-pymalloc flag (GH-1609) * Update ASan information regarding --without-pymalloc flag As discussed with @encukou on the CPython Core sprint on EuroPython 2025. We initially thought that the `--without-pymalloc` flag is needed due to the fact pymalloc must hit the begining of page when determining if the memory to be freed comes from pymalloc or was allocated by the system malloc. In other words, we thought, that ASan would crash CPython during free of big objects (allocated by system malloc). It may be that this was the case in the past, but it is not the case anymore as the `address_in_range` function used by pymalloc is annotated to be skipped from the ASan instrumentation. This code can be seen here: https://github.com/python/cpython/blob/acefb978dcb5dd554e3c49a3015ee5c2ad6bfda1/Objects/obmalloc.c#L2096-L2110 While the annotation macro is defined here: https://github.com/python/cpython/blob/acefb978dcb5dd554e3c49a3015ee5c2ad6bfda1/Include/pyport.h#L582-L598 And the corresponding attribute is documented in: * for gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-no_005fsanitize_005faddress-function-attribute * for clang: https://clang.llvm.org/docs/AttributeReference.html#no-sanitize-address-no-address-safety-analysis * Apply suggestions from code review * Apply suggestions from code review --------- Co-authored-by: Petr Viktorin --- development-tools/clang.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/development-tools/clang.rst b/development-tools/clang.rst index f06834731a..b353d82f00 100644 --- a/development-tools/clang.rst +++ b/development-tools/clang.rst @@ -103,6 +103,10 @@ Then, run ``./configure`` with the relevant flags: * ASan: ``--with-address-sanitizer --without-pymalloc`` * UBsan: ``--with-undefined-behavior-sanitizer`` +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). + It is OK to specify both sanitizers. After that, run ``make`` and ``make test`` as usual. From 8a6dd1ba8c3863dbf7bed8e5c0711068ce9862a9 Mon Sep 17 00:00:00 2001 From: Nacho Caballero Date: Sat, 19 Jul 2025 16:59:51 +0200 Subject: [PATCH 023/103] Prevent `make venv` from reporting success when it actually failed (#1611) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- Makefile | 1 + documentation/start-documenting.rst | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 9817feb155..3d485ae2da 100644 --- a/Makefile +++ b/Makefile @@ -58,6 +58,7 @@ venv: .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); \ diff --git a/documentation/start-documenting.rst b/documentation/start-documenting.rst index 973b36b122..7515992ec9 100644 --- a/documentation/start-documenting.rst +++ b/documentation/start-documenting.rst @@ -76,12 +76,22 @@ To build the documentation, follow the steps in one of the sections below. You can view the documentation after building the HTML by opening the file :file:`Doc/build/html/index.html` in a web browser. -.. note:: +Initial requirements +-------------------- + +Ensure your current working directory is the top level ``Doc/`` directory +inside your :ref:`CPython repository clone `. You can switch to +it with: + +.. code-block:: shell + + cd Doc + +Ensure your Python version is at least 3.11. You can verify it with: - The following instructions all assume your current working dir is - the ``Doc`` subdirectory in your :ref:`CPython repository clone `. - Make sure to switch to it with ``cd Doc`` if necessary. +.. code-block:: shell + python --version .. _doc-create-venv: From 2fad8516e646a9ceedd32566587f7200b1610649 Mon Sep 17 00:00:00 2001 From: Priyanshu Date: Sun, 20 Jul 2025 03:02:40 -0400 Subject: [PATCH 024/103] issue:1610 Broken link to test-with-buildbots fixed (#1612) --- triage/labels.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/triage/labels.rst b/triage/labels.rst index 8fd6f345ed..7c2de5d6b4 100644 --- a/triage/labels.rst +++ b/triage/labels.rst @@ -158,7 +158,7 @@ to trigger specific bot behaviors. * :gh-label:`skip news `: for PRs that don't need a NEWS entry. The :ref:`news-entry` section covers in details in which cases the NEWS entry can be skipped. -* :gh-label:`test-with-buildbots`: used to test the latest commit with +* :gh-label:`🔨 test-with-buildbots <%3Ahammer%3A%20test-with-buildbots>`: used to test the latest commit with the :ref:`buildbot fleet ` whenever more testing is required before merging. This may take multiple hours to complete. * :samp:`awaiting {action}`: these labels are applied and used by `bedevere`_ From 6ec3bd5058359a9a397010bf914d003ad32b89d4 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Wed, 23 Jul 2025 11:11:13 +0200 Subject: [PATCH 025/103] Add explanation to buildbots.rst about triggering buildbot on a PR (#1605) Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- testing/buildbots.rst | 35 +++++++++++++++++++++++++++++++++++ triage/labels.rst | 10 +++++++--- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/testing/buildbots.rst b/testing/buildbots.rst index 97856f7132..c25de5012c 100644 --- a/testing/buildbots.rst +++ b/testing/buildbots.rst @@ -48,6 +48,41 @@ after each commit. In particular, reference leaks builds take several hours to complete so they are done periodically. This is why it's important for you to be able to check the results yourself, too. +Triggering buildbots on a pull request +====================================== + +To trigger buildbots on a pull request you need to be a CPython triager or a +core team member. If you are not, ask someone to trigger them on your behalf. + +The simplest way to trigger most buildbots on your PR is with the +:gh-label:`🔨 test-with-buildbots` and :gh-label:`🔨 test-with-refleak-buildbots` +labels. (See :ref:`github-pr-labels`.) + +These will run buildbots on the most recent commit. If you want to trigger the +buildbots again on a later commit, you'll have to remove the label and add it +again. + +If you want to test a pull request against specific platforms, you can trigger +one or more build bots by posting a comment that begins with: + +.. code-block:: none + + !buildbot regex-matching-target + +For example to run both the iOS and Android build bot, you can use: + +.. code-block:: none + + !buildbot ios|android + +bedevere-bot will post a comment indicating which build bots, if +any, were matched. If none were matched, or you do not have the +necessary permissions to trigger a request, it will tell you that too. + +The ``!buildbot`` comment will also only run buildbots on the most recent +commit. To trigger the buildbots again on a later commit, you will have to +repeat the comment. + Checking results of automatic builds ==================================== diff --git a/triage/labels.rst b/triage/labels.rst index 7c2de5d6b4..3d2679f7fb 100644 --- a/triage/labels.rst +++ b/triage/labels.rst @@ -158,9 +158,13 @@ to trigger specific bot behaviors. * :gh-label:`skip news `: for PRs that don't need a NEWS entry. The :ref:`news-entry` section covers in details in which cases the NEWS entry can be skipped. -* :gh-label:`🔨 test-with-buildbots <%3Ahammer%3A%20test-with-buildbots>`: used to test the latest commit with - the :ref:`buildbot fleet ` whenever more testing is required - before merging. This may take multiple hours to complete. +* :gh-label:`🔨 test-with-buildbots <%3Ahammer%3A%20test-with-buildbots>`: used + to test the latest commit with the :ref:`buildbot fleet ` whenever + more testing is required before merging. This may take multiple hours to + complete. +* :gh-label:`🔨 test-with-refleak-buildbots <%3Ahammer%3A%20test-with-refleak-buildbots>`: + Run the reference leak buildbots on the latest commit. Useful for when the + code might be leaky. * :samp:`awaiting {action}`: these labels are applied and used by `bedevere`_ to indicate the stage of a PR and should not be applied manually. From 0c953f30a65d462161045f227507e69399c80640 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 23 Jul 2025 12:35:16 +0300 Subject: [PATCH 026/103] Shorter title: "Triggering on pull requests" (#1617) --- testing/buildbots.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/buildbots.rst b/testing/buildbots.rst index c25de5012c..e038499354 100644 --- a/testing/buildbots.rst +++ b/testing/buildbots.rst @@ -48,8 +48,8 @@ after each commit. In particular, reference leaks builds take several hours to complete so they are done periodically. This is why it's important for you to be able to check the results yourself, too. -Triggering buildbots on a pull request -====================================== +Triggering on pull requests +=========================== To trigger buildbots on a pull request you need to be a CPython triager or a core team member. If you are not, ask someone to trigger them on your behalf. From eae707b1d1780716bc20e0148673132ab3a16650 Mon Sep 17 00:00:00 2001 From: Marco Richetta Date: Thu, 24 Jul 2025 13:27:11 +0200 Subject: [PATCH 027/103] docs: add label to translating so it can be referenced (#1619) --- documentation/translations/translating.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/documentation/translations/translating.rst b/documentation/translations/translating.rst index 7d1e2f251e..0c22026702 100644 --- a/documentation/translations/translating.rst +++ b/documentation/translations/translating.rst @@ -1,3 +1,5 @@ +.. _translating: + =========== Translating =========== From 712088293a679773b092e198af21ec7d47ad8bf0 Mon Sep 17 00:00:00 2001 From: AN Long Date: Fri, 25 Jul 2025 22:55:54 +0900 Subject: [PATCH 028/103] Mention GraalPy in the list of other interpreters (#1618) Co-authored-by: Adam Turner <9087854+aa-turner@users.noreply.github.com> Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- index.rst | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/index.rst b/index.rst index 4f62668ac0..e19bb88263 100644 --- a/index.rst +++ b/index.rst @@ -219,14 +219,16 @@ CPython, they always have more things they would like to do than they have developers to work on them. Some major examples that may be of interest are: * PyPy_: A Python interpreter focused on high speed (JIT-compiled) operation - on major platforms + on major platforms. +* GraalPy_: A Python interpreter which has first-class support for + embedding in Java, built on GraalVM. * Jython_: A Python interpreter focused on good integration with the Java - Virtual Machine (JVM) environment + Virtual Machine (JVM) environment. * IronPython_: A Python interpreter focused on good integration with the - Common Language Runtime (CLR) provided by .NET and Mono + Common Language Runtime (CLR) provided by .NET and Mono. * Stackless_: A Python interpreter focused on providing lightweight microthreads while remaining largely compatible with CPython specific - extension modules + extension modules. * MicroPython_: A tiny Python interpreter with small subset of the Python standard library that is optimised to run on microcontrollers and in constrained environments. @@ -326,6 +328,7 @@ Full table of contents .. _Python: https://www.python.org/ .. _Core Python Mentorship: https://www.python.org/dev/core-mentorship/ .. _PyPy: https://pypy.org +.. _GraalPy: https://www.graalvm.org/python/ .. _Jython: https://www.jython.org/ .. _IronPython: https://ironpython.net/ .. _Stackless: https://github.com/stackless-dev/stackless/wiki/ From e4f4b210ed40924716ce20eb9b5db901082d4e9f Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 29 Jul 2025 19:03:48 +0300 Subject: [PATCH 029/103] Prefer 'core team' in `documentation/` and `getting-started/` (#1616) Co-authored-by: Mariatta --- documentation/translations/coordinating.rst | 2 +- getting-started/getting-help.rst | 6 +++--- getting-started/pull-request-lifecycle.rst | 22 +++++++++++---------- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/documentation/translations/coordinating.rst b/documentation/translations/coordinating.rst index d2878385ee..4240382b97 100644 --- a/documentation/translations/coordinating.rst +++ b/documentation/translations/coordinating.rst @@ -106,7 +106,7 @@ We recommend two or three coordinators, though you may begin with one. Here are some general suggestions. - Coordinator requests are to be public on the `translation mailing list `_. -- If the given language has a native core dev, the core dev has input +- If the given language has a native core team member, they have input on the coordinator request. - Anyone who wants to become coordinator for their native language and shows motivation by translating and building a community will be named diff --git a/getting-started/getting-help.rst b/getting-started/getting-help.rst index 50b7583e79..fc289fd449 100644 --- a/getting-started/getting-help.rst +++ b/getting-started/getting-help.rst @@ -5,7 +5,7 @@ Where to get help ================= If you are working on Python it is very possible you will come across an issue -where you need some assistance to solve it (this happens to core developers +where you need some assistance to solve it (this happens to the core team all the time). Should you require help, there are a :ref:`variety of options available @@ -42,7 +42,7 @@ Ask #python-dev If you are comfortable with IRC you can try asking on ``#python-dev`` (on the `Libera.Chat`_ network). Typically there are a number of experienced -developers, ranging from triagers to core developers, who can answer +contributors, ranging from triagers to the core team, who can answer questions about developing for Python. As with the mailing lists, ``#python-dev`` is for questions involving the development *of* Python whereas ``#python`` is for questions concerning development *with* Python. @@ -60,7 +60,7 @@ Core mentorship If you are interested in improving Python and contributing to its development, but don’t yet feel entirely comfortable with the public channels mentioned above, `Python Mentors`_ are here to help you. Python is fortunate to have a -community of volunteer core developers willing to mentor anyone wishing to +community of volunteer core team members willing to mentor anyone wishing to contribute code, work on bug fixes or improve documentation. Everyone is welcomed and encouraged to contribute. diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index f95ad6555a..fe810e90ff 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -131,7 +131,7 @@ You should have already :ref:`set up your system `, git commit -m '' git push origin - * If a core developer reviewing your PR pushed one or more commits to your + * If a core team member reviewing your PR pushed one or more commits to your PR branch, then after checking out your branch and before editing, run:: git pull origin # pull = fetch + merge @@ -204,7 +204,7 @@ should do to help ensure that your pull request is accepted. #. **Make sure to follow Python's style guidelines.** For Python code you should follow :PEP:`8`, and for C code you should follow :PEP:`7`. If you have - one or two discrepancies those can be fixed by the core developer who merges + one or two discrepancies those can be fixed by the core team member who merges your pull request. But if you have systematic deviations from the style guides your pull request will be put on hold until you fix the formatting issues. @@ -324,7 +324,7 @@ Furthermore, the first line should not end in a period. If this is not enough detail for a commit, a new paragraph(s) can be added to explain in proper depth what has happened (detail should be good enough -that a core developer reading the commit message understands the +that a core team member reading the commit message understands the justification for the change). Check :ref:`the Git bootcamp ` for further @@ -447,7 +447,7 @@ to ask for someone to review your pull request. When someone does manage to find the time to look at your pull request they will most likely make comments about how it can be improved -(don't worry, even core developers of Python have their pull requests sent +(don't worry, even core team members of Python have their pull requests sent back to them for changes). It is then expected that you update your pull request to address these comments, and the review process will thus iterate until a satisfactory solution has emerged. @@ -514,11 +514,13 @@ Instead of simply "approving" the pull request, leave comments. For example: #. Look at any failures in CI on the current PR. See :ref:`"Keeping CI green" ` below for simple things you can do to help move the PR forward. -Dismissing review from another core developer ---------------------------------------------- +.. _dismissing-review-from-another-core-developer: -A core developer can dismiss another core developer's review if they confirmed -that the requested changes have been made. When a core developer has assigned +Dismissing review from another core team member +----------------------------------------------- + +A core team member can dismiss another team member's review if they confirmed +that the requested changes have been made. When a core team member has assigned the PR to themselves, then it is a sign that they are actively looking after the PR, and their review should not be dismissed. @@ -589,7 +591,7 @@ Python is tricky and we simply cannot accept everyone's contributions. But if your pull request is merged it will then go into Python's :abbr:`VCS (version control system)` to be released with the next feature release of Python. It may also be backported to older -versions of Python as a bugfix if the core developer doing the merge believes +versions of Python as a bugfix if the core team member doing the merge believes it is warranted. @@ -598,7 +600,7 @@ Crediting Non-trivial contributions are credited in the ``Misc/ACKS`` file (and, most often, in a contribution's news entry as well). You may be -asked to make these edits on the behalf of the core developer who +asked to make these edits on the behalf of the core team member who accepts your pull request. .. _issue tracker: https://github.com/python/cpython/issues From cf7224007eb14bccf6b9f556540891816f20621d Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Sat, 2 Aug 2025 19:49:53 +0200 Subject: [PATCH 030/103] Document the ``type-refactor`` label (#1588) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Co-authored-by: Peter Bierma --- triage/labels.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/triage/labels.rst b/triage/labels.rst index 3d2679f7fb..34c7dc26c9 100644 --- a/triage/labels.rst +++ b/triage/labels.rst @@ -30,6 +30,8 @@ These labels are used to specify the type of issue: it is implicit that features are added to the ``main`` branch only. The `Ideas Discourse category`_ can be used to discuss enhancements before filing an issue. +* :gh-label:`type-refactor`: for general code refactoring that + does not change user-facing behaviour. * :gh-label:`type-security`: for security issues. See also `Reporting security issues in Python`_. From 9069a98c9165e16f022c76e626f0609fc1072b7e Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 3 Aug 2025 18:39:27 +0300 Subject: [PATCH 031/103] Prefer 'core team' in developer-workflow/ (#1615) --- developer-workflow/communication-channels.rst | 18 +++++++-------- developer-workflow/development-cycle.rst | 22 +++++++++---------- developer-workflow/psrt.rst | 6 ++--- developer-workflow/stdlib.rst | 16 +++++++------- 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/developer-workflow/communication-channels.rst b/developer-workflow/communication-channels.rst index e9360d2010..9b088b350e 100644 --- a/developer-workflow/communication-channels.rst +++ b/developer-workflow/communication-channels.rst @@ -84,10 +84,10 @@ 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 developers. +`_ core team. The Committers category is often used for announcements and notifications. -It is also the designated venue for the core developer promotion votes. +It is also the designated venue for the core team promotion votes. Tutorials for new users ----------------------- @@ -189,22 +189,22 @@ Discord (private chat server) ============================= For more real-time discussions, the core development team have a private Discord -server available. Core developers, Steering Council members, triagers, and +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 developers, a long lived multiple use invitation link for this server -can be found in the private core developer only section of the Discourse forum. +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 developers may update their Steering Council 🔒 `voter record`_ with +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 developers +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. @@ -225,7 +225,7 @@ set a specific `Server Nickname`_ IRC === -Some core developers still participate in the ``#python-dev`` IRC channel on +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. @@ -234,7 +234,7 @@ discuss issues related to Python's own development. See also the Blogs ===== -Several core developers are active bloggers and discuss Python's development +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 `__. diff --git a/developer-workflow/development-cycle.rst b/developer-workflow/development-cycle.rst index d807d74ec2..c8b2d5ebf7 100644 --- a/developer-workflow/development-cycle.rst +++ b/developer-workflow/development-cycle.rst @@ -4,7 +4,7 @@ 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 @@ -142,7 +142,7 @@ 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)`. @@ -159,7 +159,7 @@ avoiding breaking the buildbots). 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. @@ -171,7 +171,7 @@ 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. @@ -185,7 +185,7 @@ 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 +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. @@ -196,7 +196,7 @@ 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: @@ -316,12 +316,12 @@ 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 `, +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. diff --git a/developer-workflow/psrt.rst b/developer-workflow/psrt.rst index f469f68d12..9d9019dbfd 100644 --- a/developer-workflow/psrt.rst +++ b/developer-workflow/psrt.rst @@ -31,7 +31,7 @@ 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 members and core developers +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. @@ -74,7 +74,7 @@ severity, advisory text, and fixes. * 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 developers can be invited to collaborate by + otherwise relevant core team members can be invited to collaborate by the coordinator. * For **Low** and **Medium** severity vulnerabilities it is acceptable @@ -84,7 +84,7 @@ severity, advisory text, and fixes. * For **High** and **Critical** severity vulnerabilities the fix must be developed privately using GitHub Security Advisories' "Private Forks" feature. - Core developers can be added to the GitHub Security Advisory via "collaborators" + 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. diff --git a/developer-workflow/stdlib.rst b/developer-workflow/stdlib.rst index 60112d6d3e..b683e55e96 100644 --- a/developer-workflow/stdlib.rst +++ b/developer-workflow/stdlib.rst @@ -28,7 +28,7 @@ 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 developers and community. + 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, @@ -36,9 +36,9 @@ you can open an issue on the `issue tracker`_ with the code attached as 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. @@ -51,8 +51,8 @@ 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. @@ -76,7 +76,7 @@ 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. @@ -108,12 +108,12 @@ 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 changes 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. From 08a3197307009d6344f4822b7ec89bb54853c415 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 3 Aug 2025 18:39:38 +0300 Subject: [PATCH 032/103] Prefer 'core team' in `core-team/` (#1614) * Prefer 'core team' in core-team/ * Update contrib/core-team/ --- README.rst | 2 +- contrib/core-team/experts.rst | 3 +- contrib/core-team/index.rst | 3 +- contrib/core-team/join-team.rst | 3 +- contrib/core-team/motivations.rst | 3 +- contrib/core-team/responsibilities.rst | 3 +- contrib/core-team/team-log.rst | 3 +- core-team/committing.rst | 14 ++++---- core-team/join-team.rst | 10 +++--- core-team/memorialization.rst | 7 ++-- core-team/motivations.rst | 50 +++++++++++++------------- core-team/responsibilities.rst | 28 +++++++-------- 12 files changed, 62 insertions(+), 67 deletions(-) diff --git a/README.rst b/README.rst index fde4a6c277..e2f0c5617c 100644 --- a/README.rst +++ b/README.rst @@ -17,7 +17,7 @@ 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. diff --git a/contrib/core-team/experts.rst b/contrib/core-team/experts.rst index 73a9431c0b..aa16f10bd9 100644 --- a/contrib/core-team/experts.rst +++ b/contrib/core-team/experts.rst @@ -5,7 +5,6 @@ |purpose| -[This is the existing core developers :ref:`experts` page from the devguide. We'll -adjust "core developer" to "core team" where appropriate.] +[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 index d51a8a4e83..2ca21344b0 100644 --- a/contrib/core-team/index.rst +++ b/contrib/core-team/index.rst @@ -11,8 +11,7 @@ Core team ========= -[This is mostly re-organized from the :ref:`core-team` section of the devguide, -but with "core developer" language changed to "core team" where possible.] +[This is mostly re-organized from the :ref:`core-team` section of the devguide] .. toctree:: :maxdepth: 5 diff --git a/contrib/core-team/join-team.rst b/contrib/core-team/join-team.rst index 70557589da..932216f7c6 100644 --- a/contrib/core-team/join-team.rst +++ b/contrib/core-team/join-team.rst @@ -5,7 +5,6 @@ |purpose| -[This is the existing core developers :ref:`join-core-team` page from the devguide. We'll -adjust "core developer" to "core team" where appropriate.] +[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 index 8fc6f94dba..38ba310236 100644 --- a/contrib/core-team/motivations.rst +++ b/contrib/core-team/motivations.rst @@ -5,7 +5,6 @@ |purpose| -[This is the existing core developers :ref:`motivations` page from the devguide. We'll -adjust "core developer" to "core team" where appropriate.] +[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 index 973385a157..d6902bd780 100644 --- a/contrib/core-team/responsibilities.rst +++ b/contrib/core-team/responsibilities.rst @@ -5,7 +5,6 @@ |purpose| -[This is the existing core developers :ref:`responsibilities` page from the devguide. We'll -adjust "core developer" to "core team" where appropriate.] +[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 index d6b480d25d..ecfe856a41 100644 --- a/contrib/core-team/team-log.rst +++ b/contrib/core-team/team-log.rst @@ -5,7 +5,6 @@ |purpose| -[This is the existing core team :ref:`team-log` page from the devguide. We'll -adjust "core developer" to "core team" where appropriate.] +[This is the existing core team :ref:`team-log` page from the devguide.] .. include:: ../../core-team/team-log.rst diff --git a/core-team/committing.rst b/core-team/committing.rst index d83d423216..41cf672542 100644 --- a/core-team/committing.rst +++ b/core-team/committing.rst @@ -5,7 +5,7 @@ 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 @@ -54,7 +54,7 @@ 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 :ref:`Python Triage Team ` + the core team and members of the :ref:`Python Triage Team ` can apply labels to GitHub pull requests). * **Does the pull request pass a check indicating that the submitter has signed the CLA?** @@ -152,7 +152,7 @@ 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 core devs and contributors. +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 @@ -179,7 +179,7 @@ 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 @@ -224,12 +224,12 @@ 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. @@ -252,7 +252,7 @@ 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 :ref:`Python Triage Team ` +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 diff --git a/core-team/join-team.rst b/core-team/join-team.rst index 1067696bbb..eb0f56e09e 100644 --- a/core-team/join-team.rst +++ b/core-team/join-team.rst @@ -11,15 +11,15 @@ 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 become a core developer of Python. -You must also work well with other core developers (and people in general) +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 developer will offer you the chance to gain commit privilege. +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 developers come to that agreement are outlined in +an official offer. How core team members come to that agreement are outlined in :pep:`13`. @@ -29,7 +29,7 @@ Gaining commit privileges After a candidate has demonstrated consistent contributions, commit privileges are granted through these steps: -#. A core developer (submitter, usually the mentor) starts a poll +#. A core team member (submitter, usually the mentor) starts a poll (see the :ref:`template ` below) in the `Committers category`_ on the `Python Discourse`_. diff --git a/core-team/memorialization.rst b/core-team/memorialization.rst index 2bcf24ae12..7ab0fab02b 100644 --- a/core-team/memorialization.rst +++ b/core-team/memorialization.rst @@ -1,4 +1,5 @@ .. _memorialize-core-developer: +.. _memorialize-core-team-member: =============== Memorialization @@ -7,7 +8,7 @@ Memorialization Rationale ========= -When a core developer passes away, memorializing accounts helps create +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. @@ -16,9 +17,9 @@ The process The memorialization process is performed by a member of the PSF staff with administrative access to current and historical systems where -core developers have access. +the core team has access. -After the status of the core developer in question is confirmed, +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. diff --git a/core-team/motivations.rst b/core-team/motivations.rst index b19c3062b8..d5a87e22c9 100644 --- a/core-team/motivations.rst +++ b/core-team/motivations.rst @@ -4,22 +4,22 @@ 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). @@ -32,7 +32,7 @@ For more information on the origins and purpose of this page, see 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: @@ -43,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 @@ -112,7 +112,7 @@ participating in the CPython core development process: 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, she 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. @@ -132,7 +132,7 @@ participating in the CPython core development process: 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. @@ -194,7 +194,7 @@ participating in the CPython core development process: 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, @@ -279,12 +279,12 @@ 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, +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 accepting submitted pull requests, but also the process of -identifying, nominating and mentoring new core developers. +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 @@ -293,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 @@ -307,20 +307,20 @@ 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 @@ -336,15 +336,15 @@ time contributing to CPython development. 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 index 5cd5ed7bdb..3b2137d6b0 100644 --- a/core-team/responsibilities.rst +++ b/core-team/responsibilities.rst @@ -5,25 +5,25 @@ Responsibilities ================ As contributors to the CPython project, our shared responsibility is to -collaborate constructively with other contributors, including core developers. +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 developers accept key additional responsibilities around the ongoing +Core team members accept key additional responsibilities around the ongoing management of the project: -* core developers bear the additional responsibility of handling the +* 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 developer that merged the change -* core developers also bear the primary responsibility for deciding when + 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 @@ -31,15 +31,15 @@ management of the project: of complex changes, or changes with a potentially significant impact on end users -As a result of the additional responsibilities they accept, core developers +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 developers are also able to request +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. -Becoming a core developer isn't a binary "all-or-nothing" status - CPython -is a large project, and different core developers accept responsibility for +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`). @@ -82,7 +82,7 @@ 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 +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. @@ -90,13 +90,13 @@ can accept your own pull requests if you feel comfortable doing so. Expectations ============ -As a core developer, there are certain things that are expected of you. +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 developers whenever you discuss Python with anyone. We have a +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 developers responsibilities include following the `PSF Code of +that way. Core team responsibilities include following the `PSF Code of Conduct`_. Second, please be prompt in responding to questions. Many contributors to Python @@ -118,7 +118,7 @@ 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 +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. From 1199ca3fa90f091e5f62b914d38092d9391fbb48 Mon Sep 17 00:00:00 2001 From: Emma Smith Date: Sun, 3 Aug 2025 10:39:35 -0700 Subject: [PATCH 033/103] Add Emma Smith to Core Devs (#1622) * Add Emma Smith to Core Devs --- core-team/core-team.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/core-team/core-team.csv b/core-team/core-team.csv index 79f2e86f46..ab87c50fa8 100644 --- a/core-team/core-team.csv +++ b/core-team/core-team.csv @@ -1,3 +1,4 @@ +Emma Smith,emmatyping,2025-07-31,, Tomas Roun,tomasr8,2025-06-16,, Peter Bierma,ZeroIntensity,2025-06-16,, Diego Russo,diegorusso,2025-05-13,, From 77e9d1884fabf2d259ae54d12b491547846fe20a Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Thu, 7 Aug 2025 18:07:43 +0300 Subject: [PATCH 034/103] Update libmpdec-related instructions (#1598) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- getting-started/setup-building.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index bd026ea714..4bcf3f1163 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -781,8 +781,12 @@ some of CPython's modules (for example, ``zlib``). libncurses5-dev libreadline6-dev libsqlite3-dev libssl-dev \ lzma lzma-dev tk-dev uuid-dev zlib1g-dev libmpdec-dev libzstd-dev - Note that Debian 12 and Ubuntu 24.04 do not have the ``libmpdec-dev`` package. You can safely - remove it from the install list above and the Python build will use a bundled version. + Note that Debian 12 and Ubuntu 24.04 do not have the ``libmpdec-dev`` + package. You can safely remove it from the install list above and the + Python build will use a bundled version. But we recommend using the system + `libmpdec `_ library. + Either built it from sources or install this package from + https://deb.sury.org. .. tab:: macOS @@ -823,7 +827,6 @@ some of CPython's modules (for example, ``zlib``). $ GDBM_CFLAGS="-I$(brew --prefix gdbm)/include" \ GDBM_LIBS="-L$(brew --prefix gdbm)/lib -lgdbm" \ ./configure --with-pydebug \ - --with-system-libmpdec \ --with-openssl="$(brew --prefix openssl@3)" .. tab:: Python 3.11-3.12 From 053d92fbbd137bb5637ed541cfb7817c97d25ac4 Mon Sep 17 00:00:00 2001 From: Emma Smith Date: Fri, 8 Aug 2025 00:22:22 -0700 Subject: [PATCH 035/103] Add Emma Smith to experts index (#1625) --- core-team/experts.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core-team/experts.rst b/core-team/experts.rst index 5791ff4088..74ce892f74 100644 --- a/core-team/experts.rst +++ b/core-team/experts.rst @@ -80,8 +80,8 @@ compileall carljm compression.bz2 compression.gzip compression.lzma -compression.zlib Yhg1s, gpshead* -compression.zstd +compression.zlib Yhg1s, gpshead*, emmatyping +compression.zstd emmatyping* concurrent.futures pitrou, brianquinlan, gpshead* configparser ambv* contextlib ncoghlan, 1st1 @@ -308,7 +308,7 @@ 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* +autoconf/makefiles Yhg1s*, emmatyping issue tracker ezio-melotti buildbots zware, pablogsal bytecode benjaminp, 1st1, markshannon, brandtbucher, carljm, iritkatriel @@ -338,7 +338,7 @@ memory management tim-one, malemburg, Yhg1s, nascheme memoryview networking giampaolo, gpshead object model benjaminp, Yhg1s -packaging tarekziade, malemburg, alexis^, merwok, dstufft, pfmoore +packaging tarekziade, malemburg, alexis^, merwok, dstufft, pfmoore, emmatyping pattern matching brandtbucher* PEG parser gvanrossum, pablogsal, lysnikolaou performance vstinner, serhiy-storchaka*, 1st1, rhettinger, markshannon, From c04cc695b184ea04f59258f2e7eb71f759277898 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Wed, 13 Aug 2025 10:45:47 -0700 Subject: [PATCH 036/103] Group container instruction in Setup into a single section (#1631) Having two top-level sections that both use the container seemed unnecessary. Also update an internal link to make it easier to find the container definition file. --- getting-started/setup-building.rst | 36 +++++++++++++++++++----------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 4bcf3f1163..5da12d4ef0 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -386,14 +386,14 @@ compiler just like building for :ref:`Unix ` as well as: 1. A C compiler that can target WebAssembly (for example, `WASI SDK`_) 2. A WASI host/runtime (for example, Wasmtime_) -All of this is provided in the :ref:`devcontainer `. You can +All of this is provided in the :ref:`devcontainer `. You can also use what's installed in the container as a reference of what versions of these tools are known to work. .. note:: - CPython has only been verified with the above tools for WASI. Using - other compilers, hosts, or WASI versions *should* work, but the above tools + CPython has only been verified with the certain tools for WASI. Using + other compilers, hosts, or WASI versions *should* work, but the tools and their versions specified in the container are tested via a :ref:`buildbot `. @@ -1124,17 +1124,26 @@ every rule. .. c_directory_structure_end +.. _using-a-container: + +Using a container +================= + +There are various ways to use a container to build CPython without installing +additional tools on your machine. All approaches use the container defined in +the `cpython-devcontainers repo`_ in some way. + .. _using-codespaces: Contribute using GitHub Codespaces -================================== +---------------------------------- .. c_codespaces_start .. _codespaces-whats-codespaces: What is GitHub Codespaces? --------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^ If you'd like to start contributing to CPython without needing to set up a local developer environment, you can use @@ -1153,7 +1162,7 @@ you'd prefer to use that directly. .. _codespaces-create-a-codespace: Create a CPython codespace --------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^ Here are the basic steps needed to contribute a pull request using Codespaces. You first need to navigate to the @@ -1182,7 +1191,7 @@ up from where you left off! .. _codespaces-use-locally: Use Codespaces locally ----------------------- +^^^^^^^^^^^^^^^^^^^^^^ On the bottom left side of the codespace screen you will see a green or grey square that says :guilabel:`Codespaces`. You can click this for additional @@ -1191,10 +1200,12 @@ select the option ``Open in VS Code``. You will still be working on the remote codespace instance, thus using the remote instance's compute power. The compute power may be a much higher spec than your local machine which can be helpful. +.. c_codespaces_end + .. _devcontainer-directly: Using the dev container directly -================================ +-------------------------------- If you want more control over the environment, or to work offline, you can use the same container used in @@ -1208,7 +1219,7 @@ installed. .. _devcontainer-image: Using the pre-built container image ------------------------------------ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Dev container images `__ are available from the @@ -1232,10 +1243,10 @@ to remove caches and build output generated for your host OS. .. _devcontainer-build: Building yourself ------------------ +^^^^^^^^^^^^^^^^^ If you prefer, you can build the container image yourself. In a clone of the -`cpython-devcontainers repo `_, +`cpython-devcontainers repo`_, build the container and name it ``cpython-dev``: .. code-block:: bash @@ -1262,7 +1273,6 @@ in a clone of the CPython repository. The same caveats outlined above when running from a container image from GHCR also apply here. -.. c_codespaces_end - +.. _cpython-devcontainers repo: https://github.com/python/cpython-devcontainers .. include:: ../links.rst From a3b5d26005b29bd30201b2f294724e0c032def14 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Wed, 13 Aug 2025 15:55:38 -0700 Subject: [PATCH 037/103] Use tabs for easier use in WASI and container sections of Setup (#1632) Also make sure that relevant shell snippets are formatted such they can be copy-and-pasted. --- getting-started/setup-building.rst | 82 +++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 24 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 5da12d4ef0..0b9691c2af 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -409,11 +409,17 @@ The easiest way to get a debug build of CPython for WASI is to use the ``Tools/wasm/wasi.py build`` command (which should be run w/ a recent version of Python you have installed on your machine): -.. code-block:: shell +.. tab:: CPython 3.14 and newer + + .. code-block:: shell + + python3 Tools/wasm/wasi build --quiet -- --config-cache --with-pydebug - $ python3 Tools/wasm/wasi build --quiet -- --config-cache --with-pydebug +.. tab:: CPython 3.13 -For Python 3.14 and earlier, use ``Tools/wasm/wasi.py`` instead. + .. code-block:: shell + + python3 Tools/wasm/wasi.py build --quiet -- --config-cache --with-pydebug That single command will configure and build both the build Python and the WASI build in ``cross-build/build`` and ``cross-build/wasm32-wasi``, @@ -422,28 +428,40 @@ respectively. You can also do each configuration and build step separately; the command above is a convenience wrapper around the following commands: -.. code-block:: shell - $ python Tools/wasm/wasi configure-build-python --quiet -- --config-cache --with-pydebug - $ python Tools/wasm/wasi make-build-python --quiet - $ python Tools/wasm/wasi configure-host --quiet -- --config-cache - $ python Tools/wasm/wasi make-host --quiet +.. tab:: CPython 3.14 and newer + + .. code-block:: shell + + $ python Tools/wasm/wasi configure-build-python --quiet -- --config-cache --with-pydebug + $ python Tools/wasm/wasi make-build-python --quiet + $ python Tools/wasm/wasi configure-host --quiet -- --config-cache + $ python Tools/wasm/wasi make-host --quiet + +.. tab:: CPython 3.13 + + .. code-block:: shell + + $ python Tools/wasm/wasi.py configure-build-python --quiet -- --config-cache --with-pydebug + $ python Tools/wasm/wasi.py make-build-python --quiet + $ python Tools/wasm/wasi.py configure-host --quiet -- --config-cache + $ python Tools/wasm/wasi.py make-host --quiet .. note:: The ``configure-host`` command infers the use of ``--with-pydebug`` from the build Python. -Running the separate commands after ``wasi.py build`` is useful if you, for example, only want to -run the ``make-host`` step after making code changes. +Running the separate commands after ``wasi build`` is useful if you, for example, +only want to run the ``make-host`` step after making code changes. Once everything is complete, there will be a -``cross-build/wasm32-wasi/python.sh`` helper file which you can use to run the +``cross-build/wasm32-wasip1/python.sh`` helper file which you can use to run the ``python.wasm`` file (see the output from the ``configure-host`` subcommand): .. code-block:: shell - $ cross-build/wasm32-wasi/python.sh --version + cross-build/wasm32-wasip1/python.sh --version You can also use ``Makefile`` targets and they will work as expected thanks to the ``HOSTRUNNER`` environment variable having been set to a similar value as @@ -451,7 +469,7 @@ used in ``python.sh``: .. code-block:: shell - $ make -C cross-build/wasm32-wasi test + make -C cross-build/wasm32-wasip1 test .. note:: @@ -1228,13 +1246,18 @@ are available from the To run the container and launch a Bash shell, run one of the following commands in a clone of the CPython repository. -.. code-block:: bash +.. tab:: Podman - docker run -it --rm --volume $PWD:/workspace --workdir /workspace ghcr.io/python/devcontainer:latest + .. code-block:: bash -.. code-block:: bash + podman run -it --rm --volume $PWD:/workspace:Z --workdir /workspace ghcr.io/python/devcontainer:latest + +.. tab:: Docker + + .. code-block:: bash + + docker run -it --rm --volume $PWD:/workspace --workdir /workspace ghcr.io/python/devcontainer:latest - podman run -it --rm --volume $PWD:/workspace:Z --workdir /workspace ghcr.io/python/devcontainer:latest Note that the container has read/write access to the working directory. You may want to use a separate clone of CPython, or run ``make clean`` @@ -1249,11 +1272,17 @@ If you prefer, you can build the container image yourself. In a clone of the `cpython-devcontainers repo`_, build the container and name it ``cpython-dev``: -.. code-block:: bash +.. tab:: Podman + + .. code-block:: shell + + podman build devcontainer/ --tag cpython-dev - docker build devcontainer/ --tag cpython-dev +.. tab:: Docker -(Substitute ``podman`` for ``docker`` if you use Podman.) + .. code-block:: shell + + docker build devcontainer/ --tag cpython-dev The same command will update any existing ``cpython-dev`` container. Run it again from time to time -- especially if the container stops @@ -1262,13 +1291,18 @@ working for you. To run the container and launch a Bash shell, run one of the following commands in a clone of the CPython repository. -.. code-block:: bash +.. tab:: Podman + + .. code-block:: shell + + podman run -it --rm --volume $PWD:/workspace:Z --workdir /workspace cpython-dev bash + +.. tab:: Docker - docker run -it --rm --volume $PWD:/workspace --workdir /workspace cpython-dev + .. code-block:: shell -.. code-block:: bash + docker run -it --rm --volume $PWD:/workspace --workdir /workspace cpython-dev bash - podman run -it --rm --volume $PWD:/workspace:Z --workdir /workspace cpython-dev The same caveats outlined above when running from a container image from GHCR also apply here. From 298e76bac007de76394592968e014d02521373c2 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Fri, 15 Aug 2025 00:41:16 +0300 Subject: [PATCH 038/103] Use consistent tabs (#1634) --- getting-started/setup-building.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 0b9691c2af..fde4498b47 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -409,13 +409,13 @@ The easiest way to get a debug build of CPython for WASI is to use the ``Tools/wasm/wasi.py build`` command (which should be run w/ a recent version of Python you have installed on your machine): -.. tab:: CPython 3.14 and newer +.. tab:: Python 3.14+ .. code-block:: shell python3 Tools/wasm/wasi build --quiet -- --config-cache --with-pydebug -.. tab:: CPython 3.13 +.. tab:: Python 3.13 .. code-block:: shell @@ -429,7 +429,7 @@ You can also do each configuration and build step separately; the command above is a convenience wrapper around the following commands: -.. tab:: CPython 3.14 and newer +.. tab:: Python 3.14+ .. code-block:: shell @@ -438,7 +438,7 @@ is a convenience wrapper around the following commands: $ python Tools/wasm/wasi configure-host --quiet -- --config-cache $ python Tools/wasm/wasi make-host --quiet -.. tab:: CPython 3.13 +.. tab:: Python 3.13 .. code-block:: shell From 3d6d82551e84f7e13327e8a65e0b95d8193b0495 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Fri, 15 Aug 2025 14:21:14 +0200 Subject: [PATCH 039/103] Use a script instead of hand-editing. (#1580) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- core-team/join-team.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core-team/join-team.rst b/core-team/join-team.rst index eb0f56e09e..d7996cd424 100644 --- a/core-team/join-team.rst +++ b/core-team/join-team.rst @@ -56,8 +56,9 @@ are granted through these steps: - 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`. + - Once the python/voters update is merged, regenerate the public team membership + list at :ref:`developers`. + See "Public list of members" in the ``voters`` README. - 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 From b57b389ab5800333d08ba0ccce865a458386ce39 Mon Sep 17 00:00:00 2001 From: Lutfi Zuchri <157361852+lutfizuchri@users.noreply.github.com> Date: Sun, 17 Aug 2025 00:15:01 +0700 Subject: [PATCH 040/103] Add Lutfi Zuchri as a co-ordinator of the Indonesian translation (#1591) --- documentation/translations/translating.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/documentation/translations/translating.rst b/documentation/translations/translating.rst index 0c22026702..be98ffeef6 100644 --- a/documentation/translations/translating.rst +++ b/documentation/translations/translating.rst @@ -48,7 +48,8 @@ For more details about translations and their progress, see `the dashboard `mailing list `__ * - `Indonesian (id) `__ - | Irvan Putra (:github-user:`irvan-putra`), - | Jeff Jacobson (:github-user:`jwjacobson`) + | Jeff Jacobson (:github-user:`jwjacobson`), + | Lutfi Zuchri (:github-user:`lutfizuchri`) - :github:`GitHub ` * - `Italian (it) `__ - Alessandro Cucci (`email `__) From 4cb6ddb55e80ef8cd22396c1b5edddff912d9367 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 17 Aug 2025 20:54:42 +0300 Subject: [PATCH 041/103] Add boolean to the style guide (#1636) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- documentation/style-guide.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/documentation/style-guide.rst b/documentation/style-guide.rst index 49bd15b1d3..68350c4017 100644 --- a/documentation/style-guide.rst +++ b/documentation/style-guide.rst @@ -66,6 +66,12 @@ Specific words Some terms and words deserve special mention. These conventions should be used to ensure consistency throughout the documentation: +boolean + Lowercase in most instances. + Uppercase for *Boolean mathematics* and *Boolean logic*. + To refer to the Python or C data type, prefer using the exact, + abbreviated name with appropriate markup (for example, ``:type:`bool```). + C API Python's `API `_ used by C programmers to write extension modules. All caps and unhyphenated. From 73acea3e9ea80b1cf8006e5af3a4e5baedac26fb Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 18 Aug 2025 00:21:11 +0200 Subject: [PATCH 042/103] =?UTF-8?q?Remove=20translation=20co=C3=B6rdinator?= =?UTF-8?q?=20for=20Hungarian=20(#1640)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- documentation/translations/translating.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/documentation/translations/translating.rst b/documentation/translations/translating.rst index be98ffeef6..052c306e5f 100644 --- a/documentation/translations/translating.rst +++ b/documentation/translations/translating.rst @@ -43,9 +43,8 @@ For more details about translations and their progress, see `the dashboard - Sanyam Khurana (:github-user:`CuriousLearner`) - :github:`GitHub ` * - Hungarian (hu) - - Tamás Bajusz (:github-user:`gbtami`) - - :github:`GitHub `, - `mailing list `__ + - + - :github:`GitHub ` * - `Indonesian (id) `__ - | Irvan Putra (:github-user:`irvan-putra`), | Jeff Jacobson (:github-user:`jwjacobson`), From ec8e6baff6293c6b41ce77aaae254638619526cb Mon Sep 17 00:00:00 2001 From: Nybblista <170842536+nybblista@users.noreply.github.com> Date: Mon, 18 Aug 2025 01:22:20 +0300 Subject: [PATCH 043/103] Update EBNF abbreviation to PEG (#1639) --- getting-started/setup-building.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index fde4498b47..f6a6f6a943 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -1094,7 +1094,7 @@ every rule. See also :ref:`building-doc`. ``Grammar`` - Contains the :abbr:`EBNF (Extended Backus-Naur Form)` grammar file for + Contains the :abbr:`PEG (Parser Expression Grammar)` grammar file for Python. ``Include`` From 25cb6131352e53ca7d406a7d4aefae2534da57ba Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Mon, 18 Aug 2025 04:25:21 +0300 Subject: [PATCH 044/103] Document how to use ``*args`` in Argument Clinic (#1629) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Co-authored-by: AN Long --- development-tools/clinic.rst | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/development-tools/clinic.rst b/development-tools/clinic.rst index 2f46774303..6446d1a460 100644 --- a/development-tools/clinic.rst +++ b/development-tools/clinic.rst @@ -1495,6 +1495,37 @@ You can still use a self converter, a return converter, and specify a *type* argument to the object converter for :c:macro:`METH_O`. +How to convert ``*args`` parameters (starargs / var-positional) +--------------------------------------------------------------- + +There are two converters suitable for ``*args``: *array* and *tuple*. + +Using the *array* converter will provide the implementation function with +a C array *args* of type of :c:type:`PyObject * ` and the number +of items in the array as :c:type:`Py_ssize_t` *args_length*. +For example:: + + /*[clinic input] + var_positional_sample + + spam: int + *args: array + [clinic start generated code]*/ + +Using the *tuple* converter will provide the implementation function with +a standard :c:type:`PyTupleObject`. +For example:: + + /*[clinic input] + var_positional_sample + + spam: int + *args: tuple + [clinic start generated code]*/ + +.. versionadded:: 3.11 + + How to convert ``tp_new`` and ``tp_init`` functions --------------------------------------------------- From b0aefe917443e85fa0ae0c8d5525d0933151a41c Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 18 Aug 2025 15:48:32 +0200 Subject: [PATCH 045/103] Update `translations/coordinating.rst` (GH-1587) --- contrib/index.rst | 2 +- documentation/translations/coordinating.rst | 255 +++++++++++++----- documentation/translations/index.rst | 2 +- documentation/translations/translating.rst | 11 +- .../translations/translator-workload.svg | 191 +++++++++++++ 5 files changed, 391 insertions(+), 70 deletions(-) create mode 100644 documentation/translations/translator-workload.svg diff --git a/contrib/index.rst b/contrib/index.rst index 0b5a3edc65..e519c7dab4 100644 --- a/contrib/index.rst +++ b/contrib/index.rst @@ -75,7 +75,7 @@ major section at the top of each column.]* * :ref:`documenting` * :ref:`style-guide` * :ref:`rst-primer` - * :doc:`documentation/translations` + * :ref:`translating` * :ref:`devguide` - * :ref:`setup` diff --git a/documentation/translations/coordinating.rst b/documentation/translations/coordinating.rst index 4240382b97..aaed4b831b 100644 --- a/documentation/translations/coordinating.rst +++ b/documentation/translations/coordinating.rst @@ -3,47 +3,151 @@ Coordinating ============ Information about the Python documentation translation processes is -found in this devguide and :PEP:`545`. -Translations are built by `docsbuild-scripts -`__ and hosted on -docs.python.org. Translations -are overseen by the `Editorial Board `_ +found on this page and in :PEP:`545`. Translations are overseen by the +`Editorial Board `_. + +.. _translation-help: + +Communication/help channels +=========================== + +Discussions about translations occur on the Python Docs Discord +`#translations channel `_, `translation +mailing list `_, and the +`translations category `_ of the Python Discourse. + +For administrative issues, ping ``@python/editorial-board``. + Starting a new translation ========================== -First subscribe to the `translation mailing list `_, -and introduce yourself and the translation you're starting. +Coordination is not a one-off task, it is a long-term commitment. Before +you start your translation, carefully consider if you will be able to commit +to this. +Every coordinator should be familiar with translating: see :ref:`translating`. + +The following sections will guide you through setting up your translation. +If you have any questions or need help, ask in one of the +:ref:`help channels `. + + +Announcement +------------ + +Post an announcement introducing yourself and the translation you're +starting on `Discourse `_. Also join the other communication +channels, if possible. + + +Coordination team +----------------- + +Each translation team will decide on the number of coordinators. +While initially one person is fine, we recommend expanding to having two or +three coordinators. You can find more on choosing coordinators in the FAQ +section on this page. + + +Translation team +---------------- + +.. figure:: translator-workload.svg + :class: invert-in-dark-mode + :align: center + :alt: An exaggerated chart showing that individual translator workload + decreases with the number of translators. + + +Gather people to translate with you. You can't do it alone. +Update :ref:`this table ` via a PR on the devguide +to make your translation easier to find. In the entry you can also include links +to guides or other resources for translators. + + +Repository +---------- + +To start your translation create a GitHub repository, under any +account, with the correct Git hierarchy and folder structure. This can be done +in several ways, and depends on what translation process you plan to use. + +Each translation is assigned an appropriate lowercase +`IETF language tag `_. +The tag may have an optional subtag, joined with a dash. +For example, ``pt`` (Portuguese) or ``pt-br`` (Brazilian Portuguese). +The repository name is then: ``python-docs-TAG`` + +The name of each branch should be the Python version it holds translations +for, for example, ``3.14``. The files should be structured like the source files +in `CPython/Doc `_. +A correctly set up repository looks like this: +`python-docs-pl `_ + +Below, the recommended ways for starting your repository are described. You can +choose another way if you like; it’s up to you. + + +Cookiecutter/bootstrapper +~~~~~~~~~~~~~~~~~~~~~~~~~ -Then you can bootstrap your new translation by using the `cookiecutter +You can bootstrap your new translation by using the `cookiecutter `__ or `bootstrapper `__. -You can also start your translation using `Transifex `_ -following this `guide `_. +The repository can then be used with a pull-request based translation process. -The important steps look like this: -- Create the GitHub repo (any account) with the correct hierarchy by using one - of the bootstrappers or Transifex. -- Gather people to help you translate. You can't do it alone. -- You can use any tool to translate, as long as you can synchronize with Git. - Some use Transifex, and some use only GitHub. You can choose another - way if you like; it's up to you. -- Update :doc:`this page ` to reflect your work and progress, either via a - PR or by asking on the `translation mailing list `_. -- When ``bugs``, ``tutorial``, and ``library/functions`` are 100% - completed, ask on the `translation mailing list `_ for - your language to be added in the language switcher on docs.python.org. +Translation platform +~~~~~~~~~~~~~~~~~~~~ +You can also start your translation using +`Transifex `_. +This will allow you to translate via the web interface, and to use shared +automatically updated source files. -How to get help -=============== +This is best done with a workflow that periodically checks for translations. +An example with instructions can be found in the +`python-docs-tx-automations documentation `__. +An in-depth guide for manually doing this can also be found +in the same documentation's +`commands page `__. -Discussions about translations occur on the Python Docs Discord -`#translations channel `_, `translation -mailing list `_, and the -`translations category `_ -of the Python Discourse. +To be added as coordinators on Transifex for your language, open an issue +in the `tracker `__. + + +Glossary +-------- + +Each translation team should have a way to store translations of terms to ensure +consistency. This is often done with a glossary. More information about the use +of glossaries can be found in the :ref:`translation-style-guide`. + + +Moving the repo to the ``python`` org +------------------------------------- + +This will allow you to plug your translation into docsbuild-scripts_, and it +will be found at ``docs.python.org/LANG/``, but not in the switcher. + +.. TODO Give a general milestone when this will be done. + +Adding to the language switcher +------------------------------- + +.. TODO Specify branch: https://github.com/python/devguide/issues/1586 + +Once the following resources have been fully translated: + +- ``bugs.po``, with proper links to the language repository issue tracker +- all files in the ``tutorial/`` folder +- ``library/functions.po``, the page documenting builtins + +the translation can be added to the language switcher. This can be done with a +pull request to docsbuild-scripts_, like `this commit `__ +if your translation was previously built but not in the switcher, or like +`this commit `__ +if this is it's initial addition. PEP 545 summary @@ -51,31 +155,34 @@ PEP 545 summary Here are the essential points of :PEP:`545`: -- Each translation is assigned an appropriate lowercased language tag, - with an optional region subtag, and joined with a dash, like - ``pt-br`` or ``fr``. +- Each translation is assigned an appropriate lowercase + `IETF language tag `_. + The tag may have an optional region subtag, joined with a dash. + For example, ``pt`` (Portuguese) or ``pt-br`` (Brazilian Portuguese). -- Each translation is under CC0 and marked as such in the README (as in - the cookiecutter). +- Each translation is under CC0 and is marked as such in the README. -- Translation files are hosted on - ``https://github.com/python/python-docs-{LANGUAGE_TAG}`` (not - mandatory to start a translation, but mandatory to land on - ``docs.python.org``). +- Translation files are hosted in repositories under the Python org: + ``https://github.com/python/python-docs-{LANGUAGE_TAG}`` -- Translations having completed ``tutorial/``, ``library/stdtypes`` - and ``library/functions`` are hosted on - ``https://docs.python.org/{LANGUAGE_TAG}/{VERSION_TAG}/``. +- Translations having completed ``bugs``, ``tutorial/`` + and ``library/functions`` are added to the language switcher. -Transifex -========= +Translating Sphinx +================== -If you need help from a Transifex administrator, open an issue on the -`tracker `_. +Some messages that appear in the docs must be translated in the +`Sphinx project `__ +(`sphinx-doc on Transifex `__) or in +the `python-docs-theme `_ +(currently this is not possible; see this +`issue `__). +Coordinators should direct some translators there, so that the documentation +is fully translated. -Coordinating FAQ +Coordination FAQ ================ Are there tools to help in managing the repo? @@ -98,12 +205,26 @@ More related tools and projects can be found in the __ https://github.com/python-docs-translations -How is a coordinator elected? ------------------------------ + +How should I test my translation? +--------------------------------- + +Testing should ideally be set up in your repository, and will help catch errors +early and ensure translation quality. Testing generally consists of building, and +linting with :pypi:`sphinx-lint`. + +See `this documentation `_ +for sample workflows with usage guides. + +The `dashboard `_ +also tests translations and uploads error logs. + + +How is a coordination team chosen? +---------------------------------- Each translation team will decide on the number of coordinators. We recommend two or three coordinators, though you may begin with one. -Here are some general suggestions. - Coordinator requests are to be public on the `translation mailing list `_. - If the given language has a native core team member, they have input @@ -114,25 +235,28 @@ Here are some general suggestions. - We expect the local community to self-organize coordinators and contributors. If you have questions, please ask on the mailing list or Discourse. - If a coordinator becomes inactive or unreachable for a long - period of time, someone else can ask to be added as a primary coordinator on the `translation mailing list `_. - As a community resource, we aim to keep translations up to date with active contributors, including coordinators. + period of time, someone else can ask to be added as a primary coordinator on + the `translation mailing list `_. + As a community resource, we aim to keep translations up to date with active + contributors, including coordinators. + I have a translation, but it's not in Git. What should I do? ------------------------------------------------------------ -You can ask for help on the `translation mailing list `_, and -the team will help you create an appropriate repository. You can still use tools like transifex, -if you like. +You can ask for help in one of the :ref:`translation-help`, and +the team will help you create an appropriate repository. You can still use tools +like Transifex, if you like. My Git hierarchy does not match yours. Can I keep it? ----------------------------------------------------- -No, inside the ``github.com/python`` organization we’ll all have the +No, inside the ``github.com/python`` organization all repositories must have the exact same hierarchy so bots will be able to build all of our -translations. So you may have to convert from one hierarchy to another. -Ask for help on the `translation mailing list `_ if you’re -not sure on how to do it. +translations. So, you may have to convert from one hierarchy to another. +Ask for help in one of the :ref:`translation-help` if you’re not sure on how to +do it. What hierarchy should I use in my GitHub repository? @@ -143,9 +267,6 @@ files in the root of the repository using the ``gettext_compact=0`` style. -.. XXX Explain necessary folder structure - - Which version of the Python documentation should be translated? --------------------------------------------------------------- @@ -156,8 +277,14 @@ propagate your translation from one branch to another using :pypi:`pomerge`. The entry for my translation is missing or not up to date --------------------------------------------------------- -Ask on the `translation mailing list `_, or better, make a PR -on the `devguide `__. +Make a PR on the `devguide `__ to update it. + + +How are translations built? +--------------------------- + +Translations are built by `docsbuild-scripts `__ +and hosted on docs.python.org. Is there a Weblate instance we can translate on? @@ -170,3 +297,5 @@ for updates. .. _EB: https://python.github.io/editorial-board/ .. _translation_ml: https://mail.python.org/mailman3/lists/translation.python.org/ +.. _trans_disc: https://discuss.python.org/c/documentation/translations/ +.. _docsbuild-scripts: https://github.com/python/docsbuild-scripts diff --git a/documentation/translations/index.rst b/documentation/translations/index.rst index 2f5cfe0f40..a6d4dc4e72 100644 --- a/documentation/translations/index.rst +++ b/documentation/translations/index.rst @@ -3,7 +3,7 @@ Translations ============ .. toctree:: - :maxdepth: 3 + :maxdepth: 4 translating coordinating diff --git a/documentation/translations/translating.rst b/documentation/translations/translating.rst index 052c306e5f..ba0489020f 100644 --- a/documentation/translations/translating.rst +++ b/documentation/translations/translating.rst @@ -11,7 +11,7 @@ in production and can be found in the language switcher; others are works in progress. To get started read your repository's contributing guide, which is generally the ``README`` file, and this page. If your language isn’t listed below, feel free to start the translation! -See :doc:`coordinating` guide to get started. +See :doc:`coordination ` to get started. For more details about translations and their progress, see `the dashboard `__. @@ -126,12 +126,13 @@ General discussions about translations occur on the Python Docs Discord mailing list `_, and the `translations category <_discourse>`_ of the Python Discourse. +.. _translation-style-guide: Style guide =========== Before translating, you should familiarize yourself with the general -documentation :doc:`style guide<../style-guide>`. Some translation-specific +documentation :doc:`style guide <../style-guide>`. Some translation-specific guidelines are explained below. @@ -157,7 +158,7 @@ The Python docs contain many roles (``:role:`target```) that link to other parts of the documentation. Do not translate reStructuredText roles targets, such as ``:func:`print``` or ``:ref:`some-section``` because it will break the link. -If alternate text (``:role:`text ``` is provided, it generally +If alternate text (``:role:`text ```) is provided, it generally should be translated. You can also introduce alternate text for translation if the target is not a name or term. @@ -279,8 +280,8 @@ The coordination team for my language is inactive, what do I do? ---------------------------------------------------------------- If you would like to coordinate, open a pull request in the -`devguide `_ adding yourself, and ping -``@python/editorial-board``. +`devguide `_ adding yourself to the table +at the top of this page, and ping ``@python/editorial-board``. .. _translation_ml: https://mail.python.org/mailman3/lists/translation.python.org/ diff --git a/documentation/translations/translator-workload.svg b/documentation/translations/translator-workload.svg new file mode 100644 index 0000000000..e3e1318613 --- /dev/null +++ b/documentation/translations/translator-workload.svg @@ -0,0 +1,191 @@ + + + + + + + + 2025-06-29T10:46:39.952440 + image/svg+xml + + + Matplotlib v3.10.3, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From c53717d18847146feda573061c8fefebfa019a6c Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 18 Aug 2025 16:24:23 +0200 Subject: [PATCH 046/103] Update translating with links to github accounts. (GH-1502) --- documentation/translations/translating.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/translations/translating.rst b/documentation/translations/translating.rst index ba0489020f..2e0b79337c 100644 --- a/documentation/translations/translating.rst +++ b/documentation/translations/translating.rst @@ -51,7 +51,7 @@ For more details about translations and their progress, see `the dashboard | Lutfi Zuchri (:github-user:`lutfizuchri`) - :github:`GitHub ` * - `Italian (it) `__ - - Alessandro Cucci (`email `__) + - Alessandro Cucci (:github-user:`acuccie3`, `email `__) - :github:`GitHub `, `original announcement `__ * - `Japanese (ja) `__ @@ -99,11 +99,11 @@ For more details about translations and their progress, see `the dashboard - :github:`GitHub `, `Transifex `_ * - `Spanish (es) `__ - - Raúl Cumplido + - Raúl Cumplido (:github-user:`raulcd`) - :github:`GitHub ` * - `Traditional Chinese (zh-tw) `__ - | 王威翔 Matt Wang (:github-user:`mattwang44`), - | Josix Wang + | Josix Wang (:github-user:`josix`) - :github:`GitHub ` * - `Turkish (tr) `__ - Ege Akman (:github-user:`egeakman`) From bab815445f732c9bfbdf5375f12f31102f28bce3 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Wed, 20 Aug 2025 12:59:08 +0100 Subject: [PATCH 047/103] Fix link on translating page (GH-1642) Move the underscore to the correct position. --- documentation/translations/translating.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/translations/translating.rst b/documentation/translations/translating.rst index 2e0b79337c..f300f1fedc 100644 --- a/documentation/translations/translating.rst +++ b/documentation/translations/translating.rst @@ -123,7 +123,7 @@ Telegrams/Discords in the ``README``), join and introduce yourself. Your fellow translators will be more than happy to help! General discussions about translations occur on the Python Docs Discord `#translations channel `_, `translation -mailing list `_, and the `translations category <_discourse>`_ +mailing list `_, and the `translations category `_ of the Python Discourse. .. _translation-style-guide: From f36b0efa35b34d7ff284d29314d2d2dc4f9a5dd9 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Thu, 28 Aug 2025 03:33:23 +0100 Subject: [PATCH 048/103] Add "resources" section to page on translation (#1644) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- documentation/translations/translating.rst | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/documentation/translations/translating.rst b/documentation/translations/translating.rst index f300f1fedc..0a28edad4f 100644 --- a/documentation/translations/translating.rst +++ b/documentation/translations/translating.rst @@ -258,11 +258,19 @@ through the following resources from the Transifex documentation: For further information about Transifex see our `documentation `_. -Pull requests -============= +Resources +========= + +Some useful resources: -Several translations accept contributions by pull requests. Most have their -own guide for how to do this, and for general tips see our :ref:`git-boot-camp`. +- :ref:`git-boot-camp`: + Several translations accept contributions by pull requests. Most have their + own guide for how to do this, but this can provide useful tips. +- `Translation issues & improvements `_ GitHub project: + This project contains issues and pull requests that aim to improve + the Python documenation for translations. +- `Python Pootle archive `_: + Pootle is no longer used for translation. Contains translations for old Python versions. Translation FAQ From 9becace946c5eae239a5d0b6178fdd8d6aee3516 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Mon, 18 Aug 2025 12:08:41 +0100 Subject: [PATCH 049/103] Move ``clinic.rst`` to ``clinic/index.rst`` --- contrib/code/development-tools.rst | 2 +- development-tools/{clinic.rst => clinic/index.rst} | 0 development-tools/index.rst | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename development-tools/{clinic.rst => clinic/index.rst} (100%) diff --git a/contrib/code/development-tools.rst b/contrib/code/development-tools.rst index 348ceb95ac..769bba2b06 100644 --- a/contrib/code/development-tools.rst +++ b/contrib/code/development-tools.rst @@ -13,7 +13,7 @@ Development tools .. toctree:: :maxdepth: 5 - ../../development-tools/clinic + ../../development-tools/clinic/index ../../development-tools/gdb ../../development-tools/clang ../../development-tools/warnings diff --git a/development-tools/clinic.rst b/development-tools/clinic/index.rst similarity index 100% rename from development-tools/clinic.rst rename to development-tools/clinic/index.rst diff --git a/development-tools/index.rst b/development-tools/index.rst index 5031227a18..b564c933e8 100644 --- a/development-tools/index.rst +++ b/development-tools/index.rst @@ -7,7 +7,7 @@ Development tools .. toctree:: :maxdepth: 5 - clinic + clinic/index gdb clang warnings From 15795c9afa9bad96b8a33017ea4cd2a94689f476 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Mon, 18 Aug 2025 12:19:23 +0100 Subject: [PATCH 050/103] Move Argument Clinic How-To Guides to a new page --- development-tools/clinic/howto.rst | 1572 +++++++++++++++++++++++++++ development-tools/clinic/index.rst | 1579 +--------------------------- 2 files changed, 1577 insertions(+), 1574 deletions(-) create mode 100644 development-tools/clinic/howto.rst diff --git a/development-tools/clinic/howto.rst b/development-tools/clinic/howto.rst new file mode 100644 index 0000000000..364cf20bed --- /dev/null +++ b/development-tools/clinic/howto.rst @@ -0,0 +1,1572 @@ +.. _clinic-howtos: + +How-to guides +============= + + +How to rename C functions and variables generated by Argument Clinic +-------------------------------------------------------------------- + +Argument Clinic automatically names the functions it generates for you. +Occasionally this may cause a problem, if the generated name collides with +the name of an existing C function. There's an easy solution: override the names +used for the C functions. Just add the keyword ``"as"`` +to your function declaration line, followed by the function name you wish to use. +Argument Clinic will use that function name for the base (generated) function, +then add ``"_impl"`` to the end and use that for the name of the impl function. + +For example, if we wanted to rename the C function names generated for +:py:meth:`pickle.Pickler.dump`, it'd look like this:: + + /*[clinic input] + pickle.Pickler.dump as pickler_dumper + + ... + +The base function would now be named :c:func:`!pickler_dumper`, +and the impl function would now be named :c:func:`!pickler_dumper_impl`. + + +Similarly, you may have a problem where you want to give a parameter +a specific Python name, but that name may be inconvenient in C. Argument +Clinic allows you to give a parameter different names in Python and in C, +using the same ``"as"`` syntax:: + + /*[clinic input] + pickle.Pickler.dump + + obj: object + file as file_obj: object + protocol: object = NULL + * + fix_imports: bool = True + +Here, the name used in Python (in the signature and the ``keywords`` +array) would be *file*, but the C variable would be named ``file_obj``. + +You can use this to rename the *self* parameter too! + + +How to convert functions using ``PyArg_UnpackTuple`` +---------------------------------------------------- + +To convert a function parsing its arguments with :c:func:`PyArg_UnpackTuple`, +simply write out all the arguments, specifying each as an ``object``. You +may specify the *type* argument to cast the type as appropriate. All +arguments should be marked positional-only (add a ``/`` on a line by itself +after the last argument). + +Currently the generated code will use :c:func:`PyArg_ParseTuple`, but this +will change soon. + + +How to use optional groups +-------------------------- + +Some legacy functions have a tricky approach to parsing their arguments: +they count the number of positional arguments, then use a ``switch`` statement +to call one of several different :c:func:`PyArg_ParseTuple` calls depending on +how many positional arguments there are. (These functions cannot accept +keyword-only arguments.) This approach was used to simulate optional +arguments back before :c:func:`PyArg_ParseTupleAndKeywords` was created. + +While functions using this approach can often be converted to +use :c:func:`!PyArg_ParseTupleAndKeywords`, optional arguments, and default values, +it's not always possible. Some of these legacy functions have +behaviors :c:func:`!PyArg_ParseTupleAndKeywords` doesn't directly support. +The most obvious example is the builtin function :py:func:`!range`, which has +an optional argument on the *left* side of its required argument! +Another example is :py:meth:`curses.window.addch`, which has a group of two +arguments that must always be specified together. (The arguments are +called *x* and *y*; if you call the function passing in *x*, +you must also pass in *y* — and if you don't pass in *x* you may not +pass in *y* either.) + +In any case, the goal of Argument Clinic is to support argument parsing +for all existing CPython builtins without changing their semantics. +Therefore Argument Clinic supports +this alternate approach to parsing, using what are called *optional groups*. +Optional groups are groups of arguments that must all be passed in together. +They can be to the left or the right of the required arguments. They +can *only* be used with positional-only parameters. + +.. note:: Optional groups are *only* intended for use when converting + functions that make multiple calls to :c:func:`PyArg_ParseTuple`! + Functions that use *any* other approach for parsing arguments + should *almost never* be converted to Argument Clinic using + optional groups. Functions using optional groups currently + cannot have accurate signatures in Python, because Python just + doesn't understand the concept. Please avoid using optional + groups wherever possible. + +To specify an optional group, add a ``[`` on a line by itself before +the parameters you wish to group together, and a ``]`` on a line by itself +after these parameters. As an example, here's how :py:meth:`curses.window.addch` +uses optional groups to make the first two parameters and the last +parameter optional:: + + /*[clinic input] + + curses.window.addch + + [ + x: int + X-coordinate. + y: int + Y-coordinate. + ] + + ch: object + Character to add. + + [ + attr: long + Attributes for the character. + ] + / + + ... + + +Notes: + +* For every optional group, one additional parameter will be passed into the + impl function representing the group. The parameter will be an int named + ``group_{direction}_{number}``, + where ``{direction}`` is either ``right`` or ``left`` depending on whether the group + is before or after the required parameters, and ``{number}`` is a monotonically + increasing number (starting at 1) indicating how far away the group is from + the required parameters. When the impl is called, this parameter will be set + to zero if this group was unused, and set to non-zero if this group was used. + (By used or unused, I mean whether or not the parameters received arguments + in this invocation.) + +* If there are no required arguments, the optional groups will behave + as if they're to the right of the required arguments. + +* In the case of ambiguity, the argument parsing code + favors parameters on the left (before the required parameters). + +* Optional groups can only contain positional-only parameters. + +* Optional groups are *only* intended for legacy code. Please do not + use optional groups for new code. + + +How to use real Argument Clinic converters, instead of "legacy converters" +-------------------------------------------------------------------------- + +To save time, and to minimize how much you need to learn +to achieve your first port to Argument Clinic, the walkthrough above tells +you to use "legacy converters". "Legacy converters" are a convenience, +designed explicitly to make porting existing code to Argument Clinic +easier. + +However, in the long term we probably want all our blocks to +use Argument Clinic's real syntax for converters. Why? A couple +reasons: + +* The proper converters are far easier to read and clearer in their intent. +* There are some format units that are unsupported as "legacy converters", + because they require arguments, and the legacy converter syntax doesn't + support specifying arguments. +* In the future we may have a new argument parsing library that isn't + restricted to what :c:func:`PyArg_ParseTuple` supports; this flexibility + won't be available to parameters using legacy converters. + +Therefore, if you don't mind a little extra effort, please use the normal +converters instead of legacy converters. + +In a nutshell, the syntax for Argument Clinic (non-legacy) converters +looks like a Python function call. However, if there are no explicit +arguments to the function (all functions take their default values), +you may omit the parentheses. Thus ``bool`` and ``bool()`` are exactly +the same converters. + +All arguments to Argument Clinic converters are keyword-only. +All Argument Clinic converters accept the following arguments: + +*c_default* + The default value for this parameter when defined in C. + Specifically, this will be the initializer for the variable declared + in the "parse function". See :ref:`the section on default values ` + for how to use this. + Specified as a string. + +*annotation* + The annotation value for this parameter. Not currently supported, + because :pep:`8` mandates that the Python library may not use + annotations. + +*unused* + Wrap the argument with :c:macro:`Py_UNUSED` in the impl function signature. + +In addition, some converters accept additional arguments. Here is a list +of these arguments, along with their meanings: + +*accept* + A set of Python types (and possibly pseudo-types); + this restricts the allowable Python argument to values of these types. + (This is not a general-purpose facility; as a rule it only supports + specific lists of types as shown in the legacy converter table.) + + To accept ``None``, add ``NoneType`` to this set. + +*bitwise* + Only supported for unsigned integers. The native integer value of this + Python argument will be written to the parameter without any range checking, + even for negative values. + +*converter* + Only supported by the ``object`` converter. Specifies the name of a + :ref:`C "converter function" ` + to use to convert this object to a native type. + +*encoding* + Only supported for strings. Specifies the encoding to use when converting + this string from a Python str (Unicode) value into a C ``char *`` value. + + +*subclass_of* + Only supported for the ``object`` converter. Requires that the Python + value be a subclass of a Python type, as expressed in C. + +*type* + Only supported for the ``object`` and ``self`` converters. Specifies + the C type that will be used to declare the variable. Default value is + ``"PyObject *"``. + +*zeroes* + Only supported for strings. If true, embedded NUL bytes (``'\\0'``) are + permitted inside the value. The length of the string will be passed in + to the impl function, just after the string parameter, as a parameter named + ``_length``. + +Please note, not every possible combination of arguments will work. +Usually these arguments are implemented by specific :c:func:`PyArg_ParseTuple` +*format units*, with specific behavior. For example, currently you cannot +call ``unsigned_short`` without also specifying ``bitwise=True``. +Although it's perfectly reasonable to think this would work, these semantics don't +map to any existing format unit. So Argument Clinic doesn't support it. (Or, at +least, not yet.) + +Below is a table showing the mapping of legacy converters into real +Argument Clinic converters. On the left is the legacy converter, +on the right is the text you'd replace it with. + +========= ================================================================================= +``'B'`` ``unsigned_char(bitwise=True)`` +``'b'`` ``unsigned_char`` +``'c'`` ``char`` +``'C'`` ``int(accept={str})`` +``'d'`` ``double`` +``'D'`` ``Py_complex`` +``'es'`` ``str(encoding='name_of_encoding')`` +``'es#'`` ``str(encoding='name_of_encoding', zeroes=True)`` +``'et'`` ``str(encoding='name_of_encoding', accept={bytes, bytearray, str})`` +``'et#'`` ``str(encoding='name_of_encoding', accept={bytes, bytearray, str}, zeroes=True)`` +``'f'`` ``float`` +``'h'`` ``short`` +``'H'`` ``unsigned_short(bitwise=True)`` +``'i'`` ``int`` +``'I'`` ``unsigned_int(bitwise=True)`` +``'k'`` ``unsigned_long(bitwise=True)`` +``'K'`` ``unsigned_long_long(bitwise=True)`` +``'l'`` ``long`` +``'L'`` ``long long`` +``'n'`` ``Py_ssize_t`` +``'O'`` ``object`` +``'O!'`` ``object(subclass_of='&PySomething_Type')`` +``'O&'`` ``object(converter='name_of_c_function')`` +``'p'`` ``bool`` +``'S'`` ``PyBytesObject`` +``'s'`` ``str`` +``'s#'`` ``str(zeroes=True)`` +``'s*'`` ``Py_buffer(accept={buffer, str})`` +``'U'`` ``unicode`` +``'u'`` ``wchar_t`` +``'u#'`` ``wchar_t(zeroes=True)`` +``'w*'`` ``Py_buffer(accept={rwbuffer})`` +``'Y'`` ``PyByteArrayObject`` +``'y'`` ``str(accept={bytes})`` +``'y#'`` ``str(accept={robuffer}, zeroes=True)`` +``'y*'`` ``Py_buffer`` +``'Z'`` ``wchar_t(accept={str, NoneType})`` +``'Z#'`` ``wchar_t(accept={str, NoneType}, zeroes=True)`` +``'z'`` ``str(accept={str, NoneType})`` +``'z#'`` ``str(accept={str, NoneType}, zeroes=True)`` +``'z*'`` ``Py_buffer(accept={buffer, str, NoneType})`` +========= ================================================================================= + +As an example, here's our sample ``pickle.Pickler.dump`` using the proper +converter:: + + /*[clinic input] + pickle.Pickler.dump + + obj: object + The object to be pickled. + / + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + +One advantage of real converters is that they're more flexible than legacy +converters. For example, the ``unsigned_int`` converter (and all the +``unsigned_`` converters) can be specified without ``bitwise=True``. Their +default behavior performs range checking on the value, and they won't accept +negative numbers. You just can't do that with a legacy converter! + +Argument Clinic will show you all the converters it has +available. For each converter it'll show you all the parameters +it accepts, along with the default value for each parameter. +Just run ``Tools/clinic/clinic.py --converters`` to see the full list. + + +How to use the ``Py_buffer`` converter +-------------------------------------- + +When using the ``Py_buffer`` converter +(or the ``'s*'``, ``'w*'``, ``'*y'``, or ``'z*'`` legacy converters), +you *must* not call :c:func:`PyBuffer_Release` on the provided buffer. +Argument Clinic generates code that does it for you (in the parsing function). + + +.. _clinic-howto-advanced-converters: + +How to use advanced converters +------------------------------ + +Remember those format units you skipped for your first +time because they were advanced? Here's how to handle those too. + +The trick is, all those format units take arguments—either +conversion functions, or types, or strings specifying an encoding. +(But "legacy converters" don't support arguments. That's why we +skipped them for your first function.) The argument you specified +to the format unit is now an argument to the converter; this +argument is either *converter* (for ``O&``), *subclass_of* (for ``O!``), +or *encoding* (for all the format units that start with ``e``). + +When using *subclass_of*, you may also want to use the other +custom argument for ``object()``: *type*, which lets you set the type +actually used for the parameter. For example, if you want to ensure +that the object is a subclass of :c:var:`PyUnicode_Type`, you probably want +to use the converter ``object(type='PyUnicodeObject *', subclass_of='&PyUnicode_Type')``. + +One possible problem with using Argument Clinic: it takes away some possible +flexibility for the format units starting with ``e``. When writing a +:c:func:`!PyArg_Parse*` call by hand, you could theoretically decide at runtime what +encoding string to pass to that call. But now this string must +be hard-coded at Argument-Clinic-preprocessing-time. This limitation is deliberate; +it made supporting this format unit much easier, and may allow for future optimizations. +This restriction doesn't seem unreasonable; CPython itself always passes in static +hard-coded encoding strings for parameters whose format units start with ``e``. + + +.. _clinic-howto-default-values: +.. _default_values: + +How to assign default values to parameter +----------------------------------------- + +Default values for parameters can be any of a number of values. +At their simplest, they can be string, int, or float literals: + +.. code-block:: none + + foo: str = "abc" + bar: int = 123 + bat: float = 45.6 + +They can also use any of Python's built-in constants: + +.. code-block:: none + + yep: bool = True + nope: bool = False + nada: object = None + +There's also special support for a default value of ``NULL``, and +for simple expressions, documented in the following sections. + + +The ``NULL`` default value +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +For string and object parameters, you can set them to ``None`` to indicate +that there's no default. However, that means the C variable will be +initialized to ``Py_None``. For convenience's sakes, there's a special +value called ``NULL`` for just this reason: from Python's perspective it +behaves like a default value of ``None``, but the C variable is initialized +with ``NULL``. + + +Symbolic default values +^^^^^^^^^^^^^^^^^^^^^^^ + +The default value you provide for a parameter can't be any arbitrary +expression. Currently the following are explicitly supported: + +* Numeric constants (integer and float) +* String constants +* ``True``, ``False``, and ``None`` +* Simple symbolic constants like :py:data:`sys.maxsize`, which must + start with the name of the module + +(In the future, this may need to get even more elaborate, +to allow full expressions like ``CONSTANT - 1``.) + + +Expressions as default values +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The default value for a parameter can be more than just a literal value. +It can be an entire expression, using math operators and looking up attributes +on objects. However, this support isn't exactly simple, because of some +non-obvious semantics. + +Consider the following example: + +.. code-block:: none + + foo: Py_ssize_t = sys.maxsize - 1 + +:py:data:`sys.maxsize` can have different values on different platforms. Therefore +Argument Clinic can't simply evaluate that expression locally and hard-code it +in C. So it stores the default in such a way that it will get evaluated at +runtime, when the user asks for the function's signature. + +What namespace is available when the expression is evaluated? It's evaluated +in the context of the module the builtin came from. So, if your module has an +attribute called :py:attr:`!max_widgets`, you may simply use it: + +.. code-block:: none + + foo: Py_ssize_t = max_widgets + +If the symbol isn't found in the current module, it fails over to looking in +:py:data:`sys.modules`. That's how it can find :py:data:`sys.maxsize` for example. +(Since you don't know in advance what modules the user will load into their interpreter, +it's best to restrict yourself to modules that are preloaded by Python itself.) + +Evaluating default values only at runtime means Argument Clinic can't compute +the correct equivalent C default value. So you need to tell it explicitly. +When you use an expression, you must also specify the equivalent expression +in C, using the *c_default* parameter to the converter: + +.. code-block:: none + + foo: Py_ssize_t(c_default="PY_SSIZE_T_MAX - 1") = sys.maxsize - 1 + +Another complication: Argument Clinic can't know in advance whether or not the +expression you supply is valid. It parses it to make sure it looks legal, but +it can't *actually* know. You must be very careful when using expressions to +specify values that are guaranteed to be valid at runtime! + +Finally, because expressions must be representable as static C values, there +are many restrictions on legal expressions. Here's a list of Python features +you're not permitted to use: + +* Function calls. +* Inline if statements (``3 if foo else 5``). +* Automatic sequence unpacking (``*[1, 2, 3]``). +* List/set/dict comprehensions and generator expressions. +* Tuple/list/set/dict literals. + + +.. _clinic-howto-return-converters: + +How to use return converters +---------------------------- + +By default, the impl function Argument Clinic generates for you returns +:c:type:`PyObject * `. +But your C function often computes some C type, +then converts it into the :c:type:`!PyObject *` +at the last moment. Argument Clinic handles converting your inputs from Python types +into native C types—why not have it convert your return value from a native C type +into a Python type too? + +That's what a "return converter" does. It changes your impl function to return +some C type, then adds code to the generated (non-impl) function to handle converting +that value into the appropriate :c:type:`!PyObject *`. + +The syntax for return converters is similar to that of parameter converters. +You specify the return converter like it was a return annotation on the +function itself, using ``->`` notation. + +For example: + +.. code-block:: c + + /*[clinic input] + add -> int + + a: int + b: int + / + + [clinic start generated code]*/ + +Return converters behave much the same as parameter converters; +they take arguments, the arguments are all keyword-only, and if you're not changing +any of the default arguments you can omit the parentheses. + +(If you use both ``"as"`` *and* a return converter for your function, +the ``"as"`` should come before the return converter.) + +There's one additional complication when using return converters: how do you +indicate an error has occurred? Normally, a function returns a valid (non-``NULL``) +pointer for success, and ``NULL`` for failure. But if you use an integer return converter, +all integers are valid. How can Argument Clinic detect an error? Its solution: each return +converter implicitly looks for a special value that indicates an error. If you return +that value, and an error has been set (c:func:`PyErr_Occurred` returns a true +value), then the generated code will propagate the error. Otherwise it will +encode the value you return like normal. + +Currently Argument Clinic supports only a few return converters: + +.. code-block:: none + + bool + double + float + int + long + Py_ssize_t + size_t + unsigned int + unsigned long + +None of these take parameters. +For all of these, return ``-1`` to indicate error. + +To see all the return converters Argument Clinic supports, along with +their parameters (if any), +just run ``Tools/clinic/clinic.py --converters`` for the full list. + + +How to clone existing functions +------------------------------- + +If you have a number of functions that look similar, you may be able to +use Clinic's "clone" feature. When you clone an existing function, +you reuse: + +* its parameters, including + + * their names, + + * their converters, with all parameters, + + * their default values, + + * their per-parameter docstrings, + + * their *kind* (whether they're positional only, + positional or keyword, or keyword only), and + +* its return converter. + +The only thing not copied from the original function is its docstring; +the syntax allows you to specify a new docstring. + +Here's the syntax for cloning a function:: + + /*[clinic input] + module.class.new_function [as c_basename] = module.class.existing_function + + Docstring for new_function goes here. + [clinic start generated code]*/ + +(The functions can be in different modules or classes. I wrote +``module.class`` in the sample just to illustrate that you must +use the full path to *both* functions.) + +Sorry, there's no syntax for partially cloning a function, or cloning a function +then modifying it. Cloning is an all-or nothing proposition. + +Also, the function you are cloning from must have been previously defined +in the current file. + + +How to call Python code +----------------------- + +The rest of the advanced topics require you to write Python code +which lives inside your C file and modifies Argument Clinic's +runtime state. This is simple: you simply define a Python block. + +A Python block uses different delimiter lines than an Argument +Clinic function block. It looks like this:: + + /*[python input] + # python code goes here + [python start generated code]*/ + +All the code inside the Python block is executed at the +time it's parsed. All text written to stdout inside the block +is redirected into the "output" after the block. + +As an example, here's a Python block that adds a static integer +variable to the C code:: + + /*[python input] + print('static int __ignored_unused_variable__ = 0;') + [python start generated code]*/ + static int __ignored_unused_variable__ = 0; + /*[python checksum:...]*/ + + +.. _clinic-howto-self-converter: + +How to use the "self converter" +------------------------------- + +Argument Clinic automatically adds a "self" parameter for you +using a default converter. It automatically sets the ``type`` +of this parameter to the "pointer to an instance" you specified +when you declared the type. However, you can override +Argument Clinic's converter and specify one yourself. +Just add your own *self* parameter as the first parameter in a +block, and ensure that its converter is an instance of +:class:`!self_converter` or a subclass thereof. + +What's the point? This lets you override the type of ``self``, +or give it a different default name. + +How do you specify the custom type you want to cast ``self`` to? +If you only have one or two functions with the same type for ``self``, +you can directly use Argument Clinic's existing ``self`` converter, +passing in the type you want to use as the *type* parameter:: + + /*[clinic input] + + _pickle.Pickler.dump + + self: self(type="PicklerObject *") + obj: object + / + + Write a pickled representation of the given object to the open file. + [clinic start generated code]*/ + +On the other hand, if you have a lot of functions that will use the same +type for ``self``, it's best to create your own converter, subclassing +:class:`!self_converter` but overwriting the :py:attr:`!type` member:: + + /*[python input] + class PicklerObject_converter(self_converter): + type = "PicklerObject *" + [python start generated code]*/ + + /*[clinic input] + + _pickle.Pickler.dump + + self: PicklerObject + obj: object + / + + Write a pickled representation of the given object to the open file. + [clinic start generated code]*/ + + +How to use the "defining class" converter +----------------------------------------- + +Argument Clinic facilitates gaining access to the defining class of a method. +This is useful for :ref:`heap type ` methods that need to fetch +module level state. Use :c:func:`PyType_FromModuleAndSpec` to associate a new +heap type with a module. You can now use :c:func:`PyType_GetModuleState` on +the defining class to fetch the module state, for example from a module method. + +Example from :cpy-file:`Modules/zlibmodule.c`. +First, ``defining_class`` is added to the clinic input:: + + /*[clinic input] + zlib.Compress.compress + + cls: defining_class + data: Py_buffer + Binary data to be compressed. + / + + +After running the Argument Clinic tool, the following function signature is +generated:: + + /*[clinic start generated code]*/ + static PyObject * + zlib_Compress_compress_impl(compobject *self, PyTypeObject *cls, + Py_buffer *data) + /*[clinic end generated code: output=6731b3f0ff357ca6 input=04d00f65ab01d260]*/ + + +The following code can now use ``PyType_GetModuleState(cls)`` to fetch the +module state:: + + zlibstate *state = PyType_GetModuleState(cls); + + +Each method may only have one argument using this converter, and it must appear +after ``self``, or, if ``self`` is not used, as the first argument. The argument +will be of type ``PyTypeObject *``. The argument will not appear in the +:py:attr:`!__text_signature__`. + +The ``defining_class`` converter is not compatible with :py:meth:`!__init__` +and :py:meth:`!__new__` methods, which cannot use the :c:macro:`METH_METHOD` +convention. + +It is not possible to use ``defining_class`` with slot methods. In order to +fetch the module state from such methods, use :c:func:`PyType_GetModuleByDef` +to look up the module and then :c:func:`PyModule_GetState` to fetch the module +state. Example from the ``setattro`` slot method in +:cpy-file:`Modules/_threadmodule.c`:: + + static int + local_setattro(localobject *self, PyObject *name, PyObject *v) + { + PyObject *module = PyType_GetModuleByDef(Py_TYPE(self), &thread_module); + thread_module_state *state = get_thread_state(module); + ... + } + + +See also :pep:`573`. + + +.. _clinic-howto-custom-converter: + +How to write a custom converter +------------------------------- + +A converter is a Python class that inherits from :py:class:`CConverter`. +The main purpose of a custom converter, is for parameters parsed with +the ``O&`` format unit --- parsing such a parameter means calling +a :c:func:`PyArg_ParseTuple` "converter function". + +Your converter class should be named :samp:`{ConverterName}_converter`. +By following this convention, your converter class will be automatically +registered with Argument Clinic, with its *converter name* being the name of +your converter class with the ``_converter`` suffix stripped off. + +Instead of subclassing :py:meth:`!CConverter.__init__`, +write a :py:meth:`!converter_init` method. +:py:meth:`!converter_init` always accepts a *self* parameter. +After *self*, all additional parameters **must** be keyword-only. +Any arguments passed to the converter in Argument Clinic +will be passed along to your :py:meth:`!converter_init` method. +See :py:class:`CConverter` for a list of members you may wish to specify in +your subclass. + +Here's the simplest example of a custom converter, from :cpy-file:`Modules/zlibmodule.c`:: + + /*[python input] + + class ssize_t_converter(CConverter): + type = 'Py_ssize_t' + converter = 'ssize_t_converter' + + [python start generated code]*/ + /*[python end generated code: output=da39a3ee5e6b4b0d input=35521e4e733823c7]*/ + +This block adds a converter named ``ssize_t`` to Argument Clinic. +Parameters declared as ``ssize_t`` will be declared with type :c:type:`Py_ssize_t`, +and will be parsed by the ``'O&'`` format unit, +which will call the :c:func:`!ssize_t_converter` converter C function. +``ssize_t`` variables automatically support default values. + +More sophisticated custom converters can insert custom C code to +handle initialization and cleanup. +You can see more examples of custom converters in the CPython +source tree; grep the C files for the string ``CConverter``. + + +How to write a custom return converter +-------------------------------------- + +Writing a custom return converter is much like writing +a custom converter. Except it's somewhat simpler, because return +converters are themselves much simpler. + +Return converters must subclass :py:class:`!CReturnConverter`. +There are no examples yet of custom return converters, +because they are not widely used yet. If you wish to +write your own return converter, please read :cpy-file:`Tools/clinic/clinic.py`, +specifically the implementation of :py:class:`!CReturnConverter` and +all its subclasses. + + +How to convert ``METH_O`` and ``METH_NOARGS`` functions +------------------------------------------------------- + +To convert a function using :c:macro:`METH_O`, make sure the function's +single argument is using the ``object`` converter, and mark the +arguments as positional-only:: + + /*[clinic input] + meth_o_sample + + argument: object + / + [clinic start generated code]*/ + + +To convert a function using :c:macro:`METH_NOARGS`, just don't specify +any arguments. + +You can still use a self converter, a return converter, and specify +a *type* argument to the object converter for :c:macro:`METH_O`. + + +How to convert ``*args`` parameters (starargs / var-positional) +--------------------------------------------------------------- + +There are two converters suitable for ``*args``: *array* and *tuple*. + +Using the *array* converter will provide the implementation function with +a C array *args* of type of :c:type:`PyObject * ` and the number +of items in the array as :c:type:`Py_ssize_t` *args_length*. +For example:: + + /*[clinic input] + var_positional_sample + + spam: int + *args: array + [clinic start generated code]*/ + +Using the *tuple* converter will provide the implementation function with +a standard :c:type:`PyTupleObject`. +For example:: + + /*[clinic input] + var_positional_sample + + spam: int + *args: tuple + [clinic start generated code]*/ + +.. versionadded:: 3.11 + + +How to convert ``tp_new`` and ``tp_init`` functions +--------------------------------------------------- + +You can convert :c:member:`~PyTypeObject.tp_new` and +:c:member:`~PyTypeObject.tp_init` functions. +Just name them ``__new__`` or ``__init__`` as appropriate. Notes: + +* The function name generated for ``__new__`` doesn't end in ``__new__`` + like it would by default. It's just the name of the class, converted + into a valid C identifier. + +* No :c:type:`PyMethodDef` ``#define`` is generated for these functions. + +* ``__init__`` functions return ``int``, not ``PyObject *``. + +* Use the docstring as the class docstring. + +* Although ``__new__`` and ``__init__`` functions must always + accept both the ``args`` and ``kwargs`` objects, when converting + you may specify any signature for these functions that you like. + (If your function doesn't support keywords, the parsing function + generated will throw an exception if it receives any.) + + +How to change and redirect Clinic's output +------------------------------------------ + +It can be inconvenient to have Clinic's output interspersed with +your conventional hand-edited C code. Luckily, Clinic is configurable: +you can buffer up its output for printing later (or earlier!), or write +its output to a separate file. You can also add a prefix or suffix to +every line of Clinic's generated output. + +While changing Clinic's output in this manner can be a boon to readability, +it may result in Clinic code using types before they are defined, or +your code attempting to use Clinic-generated code before it is defined. +These problems can be easily solved by rearranging the declarations in your file, +or moving where Clinic's generated code goes. (This is why the default behavior +of Clinic is to output everything into the current block; while many people +consider this hampers readability, it will never require rearranging your +code to fix definition-before-use problems.) + +Let's start with defining some terminology: + +*field* + A field, in this context, is a subsection of Clinic's output. + For example, the ``#define`` for the :c:type:`PyMethodDef` structure + is a field, called ``methoddef_define``. Clinic has seven + different fields it can output per function definition: + + .. code-block:: none + + docstring_prototype + docstring_definition + methoddef_define + impl_prototype + parser_prototype + parser_definition + impl_definition + + All the names are of the form ``"_"``, + where ``""`` is the semantic object represented (the parsing function, + the impl function, the docstring, or the methoddef structure) and ``""`` + represents what kind of statement the field is. Field names that end in + ``"_prototype"`` + represent forward declarations of that thing, without the actual body/data + of the thing; field names that end in ``"_definition"`` represent the actual + definition of the thing, with the body/data of the thing. (``"methoddef"`` + is special, it's the only one that ends with ``"_define"``, representing that + it's a preprocessor #define.) + +*destination* + A destination is a place Clinic can write output to. There are + five built-in destinations: + + ``block`` + The default destination: printed in the output section of + the current Clinic block. + + ``buffer`` + A text buffer where you can save text for later. Text sent + here is appended to the end of any existing text. It's an + error to have any text left in the buffer when Clinic finishes + processing a file. + + ``file`` + A separate "clinic file" that will be created automatically by Clinic. + The filename chosen for the file is ``{basename}.clinic{extension}``, + where ``basename`` and ``extension`` were assigned the output + from ``os.path.splitext()`` run on the current file. (Example: + the ``file`` destination for :file:`_pickle.c` would be written to + :file:`_pickle.clinic.c`.) + + **Important: When using a** ``file`` **destination, you** + *must check in* **the generated file!** + + ``two-pass`` + A buffer like ``buffer``. However, a two-pass buffer can only + be dumped once, and it prints out all text sent to it during + all processing, even from Clinic blocks *after* the dumping point. + + ``suppress`` + The text is suppressed—thrown away. + + +Clinic defines five new directives that let you reconfigure its output. + +The first new directive is ``dump``: + +.. code-block:: none + + dump + +This dumps the current contents of the named destination into the output of +the current block, and empties it. This only works with ``buffer`` and +``two-pass`` destinations. + +The second new directive is ``output``. The most basic form of ``output`` +is like this: + +.. code-block:: none + + output + +This tells Clinic to output *field* to *destination*. ``output`` also +supports a special meta-destination, called ``everything``, which tells +Clinic to output *all* fields to that *destination*. + +``output`` has a number of other functions: + +.. code-block:: none + + output push + output pop + output preset + + +``output push`` and ``output pop`` allow you to push and pop +configurations on an internal configuration stack, so that you +can temporarily modify the output configuration, then easily restore +the previous configuration. Simply push before your change to save +the current configuration, then pop when you wish to restore the +previous configuration. + +``output preset`` sets Clinic's output to one of several built-in +preset configurations, as follows: + +``block`` + Clinic's original starting configuration. Writes everything + immediately after the input block. + + Suppress the ``parser_prototype`` + and ``docstring_prototype``, write everything else to ``block``. + +``file`` + Designed to write everything to the "clinic file" that it can. + You then ``#include`` this file near the top of your file. + You may need to rearrange your file to make this work, though + usually this just means creating forward declarations for various + ``typedef`` and ``PyTypeObject`` definitions. + + Suppress the ``parser_prototype`` + and ``docstring_prototype``, write the ``impl_definition`` to + ``block``, and write everything else to ``file``. + + The default filename is ``"{dirname}/clinic/{basename}.h"``. + +``buffer`` + Save up most of the output from Clinic, to be written into + your file near the end. For Python files implementing modules + or builtin types, it's recommended that you dump the buffer + just above the static structures for your module or + builtin type; these are normally very near the end. Using + ``buffer`` may require even more editing than ``file``, if + your file has static ``PyMethodDef`` arrays defined in the + middle of the file. + + Suppress the ``parser_prototype``, ``impl_prototype``, + and ``docstring_prototype``, write the ``impl_definition`` to + ``block``, and write everything else to ``file``. + +``two-pass`` + Similar to the ``buffer`` preset, but writes forward declarations to + the ``two-pass`` buffer, and definitions to the ``buffer``. + This is similar to the ``buffer`` preset, but may require + less editing than ``buffer``. Dump the ``two-pass`` buffer + near the top of your file, and dump the ``buffer`` near + the end just like you would when using the ``buffer`` preset. + + Suppresses the ``impl_prototype``, write the ``impl_definition`` + to ``block``, write ``docstring_prototype``, ``methoddef_define``, + and ``parser_prototype`` to ``two-pass``, write everything else + to ``buffer``. + +``partial-buffer`` + Similar to the ``buffer`` preset, but writes more things to ``block``, + only writing the really big chunks of generated code to ``buffer``. + This avoids the definition-before-use problem of ``buffer`` completely, + at the small cost of having slightly more stuff in the block's output. + Dump the ``buffer`` near the end, just like you would when using + the ``buffer`` preset. + + Suppresses the ``impl_prototype``, write the ``docstring_definition`` + and ``parser_definition`` to ``buffer``, write everything else to ``block``. + +The third new directive is ``destination``: + +.. code-block:: none + + destination [...] + +This performs an operation on the destination named ``name``. + +There are two defined subcommands: ``new`` and ``clear``. + +The ``new`` subcommand works like this: + +.. code-block:: none + + destination new + +This creates a new destination with name ```` and type ````. + +There are five destination types: + +``suppress`` + Throws the text away. + +``block`` + Writes the text to the current block. This is what Clinic + originally did. + +``buffer`` + A simple text buffer, like the "buffer" builtin destination above. + +``file`` + A text file. The file destination takes an extra argument, + a template to use for building the filename, like so:: + + destination new + + The template can use three strings internally that will be replaced + by bits of the filename: + + ``{path}`` + The full path to the file, including directory and full filename. + ``{dirname}`` + The name of the directory the file is in. + ``{basename}`` + Just the name of the file, not including the directory. + ``{basename_root}`` + Basename with the extension clipped off + (everything up to but not including the last '.'). + ``{basename_extension}`` + The last '.' and everything after it. If the basename + does not contain a period, this will be the empty string. + + If there are no periods in the filename, ``{basename}`` and ``{filename}`` + are the same, and ``{extension}`` is empty. ``{basename}{extension}`` + is always exactly the same as ``{filename}``. + +``two-pass`` + A two-pass buffer, like the "two-pass" builtin destination above. + + +The ``clear`` subcommand works like this: + +.. code-block:: none + + destination clear + +It removes all the accumulated text up to this point in the destination. +(I don't know what you'd need this for, but I thought maybe it'd be +useful while someone's experimenting.) + +The fourth new directive is ``set``: + +.. code-block:: none + + set line_prefix "string" + set line_suffix "string" + +``set`` lets you set two internal variables in Clinic. +``line_prefix`` is a string that will be prepended to every line of Clinic's output; +``line_suffix`` is a string that will be appended to every line of Clinic's output. + +Both of these support two format strings: + +``{block comment start}`` + Turns into the string ``/*``, the start-comment text sequence for C files. + +``{block comment end}`` + Turns into the string ``*/``, the end-comment text sequence for C files. + +The final new directive is one you shouldn't need to use directly, +called ``preserve``: + +.. code-block:: none + + preserve + +This tells Clinic that the current contents of the output should be kept, unmodified. +This is used internally by Clinic when dumping output into ``file`` files; wrapping +it in a Clinic block lets Clinic use its existing checksum functionality to ensure +the file was not modified by hand before it gets overwritten. + + +How to use the ``#ifdef`` trick +------------------------------- + +If you're converting a function that isn't available on all platforms, +there's a trick you can use to make life a little easier. The existing +code probably looks like this:: + + #ifdef HAVE_FUNCTIONNAME + static module_functionname(...) + { + ... + } + #endif /* HAVE_FUNCTIONNAME */ + +And then in the ``PyMethodDef`` structure at the bottom the existing code +will have: + +.. code-block:: none + + #ifdef HAVE_FUNCTIONNAME + {'functionname', ... }, + #endif /* HAVE_FUNCTIONNAME */ + +In this scenario, you should enclose the body of your impl function inside the ``#ifdef``, +like so:: + + #ifdef HAVE_FUNCTIONNAME + /*[clinic input] + module.functionname + ... + [clinic start generated code]*/ + static module_functionname(...) + { + ... + } + #endif /* HAVE_FUNCTIONNAME */ + +Then, remove those three lines from the :c:type:`PyMethodDef` structure, +replacing them with the macro Argument Clinic generated: + +.. code-block:: none + + MODULE_FUNCTIONNAME_METHODDEF + +(You can find the real name for this macro inside the generated code. +Or you can calculate it yourself: it's the name of your function as defined +on the first line of your block, but with periods changed to underscores, +uppercased, and ``"_METHODDEF"`` added to the end.) + +Perhaps you're wondering: what if ``HAVE_FUNCTIONNAME`` isn't defined? +The ``MODULE_FUNCTIONNAME_METHODDEF`` macro won't be defined either! + +Here's where Argument Clinic gets very clever. It actually detects that the +Argument Clinic block might be deactivated by the ``#ifdef``. When that +happens, it generates a little extra code that looks like this:: + + #ifndef MODULE_FUNCTIONNAME_METHODDEF + #define MODULE_FUNCTIONNAME_METHODDEF + #endif /* !defined(MODULE_FUNCTIONNAME_METHODDEF) */ + +That means the macro always works. If the function is defined, this turns +into the correct structure, including the trailing comma. If the function is +undefined, this turns into nothing. + +However, this causes one ticklish problem: where should Argument Clinic put this +extra code when using the "block" output preset? It can't go in the output block, +because that could be deactivated by the ``#ifdef``. (That's the whole point!) + +In this situation, Argument Clinic writes the extra code to the "buffer" destination. +This may mean that you get a complaint from Argument Clinic: + +.. code-block:: none + + Warning in file "Modules/posixmodule.c" on line 12357: + Destination buffer 'buffer' not empty at end of file, emptying. + +When this happens, just open your file, find the ``dump buffer`` block that +Argument Clinic added to your file (it'll be at the very bottom), then +move it above the :c:type:`PyMethodDef` structure where that macro is used. + + +How to use Argument Clinic in Python files +------------------------------------------ + +It's actually possible to use Argument Clinic to preprocess Python files. +There's no point to using Argument Clinic blocks, of course, as the output +wouldn't make any sense to the Python interpreter. But using Argument Clinic +to run Python blocks lets you use Python as a Python preprocessor! + +Since Python comments are different from C comments, Argument Clinic +blocks embedded in Python files look slightly different. They look like this: + +.. code-block:: python3 + + #/*[python input] + #print("def foo(): pass") + #[python start generated code]*/ + def foo(): pass + #/*[python checksum:...]*/ + + +.. _clinic-howto-limited-capi: + +How to use the Limited C API +---------------------------- + +If Argument Clinic :term:`input` is located within a C source file +that contains ``#define Py_LIMITED_API``, Argument Clinic will generate C code +that uses the :ref:`Limited API ` to parse arguments. The +advantage of this is that the generated code will not use private functions. +However, this *can* result in Argument Clinic generating less efficient code +in some cases. The extent of the performance penalty will depend +on the parameters (types, number, etc.). + +.. versionadded:: 3.13 + + +.. _clinic-howto-override-signature: + +How to override the generated signature +--------------------------------------- + +You can use the ``@text_signature`` directive to override the default generated +signature in the docstring. +This can be useful for complex signatures that Argument Clinic cannot handle. +The ``@text_signature`` directive takes one argument: +the custom signature as a string. +The provided signature is copied verbatim to the generated docstring. + +Example from :cpy-file:`Objects/codeobject.c`:: + + /*[clinic input] + @text_signature "($self, /, **changes)" + code.replace + * + co_argcount: int(c_default="self->co_argcount") = unchanged + co_posonlyargcount: int(c_default="self->co_posonlyargcount") = unchanged + # etc ... + + Return a copy of the code object with new values for the specified fields. + [clinic start generated output]*/ + +The generated docstring ends up looking like this: + +.. code-block:: none + + replace($self, /, **changes) + -- + + Return a copy of the code object with new values for the specified fields. + + +.. _clinic-howto-critical-sections: + +How to use critical sections with Argument Clinic +------------------------------------------------- + +You can use the ``@critical_section`` directive to instruct Argument Clinic to +wrap the call to the "impl" function in a "Python critical section". +In builds of CPython without the Global Interpreter Lock ("GIL"), +critical sections are required in order to achieve +thread safety without causing deadlocks between threads. +When a critical section is entered into, a per-object lock associated +with the first argument of the decorated function is acquired. +The lock is released on exiting the critical section. + +Python critical sections are no-ops in builds of CPython with the GIL. +See :cpy-file:`Include/internal/pycore_critical_section.h` +and :pep:`PEP 703 <703#python-critical-sections>` +for more details about critical sections. + +Example from :cpy-file:`Modules/_io/bufferedio.c`:: + + /*[clinic input] + @critical_section + _io._Buffered.close + [clinic start generated code]*/ + +The generated glue code looks like this: + +.. code-block:: c + + static PyObject * + _io__Buffered_close(buffered *self, PyObject *Py_UNUSED(ignored)) + { + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io__Buffered_close_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; + } + +You can lock one or two additional objects +by supplying their C variable names as arguments +to the ``@critical_section`` directive. +This example from :cpy-file:`Modules/_weakref.c` takes +one additional argument (a C variable named ``object``):: + + /*[clinic input] + @critical_section object + _weakref.getweakrefcount -> Py_ssize_t + + object: object + / + Return the number of weak references to 'object'. + [clinic start generated code]*/ + +The generated glue code looks like this: + +.. code-block:: c + + static PyObject * + _weakref_getweakrefs(PyObject *module, PyObject *object) + { + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(object); + return_value = _weakref_getweakrefs_impl(module, object); + Py_END_CRITICAL_SECTION(); + + return return_value; + } + +.. versionadded:: 3.13 + + +.. _clinic-howto-pygetsetdef: + +How to declare ``PyGetSetDef`` ("getter/setter") functions +---------------------------------------------------------- + +"Getters" and "setters" are C functions defined in a :c:type:`PyGetSetDef` struct +that facilitate :py:class:`property`-like access for a class. +You can use the ``@getter`` and ``@setter`` directives to generate +"impl" functions using Argument Clinic. + +This example --- taken from :cpy-file:`Modules/_io/textio.c` --- +shows the use of ``@getter`` and ``@setter`` in combination with +the :ref:`@critical_section ` directive +(which achieves thread safety without causing deadlocks between threads):: + + /*[clinic input] + @critical_section + @getter + _io.TextIOWrapper._CHUNK_SIZE + [clinic start generated code]*/ + + /*[clinic input] + @critical_section + @setter + _io.TextIOWrapper._CHUNK_SIZE + [clinic start generated code]*/ + +The generated glue code looks like this: + +.. code-block:: c + + static PyObject * + _io_TextIOWrapper__CHUNK_SIZE_get(textio *self, void *Py_UNUSED(context)) + { + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_TextIOWrapper__CHUNK_SIZE_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; + } + + static int + _io_TextIOWrapper__CHUNK_SIZE_set(textio *self, PyObject *value, void *Py_UNUSED(context)) + { + int return_value; + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_TextIOWrapper__CHUNK_SIZE_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + return return_value; + } + +.. note:: + + Getters and setters must be declared as separate functions. + The *value* parameter for a "setter" is added implicitly by Argument Clinic. + It is possible to create a docstring for the property by adding it to + the ``@getter``. + +And then the implementation will work the same as a Python method which is +decorated by :py:class:`property`: + +.. code-block:: pycon + + >>> import sys, _io + >>> a = _io.TextIOWrapper(sys.stdout) + >>> a._CHUNK_SIZE + 8192 + >>> a._CHUNK_SIZE = 30 + >>> a._CHUNK_SIZE + 30 + +.. versionadded:: 3.13 + + +.. _clinic-howto-deprecate-positional: +.. _clinic-howto-deprecate-keyword: + +How to deprecate passing parameters positionally or by keyword +-------------------------------------------------------------- + +Argument Clinic provides syntax that makes it possible to generate code that +deprecates passing :term:`arguments ` for positional-or-keyword +:term:`parameters ` positionally or by keyword. +For example, say we've got a module-level function :py:func:`!foo.myfunc` +that has five parameters: a positional-only parameter *a*, three +positional-or-keyword parameters *b*, *c* and *d*, and a keyword-only +parameter *e*:: + + /*[clinic input] + module foo + myfunc + a: int + / + b: int + c: int + d: int + * + e: int + [clinic start generated output]*/ + +We now want to make the *b* parameter positional-only and the *d* parameter +keyword-only; +however, we'll have to wait two releases before making these changes, +as mandated by Python's backwards-compatibility policy (see :pep:`387`). +For this example, imagine we're in the development phase for Python 3.12: +that means we'll be allowed to introduce deprecation warnings in Python 3.12 +whenever an argument for the *b* parameter is passed by keyword or an argument +for the *d* parameter is passed positionally, and we'll be allowed to make +them positional-only and keyword-only respectively in Python 3.14 at +the earliest. + +We can use Argument Clinic to emit the desired deprecation warnings +using the ``[from ...]`` syntax, by adding the line ``/ [from 3.14]`` right +below the *b* parameter and adding the line ``* [from 3.14]`` right above +the *d* parameter:: + + /*[clinic input] + module foo + myfunc + a: int + / + b: int + / [from 3.14] + c: int + * [from 3.14] + d: int + * + e: int + [clinic start generated output]*/ + +Next, regenerate Argument Clinic code (``make clinic``), +and add unit tests for the new behaviour. + +The generated code will now emit a :exc:`DeprecationWarning` +when an :term:`argument` for the :term:`parameter` *d* is passed positionally +(e.g ``myfunc(1, 2, 3, 4, e=5)``) or an argument for the parameter *b* is +passed by keyword (e.g ``myfunc(1, b=2, c=3, d=4, e=5)``). +C preprocessor directives are also generated for emitting +compiler warnings if the ``[from ...]`` lines have not been removed +from the Argument Clinic input when the deprecation period is over, +which means when the alpha phase of the specified Python version kicks in. + +Let's return to our example and skip ahead two years: +Python 3.14 development has now entered the alpha phase, +but we forgot all about updating the Argument Clinic code +for :py:func:`!myfunc`! +Luckily for us, compiler warnings are now generated: + +.. code-block:: none + + In file included from Modules/foomodule.c:139: + Modules/clinic/foomodule.c.h:139:8: warning: In 'foomodule.c', update the clinic input of 'mymod.myfunc'. [-W#warnings] + # warning "In 'foomodule.c', update the clinic input of 'mymod.myfunc'. [-W#warnings]" + ^ + +We now close the deprecation phase by making *a* positional-only and *c* +keyword-only; +replace the ``/ [from ...]`` line below *b* with the ``/`` from the line +below *a* and the ``* [from ...]`` line above *d* with the ``*`` from +the line above *e*:: + + /*[clinic input] + module foo + myfunc + a: int + b: int + / + c: int + * + d: int + e: int + [clinic start generated output]*/ + +Finally, run ``make clinic`` to regenerate the Argument Clinic code, +and update your unit tests to reflect the new behaviour. + +.. note:: + + If you forget to update your input block during the alpha and beta phases, + the compiler warning will turn into a compiler error when the + release candidate phase begins. diff --git a/development-tools/clinic/index.rst b/development-tools/clinic/index.rst index 6446d1a460..69fb99e910 100644 --- a/development-tools/clinic/index.rst +++ b/development-tools/clinic/index.rst @@ -22,6 +22,11 @@ This document is divided in four major sections: * :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. +.. toctree:: + :maxdepth: 2 + :hidden: + + howto .. note:: @@ -670,1577 +675,3 @@ except for one difference: :py:func:`inspect.signature` run on your function should now provide a valid signature! Congratulations, you've ported your first function to work with Argument Clinic! - - -.. _clinic-howtos: - -How-to guides -============= - - -How to rename C functions and variables generated by Argument Clinic --------------------------------------------------------------------- - -Argument Clinic automatically names the functions it generates for you. -Occasionally this may cause a problem, if the generated name collides with -the name of an existing C function. There's an easy solution: override the names -used for the C functions. Just add the keyword ``"as"`` -to your function declaration line, followed by the function name you wish to use. -Argument Clinic will use that function name for the base (generated) function, -then add ``"_impl"`` to the end and use that for the name of the impl function. - -For example, if we wanted to rename the C function names generated for -:py:meth:`pickle.Pickler.dump`, it'd look like this:: - - /*[clinic input] - pickle.Pickler.dump as pickler_dumper - - ... - -The base function would now be named :c:func:`!pickler_dumper`, -and the impl function would now be named :c:func:`!pickler_dumper_impl`. - - -Similarly, you may have a problem where you want to give a parameter -a specific Python name, but that name may be inconvenient in C. Argument -Clinic allows you to give a parameter different names in Python and in C, -using the same ``"as"`` syntax:: - - /*[clinic input] - pickle.Pickler.dump - - obj: object - file as file_obj: object - protocol: object = NULL - * - fix_imports: bool = True - -Here, the name used in Python (in the signature and the ``keywords`` -array) would be *file*, but the C variable would be named ``file_obj``. - -You can use this to rename the *self* parameter too! - - -How to convert functions using ``PyArg_UnpackTuple`` ----------------------------------------------------- - -To convert a function parsing its arguments with :c:func:`PyArg_UnpackTuple`, -simply write out all the arguments, specifying each as an ``object``. You -may specify the *type* argument to cast the type as appropriate. All -arguments should be marked positional-only (add a ``/`` on a line by itself -after the last argument). - -Currently the generated code will use :c:func:`PyArg_ParseTuple`, but this -will change soon. - - -How to use optional groups --------------------------- - -Some legacy functions have a tricky approach to parsing their arguments: -they count the number of positional arguments, then use a ``switch`` statement -to call one of several different :c:func:`PyArg_ParseTuple` calls depending on -how many positional arguments there are. (These functions cannot accept -keyword-only arguments.) This approach was used to simulate optional -arguments back before :c:func:`PyArg_ParseTupleAndKeywords` was created. - -While functions using this approach can often be converted to -use :c:func:`!PyArg_ParseTupleAndKeywords`, optional arguments, and default values, -it's not always possible. Some of these legacy functions have -behaviors :c:func:`!PyArg_ParseTupleAndKeywords` doesn't directly support. -The most obvious example is the builtin function :py:func:`!range`, which has -an optional argument on the *left* side of its required argument! -Another example is :py:meth:`curses.window.addch`, which has a group of two -arguments that must always be specified together. (The arguments are -called *x* and *y*; if you call the function passing in *x*, -you must also pass in *y* — and if you don't pass in *x* you may not -pass in *y* either.) - -In any case, the goal of Argument Clinic is to support argument parsing -for all existing CPython builtins without changing their semantics. -Therefore Argument Clinic supports -this alternate approach to parsing, using what are called *optional groups*. -Optional groups are groups of arguments that must all be passed in together. -They can be to the left or the right of the required arguments. They -can *only* be used with positional-only parameters. - -.. note:: Optional groups are *only* intended for use when converting - functions that make multiple calls to :c:func:`PyArg_ParseTuple`! - Functions that use *any* other approach for parsing arguments - should *almost never* be converted to Argument Clinic using - optional groups. Functions using optional groups currently - cannot have accurate signatures in Python, because Python just - doesn't understand the concept. Please avoid using optional - groups wherever possible. - -To specify an optional group, add a ``[`` on a line by itself before -the parameters you wish to group together, and a ``]`` on a line by itself -after these parameters. As an example, here's how :py:meth:`curses.window.addch` -uses optional groups to make the first two parameters and the last -parameter optional:: - - /*[clinic input] - - curses.window.addch - - [ - x: int - X-coordinate. - y: int - Y-coordinate. - ] - - ch: object - Character to add. - - [ - attr: long - Attributes for the character. - ] - / - - ... - - -Notes: - -* For every optional group, one additional parameter will be passed into the - impl function representing the group. The parameter will be an int named - ``group_{direction}_{number}``, - where ``{direction}`` is either ``right`` or ``left`` depending on whether the group - is before or after the required parameters, and ``{number}`` is a monotonically - increasing number (starting at 1) indicating how far away the group is from - the required parameters. When the impl is called, this parameter will be set - to zero if this group was unused, and set to non-zero if this group was used. - (By used or unused, I mean whether or not the parameters received arguments - in this invocation.) - -* If there are no required arguments, the optional groups will behave - as if they're to the right of the required arguments. - -* In the case of ambiguity, the argument parsing code - favors parameters on the left (before the required parameters). - -* Optional groups can only contain positional-only parameters. - -* Optional groups are *only* intended for legacy code. Please do not - use optional groups for new code. - - -How to use real Argument Clinic converters, instead of "legacy converters" --------------------------------------------------------------------------- - -To save time, and to minimize how much you need to learn -to achieve your first port to Argument Clinic, the walkthrough above tells -you to use "legacy converters". "Legacy converters" are a convenience, -designed explicitly to make porting existing code to Argument Clinic -easier. - -However, in the long term we probably want all our blocks to -use Argument Clinic's real syntax for converters. Why? A couple -reasons: - -* The proper converters are far easier to read and clearer in their intent. -* There are some format units that are unsupported as "legacy converters", - because they require arguments, and the legacy converter syntax doesn't - support specifying arguments. -* In the future we may have a new argument parsing library that isn't - restricted to what :c:func:`PyArg_ParseTuple` supports; this flexibility - won't be available to parameters using legacy converters. - -Therefore, if you don't mind a little extra effort, please use the normal -converters instead of legacy converters. - -In a nutshell, the syntax for Argument Clinic (non-legacy) converters -looks like a Python function call. However, if there are no explicit -arguments to the function (all functions take their default values), -you may omit the parentheses. Thus ``bool`` and ``bool()`` are exactly -the same converters. - -All arguments to Argument Clinic converters are keyword-only. -All Argument Clinic converters accept the following arguments: - -*c_default* - The default value for this parameter when defined in C. - Specifically, this will be the initializer for the variable declared - in the "parse function". See :ref:`the section on default values ` - for how to use this. - Specified as a string. - -*annotation* - The annotation value for this parameter. Not currently supported, - because :pep:`8` mandates that the Python library may not use - annotations. - -*unused* - Wrap the argument with :c:macro:`Py_UNUSED` in the impl function signature. - -In addition, some converters accept additional arguments. Here is a list -of these arguments, along with their meanings: - -*accept* - A set of Python types (and possibly pseudo-types); - this restricts the allowable Python argument to values of these types. - (This is not a general-purpose facility; as a rule it only supports - specific lists of types as shown in the legacy converter table.) - - To accept ``None``, add ``NoneType`` to this set. - -*bitwise* - Only supported for unsigned integers. The native integer value of this - Python argument will be written to the parameter without any range checking, - even for negative values. - -*converter* - Only supported by the ``object`` converter. Specifies the name of a - :ref:`C "converter function" ` - to use to convert this object to a native type. - -*encoding* - Only supported for strings. Specifies the encoding to use when converting - this string from a Python str (Unicode) value into a C ``char *`` value. - - -*subclass_of* - Only supported for the ``object`` converter. Requires that the Python - value be a subclass of a Python type, as expressed in C. - -*type* - Only supported for the ``object`` and ``self`` converters. Specifies - the C type that will be used to declare the variable. Default value is - ``"PyObject *"``. - -*zeroes* - Only supported for strings. If true, embedded NUL bytes (``'\\0'``) are - permitted inside the value. The length of the string will be passed in - to the impl function, just after the string parameter, as a parameter named - ``_length``. - -Please note, not every possible combination of arguments will work. -Usually these arguments are implemented by specific :c:func:`PyArg_ParseTuple` -*format units*, with specific behavior. For example, currently you cannot -call ``unsigned_short`` without also specifying ``bitwise=True``. -Although it's perfectly reasonable to think this would work, these semantics don't -map to any existing format unit. So Argument Clinic doesn't support it. (Or, at -least, not yet.) - -Below is a table showing the mapping of legacy converters into real -Argument Clinic converters. On the left is the legacy converter, -on the right is the text you'd replace it with. - -========= ================================================================================= -``'B'`` ``unsigned_char(bitwise=True)`` -``'b'`` ``unsigned_char`` -``'c'`` ``char`` -``'C'`` ``int(accept={str})`` -``'d'`` ``double`` -``'D'`` ``Py_complex`` -``'es'`` ``str(encoding='name_of_encoding')`` -``'es#'`` ``str(encoding='name_of_encoding', zeroes=True)`` -``'et'`` ``str(encoding='name_of_encoding', accept={bytes, bytearray, str})`` -``'et#'`` ``str(encoding='name_of_encoding', accept={bytes, bytearray, str}, zeroes=True)`` -``'f'`` ``float`` -``'h'`` ``short`` -``'H'`` ``unsigned_short(bitwise=True)`` -``'i'`` ``int`` -``'I'`` ``unsigned_int(bitwise=True)`` -``'k'`` ``unsigned_long(bitwise=True)`` -``'K'`` ``unsigned_long_long(bitwise=True)`` -``'l'`` ``long`` -``'L'`` ``long long`` -``'n'`` ``Py_ssize_t`` -``'O'`` ``object`` -``'O!'`` ``object(subclass_of='&PySomething_Type')`` -``'O&'`` ``object(converter='name_of_c_function')`` -``'p'`` ``bool`` -``'S'`` ``PyBytesObject`` -``'s'`` ``str`` -``'s#'`` ``str(zeroes=True)`` -``'s*'`` ``Py_buffer(accept={buffer, str})`` -``'U'`` ``unicode`` -``'u'`` ``wchar_t`` -``'u#'`` ``wchar_t(zeroes=True)`` -``'w*'`` ``Py_buffer(accept={rwbuffer})`` -``'Y'`` ``PyByteArrayObject`` -``'y'`` ``str(accept={bytes})`` -``'y#'`` ``str(accept={robuffer}, zeroes=True)`` -``'y*'`` ``Py_buffer`` -``'Z'`` ``wchar_t(accept={str, NoneType})`` -``'Z#'`` ``wchar_t(accept={str, NoneType}, zeroes=True)`` -``'z'`` ``str(accept={str, NoneType})`` -``'z#'`` ``str(accept={str, NoneType}, zeroes=True)`` -``'z*'`` ``Py_buffer(accept={buffer, str, NoneType})`` -========= ================================================================================= - -As an example, here's our sample ``pickle.Pickler.dump`` using the proper -converter:: - - /*[clinic input] - pickle.Pickler.dump - - obj: object - The object to be pickled. - / - - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ - -One advantage of real converters is that they're more flexible than legacy -converters. For example, the ``unsigned_int`` converter (and all the -``unsigned_`` converters) can be specified without ``bitwise=True``. Their -default behavior performs range checking on the value, and they won't accept -negative numbers. You just can't do that with a legacy converter! - -Argument Clinic will show you all the converters it has -available. For each converter it'll show you all the parameters -it accepts, along with the default value for each parameter. -Just run ``Tools/clinic/clinic.py --converters`` to see the full list. - - -How to use the ``Py_buffer`` converter --------------------------------------- - -When using the ``Py_buffer`` converter -(or the ``'s*'``, ``'w*'``, ``'*y'``, or ``'z*'`` legacy converters), -you *must* not call :c:func:`PyBuffer_Release` on the provided buffer. -Argument Clinic generates code that does it for you (in the parsing function). - - -.. _clinic-howto-advanced-converters: - -How to use advanced converters ------------------------------- - -Remember those format units you skipped for your first -time because they were advanced? Here's how to handle those too. - -The trick is, all those format units take arguments—either -conversion functions, or types, or strings specifying an encoding. -(But "legacy converters" don't support arguments. That's why we -skipped them for your first function.) The argument you specified -to the format unit is now an argument to the converter; this -argument is either *converter* (for ``O&``), *subclass_of* (for ``O!``), -or *encoding* (for all the format units that start with ``e``). - -When using *subclass_of*, you may also want to use the other -custom argument for ``object()``: *type*, which lets you set the type -actually used for the parameter. For example, if you want to ensure -that the object is a subclass of :c:var:`PyUnicode_Type`, you probably want -to use the converter ``object(type='PyUnicodeObject *', subclass_of='&PyUnicode_Type')``. - -One possible problem with using Argument Clinic: it takes away some possible -flexibility for the format units starting with ``e``. When writing a -:c:func:`!PyArg_Parse*` call by hand, you could theoretically decide at runtime what -encoding string to pass to that call. But now this string must -be hard-coded at Argument-Clinic-preprocessing-time. This limitation is deliberate; -it made supporting this format unit much easier, and may allow for future optimizations. -This restriction doesn't seem unreasonable; CPython itself always passes in static -hard-coded encoding strings for parameters whose format units start with ``e``. - - -.. _clinic-howto-default-values: -.. _default_values: - -How to assign default values to parameter ------------------------------------------ - -Default values for parameters can be any of a number of values. -At their simplest, they can be string, int, or float literals: - -.. code-block:: none - - foo: str = "abc" - bar: int = 123 - bat: float = 45.6 - -They can also use any of Python's built-in constants: - -.. code-block:: none - - yep: bool = True - nope: bool = False - nada: object = None - -There's also special support for a default value of ``NULL``, and -for simple expressions, documented in the following sections. - - -The ``NULL`` default value -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -For string and object parameters, you can set them to ``None`` to indicate -that there's no default. However, that means the C variable will be -initialized to ``Py_None``. For convenience's sakes, there's a special -value called ``NULL`` for just this reason: from Python's perspective it -behaves like a default value of ``None``, but the C variable is initialized -with ``NULL``. - - -Symbolic default values -^^^^^^^^^^^^^^^^^^^^^^^ - -The default value you provide for a parameter can't be any arbitrary -expression. Currently the following are explicitly supported: - -* Numeric constants (integer and float) -* String constants -* ``True``, ``False``, and ``None`` -* Simple symbolic constants like :py:data:`sys.maxsize`, which must - start with the name of the module - -(In the future, this may need to get even more elaborate, -to allow full expressions like ``CONSTANT - 1``.) - - -Expressions as default values -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The default value for a parameter can be more than just a literal value. -It can be an entire expression, using math operators and looking up attributes -on objects. However, this support isn't exactly simple, because of some -non-obvious semantics. - -Consider the following example: - -.. code-block:: none - - foo: Py_ssize_t = sys.maxsize - 1 - -:py:data:`sys.maxsize` can have different values on different platforms. Therefore -Argument Clinic can't simply evaluate that expression locally and hard-code it -in C. So it stores the default in such a way that it will get evaluated at -runtime, when the user asks for the function's signature. - -What namespace is available when the expression is evaluated? It's evaluated -in the context of the module the builtin came from. So, if your module has an -attribute called :py:attr:`!max_widgets`, you may simply use it: - -.. code-block:: none - - foo: Py_ssize_t = max_widgets - -If the symbol isn't found in the current module, it fails over to looking in -:py:data:`sys.modules`. That's how it can find :py:data:`sys.maxsize` for example. -(Since you don't know in advance what modules the user will load into their interpreter, -it's best to restrict yourself to modules that are preloaded by Python itself.) - -Evaluating default values only at runtime means Argument Clinic can't compute -the correct equivalent C default value. So you need to tell it explicitly. -When you use an expression, you must also specify the equivalent expression -in C, using the *c_default* parameter to the converter: - -.. code-block:: none - - foo: Py_ssize_t(c_default="PY_SSIZE_T_MAX - 1") = sys.maxsize - 1 - -Another complication: Argument Clinic can't know in advance whether or not the -expression you supply is valid. It parses it to make sure it looks legal, but -it can't *actually* know. You must be very careful when using expressions to -specify values that are guaranteed to be valid at runtime! - -Finally, because expressions must be representable as static C values, there -are many restrictions on legal expressions. Here's a list of Python features -you're not permitted to use: - -* Function calls. -* Inline if statements (``3 if foo else 5``). -* Automatic sequence unpacking (``*[1, 2, 3]``). -* List/set/dict comprehensions and generator expressions. -* Tuple/list/set/dict literals. - - -.. _clinic-howto-return-converters: - -How to use return converters ----------------------------- - -By default, the impl function Argument Clinic generates for you returns -:c:type:`PyObject * `. -But your C function often computes some C type, -then converts it into the :c:type:`!PyObject *` -at the last moment. Argument Clinic handles converting your inputs from Python types -into native C types—why not have it convert your return value from a native C type -into a Python type too? - -That's what a "return converter" does. It changes your impl function to return -some C type, then adds code to the generated (non-impl) function to handle converting -that value into the appropriate :c:type:`!PyObject *`. - -The syntax for return converters is similar to that of parameter converters. -You specify the return converter like it was a return annotation on the -function itself, using ``->`` notation. - -For example: - -.. code-block:: c - - /*[clinic input] - add -> int - - a: int - b: int - / - - [clinic start generated code]*/ - -Return converters behave much the same as parameter converters; -they take arguments, the arguments are all keyword-only, and if you're not changing -any of the default arguments you can omit the parentheses. - -(If you use both ``"as"`` *and* a return converter for your function, -the ``"as"`` should come before the return converter.) - -There's one additional complication when using return converters: how do you -indicate an error has occurred? Normally, a function returns a valid (non-``NULL``) -pointer for success, and ``NULL`` for failure. But if you use an integer return converter, -all integers are valid. How can Argument Clinic detect an error? Its solution: each return -converter implicitly looks for a special value that indicates an error. If you return -that value, and an error has been set (c:func:`PyErr_Occurred` returns a true -value), then the generated code will propagate the error. Otherwise it will -encode the value you return like normal. - -Currently Argument Clinic supports only a few return converters: - -.. code-block:: none - - bool - double - float - int - long - Py_ssize_t - size_t - unsigned int - unsigned long - -None of these take parameters. -For all of these, return ``-1`` to indicate error. - -To see all the return converters Argument Clinic supports, along with -their parameters (if any), -just run ``Tools/clinic/clinic.py --converters`` for the full list. - - -How to clone existing functions -------------------------------- - -If you have a number of functions that look similar, you may be able to -use Clinic's "clone" feature. When you clone an existing function, -you reuse: - -* its parameters, including - - * their names, - - * their converters, with all parameters, - - * their default values, - - * their per-parameter docstrings, - - * their *kind* (whether they're positional only, - positional or keyword, or keyword only), and - -* its return converter. - -The only thing not copied from the original function is its docstring; -the syntax allows you to specify a new docstring. - -Here's the syntax for cloning a function:: - - /*[clinic input] - module.class.new_function [as c_basename] = module.class.existing_function - - Docstring for new_function goes here. - [clinic start generated code]*/ - -(The functions can be in different modules or classes. I wrote -``module.class`` in the sample just to illustrate that you must -use the full path to *both* functions.) - -Sorry, there's no syntax for partially cloning a function, or cloning a function -then modifying it. Cloning is an all-or nothing proposition. - -Also, the function you are cloning from must have been previously defined -in the current file. - - -How to call Python code ------------------------ - -The rest of the advanced topics require you to write Python code -which lives inside your C file and modifies Argument Clinic's -runtime state. This is simple: you simply define a Python block. - -A Python block uses different delimiter lines than an Argument -Clinic function block. It looks like this:: - - /*[python input] - # python code goes here - [python start generated code]*/ - -All the code inside the Python block is executed at the -time it's parsed. All text written to stdout inside the block -is redirected into the "output" after the block. - -As an example, here's a Python block that adds a static integer -variable to the C code:: - - /*[python input] - print('static int __ignored_unused_variable__ = 0;') - [python start generated code]*/ - static int __ignored_unused_variable__ = 0; - /*[python checksum:...]*/ - - -.. _clinic-howto-self-converter: - -How to use the "self converter" -------------------------------- - -Argument Clinic automatically adds a "self" parameter for you -using a default converter. It automatically sets the ``type`` -of this parameter to the "pointer to an instance" you specified -when you declared the type. However, you can override -Argument Clinic's converter and specify one yourself. -Just add your own *self* parameter as the first parameter in a -block, and ensure that its converter is an instance of -:class:`!self_converter` or a subclass thereof. - -What's the point? This lets you override the type of ``self``, -or give it a different default name. - -How do you specify the custom type you want to cast ``self`` to? -If you only have one or two functions with the same type for ``self``, -you can directly use Argument Clinic's existing ``self`` converter, -passing in the type you want to use as the *type* parameter:: - - /*[clinic input] - - _pickle.Pickler.dump - - self: self(type="PicklerObject *") - obj: object - / - - Write a pickled representation of the given object to the open file. - [clinic start generated code]*/ - -On the other hand, if you have a lot of functions that will use the same -type for ``self``, it's best to create your own converter, subclassing -:class:`!self_converter` but overwriting the :py:attr:`!type` member:: - - /*[python input] - class PicklerObject_converter(self_converter): - type = "PicklerObject *" - [python start generated code]*/ - - /*[clinic input] - - _pickle.Pickler.dump - - self: PicklerObject - obj: object - / - - Write a pickled representation of the given object to the open file. - [clinic start generated code]*/ - - -How to use the "defining class" converter ------------------------------------------ - -Argument Clinic facilitates gaining access to the defining class of a method. -This is useful for :ref:`heap type ` methods that need to fetch -module level state. Use :c:func:`PyType_FromModuleAndSpec` to associate a new -heap type with a module. You can now use :c:func:`PyType_GetModuleState` on -the defining class to fetch the module state, for example from a module method. - -Example from :cpy-file:`Modules/zlibmodule.c`. -First, ``defining_class`` is added to the clinic input:: - - /*[clinic input] - zlib.Compress.compress - - cls: defining_class - data: Py_buffer - Binary data to be compressed. - / - - -After running the Argument Clinic tool, the following function signature is -generated:: - - /*[clinic start generated code]*/ - static PyObject * - zlib_Compress_compress_impl(compobject *self, PyTypeObject *cls, - Py_buffer *data) - /*[clinic end generated code: output=6731b3f0ff357ca6 input=04d00f65ab01d260]*/ - - -The following code can now use ``PyType_GetModuleState(cls)`` to fetch the -module state:: - - zlibstate *state = PyType_GetModuleState(cls); - - -Each method may only have one argument using this converter, and it must appear -after ``self``, or, if ``self`` is not used, as the first argument. The argument -will be of type ``PyTypeObject *``. The argument will not appear in the -:py:attr:`!__text_signature__`. - -The ``defining_class`` converter is not compatible with :py:meth:`!__init__` -and :py:meth:`!__new__` methods, which cannot use the :c:macro:`METH_METHOD` -convention. - -It is not possible to use ``defining_class`` with slot methods. In order to -fetch the module state from such methods, use :c:func:`PyType_GetModuleByDef` -to look up the module and then :c:func:`PyModule_GetState` to fetch the module -state. Example from the ``setattro`` slot method in -:cpy-file:`Modules/_threadmodule.c`:: - - static int - local_setattro(localobject *self, PyObject *name, PyObject *v) - { - PyObject *module = PyType_GetModuleByDef(Py_TYPE(self), &thread_module); - thread_module_state *state = get_thread_state(module); - ... - } - - -See also :pep:`573`. - - -.. _clinic-howto-custom-converter: - -How to write a custom converter -------------------------------- - -A converter is a Python class that inherits from :py:class:`CConverter`. -The main purpose of a custom converter, is for parameters parsed with -the ``O&`` format unit --- parsing such a parameter means calling -a :c:func:`PyArg_ParseTuple` "converter function". - -Your converter class should be named :samp:`{ConverterName}_converter`. -By following this convention, your converter class will be automatically -registered with Argument Clinic, with its *converter name* being the name of -your converter class with the ``_converter`` suffix stripped off. - -Instead of subclassing :py:meth:`!CConverter.__init__`, -write a :py:meth:`!converter_init` method. -:py:meth:`!converter_init` always accepts a *self* parameter. -After *self*, all additional parameters **must** be keyword-only. -Any arguments passed to the converter in Argument Clinic -will be passed along to your :py:meth:`!converter_init` method. -See :py:class:`CConverter` for a list of members you may wish to specify in -your subclass. - -Here's the simplest example of a custom converter, from :cpy-file:`Modules/zlibmodule.c`:: - - /*[python input] - - class ssize_t_converter(CConverter): - type = 'Py_ssize_t' - converter = 'ssize_t_converter' - - [python start generated code]*/ - /*[python end generated code: output=da39a3ee5e6b4b0d input=35521e4e733823c7]*/ - -This block adds a converter named ``ssize_t`` to Argument Clinic. -Parameters declared as ``ssize_t`` will be declared with type :c:type:`Py_ssize_t`, -and will be parsed by the ``'O&'`` format unit, -which will call the :c:func:`!ssize_t_converter` converter C function. -``ssize_t`` variables automatically support default values. - -More sophisticated custom converters can insert custom C code to -handle initialization and cleanup. -You can see more examples of custom converters in the CPython -source tree; grep the C files for the string ``CConverter``. - - -How to write a custom return converter --------------------------------------- - -Writing a custom return converter is much like writing -a custom converter. Except it's somewhat simpler, because return -converters are themselves much simpler. - -Return converters must subclass :py:class:`!CReturnConverter`. -There are no examples yet of custom return converters, -because they are not widely used yet. If you wish to -write your own return converter, please read :cpy-file:`Tools/clinic/clinic.py`, -specifically the implementation of :py:class:`!CReturnConverter` and -all its subclasses. - - -How to convert ``METH_O`` and ``METH_NOARGS`` functions -------------------------------------------------------- - -To convert a function using :c:macro:`METH_O`, make sure the function's -single argument is using the ``object`` converter, and mark the -arguments as positional-only:: - - /*[clinic input] - meth_o_sample - - argument: object - / - [clinic start generated code]*/ - - -To convert a function using :c:macro:`METH_NOARGS`, just don't specify -any arguments. - -You can still use a self converter, a return converter, and specify -a *type* argument to the object converter for :c:macro:`METH_O`. - - -How to convert ``*args`` parameters (starargs / var-positional) ---------------------------------------------------------------- - -There are two converters suitable for ``*args``: *array* and *tuple*. - -Using the *array* converter will provide the implementation function with -a C array *args* of type of :c:type:`PyObject * ` and the number -of items in the array as :c:type:`Py_ssize_t` *args_length*. -For example:: - - /*[clinic input] - var_positional_sample - - spam: int - *args: array - [clinic start generated code]*/ - -Using the *tuple* converter will provide the implementation function with -a standard :c:type:`PyTupleObject`. -For example:: - - /*[clinic input] - var_positional_sample - - spam: int - *args: tuple - [clinic start generated code]*/ - -.. versionadded:: 3.11 - - -How to convert ``tp_new`` and ``tp_init`` functions ---------------------------------------------------- - -You can convert :c:member:`~PyTypeObject.tp_new` and -:c:member:`~PyTypeObject.tp_init` functions. -Just name them ``__new__`` or ``__init__`` as appropriate. Notes: - -* The function name generated for ``__new__`` doesn't end in ``__new__`` - like it would by default. It's just the name of the class, converted - into a valid C identifier. - -* No :c:type:`PyMethodDef` ``#define`` is generated for these functions. - -* ``__init__`` functions return ``int``, not ``PyObject *``. - -* Use the docstring as the class docstring. - -* Although ``__new__`` and ``__init__`` functions must always - accept both the ``args`` and ``kwargs`` objects, when converting - you may specify any signature for these functions that you like. - (If your function doesn't support keywords, the parsing function - generated will throw an exception if it receives any.) - - -How to change and redirect Clinic's output ------------------------------------------- - -It can be inconvenient to have Clinic's output interspersed with -your conventional hand-edited C code. Luckily, Clinic is configurable: -you can buffer up its output for printing later (or earlier!), or write -its output to a separate file. You can also add a prefix or suffix to -every line of Clinic's generated output. - -While changing Clinic's output in this manner can be a boon to readability, -it may result in Clinic code using types before they are defined, or -your code attempting to use Clinic-generated code before it is defined. -These problems can be easily solved by rearranging the declarations in your file, -or moving where Clinic's generated code goes. (This is why the default behavior -of Clinic is to output everything into the current block; while many people -consider this hampers readability, it will never require rearranging your -code to fix definition-before-use problems.) - -Let's start with defining some terminology: - -*field* - A field, in this context, is a subsection of Clinic's output. - For example, the ``#define`` for the :c:type:`PyMethodDef` structure - is a field, called ``methoddef_define``. Clinic has seven - different fields it can output per function definition: - - .. code-block:: none - - docstring_prototype - docstring_definition - methoddef_define - impl_prototype - parser_prototype - parser_definition - impl_definition - - All the names are of the form ``"_"``, - where ``""`` is the semantic object represented (the parsing function, - the impl function, the docstring, or the methoddef structure) and ``""`` - represents what kind of statement the field is. Field names that end in - ``"_prototype"`` - represent forward declarations of that thing, without the actual body/data - of the thing; field names that end in ``"_definition"`` represent the actual - definition of the thing, with the body/data of the thing. (``"methoddef"`` - is special, it's the only one that ends with ``"_define"``, representing that - it's a preprocessor #define.) - -*destination* - A destination is a place Clinic can write output to. There are - five built-in destinations: - - ``block`` - The default destination: printed in the output section of - the current Clinic block. - - ``buffer`` - A text buffer where you can save text for later. Text sent - here is appended to the end of any existing text. It's an - error to have any text left in the buffer when Clinic finishes - processing a file. - - ``file`` - A separate "clinic file" that will be created automatically by Clinic. - The filename chosen for the file is ``{basename}.clinic{extension}``, - where ``basename`` and ``extension`` were assigned the output - from ``os.path.splitext()`` run on the current file. (Example: - the ``file`` destination for :file:`_pickle.c` would be written to - :file:`_pickle.clinic.c`.) - - **Important: When using a** ``file`` **destination, you** - *must check in* **the generated file!** - - ``two-pass`` - A buffer like ``buffer``. However, a two-pass buffer can only - be dumped once, and it prints out all text sent to it during - all processing, even from Clinic blocks *after* the dumping point. - - ``suppress`` - The text is suppressed—thrown away. - - -Clinic defines five new directives that let you reconfigure its output. - -The first new directive is ``dump``: - -.. code-block:: none - - dump - -This dumps the current contents of the named destination into the output of -the current block, and empties it. This only works with ``buffer`` and -``two-pass`` destinations. - -The second new directive is ``output``. The most basic form of ``output`` -is like this: - -.. code-block:: none - - output - -This tells Clinic to output *field* to *destination*. ``output`` also -supports a special meta-destination, called ``everything``, which tells -Clinic to output *all* fields to that *destination*. - -``output`` has a number of other functions: - -.. code-block:: none - - output push - output pop - output preset - - -``output push`` and ``output pop`` allow you to push and pop -configurations on an internal configuration stack, so that you -can temporarily modify the output configuration, then easily restore -the previous configuration. Simply push before your change to save -the current configuration, then pop when you wish to restore the -previous configuration. - -``output preset`` sets Clinic's output to one of several built-in -preset configurations, as follows: - -``block`` - Clinic's original starting configuration. Writes everything - immediately after the input block. - - Suppress the ``parser_prototype`` - and ``docstring_prototype``, write everything else to ``block``. - -``file`` - Designed to write everything to the "clinic file" that it can. - You then ``#include`` this file near the top of your file. - You may need to rearrange your file to make this work, though - usually this just means creating forward declarations for various - ``typedef`` and ``PyTypeObject`` definitions. - - Suppress the ``parser_prototype`` - and ``docstring_prototype``, write the ``impl_definition`` to - ``block``, and write everything else to ``file``. - - The default filename is ``"{dirname}/clinic/{basename}.h"``. - -``buffer`` - Save up most of the output from Clinic, to be written into - your file near the end. For Python files implementing modules - or builtin types, it's recommended that you dump the buffer - just above the static structures for your module or - builtin type; these are normally very near the end. Using - ``buffer`` may require even more editing than ``file``, if - your file has static ``PyMethodDef`` arrays defined in the - middle of the file. - - Suppress the ``parser_prototype``, ``impl_prototype``, - and ``docstring_prototype``, write the ``impl_definition`` to - ``block``, and write everything else to ``file``. - -``two-pass`` - Similar to the ``buffer`` preset, but writes forward declarations to - the ``two-pass`` buffer, and definitions to the ``buffer``. - This is similar to the ``buffer`` preset, but may require - less editing than ``buffer``. Dump the ``two-pass`` buffer - near the top of your file, and dump the ``buffer`` near - the end just like you would when using the ``buffer`` preset. - - Suppresses the ``impl_prototype``, write the ``impl_definition`` - to ``block``, write ``docstring_prototype``, ``methoddef_define``, - and ``parser_prototype`` to ``two-pass``, write everything else - to ``buffer``. - -``partial-buffer`` - Similar to the ``buffer`` preset, but writes more things to ``block``, - only writing the really big chunks of generated code to ``buffer``. - This avoids the definition-before-use problem of ``buffer`` completely, - at the small cost of having slightly more stuff in the block's output. - Dump the ``buffer`` near the end, just like you would when using - the ``buffer`` preset. - - Suppresses the ``impl_prototype``, write the ``docstring_definition`` - and ``parser_definition`` to ``buffer``, write everything else to ``block``. - -The third new directive is ``destination``: - -.. code-block:: none - - destination [...] - -This performs an operation on the destination named ``name``. - -There are two defined subcommands: ``new`` and ``clear``. - -The ``new`` subcommand works like this: - -.. code-block:: none - - destination new - -This creates a new destination with name ```` and type ````. - -There are five destination types: - -``suppress`` - Throws the text away. - -``block`` - Writes the text to the current block. This is what Clinic - originally did. - -``buffer`` - A simple text buffer, like the "buffer" builtin destination above. - -``file`` - A text file. The file destination takes an extra argument, - a template to use for building the filename, like so:: - - destination new - - The template can use three strings internally that will be replaced - by bits of the filename: - - ``{path}`` - The full path to the file, including directory and full filename. - ``{dirname}`` - The name of the directory the file is in. - ``{basename}`` - Just the name of the file, not including the directory. - ``{basename_root}`` - Basename with the extension clipped off - (everything up to but not including the last '.'). - ``{basename_extension}`` - The last '.' and everything after it. If the basename - does not contain a period, this will be the empty string. - - If there are no periods in the filename, ``{basename}`` and ``{filename}`` - are the same, and ``{extension}`` is empty. ``{basename}{extension}`` - is always exactly the same as ``{filename}``. - -``two-pass`` - A two-pass buffer, like the "two-pass" builtin destination above. - - -The ``clear`` subcommand works like this: - -.. code-block:: none - - destination clear - -It removes all the accumulated text up to this point in the destination. -(I don't know what you'd need this for, but I thought maybe it'd be -useful while someone's experimenting.) - -The fourth new directive is ``set``: - -.. code-block:: none - - set line_prefix "string" - set line_suffix "string" - -``set`` lets you set two internal variables in Clinic. -``line_prefix`` is a string that will be prepended to every line of Clinic's output; -``line_suffix`` is a string that will be appended to every line of Clinic's output. - -Both of these support two format strings: - -``{block comment start}`` - Turns into the string ``/*``, the start-comment text sequence for C files. - -``{block comment end}`` - Turns into the string ``*/``, the end-comment text sequence for C files. - -The final new directive is one you shouldn't need to use directly, -called ``preserve``: - -.. code-block:: none - - preserve - -This tells Clinic that the current contents of the output should be kept, unmodified. -This is used internally by Clinic when dumping output into ``file`` files; wrapping -it in a Clinic block lets Clinic use its existing checksum functionality to ensure -the file was not modified by hand before it gets overwritten. - - -How to use the ``#ifdef`` trick -------------------------------- - -If you're converting a function that isn't available on all platforms, -there's a trick you can use to make life a little easier. The existing -code probably looks like this:: - - #ifdef HAVE_FUNCTIONNAME - static module_functionname(...) - { - ... - } - #endif /* HAVE_FUNCTIONNAME */ - -And then in the ``PyMethodDef`` structure at the bottom the existing code -will have: - -.. code-block:: none - - #ifdef HAVE_FUNCTIONNAME - {'functionname', ... }, - #endif /* HAVE_FUNCTIONNAME */ - -In this scenario, you should enclose the body of your impl function inside the ``#ifdef``, -like so:: - - #ifdef HAVE_FUNCTIONNAME - /*[clinic input] - module.functionname - ... - [clinic start generated code]*/ - static module_functionname(...) - { - ... - } - #endif /* HAVE_FUNCTIONNAME */ - -Then, remove those three lines from the :c:type:`PyMethodDef` structure, -replacing them with the macro Argument Clinic generated: - -.. code-block:: none - - MODULE_FUNCTIONNAME_METHODDEF - -(You can find the real name for this macro inside the generated code. -Or you can calculate it yourself: it's the name of your function as defined -on the first line of your block, but with periods changed to underscores, -uppercased, and ``"_METHODDEF"`` added to the end.) - -Perhaps you're wondering: what if ``HAVE_FUNCTIONNAME`` isn't defined? -The ``MODULE_FUNCTIONNAME_METHODDEF`` macro won't be defined either! - -Here's where Argument Clinic gets very clever. It actually detects that the -Argument Clinic block might be deactivated by the ``#ifdef``. When that -happens, it generates a little extra code that looks like this:: - - #ifndef MODULE_FUNCTIONNAME_METHODDEF - #define MODULE_FUNCTIONNAME_METHODDEF - #endif /* !defined(MODULE_FUNCTIONNAME_METHODDEF) */ - -That means the macro always works. If the function is defined, this turns -into the correct structure, including the trailing comma. If the function is -undefined, this turns into nothing. - -However, this causes one ticklish problem: where should Argument Clinic put this -extra code when using the "block" output preset? It can't go in the output block, -because that could be deactivated by the ``#ifdef``. (That's the whole point!) - -In this situation, Argument Clinic writes the extra code to the "buffer" destination. -This may mean that you get a complaint from Argument Clinic: - -.. code-block:: none - - Warning in file "Modules/posixmodule.c" on line 12357: - Destination buffer 'buffer' not empty at end of file, emptying. - -When this happens, just open your file, find the ``dump buffer`` block that -Argument Clinic added to your file (it'll be at the very bottom), then -move it above the :c:type:`PyMethodDef` structure where that macro is used. - - -How to use Argument Clinic in Python files ------------------------------------------- - -It's actually possible to use Argument Clinic to preprocess Python files. -There's no point to using Argument Clinic blocks, of course, as the output -wouldn't make any sense to the Python interpreter. But using Argument Clinic -to run Python blocks lets you use Python as a Python preprocessor! - -Since Python comments are different from C comments, Argument Clinic -blocks embedded in Python files look slightly different. They look like this: - -.. code-block:: python3 - - #/*[python input] - #print("def foo(): pass") - #[python start generated code]*/ - def foo(): pass - #/*[python checksum:...]*/ - - -.. _clinic-howto-limited-capi: - -How to use the Limited C API ----------------------------- - -If Argument Clinic :term:`input` is located within a C source file -that contains ``#define Py_LIMITED_API``, Argument Clinic will generate C code -that uses the :ref:`Limited API ` to parse arguments. The -advantage of this is that the generated code will not use private functions. -However, this *can* result in Argument Clinic generating less efficient code -in some cases. The extent of the performance penalty will depend -on the parameters (types, number, etc.). - -.. versionadded:: 3.13 - - -.. _clinic-howto-override-signature: - -How to override the generated signature ---------------------------------------- - -You can use the ``@text_signature`` directive to override the default generated -signature in the docstring. -This can be useful for complex signatures that Argument Clinic cannot handle. -The ``@text_signature`` directive takes one argument: -the custom signature as a string. -The provided signature is copied verbatim to the generated docstring. - -Example from :cpy-file:`Objects/codeobject.c`:: - - /*[clinic input] - @text_signature "($self, /, **changes)" - code.replace - * - co_argcount: int(c_default="self->co_argcount") = unchanged - co_posonlyargcount: int(c_default="self->co_posonlyargcount") = unchanged - # etc ... - - Return a copy of the code object with new values for the specified fields. - [clinic start generated output]*/ - -The generated docstring ends up looking like this: - -.. code-block:: none - - replace($self, /, **changes) - -- - - Return a copy of the code object with new values for the specified fields. - - -.. _clinic-howto-critical-sections: - -How to use critical sections with Argument Clinic -------------------------------------------------- - -You can use the ``@critical_section`` directive to instruct Argument Clinic to -wrap the call to the "impl" function in a "Python critical section". -In builds of CPython without the Global Interpreter Lock ("GIL"), -critical sections are required in order to achieve -thread safety without causing deadlocks between threads. -When a critical section is entered into, a per-object lock associated -with the first argument of the decorated function is acquired. -The lock is released on exiting the critical section. - -Python critical sections are no-ops in builds of CPython with the GIL. -See :cpy-file:`Include/internal/pycore_critical_section.h` -and :pep:`PEP 703 <703#python-critical-sections>` -for more details about critical sections. - -Example from :cpy-file:`Modules/_io/bufferedio.c`:: - - /*[clinic input] - @critical_section - _io._Buffered.close - [clinic start generated code]*/ - -The generated glue code looks like this: - -.. code-block:: c - - static PyObject * - _io__Buffered_close(buffered *self, PyObject *Py_UNUSED(ignored)) - { - PyObject *return_value = NULL; - - Py_BEGIN_CRITICAL_SECTION(self); - return_value = _io__Buffered_close_impl(self); - Py_END_CRITICAL_SECTION(); - - return return_value; - } - -You can lock one or two additional objects -by supplying their C variable names as arguments -to the ``@critical_section`` directive. -This example from :cpy-file:`Modules/_weakref.c` takes -one additional argument (a C variable named ``object``):: - - /*[clinic input] - @critical_section object - _weakref.getweakrefcount -> Py_ssize_t - - object: object - / - Return the number of weak references to 'object'. - [clinic start generated code]*/ - -The generated glue code looks like this: - -.. code-block:: c - - static PyObject * - _weakref_getweakrefs(PyObject *module, PyObject *object) - { - PyObject *return_value = NULL; - - Py_BEGIN_CRITICAL_SECTION(object); - return_value = _weakref_getweakrefs_impl(module, object); - Py_END_CRITICAL_SECTION(); - - return return_value; - } - -.. versionadded:: 3.13 - - -.. _clinic-howto-pygetsetdef: - -How to declare ``PyGetSetDef`` ("getter/setter") functions ----------------------------------------------------------- - -"Getters" and "setters" are C functions defined in a :c:type:`PyGetSetDef` struct -that facilitate :py:class:`property`-like access for a class. -You can use the ``@getter`` and ``@setter`` directives to generate -"impl" functions using Argument Clinic. - -This example --- taken from :cpy-file:`Modules/_io/textio.c` --- -shows the use of ``@getter`` and ``@setter`` in combination with -the :ref:`@critical_section ` directive -(which achieves thread safety without causing deadlocks between threads):: - - /*[clinic input] - @critical_section - @getter - _io.TextIOWrapper._CHUNK_SIZE - [clinic start generated code]*/ - - /*[clinic input] - @critical_section - @setter - _io.TextIOWrapper._CHUNK_SIZE - [clinic start generated code]*/ - -The generated glue code looks like this: - -.. code-block:: c - - static PyObject * - _io_TextIOWrapper__CHUNK_SIZE_get(textio *self, void *Py_UNUSED(context)) - { - PyObject *return_value = NULL; - - Py_BEGIN_CRITICAL_SECTION(self); - return_value = _io_TextIOWrapper__CHUNK_SIZE_get_impl(self); - Py_END_CRITICAL_SECTION(); - - return return_value; - } - - static int - _io_TextIOWrapper__CHUNK_SIZE_set(textio *self, PyObject *value, void *Py_UNUSED(context)) - { - int return_value; - Py_BEGIN_CRITICAL_SECTION(self); - return_value = _io_TextIOWrapper__CHUNK_SIZE_set_impl(self, value); - Py_END_CRITICAL_SECTION(); - return return_value; - } - -.. note:: - - Getters and setters must be declared as separate functions. - The *value* parameter for a "setter" is added implicitly by Argument Clinic. - It is possible to create a docstring for the property by adding it to - the ``@getter``. - -And then the implementation will work the same as a Python method which is -decorated by :py:class:`property`: - -.. code-block:: pycon - - >>> import sys, _io - >>> a = _io.TextIOWrapper(sys.stdout) - >>> a._CHUNK_SIZE - 8192 - >>> a._CHUNK_SIZE = 30 - >>> a._CHUNK_SIZE - 30 - -.. versionadded:: 3.13 - - -.. _clinic-howto-deprecate-positional: -.. _clinic-howto-deprecate-keyword: - -How to deprecate passing parameters positionally or by keyword --------------------------------------------------------------- - -Argument Clinic provides syntax that makes it possible to generate code that -deprecates passing :term:`arguments ` for positional-or-keyword -:term:`parameters ` positionally or by keyword. -For example, say we've got a module-level function :py:func:`!foo.myfunc` -that has five parameters: a positional-only parameter *a*, three -positional-or-keyword parameters *b*, *c* and *d*, and a keyword-only -parameter *e*:: - - /*[clinic input] - module foo - myfunc - a: int - / - b: int - c: int - d: int - * - e: int - [clinic start generated output]*/ - -We now want to make the *b* parameter positional-only and the *d* parameter -keyword-only; -however, we'll have to wait two releases before making these changes, -as mandated by Python's backwards-compatibility policy (see :pep:`387`). -For this example, imagine we're in the development phase for Python 3.12: -that means we'll be allowed to introduce deprecation warnings in Python 3.12 -whenever an argument for the *b* parameter is passed by keyword or an argument -for the *d* parameter is passed positionally, and we'll be allowed to make -them positional-only and keyword-only respectively in Python 3.14 at -the earliest. - -We can use Argument Clinic to emit the desired deprecation warnings -using the ``[from ...]`` syntax, by adding the line ``/ [from 3.14]`` right -below the *b* parameter and adding the line ``* [from 3.14]`` right above -the *d* parameter:: - - /*[clinic input] - module foo - myfunc - a: int - / - b: int - / [from 3.14] - c: int - * [from 3.14] - d: int - * - e: int - [clinic start generated output]*/ - -Next, regenerate Argument Clinic code (``make clinic``), -and add unit tests for the new behaviour. - -The generated code will now emit a :exc:`DeprecationWarning` -when an :term:`argument` for the :term:`parameter` *d* is passed positionally -(e.g ``myfunc(1, 2, 3, 4, e=5)``) or an argument for the parameter *b* is -passed by keyword (e.g ``myfunc(1, b=2, c=3, d=4, e=5)``). -C preprocessor directives are also generated for emitting -compiler warnings if the ``[from ...]`` lines have not been removed -from the Argument Clinic input when the deprecation period is over, -which means when the alpha phase of the specified Python version kicks in. - -Let's return to our example and skip ahead two years: -Python 3.14 development has now entered the alpha phase, -but we forgot all about updating the Argument Clinic code -for :py:func:`!myfunc`! -Luckily for us, compiler warnings are now generated: - -.. code-block:: none - - In file included from Modules/foomodule.c:139: - Modules/clinic/foomodule.c.h:139:8: warning: In 'foomodule.c', update the clinic input of 'mymod.myfunc'. [-W#warnings] - # warning "In 'foomodule.c', update the clinic input of 'mymod.myfunc'. [-W#warnings]" - ^ - -We now close the deprecation phase by making *a* positional-only and *c* -keyword-only; -replace the ``/ [from ...]`` line below *b* with the ``/`` from the line -below *a* and the ``* [from ...]`` line above *d* with the ``*`` from -the line above *e*:: - - /*[clinic input] - module foo - myfunc - a: int - b: int - / - c: int - * - d: int - e: int - [clinic start generated output]*/ - -Finally, run ``make clinic`` to regenerate the Argument Clinic code, -and update your unit tests to reflect the new behaviour. - -.. note:: - - If you forget to update your input block during the alpha and beta phases, - the compiler warning will turn into a compiler error when the - release candidate phase begins. From 52bdc842106eb098261961503ae1351dca21041c Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Mon, 18 Aug 2025 12:22:29 +0100 Subject: [PATCH 051/103] Move Argument Clinic Tutorial to a new page --- development-tools/clinic/index.rst | 411 +------------------------- development-tools/clinic/tutorial.rst | 408 +++++++++++++++++++++++++ 2 files changed, 409 insertions(+), 410 deletions(-) create mode 100644 development-tools/clinic/tutorial.rst diff --git a/development-tools/clinic/index.rst b/development-tools/clinic/index.rst index 69fb99e910..a6ddd5c721 100644 --- a/development-tools/clinic/index.rst +++ b/development-tools/clinic/index.rst @@ -26,6 +26,7 @@ This document is divided in four major sections: :maxdepth: 2 :hidden: + tutorial howto .. note:: @@ -265,413 +266,3 @@ Classes for extending Argument Clinic A boolean value. If true, Argument Clinic will add a ``&`` in front of the name of the variable when passing it into :c:func:`PyArg_ParseTuple`. - - -.. _clinic-tutorial: - -Tutorial -======== - -The best way to get a sense of how Argument Clinic works is to -convert a function to work with it. Here, then, are the bare -minimum steps you'd need to follow to convert a function to -work with Argument Clinic. Note that for code you plan to -check in to CPython, you really should take the conversion farther, -using some of the :ref:`advanced concepts ` -you'll see later on in the document, -like :ref:`clinic-howto-return-converters` -and :ref:`clinic-howto-self-converter`. -But we'll keep it simple for this walkthrough so you can learn. - -First, make sure you're working with a freshly updated checkout -of the CPython trunk. - -Next, find a Python builtin that calls either :c:func:`PyArg_ParseTuple` -or :c:func:`PyArg_ParseTupleAndKeywords`, and hasn't been converted -to work with Argument Clinic yet. -For this tutorial, we'll be using -:py:meth:`_pickle.Pickler.dump `. - -If the call to the :c:func:`!PyArg_Parse*` function uses any of the -following format units...: - -.. code-block:: none - - O& - O! - es - es# - et - et# - -... or if it has multiple calls to :c:func:`PyArg_ParseTuple`, -you should choose a different function. -(See :ref:`clinic-howto-advanced-converters` for those scenarios.) - -Also, if the function has multiple calls to :c:func:`!PyArg_ParseTuple` -or :c:func:`PyArg_ParseTupleAndKeywords` where it supports different -types for the same argument, or if the function uses something besides -:c:func:`!PyArg_Parse*` functions to parse its arguments, it probably -isn't suitable for conversion to Argument Clinic. Argument Clinic -doesn't support generic functions or polymorphic parameters. - -Next, add the following boilerplate above the function, -creating our input block:: - - /*[clinic input] - [clinic start generated code]*/ - -Cut the docstring and paste it in between the ``[clinic]`` lines, -removing all the junk that makes it a properly quoted C string. -When you're done you should have just the text, based at the left -margin, with no line wider than 80 characters. -Argument Clinic will preserve indents inside the docstring. - -If the old docstring had a first line that looked like a function -signature, throw that line away; The docstring doesn't need it anymore --- -when you use :py:func:`help` on your builtin in the future, -the first line will be built automatically based on the function's signature. - -Example docstring summary line:: - - /*[clinic input] - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ - -If your docstring doesn't have a "summary" line, Argument Clinic will -complain, so let's make sure it has one. The "summary" line should -be a paragraph consisting of a single 80-column line -at the beginning of the docstring. -(See :pep:`257` regarding docstring conventions.) - -Our example docstring consists solely of a summary line, so the sample -code doesn't have to change for this step. - -Now, above the docstring, enter the name of the function, followed -by a blank line. This should be the Python name of the function, -and should be the full dotted path to the function --- -it should start with the name of the module, -include any sub-modules, and if the function is a method on -a class it should include the class name too. - -In our example, :mod:`!_pickle` is the module, :py:class:`!Pickler` is the class, -and :py:meth:`!dump` is the method, so the name becomes -:py:meth:`!_pickle.Pickler.dump`:: - - /*[clinic input] - _pickle.Pickler.dump - - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ - -If this is the first time that module or class has been used with Argument -Clinic in this C file, -you must declare the module and/or class. Proper Argument Clinic hygiene -prefers declaring these in a separate block somewhere near the -top of the C file, in the same way that include files and statics go at -the top. -In our sample code we'll just show the two blocks next to each other. - -The name of the class and module should be the same as the one -seen by Python. Check the name defined in the :c:type:`PyModuleDef` -or :c:type:`PyTypeObject` as appropriate. - -When you declare a class, you must also specify two aspects of its type -in C: the type declaration you'd use for a pointer to an instance of -this class, and a pointer to the :c:type:`!PyTypeObject` for this class:: - - /*[clinic input] - module _pickle - class _pickle.Pickler "PicklerObject *" "&Pickler_Type" - [clinic start generated code]*/ - - /*[clinic input] - _pickle.Pickler.dump - - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ - -Declare each of the parameters to the function. Each parameter -should get its own line. All the parameter lines should be -indented from the function name and the docstring. -The general form of these parameter lines is as follows: - -.. code-block:: none - - name_of_parameter: converter - -If the parameter has a default value, add that after the -converter: - -.. code-block:: none - - name_of_parameter: converter = default_value - -Argument Clinic's support for "default values" is quite sophisticated; -see :ref:`clinic-howto-default-values` for more information. - -Next, add a blank line below the parameters. - -What's a "converter"? -It establishes both the type of the variable used in C, -and the method to convert the Python value into a C value at runtime. -For now you're going to use what's called a "legacy converter" --- -a convenience syntax intended to make porting old code into Argument -Clinic easier. - -For each parameter, copy the "format unit" for that -parameter from the :c:func:`PyArg_Parse` format argument and -specify *that* as its converter, as a quoted string. -The "format unit" is the formal name for the one-to-three -character substring of the *format* parameter that tells -the argument parsing function what the type of the variable -is and how to convert it. -For more on format units please see :ref:`arg-parsing`. - -For multicharacter format units like ``z#``, -use the entire two-or-three character string. - -Sample:: - - /*[clinic input] - module _pickle - class _pickle.Pickler "PicklerObject *" "&Pickler_Type" - [clinic start generated code]*/ - - /*[clinic input] - _pickle.Pickler.dump - - obj: 'O' - - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ - -If your function has ``|`` in the format string, -meaning some parameters have default values, you can ignore it. -Argument Clinic infers which parameters are optional -based on whether or not they have default values. - -If your function has ``$`` in the format string, -meaning it takes keyword-only arguments, -specify ``*`` on a line by itself before the first keyword-only argument, -indented the same as the parameter lines. - -:py:meth:`!_pickle.Pickler.dump` has neither, so our sample is unchanged. - -Next, if the existing C function calls :c:func:`PyArg_ParseTuple` -(as opposed to :c:func:`PyArg_ParseTupleAndKeywords`), then all its -arguments are positional-only. - -To mark parameters as positional-only in Argument Clinic, -add a ``/`` on a line by itself after the last positional-only parameter, -indented the same as the parameter lines. - -Sample:: - - /*[clinic input] - module _pickle - class _pickle.Pickler "PicklerObject *" "&Pickler_Type" - [clinic start generated code]*/ - - /*[clinic input] - _pickle.Pickler.dump - - obj: 'O' - / - - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ - -It can be helpful to write a per-parameter docstring for each parameter. -Since per-parameter docstrings are optional, -you can skip this step if you prefer. - -Nevertheless, here's how to add a per-parameter docstring. -The first line of the per-parameter docstring -must be indented further than the parameter definition. -The left margin of this first line establishes -the left margin for the whole per-parameter docstring; -all the text you write will be outdented by this amount. -You can write as much text as you like, across multiple lines if you wish. - -Sample:: - - /*[clinic input] - module _pickle - class _pickle.Pickler "PicklerObject *" "&Pickler_Type" - [clinic start generated code]*/ - - /*[clinic input] - _pickle.Pickler.dump - - obj: 'O' - The object to be pickled. - / - - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ - -Save and close the file, then run ``Tools/clinic/clinic.py`` on it. -With luck everything worked---your block now has output, -and a :file:`.c.h` file has been generated! -Reload the file in your text editor to see the generated code:: - - /*[clinic input] - _pickle.Pickler.dump - - obj: 'O' - The object to be pickled. - / - - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ - - static PyObject * - _pickle_Pickler_dump(PicklerObject *self, PyObject *obj) - /*[clinic end generated code: output=87ecad1261e02ac7 input=552eb1c0f52260d9]*/ - -Obviously, if Argument Clinic didn't produce any output, -it's because it found an error in your input. -Keep fixing your errors and retrying until Argument Clinic processes your file -without complaint. - -For readability, most of the glue code has been generated to a :file:`.c.h` -file. You'll need to include that in your original :file:`.c` file, -typically right after the clinic module block:: - - #include "clinic/_pickle.c.h" - -Double-check that the argument-parsing code Argument Clinic generated -looks basically the same as the existing code. - -First, ensure both places use the same argument-parsing function. -The existing code must call either -:c:func:`PyArg_ParseTuple` or :c:func:`PyArg_ParseTupleAndKeywords`; -ensure that the code generated by Argument Clinic calls the -*exact* same function. - -Second, the format string passed in to :c:func:`!PyArg_ParseTuple` or -:c:func:`!PyArg_ParseTupleAndKeywords` should be *exactly* the same -as the hand-written one in the existing function, -up to the colon or semi-colon. - -Argument Clinic always generates its format strings -with a ``:`` followed by the name of the function. -If the existing code's format string ends with ``;``, -to provide usage help, this change is harmless --- don't worry about it. - -Third, for parameters whose format units require two arguments, -like a length variable, an encoding string, or a pointer -to a conversion function, ensure that the second argument is -*exactly* the same between the two invocations. - -Fourth, inside the output portion of the block, -you'll find a preprocessor macro defining the appropriate static -:c:type:`PyMethodDef` structure for this builtin:: - - #define __PICKLE_PICKLER_DUMP_METHODDEF \ - {"dump", (PyCFunction)__pickle_Pickler_dump, METH_O, __pickle_Pickler_dump__doc__}, - -This static structure should be *exactly* the same as the existing static -:c:type:`!PyMethodDef` structure for this builtin. - -If any of these items differ in *any way*, -adjust your Argument Clinic function specification and rerun -``Tools/clinic/clinic.py`` until they *are* the same. - -Notice that the last line of its output is the declaration -of your "impl" function. This is where the builtin's implementation goes. -Delete the existing prototype of the function you're modifying, but leave -the opening curly brace. Now delete its argument parsing code and the -declarations of all the variables it dumps the arguments into. -Notice how the Python arguments are now arguments to this impl function; -if the implementation used different names for these variables, fix it. - -Let's reiterate, just because it's kind of weird. -Your code should now look like this:: - - static return_type - your_function_impl(...) - /*[clinic end generated code: input=..., output=...]*/ - { - ... - -Argument Clinic generated the checksum line and the function prototype just -above it. You should write the opening and closing curly braces for the -function, and the implementation inside. - -Sample:: - - /*[clinic input] - module _pickle - class _pickle.Pickler "PicklerObject *" "&Pickler_Type" - [clinic start generated code]*/ - /*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ - - /*[clinic input] - _pickle.Pickler.dump - - obj: 'O' - The object to be pickled. - / - - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ - - PyDoc_STRVAR(__pickle_Pickler_dump__doc__, - "Write a pickled representation of obj to the open file.\n" - "\n" - ... - static PyObject * - _pickle_Pickler_dump_impl(PicklerObject *self, PyObject *obj) - /*[clinic end generated code: checksum=3bd30745bf206a48f8b576a1da3d90f55a0a4187]*/ - { - /* Check whether the Pickler was initialized correctly (issue3664). - Developers often forget to call __init__() in their subclasses, which - would trigger a segfault without this check. */ - if (self->write == NULL) { - PyErr_Format(PicklingError, - "Pickler.__init__() was not called by %s.__init__()", - Py_TYPE(self)->tp_name); - return NULL; - } - - if (_Pickler_ClearBuffer(self) < 0) { - return NULL; - } - - ... - -Remember the macro with the :c:type:`PyMethodDef` structure for this function? -Find the existing :c:type:`!PyMethodDef` structure for this -function and replace it with a reference to the macro. If the builtin -is at module scope, this will probably be very near the end of the file; -if the builtin is a class method, this will probably be below but relatively -near to the implementation. - -Note that the body of the macro contains a trailing comma; when you -replace the existing static :c:type:`!PyMethodDef` structure with the macro, -*don't* add a comma to the end. - -Sample:: - - static struct PyMethodDef Pickler_methods[] = { - __PICKLE_PICKLER_DUMP_METHODDEF - __PICKLE_PICKLER_CLEAR_MEMO_METHODDEF - {NULL, NULL} /* sentinel */ - }; - -Argument Clinic may generate new instances of ``_Py_ID``. For example:: - - &_Py_ID(new_unique_py_id) - -If it does, you'll have to run ``make regen-global-objects`` -to regenerate the list of precompiled identifiers at this point. - -Finally, compile, then run the relevant portions of the regression-test suite. -This change should not introduce any new compile-time warnings or errors, -and there should be no externally visible change to Python's behavior, -except for one difference: :py:func:`inspect.signature` run on your function -should now provide a valid signature! - -Congratulations, you've ported your first function to work with Argument Clinic! diff --git a/development-tools/clinic/tutorial.rst b/development-tools/clinic/tutorial.rst new file mode 100644 index 0000000000..6acfaee4bd --- /dev/null +++ b/development-tools/clinic/tutorial.rst @@ -0,0 +1,408 @@ +.. _clinic-tutorial: + +Tutorial +======== + +The best way to get a sense of how Argument Clinic works is to +convert a function to work with it. Here, then, are the bare +minimum steps you'd need to follow to convert a function to +work with Argument Clinic. Note that for code you plan to +check in to CPython, you really should take the conversion farther, +using some of the :ref:`advanced concepts ` +you'll see later on in the document, +like :ref:`clinic-howto-return-converters` +and :ref:`clinic-howto-self-converter`. +But we'll keep it simple for this walkthrough so you can learn. + +First, make sure you're working with a freshly updated checkout +of the CPython trunk. + +Next, find a Python builtin that calls either :c:func:`PyArg_ParseTuple` +or :c:func:`PyArg_ParseTupleAndKeywords`, and hasn't been converted +to work with Argument Clinic yet. +For this tutorial, we'll be using +:py:meth:`_pickle.Pickler.dump `. + +If the call to the :c:func:`!PyArg_Parse*` function uses any of the +following format units...: + +.. code-block:: none + + O& + O! + es + es# + et + et# + +... or if it has multiple calls to :c:func:`PyArg_ParseTuple`, +you should choose a different function. +(See :ref:`clinic-howto-advanced-converters` for those scenarios.) + +Also, if the function has multiple calls to :c:func:`!PyArg_ParseTuple` +or :c:func:`PyArg_ParseTupleAndKeywords` where it supports different +types for the same argument, or if the function uses something besides +:c:func:`!PyArg_Parse*` functions to parse its arguments, it probably +isn't suitable for conversion to Argument Clinic. Argument Clinic +doesn't support generic functions or polymorphic parameters. + +Next, add the following boilerplate above the function, +creating our input block:: + + /*[clinic input] + [clinic start generated code]*/ + +Cut the docstring and paste it in between the ``[clinic]`` lines, +removing all the junk that makes it a properly quoted C string. +When you're done you should have just the text, based at the left +margin, with no line wider than 80 characters. +Argument Clinic will preserve indents inside the docstring. + +If the old docstring had a first line that looked like a function +signature, throw that line away; The docstring doesn't need it anymore --- +when you use :py:func:`help` on your builtin in the future, +the first line will be built automatically based on the function's signature. + +Example docstring summary line:: + + /*[clinic input] + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + +If your docstring doesn't have a "summary" line, Argument Clinic will +complain, so let's make sure it has one. The "summary" line should +be a paragraph consisting of a single 80-column line +at the beginning of the docstring. +(See :pep:`257` regarding docstring conventions.) + +Our example docstring consists solely of a summary line, so the sample +code doesn't have to change for this step. + +Now, above the docstring, enter the name of the function, followed +by a blank line. This should be the Python name of the function, +and should be the full dotted path to the function --- +it should start with the name of the module, +include any sub-modules, and if the function is a method on +a class it should include the class name too. + +In our example, :mod:`!_pickle` is the module, :py:class:`!Pickler` is the class, +and :py:meth:`!dump` is the method, so the name becomes +:py:meth:`!_pickle.Pickler.dump`:: + + /*[clinic input] + _pickle.Pickler.dump + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + +If this is the first time that module or class has been used with Argument +Clinic in this C file, +you must declare the module and/or class. Proper Argument Clinic hygiene +prefers declaring these in a separate block somewhere near the +top of the C file, in the same way that include files and statics go at +the top. +In our sample code we'll just show the two blocks next to each other. + +The name of the class and module should be the same as the one +seen by Python. Check the name defined in the :c:type:`PyModuleDef` +or :c:type:`PyTypeObject` as appropriate. + +When you declare a class, you must also specify two aspects of its type +in C: the type declaration you'd use for a pointer to an instance of +this class, and a pointer to the :c:type:`!PyTypeObject` for this class:: + + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ + + /*[clinic input] + _pickle.Pickler.dump + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + +Declare each of the parameters to the function. Each parameter +should get its own line. All the parameter lines should be +indented from the function name and the docstring. +The general form of these parameter lines is as follows: + +.. code-block:: none + + name_of_parameter: converter + +If the parameter has a default value, add that after the +converter: + +.. code-block:: none + + name_of_parameter: converter = default_value + +Argument Clinic's support for "default values" is quite sophisticated; +see :ref:`clinic-howto-default-values` for more information. + +Next, add a blank line below the parameters. + +What's a "converter"? +It establishes both the type of the variable used in C, +and the method to convert the Python value into a C value at runtime. +For now you're going to use what's called a "legacy converter" --- +a convenience syntax intended to make porting old code into Argument +Clinic easier. + +For each parameter, copy the "format unit" for that +parameter from the :c:func:`PyArg_Parse` format argument and +specify *that* as its converter, as a quoted string. +The "format unit" is the formal name for the one-to-three +character substring of the *format* parameter that tells +the argument parsing function what the type of the variable +is and how to convert it. +For more on format units please see :ref:`arg-parsing`. + +For multicharacter format units like ``z#``, +use the entire two-or-three character string. + +Sample:: + + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ + + /*[clinic input] + _pickle.Pickler.dump + + obj: 'O' + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + +If your function has ``|`` in the format string, +meaning some parameters have default values, you can ignore it. +Argument Clinic infers which parameters are optional +based on whether or not they have default values. + +If your function has ``$`` in the format string, +meaning it takes keyword-only arguments, +specify ``*`` on a line by itself before the first keyword-only argument, +indented the same as the parameter lines. + +:py:meth:`!_pickle.Pickler.dump` has neither, so our sample is unchanged. + +Next, if the existing C function calls :c:func:`PyArg_ParseTuple` +(as opposed to :c:func:`PyArg_ParseTupleAndKeywords`), then all its +arguments are positional-only. + +To mark parameters as positional-only in Argument Clinic, +add a ``/`` on a line by itself after the last positional-only parameter, +indented the same as the parameter lines. + +Sample:: + + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ + + /*[clinic input] + _pickle.Pickler.dump + + obj: 'O' + / + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + +It can be helpful to write a per-parameter docstring for each parameter. +Since per-parameter docstrings are optional, +you can skip this step if you prefer. + +Nevertheless, here's how to add a per-parameter docstring. +The first line of the per-parameter docstring +must be indented further than the parameter definition. +The left margin of this first line establishes +the left margin for the whole per-parameter docstring; +all the text you write will be outdented by this amount. +You can write as much text as you like, across multiple lines if you wish. + +Sample:: + + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ + + /*[clinic input] + _pickle.Pickler.dump + + obj: 'O' + The object to be pickled. + / + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + +Save and close the file, then run ``Tools/clinic/clinic.py`` on it. +With luck everything worked---your block now has output, +and a :file:`.c.h` file has been generated! +Reload the file in your text editor to see the generated code:: + + /*[clinic input] + _pickle.Pickler.dump + + obj: 'O' + The object to be pickled. + / + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + + static PyObject * + _pickle_Pickler_dump(PicklerObject *self, PyObject *obj) + /*[clinic end generated code: output=87ecad1261e02ac7 input=552eb1c0f52260d9]*/ + +Obviously, if Argument Clinic didn't produce any output, +it's because it found an error in your input. +Keep fixing your errors and retrying until Argument Clinic processes your file +without complaint. + +For readability, most of the glue code has been generated to a :file:`.c.h` +file. You'll need to include that in your original :file:`.c` file, +typically right after the clinic module block:: + + #include "clinic/_pickle.c.h" + +Double-check that the argument-parsing code Argument Clinic generated +looks basically the same as the existing code. + +First, ensure both places use the same argument-parsing function. +The existing code must call either +:c:func:`PyArg_ParseTuple` or :c:func:`PyArg_ParseTupleAndKeywords`; +ensure that the code generated by Argument Clinic calls the +*exact* same function. + +Second, the format string passed in to :c:func:`!PyArg_ParseTuple` or +:c:func:`!PyArg_ParseTupleAndKeywords` should be *exactly* the same +as the hand-written one in the existing function, +up to the colon or semi-colon. + +Argument Clinic always generates its format strings +with a ``:`` followed by the name of the function. +If the existing code's format string ends with ``;``, +to provide usage help, this change is harmless --- don't worry about it. + +Third, for parameters whose format units require two arguments, +like a length variable, an encoding string, or a pointer +to a conversion function, ensure that the second argument is +*exactly* the same between the two invocations. + +Fourth, inside the output portion of the block, +you'll find a preprocessor macro defining the appropriate static +:c:type:`PyMethodDef` structure for this builtin:: + + #define __PICKLE_PICKLER_DUMP_METHODDEF \ + {"dump", (PyCFunction)__pickle_Pickler_dump, METH_O, __pickle_Pickler_dump__doc__}, + +This static structure should be *exactly* the same as the existing static +:c:type:`!PyMethodDef` structure for this builtin. + +If any of these items differ in *any way*, +adjust your Argument Clinic function specification and rerun +``Tools/clinic/clinic.py`` until they *are* the same. + +Notice that the last line of its output is the declaration +of your "impl" function. This is where the builtin's implementation goes. +Delete the existing prototype of the function you're modifying, but leave +the opening curly brace. Now delete its argument parsing code and the +declarations of all the variables it dumps the arguments into. +Notice how the Python arguments are now arguments to this impl function; +if the implementation used different names for these variables, fix it. + +Let's reiterate, just because it's kind of weird. +Your code should now look like this:: + + static return_type + your_function_impl(...) + /*[clinic end generated code: input=..., output=...]*/ + { + ... + +Argument Clinic generated the checksum line and the function prototype just +above it. You should write the opening and closing curly braces for the +function, and the implementation inside. + +Sample:: + + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ + /*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + + /*[clinic input] + _pickle.Pickler.dump + + obj: 'O' + The object to be pickled. + / + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + + PyDoc_STRVAR(__pickle_Pickler_dump__doc__, + "Write a pickled representation of obj to the open file.\n" + "\n" + ... + static PyObject * + _pickle_Pickler_dump_impl(PicklerObject *self, PyObject *obj) + /*[clinic end generated code: checksum=3bd30745bf206a48f8b576a1da3d90f55a0a4187]*/ + { + /* Check whether the Pickler was initialized correctly (issue3664). + Developers often forget to call __init__() in their subclasses, which + would trigger a segfault without this check. */ + if (self->write == NULL) { + PyErr_Format(PicklingError, + "Pickler.__init__() was not called by %s.__init__()", + Py_TYPE(self)->tp_name); + return NULL; + } + + if (_Pickler_ClearBuffer(self) < 0) { + return NULL; + } + + ... + +Remember the macro with the :c:type:`PyMethodDef` structure for this function? +Find the existing :c:type:`!PyMethodDef` structure for this +function and replace it with a reference to the macro. If the builtin +is at module scope, this will probably be very near the end of the file; +if the builtin is a class method, this will probably be below but relatively +near to the implementation. + +Note that the body of the macro contains a trailing comma; when you +replace the existing static :c:type:`!PyMethodDef` structure with the macro, +*don't* add a comma to the end. + +Sample:: + + static struct PyMethodDef Pickler_methods[] = { + __PICKLE_PICKLER_DUMP_METHODDEF + __PICKLE_PICKLER_CLEAR_MEMO_METHODDEF + {NULL, NULL} /* sentinel */ + }; + +Argument Clinic may generate new instances of ``_Py_ID``. For example:: + + &_Py_ID(new_unique_py_id) + +If it does, you'll have to run ``make regen-global-objects`` +to regenerate the list of precompiled identifiers at this point. + +Finally, compile, then run the relevant portions of the regression-test suite. +This change should not introduce any new compile-time warnings or errors, +and there should be no externally visible change to Python's behavior, +except for one difference: :py:func:`inspect.signature` run on your function +should now provide a valid signature! + +Congratulations, you've ported your first function to work with Argument Clinic! From d76bd953f758935ce84d00ea829178c213f23bdf Mon Sep 17 00:00:00 2001 From: Daniel Nylander Date: Sun, 31 Aug 2025 22:26:18 +0200 Subject: [PATCH 052/103] Add Swedish to the list of translations (#1633) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> --- documentation/translations/translating.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/documentation/translations/translating.rst b/documentation/translations/translating.rst index 0a28edad4f..ebd0dc6315 100644 --- a/documentation/translations/translating.rst +++ b/documentation/translations/translating.rst @@ -101,6 +101,9 @@ For more details about translations and their progress, see `the dashboard * - `Spanish (es) `__ - Raúl Cumplido (:github-user:`raulcd`) - :github:`GitHub ` + * - Swedish (sv) + - Daniel Nylander (:github-user:`yeager`) + - :github:`GitHub ` * - `Traditional Chinese (zh-tw) `__ - | 王威翔 Matt Wang (:github-user:`mattwang44`), | Josix Wang (:github-user:`josix`) From 53d880491cf2401bf0684237190532fa3f7bdf8a Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 1 Sep 2025 18:15:33 +0100 Subject: [PATCH 053/103] Add translating to the ``help-documenting`` page (#1648) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- documentation/help-documenting.rst | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/documentation/help-documenting.rst b/documentation/help-documenting.rst index 0b287df928..1c64b4832c 100644 --- a/documentation/help-documenting.rst +++ b/documentation/help-documenting.rst @@ -65,7 +65,14 @@ By following the steps in the :ref:`Quick Guide to Pull Requests ` to get started. Proofreading From 7ef583e2a01f771b093754a4515f8e279ffb0d7b Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Fri, 12 Sep 2025 07:56:13 +0100 Subject: [PATCH 054/103] Note how to translate `python-docs-theme` (GH-1650) Co-authored-by: Lysandros Nikolaou Co-authored-by: Rafael Fontenelle Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- documentation/translations/coordinating.rst | 4 +- documentation/translations/translating.rst | 48 ++++++++++++++++++++- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/documentation/translations/coordinating.rst b/documentation/translations/coordinating.rst index aaed4b831b..31ab4359e7 100644 --- a/documentation/translations/coordinating.rst +++ b/documentation/translations/coordinating.rst @@ -175,9 +175,7 @@ Translating Sphinx Some messages that appear in the docs must be translated in the `Sphinx project `__ (`sphinx-doc on Transifex `__) or in -the `python-docs-theme `_ -(currently this is not possible; see this -`issue `__). +the :ref:`Python Docs Sphinx Theme `. Coordinators should direct some translators there, so that the documentation is fully translated. diff --git a/documentation/translations/translating.rst b/documentation/translations/translating.rst index ebd0dc6315..af86ca8038 100644 --- a/documentation/translations/translating.rst +++ b/documentation/translations/translating.rst @@ -209,7 +209,7 @@ Some general guidelines for deciding on a translation: Dialects -------- -Some translation receive contributions from people of several different dialects, +Some translations receive contributions from people of several different dialects, understandably the language will differ. It is recommended however that translators try to keep files and sections consistent. @@ -234,6 +234,8 @@ is provided below: print(kw, ":", keywords[kw]) +.. _transifex-use: + Transifex ========= @@ -241,7 +243,7 @@ Transifex There are many translations in the `python-doc organization on Transifex `_, some of which, however, are not used or do not have a coordination team. - Confirm this is not the case before you begin translating. + Confirm that a coordination team exists before you begin translating. Several language projects use Transifex as their translation interface. Translations on Transifex are carried out via a web interface, similar to Weblate. @@ -258,6 +260,9 @@ through the following resources from the Transifex documentation: - `Starting with the basics `__: A group of documents with basic information. +Within the organization, a project for translating the +:github:`Python Docs Sphinx Theme ` can also be +found. For further information about Transifex see our `documentation `_. @@ -287,6 +292,45 @@ be the latest non-alpha branch), the translations should then be propagated by your languages coordination team. +.. _python-docs-theme-i18n: + +How do I translate the Python Docs Sphinx Theme? +------------------------------------------------ + +The Sphinx theme for the Python documentation supports localization. + +You can translate either on +`Transifex `_ +(see :ref:`translating on Transifex ` for more information) +or locally by following the steps outlined below. + +To translate locally, clone the :github:`Python Docs Sphinx Theme repository ` and run the following +commands to generate the PO files. Replace ``LANG`` with the same language code +that is used for the docs translation: + +.. code-block:: bash + + python babel_runner.py extract + python babel_runner.py init -l LANG + +The file can then be found at: + +.. code-block:: text + + python-docs-theme/locale/LANG/LC_MESSAGES/python-docs-theme.po + +After translating, submit your PO file via a pull request to the +:github:`repository `. +See our :ref:`git-boot-camp` for more information about using Git. + +To update an existing translation after source changes, run: + +.. code-block:: bash + + python babel_runner.py update # To update source for all languages + python babel_runner.py update -l LANG # To update source just for LANG + + The coordination team for my language is inactive, what do I do? ---------------------------------------------------------------- From fe9675ed3d3e58dc5f36e9bc43e7ff5ecadfdf72 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Sat, 13 Sep 2025 21:06:31 +0100 Subject: [PATCH 055/103] Translation: Mailing list has been retired (#1657) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- documentation/translations/coordinating.rst | 11 +++++------ documentation/translations/translating.rst | 6 ++---- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/documentation/translations/coordinating.rst b/documentation/translations/coordinating.rst index 31ab4359e7..13cf617b83 100644 --- a/documentation/translations/coordinating.rst +++ b/documentation/translations/coordinating.rst @@ -12,8 +12,7 @@ Communication/help channels =========================== Discussions about translations occur on the Python Docs Discord -`#translations channel `_, `translation -mailing list `_, and the +`#translations channel `_ and the `translations category `_ of the Python Discourse. For administrative issues, ping ``@python/editorial-board``. @@ -224,7 +223,8 @@ How is a coordination team chosen? Each translation team will decide on the number of coordinators. We recommend two or three coordinators, though you may begin with one. -- Coordinator requests are to be public on the `translation mailing list `_. +- Coordinator requests are to be public in the `translations category of the + Python Discourse `_. - If the given language has a native core team member, they have input on the coordinator request. - Anyone who wants to become coordinator for their native language and shows @@ -233,8 +233,8 @@ We recommend two or three coordinators, though you may begin with one. - We expect the local community to self-organize coordinators and contributors. If you have questions, please ask on the mailing list or Discourse. - If a coordinator becomes inactive or unreachable for a long - period of time, someone else can ask to be added as a primary coordinator on - the `translation mailing list `_. + period of time, someone else can ask to be added as a primary coordinator in + the `translations category of the Python Discourse `_. As a community resource, we aim to keep translations up to date with active contributors, including coordinators. @@ -294,6 +294,5 @@ for updates. .. _EB: https://python.github.io/editorial-board/ -.. _translation_ml: https://mail.python.org/mailman3/lists/translation.python.org/ .. _trans_disc: https://discuss.python.org/c/documentation/translations/ .. _docsbuild-scripts: https://github.com/python/docsbuild-scripts diff --git a/documentation/translations/translating.rst b/documentation/translations/translating.rst index af86ca8038..7ed46b1bd2 100644 --- a/documentation/translations/translating.rst +++ b/documentation/translations/translating.rst @@ -125,9 +125,8 @@ If there is already a repository for your language team (there may be links to Telegrams/Discords in the ``README``), join and introduce yourself. Your fellow translators will be more than happy to help! General discussions about translations occur on the Python Docs Discord -`#translations channel `_, `translation -mailing list `_, and the `translations category `_ -of the Python Discourse. +`#translations channel `_ and the +`translations category `_ of the Python Discourse. .. _translation-style-guide: @@ -339,6 +338,5 @@ If you would like to coordinate, open a pull request in the at the top of this page, and ping ``@python/editorial-board``. -.. _translation_ml: https://mail.python.org/mailman3/lists/translation.python.org/ .. _discourse: https://discuss.python.org/c/documentation/translations/ .. _tx: https://explore.transifex.com/python-doc/python-newest/ From 759a7c85757bff3690486c85c2e907b55c9fe99c Mon Sep 17 00:00:00 2001 From: Vessel9817 <151808241+Vessel9817@users.noreply.github.com> Date: Mon, 15 Sep 2025 10:21:41 +0000 Subject: [PATCH 056/103] Added dependency for containerized Ubuntu installation (GH-1655) --- getting-started/setup-building.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index f6a6f6a943..39125c35ef 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -797,7 +797,8 @@ some of CPython's modules (for example, ``zlib``). $ sudo apt-get install build-essential gdb lcov pkg-config \ libbz2-dev libffi-dev libgdbm-dev libgdbm-compat-dev liblzma-dev \ libncurses5-dev libreadline6-dev libsqlite3-dev libssl-dev \ - lzma lzma-dev tk-dev uuid-dev zlib1g-dev libmpdec-dev libzstd-dev + lzma lzma-dev tk-dev uuid-dev zlib1g-dev libmpdec-dev libzstd-dev \ + inetutils-inetd Note that Debian 12 and Ubuntu 24.04 do not have the ``libmpdec-dev`` package. You can safely remove it from the install list above and the From 23d4a35dec87f0224d28401af6be8e033944d5c7 Mon Sep 17 00:00:00 2001 From: Paul Ganssle <1377457+pganssle@users.noreply.github.com> Date: Wed, 17 Sep 2025 13:44:31 +0100 Subject: [PATCH 057/103] Add pganssle to zoneinfo experts list (#1658) --- core-team/experts.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/core-team/experts.rst b/core-team/experts.rst index 74ce892f74..2fb37cb3f9 100644 --- a/core-team/experts.rst +++ b/core-team/experts.rst @@ -251,6 +251,7 @@ xmlrpc zipapp pfmoore zipfile alanmcintyre^, serhiy-storchaka, Yhg1s, gpshead zipimport Yhg1s* +zoneinfo pganssle ==================== ============================================= From 87c99bc0b0aa84d851c34726d36579dd5c2f85cf Mon Sep 17 00:00:00 2001 From: adam j hartz Date: Wed, 17 Sep 2025 10:33:14 -0400 Subject: [PATCH 058/103] Update documentation for Emscripten Builds (#1621) Co-authored-by: Russell Keith-Magee Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- getting-started/setup-building.rst | 31 +++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 39125c35ef..2cf30d1e71 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -511,13 +511,26 @@ The simplest way to install the Emscripten compiler is: # Install Emscripten git clone https://github.com/emscripten-core/emsdk - ./emsdk/emsdk install 4.0.5 - ./emsdk/emsdk activate 4.0.5 + ./emsdk/emsdk install 4.0.12 + ./emsdk/emsdk activate 4.0.12 source ./emsdk/emsdk_env.sh -Updating the Emscripten compiler version often causes breakages. For the best -compatibility, use the Emscripten version suggested in the cpython repository in -``Tools/wasm/README.md``. +Updating the Emscripten compiler version can cause breakages. For the best +compatibility, use the appropriate Emscripten version based on the version of +CPython you're building: + +* For building CPython 3.14, use ``emsdk`` version ``4.0.12``. +* For building the main branch of the CPython repository, you may wish to use + ``latest`` instead of a specific version. + +It is possible (but not necessary) to enable ``ccache`` for Emscripten builds +by setting the ``EM_COMPILER_WRAPPER`` environment, but this step will only +take effect if it is done **after** ``emsdk_env.sh`` is sourced (otherwise, the +sourced script removes the environment variable): + +.. code-block:: sh + + export EM_COMPILER_WRAPPER=ccache Building for Emscripten requires doing a cross-build where you have a *build* Python to help produce an Emscripten build of CPython. This means you build @@ -526,8 +539,8 @@ another that's the build you ultimately care about (that is, the build Python is not meant for use by you directly, only the build system). The easiest way to get a debug build of CPython for Emscripten is to use the -``Tools/wasm/emscripten build`` command (which should be run with a recent -version of Python you have installed on your machine): +``Tools/wasm/emscripten build`` command, which should be run with a recent +version of Python (3.13 or newer) already installed on your machine: .. code-block:: shell @@ -545,6 +558,7 @@ is a convenience wrapper around the following commands: python Tools/wasm/emscripten configure-build-python --quiet -- --config-cache --with-pydebug python Tools/wasm/emscripten make-build-python --quiet python Tools/wasm/emscripten make-libffi --quiet + python Tools/wasm/emscripten make-mpdec --quiet python Tools/wasm/emscripten configure-host --quiet -- --config-cache python Tools/wasm/emscripten make-host --quiet @@ -572,6 +586,9 @@ used in ``python.sh``: make -C cross-build/wasm32-emscripten/build/python/ test +Additional instructions for running the resulting builds (through Node.js and/or +through web browsers) are available in the CPython repository at +:cpy-file:`Tools/wasm/README.md`. .. _Emscripten: https://emscripten.org/ .. _WebAssembly: https://webassembly.org From f3cf8fa68cc7a9b2356f8cba72f08a156a0b172b Mon Sep 17 00:00:00 2001 From: Seth Michael Larson Date: Tue, 30 Sep 2025 12:38:44 +0000 Subject: [PATCH 059/103] Add runbook for code signing certificate reports to PSRT (#1651) Co-authored-by: Steve Dower Co-authored-by: Ezio Melotti Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- developer-workflow/psrt.rst | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/developer-workflow/psrt.rst b/developer-workflow/psrt.rst index 9d9019dbfd..cf5acd2b70 100644 --- a/developer-workflow/psrt.rst +++ b/developer-workflow/psrt.rst @@ -93,6 +93,40 @@ severity, advisory text, and fixes. 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. +Handling code signing certificate reports +----------------------------------------- + +Python signs binaries using Azure Trusted Signing and Apple Developer ID +certificates. If a code signing certificate is reported as "compromised" or +"malware signed with certificate", the Python Security Response Team must +request the following information from the reporter: + +* Checksum(s) of binaries signed by certificate. +* Signature(s) of binaries signed by certificate. + +To avoid unnecessary user confusion and churn around revoking code signing +certificates, any reports **must be verifiable independently by the PSRT before +taking destructive actions**, such as revoking certificates. With this +information the PSRT can take investigative steps to verify the report, such as: + +* Downloading and checking artifacts from the associated Azure Pipelines + executions against the reported list of checksums. +* Verifying the validity of the signatures. `Past reports + `__ have contained signatures that + purported to be from Python code signing certificates, but were not valid. +* Checking the Azure Pipelines and Azure Trusted Signing audit logs for signs of + compromise. + +If any signs of compromise or incorrectly signed binaries are discovered by the +PSRT, only then will certificates be revoked and an advisory published. +If compromise is reported, the following non-destructive actions can be taken by +the PSRT without verifying the reported information as a precaution, if +relevant: + +* Rotating secrets associated with code signing (``TrustedSigningSecret`` for + Azure Trusted Publishing). +* Resetting passwords for accounts with access to signing certificates. + Template responses ------------------ From 2f1f3460cb03c432ca8cf85a94f0d0fffa7ac500 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Wed, 1 Oct 2025 17:47:23 -0700 Subject: [PATCH 060/103] Update Savannah's last name (#1663) --- core-team/core-team.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-team/core-team.csv b/core-team/core-team.csv index ab87c50fa8..8c46254931 100644 --- a/core-team/core-team.csv +++ b/core-team/core-team.csv @@ -3,7 +3,7 @@ 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,, +Savannah Ostrowski,savannahostrowski,2024-11-13,, Matt Page,mpage,2024-10-10,, Kirill Podoprigora,Eclips4,2024-09-20,, Ned Batchelder,nedbat,2024-07-16,, From 99e8ba57b6e111194b38715df550b7d28625ecad Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 7 Oct 2025 17:28:37 +0300 Subject: [PATCH 061/103] Latest and greatest (3.14.0) (#1665) --- include/release-cycle.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/release-cycle.json b/include/release-cycle.json index 214871b64a..abdcd1869a 100644 --- a/include/release-cycle.json +++ b/include/release-cycle.json @@ -10,7 +10,7 @@ "3.14": { "branch": "3.14", "pep": 745, - "status": "prerelease", + "status": "bugfix", "first_release": "2025-10-07", "end_of_life": "2030-10", "release_manager": "Hugo van Kemenade" From 622083ee26ef094eed092ee9aac42ad40cb303c4 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Sat, 18 Oct 2025 09:58:51 +0100 Subject: [PATCH 062/103] Add a section on building a docs translation (#1661) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Co-authored-by: Rafael Fontenelle Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- documentation/start-documenting.rst | 2 ++ documentation/translations/translating.rst | 26 ++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/documentation/start-documenting.rst b/documentation/start-documenting.rst index 7515992ec9..7865f125d6 100644 --- a/documentation/start-documenting.rst +++ b/documentation/start-documenting.rst @@ -162,6 +162,8 @@ To build the docs as HTML, run: * Replace ``html`` with ``htmllive`` to rebuild the docs, start a local server, and automatically reload the page in your browser when you make changes to reST files (Unix only). + * To build a documentation translation, see this + :ref:`guide `. It is also possible to build only certain pages of the documentation in order to save time during the build process. Following is an example for building two diff --git a/documentation/translations/translating.rst b/documentation/translations/translating.rst index 7ed46b1bd2..9295373557 100644 --- a/documentation/translations/translating.rst +++ b/documentation/translations/translating.rst @@ -283,6 +283,32 @@ Some useful resources: Translation FAQ =============== +.. _docs-build-translation: + +How do I build a docs translation? +---------------------------------- + +To build a documentation translation for a specific language, +you need to have Python installed and a +local copy of the :github:`CPython repository ` and +translation repository (see table above). The PO files must be placed +in a :samp:`locales/{LANG}/LC_MESSAGES/` (replacing :samp:`{LANG}` with the translation's +language code) folder inside the :file:`Doc/` directory of the CPython repository. + +You can then build with :ref:`make ` by adding +a ``SPHINXOPTS="-D language=LANG"`` variable before the target +or by using :ref:`Sphinx directly ` and adding a +``-D language=LANG`` option. For example: + +.. code-block:: bash + + # Build the HTML format of the Polish translation using make + make SPHINXOPTS="-D language=pl" html + + # Build the HTML format of the Romanian translation using Sphinx directly + python -m sphinx -b html . build/html -D language=ro + + Which version of the Python documentation should I work on? ----------------------------------------------------------- From 0ea8758e7ddc07b5a3b269c6dd531d204e1d710d Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Mon, 20 Oct 2025 06:35:20 -0400 Subject: [PATCH 063/103] Add more to Changing Python (#1671) * Add more to Changing Python * simple tweaks from review * typo * more changes from review * review tweaks * almost always get at least some push-back * a few tweaks * clearer opening paragraph * don't re-wrap, and avoid two-space * balance brevity and detail * clarify that it's Python as language we're talking about * peps need a sponsor from the core team * changes from tim hoffman's review * don't use bold for abbreviations --- developer-workflow/index.rst | 2 +- developer-workflow/lang-changes.rst | 190 ++++++++++++++++++++-------- 2 files changed, 140 insertions(+), 52 deletions(-) diff --git a/developer-workflow/index.rst b/developer-workflow/index.rst index e73927f1dd..9919398e62 100644 --- a/developer-workflow/index.rst +++ b/developer-workflow/index.rst @@ -8,11 +8,11 @@ Development workflow :maxdepth: 5 communication-channels + lang-changes development-cycle stdlib extension-modules c-api - lang-changes grammar porting sbom diff --git a/developer-workflow/lang-changes.rst b/developer-workflow/lang-changes.rst index 52aabb15dd..0b2c613fa7 100644 --- a/developer-workflow/lang-changes.rst +++ b/developer-workflow/lang-changes.rst @@ -1,37 +1,43 @@ .. _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. +Changing Python +=============== +On occasion people come up with an idea for changing or improving the Python +language or standard library. +This page explains how to propose changes and what to expect during the +process. -What qualifies + +Considerations -------------- -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 + +First, understand that changes to Python +are difficult to make. When the language changes, +**every** Python programmer 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 +need to be learned. Changes to Python 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`. +Backward compatibility is a significant concern. Existing Python code has to +continue to work. There are exceptions to this rule, but they are very rare +and are only allowed when the benefits of the change greatly outweigh the costs +of breaking existing code. -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. +Because of the seriousness of changing the language, any change must be +beneficial to many Python users. If the change only helps 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 discuss it in +the `Ideas category in Discourse `_. You can also look in Python's standard +library to find examples of code which would benefit from your proposed change. +.. important:: + For all of these reasons, most proposed changes to Python are rejected. This + doesn't mean you shouldn't suggest them. It can be useful to explore + alternatives and to get feedback from the community. Just be aware that + getting a change accepted is difficult. Don't take it personally. .. index:: single: PEP process @@ -41,25 +47,107 @@ Council can truly classify something as Pythonic, you can read the 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. +Proposing a change involves the following steps: + +- Describe your idea in detail. + +- Engage in discussion about the idea. + +- Rarely, the idea will advance to a formal proposal stage. + + +Describe your idea +^^^^^^^^^^^^^^^^^^ + +The `Ideas category in Discourse `_ is specifically intended for discussion +of new features and language changes. Make your proposal as a `new topic +`_ there. + +Your proposal needs to be **detailed**. Describe the change you want to make, +why you want to make it, and what benefits it will bring to Python users. Be +specific. Show that you have considered the effect of the change on existing +code. + +Some things you should **not** do: + +- **Don't** format your idea as a Python Enhancement Proposal (PEP). + It's good to use the PEP template as a guide for what information to include, + but don't try to write a full PEP until the idea has been accepted for + further consideration. + +- **Don't** create a list of proposed changes. Each idea needs its own + discussion. Proposing a change is significant work. You will need to spend + time on each proposal. A tossed-off list will not be taken seriously. + +When justifying your idea, these are **not good reasons** to make a change: + +- "Other languages work this way." Languages are different. What works well + in one language may not work well in Python, or Python may already have a + way to do a similar thing. + +- "It would be nice." This is too vague. Be specific about the benefits + your change will bring, and consider the costs as well. + +Some things you **should** do: + +- Research whether your idea has been proposed before. There are many + suggestions that have been made and rejected in the past. If your idea has a + history, read the discussion to see why it was rejected. Previously rejected + ideas are especially unlikely to get accepted. If you can address the + concerns raised in the previous discussion, mention that in your proposal. + +- Read other ideas to see how they are presented. This will help you flesh out + your proposal. + +- Read other ideas to understand the kinds of concerns that are raised and + objections that must be answered. Your proposal will be stronger if you can + address these concerns up front. + +- Provide enough detail to fully explain your idea, and to show that you have + considered all the implications of the change. Strike the right balance + between brevity and completeness. A shorter proposal will be easier to + discuss, so long as it includes all the necessary information. + + +Engage in discussion +^^^^^^^^^^^^^^^^^^^^ + +Once you post your proposal, people will respond. You need to continue +the discussion, answer questions, and address objections. This is an important +part of the process. Other people's perspectives will help explore the full +impact of the idea and find strengths or weaknesses you may not have +considered. + +You will almost always get at least some push-back. Don't be disappointed, +and don't take it personally. +As the long list of :pep:`Withdrawn and Rejected PEPs +<0#rejected-superseded-and-withdrawn-peps>` in the :pep:`PEP Index <0>` +attests, and as befits a mature programming language, getting significant +changes into Python isn't a simple task. + +Engage in good faith. The goal of the discussion is to find the best balance +between competing concerns. If your idea has merit, the discussion will help +refine it and make it stronger. If your idea has flaws, the discussion will +help identify them so you can address them or move on. Keep the discussion +productive and focused on the issues, not on personalities. + +It is especially useful to discuss with core team members since +they know the language and design considerations well. +If your proposal makes it to the PEP stage, +you'll need a core team member as a sponsor. +Sometimes they will differ in opinion, or merely be unconvinced. When there +isn't a clear positive sentiment, the `Status Quo Wins a Stalemate`_. + +Even if your idea is not accepted, the discussion can help you and others +understand the design of Python better, and help inform future proposals. -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`_. +Formal proposal +^^^^^^^^^^^^^^^ -For some examples on language changes that were accepted, -see `Justifying Python Language Changes`_. +If the idea gets positive discussion, 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`. Congratulations! .. index:: PEP process @@ -69,20 +157,20 @@ see `Justifying Python Language Changes`_. 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. +Once you have a proposal which will appeal to +the general Python community, you can begin the PEP +process to officially propose the change. +This starts with finding a sponsor from the core team. +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. +If the PEP is accepted, then your language change will be introduced in a +future 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 +.. _ideas: https://discuss.python.org/c/ideas/6 +.. _Status Quo Wins a Stalemate: https://www.curiousefficiency.org/posts/2011/02/status-quo-wins-stalemate/ From 2b075b9d94309032418405713dcbca07ff36e69f Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Sat, 18 Oct 2025 19:58:14 +0100 Subject: [PATCH 064/103] Commit --- documentation/translations/translating.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/documentation/translations/translating.rst b/documentation/translations/translating.rst index 9295373557..7a314e017c 100644 --- a/documentation/translations/translating.rst +++ b/documentation/translations/translating.rst @@ -76,9 +76,6 @@ For more details about translations and their progress, see `the dashboard - :github:`GitHub `, `Transifex `_, `original announcement `__ - * - Portuguese (pt) - - Gustavo Toffo - - * - `Brazilian Portuguese (pt-br) `__ - | Rafael Fontenelle (:github-user:`rffontenelle`), | Marco Rougeth (:github-user:`rougeth`) From 024490ce11d58f8b5165716adbd7058e3e0b0701 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Sun, 26 Oct 2025 16:36:30 +0000 Subject: [PATCH 065/103] Fix typo in Translations Doc (#1673) --- documentation/translations/translating.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/translations/translating.rst b/documentation/translations/translating.rst index 7a314e017c..17fe000b49 100644 --- a/documentation/translations/translating.rst +++ b/documentation/translations/translating.rst @@ -272,7 +272,7 @@ Some useful resources: own guide for how to do this, but this can provide useful tips. - `Translation issues & improvements `_ GitHub project: This project contains issues and pull requests that aim to improve - the Python documenation for translations. + the Python documentation for translations. - `Python Pootle archive `_: Pootle is no longer used for translation. Contains translations for old Python versions. From 49b4fe70ad91a1568012b408c4e5b20629054912 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 27 Oct 2025 15:53:15 +0200 Subject: [PATCH 066/103] Default EOL to end of month in SVG (#1672) --- _tools/generate_release_cycle.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/_tools/generate_release_cycle.py b/_tools/generate_release_cycle.py index 63d98cfced..dd0a3a7c65 100644 --- a/_tools/generate_release_cycle.py +++ b/_tools/generate_release_cycle.py @@ -3,6 +3,7 @@ from __future__ import annotations import argparse +import calendar import csv import datetime as dt import json @@ -18,10 +19,17 @@ def csv_date(date_str: str, now_str: str) -> str: return date_str -def parse_date(date_str: str) -> dt.date: +def parse_date(date_str: str, *, last: bool = False) -> 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") + if last: + # Last day of month + year, month = map(int, date_str.split("-")) + last_day = calendar.monthrange(year, month)[1] + return dt.date(year, month, last_day) + else: + return dt.date.fromisoformat(date_str + "-01") + return dt.date.fromisoformat(date_str) @@ -46,7 +54,7 @@ def __init__(self, *, limit_to_active=False, special_py27=False) -> None: 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"]) + version["end_of_life_date"] = parse_date(version["end_of_life"], last=True) self.cutoff = min(ver["first_release_date"] for ver in self.versions.values()) From e5f12da3e8ecdefa7ca61d261f55fac88493bf15 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Thu, 30 Oct 2025 09:26:56 -0700 Subject: [PATCH 067/103] Document that there are alternative dev containers (#1675) Purposefully didn't go into too much detail as it's a bit of an advanced topic. As well, fix a warning being triggered from `conf.py`. --- conf.py | 4 +-- getting-started/setup-building.rst | 42 +++++++++++++++++++++--------- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/conf.py b/conf.py index 5050f5c45c..0f6a820d88 100644 --- a/conf.py +++ b/conf.py @@ -225,11 +225,11 @@ 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 = [ +ogp_custom_meta_tags = ( '', '', '', -] +) # Strip the dollar prompt when copying code # https://sphinx-copybutton.readthedocs.io/en/latest/use.html#strip-and-configure-input-prompts-for-code-cells diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 2cf30d1e71..d86800f67e 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -386,24 +386,26 @@ compiler just like building for :ref:`Unix ` as well as: 1. A C compiler that can target WebAssembly (for example, `WASI SDK`_) 2. A WASI host/runtime (for example, Wasmtime_) -All of this is provided in the :ref:`devcontainer `. You can -also use what's installed in the container as a reference of what versions of -these tools are known to work. +All of this is provided in the WASI :ref:`dev container ` +(which you can select as an alternative container when using a +:ref:`codespace `). You can also use what's +installed in the container as a reference of what versions of these tools are +known to work. .. note:: CPython has only been verified with the certain tools for WASI. Using other compilers, hosts, or WASI versions *should* work, but the tools - and their versions specified in the container are tested via a - :ref:`buildbot `. + and their versions specified in the container and build scripts are + tested via a :ref:`buildbot `. Building for WASI requires doing a cross-build where you have a *build* Python to help produce a WASI build of CPython (technically it's a "host x host" cross-build because the build Python is also the target Python while the host build is the WASI build). This means you effectively build CPython twice: once to have a version of Python for the build system to use and another that's the -build you ultimately care about (that is, the build Python is not meant for use by -you directly, only the build system). +build you ultimately care about (that is, the build Python is not meant for use +by you directly, only the build system). The easiest way to get a debug build of CPython for WASI is to use the ``Tools/wasm/wasi.py build`` command (which should be run w/ a recent version of @@ -1206,10 +1208,24 @@ You first need to navigate to the Then you will need to: -1. Press the ``,`` key to launch the codespace setup screen for the current - branch (alternatively, click the green :guilabel:`Code` button and choose - the ``codespaces`` tab and then press the - green :guilabel:`Create codespace on main` button). +1. Launch the codespace + + - Press the ``,`` key to launch the codespace setup screen for the current + branch + + - For the default dev container (which is what you very likely want), click + the green :guilabel:`Create new codespace` button + - For alternative containers, click :guilabel:`Change options` and + choose the appropriate container + + - Alternatively, click the green :guilabel:`Code` button and choose + the :guilabel:`codespaces` tab + + - For the default dev container (which is what you very likely want), click + the green :guilabel:`Create codespace on main` button + - For alternative containers, go to the :guilabel:`…` menu and choose + :guilabel:`New with options…` + 2. A screen should appear that lets you know your codespace is being set up. (Note: Since the CPython devcontainer is provided, codespaces will use the configuration it specifies.) @@ -1250,7 +1266,9 @@ This is meant for users who have (or want to get) some experience with containers. These instructions assume a Unix-like environment with `Docker `__ or `Podman `__ -installed. +installed. The instructions also assume you want the default dev container; +tweak the commands as appropriate if you want to use an alternative container +(e.g. the WASI dev container). .. _devcontainer-image: From acedd6c53cabda272e29b1f92b2304eb310cbac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Fri, 31 Oct 2025 20:48:46 +0100 Subject: [PATCH 068/103] Mark 3.9 as EOL (#1676) --- include/release-cycle.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/release-cycle.json b/include/release-cycle.json index abdcd1869a..26436bf003 100644 --- a/include/release-cycle.json +++ b/include/release-cycle.json @@ -50,9 +50,9 @@ "3.9": { "branch": "3.9", "pep": 596, - "status": "security", + "status": "end-of-life", "first_release": "2020-10-05", - "end_of_life": "2025-10", + "end_of_life": "2025-10-31", "release_manager": "Łukasz Langa" }, "3.8": { From 710b132ddd236c72d5daee4e596bab22bd761c15 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Nov 2025 12:08:50 +0800 Subject: [PATCH 069/103] Bump sphinx-lint from 1.0.0 to 1.0.1 (#1677) Bumps [sphinx-lint](https://github.com/sphinx-contrib/sphinx-lint) from 1.0.0 to 1.0.1. - [Release notes](https://github.com/sphinx-contrib/sphinx-lint/releases) - [Commits](https://github.com/sphinx-contrib/sphinx-lint/compare/v1.0.0...v1.0.1) --- updated-dependencies: - dependency-name: sphinx-lint dependency-version: 1.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index bad565b8c9..033fac6495 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ furo>=2022.6.4 jinja2 sphinx-autobuild>=2024.9.19 sphinx-inline-tabs>=2023.4.21 -sphinx-lint==1.0.0 +sphinx-lint==1.0.1 sphinx-notfound-page>=1.0.0 sphinx_copybutton>=0.3.3 sphinxext-opengraph>=0.7.1 From 3029299fd2ced486980e1158e99859b89a88936b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Nov 2025 12:09:49 +0800 Subject: [PATCH 070/103] Update sphinx requirement from ~=8.2.1 to ~=8.2.3 (#1678) Updates the requirements on [sphinx](https://github.com/sphinx-doc/sphinx) to permit the latest version. - [Release notes](https://github.com/sphinx-doc/sphinx/releases) - [Changelog](https://github.com/sphinx-doc/sphinx/blob/master/CHANGES.rst) - [Commits](https://github.com/sphinx-doc/sphinx/compare/v8.2.1...v8.2.3) --- updated-dependencies: - dependency-name: sphinx dependency-version: 8.2.3 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 033fac6495..9d124749aa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,4 @@ sphinx-notfound-page>=1.0.0 sphinx_copybutton>=0.3.3 sphinxext-opengraph>=0.7.1 sphinxext-rediraffe -Sphinx~=8.2.1 +Sphinx~=8.2.3 From 314bb55c322b6db229a8c28cb1a3a4f13e264e37 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Thu, 6 Nov 2025 11:32:56 +0200 Subject: [PATCH 071/103] Remove outdated whitespace checks from patchcheck list (#1592) Co-authored-by: Ezio Melotti --- getting-started/pull-request-lifecycle.rst | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index fe810e90ff..9a0bbf2e86 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -277,10 +277,6 @@ On *Windows* (after any successful build): The automated checklist runs through: -* Are there any whitespace problems in Python files? - (using :cpy-file:`Tools/patchcheck/reindent.py`) -* Are there any whitespace problems in C files? -* Are there any whitespace problems in the documentation? * Has the documentation been updated? * Has the test suite been updated? * Has an entry under ``Misc/NEWS.d/next`` been added? @@ -290,10 +286,8 @@ The automated checklist runs through: * Has ``configure`` been regenerated, if necessary? * Has ``pyconfig.h.in`` been regenerated, if necessary? -The automated checks don't actually *answer* all of these -questions. Aside from the whitespace checks, the tool is -a memory aid for the various elements that can go into -making a complete pull request. +This will help you remember things that you need +to check before submitting a complete pull request. .. _good-commits: From 6cc1e511a0efdd8e05e9ac4c625b9d9369163ffd Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Thu, 6 Nov 2025 11:34:10 +0200 Subject: [PATCH 072/103] Why do I need to sign the CLA again? (#1680) --- getting-started/pull-request-lifecycle.rst | 36 +++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index 9a0bbf2e86..3d74e84406 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -362,6 +362,40 @@ Here are the steps needed in order to sign the CLA: .. _contributor form: https://www.python.org/psf/contrib/contrib-form/ .. _Python Software Foundation: https://www.python.org/psf-landing/ +Why do I need to sign the CLA again? +------------------------------------ + +Sometimes the CLA bot asks you to sign the CLA for a backport PR, +when you've already signed it for the original PR. +This is because you need to sign the CLA for all the email addresses you commit +with. + +This can happen when you've `configured your Git client +`__ +with one email address, and signed the CLA with this, but have +`configured your GitHub account `__ +with another primary email +(often this is the private ``id+username@users.noreply.github.com`` address). + +1. In the original PR, the CLA bot verifies all the emails in the commits have + signed the CLA. + +2. We then squash merge the PR, which creates a single new commit using the + author's primary email. This can be different from the one you originally + committed with. + +3. Backports often only have this new single commit. + The CLA bot then checks if the primary email has signed the CLA. + +4. The solution is to click the :guilabel:`CLA not signed -- click to sign` + button in the backport PR. + +.. tip:: Run ``git config user.email`` to see your Git client config, + and append ``.patch`` to a PR URL to see the emails used for its commits: + + * https://github.com/python/cpython/pull/1 + * https://github.com/python/cpython/pull/1.patch + Submitting ========== @@ -541,7 +575,7 @@ affects other PRs. If you still don't see where the failure originates from, check for a "This branch is out-of-date with the base branch" sign next to the -list of executed checks. Clicking "Update branch" next to this message +list of executed checks. Clicking :guilabel:`Update branch` next to this message will merge in the latest changes from the base branch into the PR. If this still doesn't help with the failure on the PR, you can try From 006ad0e43c837e2e3382ed4a42d49a7d8128dbb6 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Fri, 7 Nov 2025 00:12:31 +0200 Subject: [PATCH 073/103] Update CPython repo admins (#1682) --- developer-workflow/development-cycle.rst | 43 ++++++++++++------------ 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/developer-workflow/development-cycle.rst b/developer-workflow/development-cycle.rst index c8b2d5ebf7..7f82ea42f0 100644 --- a/developer-workflow/development-cycle.rst +++ b/developer-workflow/development-cycle.rst @@ -332,27 +332,28 @@ Administrator of the repository. Current administrators ^^^^^^^^^^^^^^^^^^^^^^ -+-------------------+----------------------------------------------------------+-----------------+ -| Name | Role | GitHub Username | -+===================+==========================================================+=================+ -| Hugo van Kemenade | Python 3.14 and 3.15 Release Manager | hugovk | -+-------------------+----------------------------------------------------------+-----------------+ -| Thomas Wouters | Python 3.12 and 3.13 Release Manager | Yhg1s | -+-------------------+----------------------------------------------------------+-----------------+ -| Pablo Galindo | Python 3.10 and 3.11 Release Manager, | pablogsal | -| | Maintainer of buildbot.python.org | | -+-------------------+----------------------------------------------------------+-----------------+ -| Łukasz Langa | Python 3.9 Release Manager, | ambv | -| | PSF CPython Developer in Residence 2021-present | | -+-------------------+----------------------------------------------------------+-----------------+ -| Brett Cannon | | brettcannon | -+-------------------+----------------------------------------------------------+-----------------+ -| Ezio Melotti | Maintainer of bugs.python.org GitHub webhook integration | ezio-melotti | -+-------------------+----------------------------------------------------------+-----------------+ -| Mariatta Wijaya | Maintainer of bedevere, blurb_it and miss-islington | Mariatta | -+-------------------+----------------------------------------------------------+-----------------+ -| Seth Larson | PSF Security Developer-in-Residence | sethmlarson | -+-------------------+----------------------------------------------------------+-----------------+ ++--------------------+----------------------------------------------------------+-------------------+ +| Name | Role | GitHub Username | ++====================+==========================================================+===================+ +| Savannah Ostrowski | Python 3.16 and 3.17 Release Manager | savannahostrowski | ++--------------------+----------------------------------------------------------+-------------------+ +| Hugo van Kemenade | Python 3.14 and 3.15 Release Manager | hugovk | ++--------------------+----------------------------------------------------------+-------------------+ +| Thomas Wouters | Python 3.12 and 3.13 Release Manager | Yhg1s | ++--------------------+----------------------------------------------------------+-------------------+ +| Pablo Galindo | Python 3.10 and 3.11 Release Manager, | pablogsal | +| | Maintainer of buildbot.python.org | | ++--------------------+----------------------------------------------------------+-------------------+ +| Łukasz Langa | PSF CPython Developer in Residence 2021-present | ambv | ++--------------------+----------------------------------------------------------+-------------------+ +| Brett Cannon | | brettcannon | ++--------------------+----------------------------------------------------------+-------------------+ +| Ezio Melotti | Maintainer of bugs.python.org GitHub webhook integration | ezio-melotti | ++--------------------+----------------------------------------------------------+-------------------+ +| Mariatta Wijaya | Maintainer of bedevere, blurb_it and miss-islington | Mariatta | ++--------------------+----------------------------------------------------------+-------------------+ +| Seth Larson | PSF Security Developer-in-Residence | sethmlarson | ++--------------------+----------------------------------------------------------+-------------------+ Repository release manager role policy ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 01c6b879da50f7d75eedfd2f808bcc4d6a6444c6 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Sun, 9 Nov 2025 13:09:46 +0900 Subject: [PATCH 074/103] generative-ai: Add anti pattern example (gh-1679) * generative-ai: Add anti pattern example * reformat * Address code review * Add one more case * reformat * Address code review * fix * Update heading and use sentence case Co-authored-by: Ned Batchelder * Improve wording and spacing for principles Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Carol Willing --------- Co-authored-by: Carol Willing Co-authored-by: Ned Batchelder Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- getting-started/generative-ai.rst | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/getting-started/generative-ai.rst b/getting-started/generative-ai.rst index 90fe020f3f..e4aa3e7586 100644 --- a/getting-started/generative-ai.rst +++ b/getting-started/generative-ai.rst @@ -4,10 +4,10 @@ Generative AI ============= -Generative AI has evolved rapidly over the past decade and will continue in the future. -Using generative AI and large language models (LLMs) can be helpful tools for contributors. -Their overuse can also be problematic, such as generation of incorrect code, inaccurate documentation, and unneeded code churn. -Discretion, good judgement, and critical thinking **must** be used when opening issues and pull requests. +Generative AI tools have evolved rapidly, and their suggested results can be helpful. As with using any tool, the resulting contribution is +the responsibility of the contributor. We value good code, concise accurate documentation, and avoiding unneeded code +churn. Discretion, good judgment, and critical thinking are the foundation of all good contributions, regardless of the +tools used in their creation. Acceptable uses =============== @@ -24,3 +24,17 @@ Unacceptable uses Maintainers may close issues and PRs that are not useful or productive, including those that are fully generated by AI. If a contributor repeatedly opens unproductive issues or PRs, they may be blocked. + +Considerations for success +========================== +- While AI assisted tools such as autocompletion can enhance productivity, they sometimes rewrite entire code blocks instead of making small, focused edits. + This can make it more difficult to review changes and to fully understand both the original intent of the code and the rationale behind the new modifications. + Maintaining consistency with the original code helps preserve clarity, traceability, and meaningful reviews and also helps us avoid unnecessary code churn. +- Sometimes AI assisted tools make failing unit tests pass by altering or bypassing the tests rather than addressing the underlying problem in the code. + Such changes do not represent a real fix. Authors must review the work done by AI tooling in detail to ensure it actually makes sense before proposing it as a PR. +- Keep the following principles for the quality of your contributions in mind whether you use generative AI or not: + + - Consider whether the change is necessary + - Make minimal, focused changes + - Follow existing coding style and patterns + - Write tests that exercise the change From 587de2e3475e8a821f54d097d0c90e5b230f8d69 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 9 Nov 2025 09:53:12 +0200 Subject: [PATCH 075/103] Remove 3.9 from tab (#1684) --- getting-started/setup-building.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index d86800f67e..20ca9e4128 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -876,9 +876,9 @@ some of CPython's modules (for example, ``zlib``). ./configure --with-pydebug \ --with-openssl="$(brew --prefix openssl@3)" - .. tab:: Python 3.9-3.10 + .. tab:: Python 3.10 - For Python 3.9 and 3.10:: + For Python 3.10:: $ CPPFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \ LDFLAGS="-L$(brew --prefix gdbm)/lib -L$(brew --prefix xz)/lib" \ From f9c39544619931b86e5225a476708aa9793cfbaa Mon Sep 17 00:00:00 2001 From: Colin Marquardt Date: Mon, 10 Nov 2025 21:06:01 +0100 Subject: [PATCH 076/103] Add the ``:deco:`` role (#1686) --- documentation/markup.rst | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/documentation/markup.rst b/documentation/markup.rst index ce9ba648d5..cad0b4d9c3 100644 --- a/documentation/markup.rst +++ b/documentation/markup.rst @@ -544,8 +544,8 @@ The directives are: Set name of the decorated function to *name*. - There is no ``deco`` role to link to a decorator that is marked up with - this directive; rather, use the ``:func:`` role. + To link to a decorator that is marked up with this directive, + use the ``:deco:`` role. .. describe:: class @@ -806,6 +806,10 @@ a matching identifier is found: The name of an exception. A dotted name may be used. +.. describe:: deco + + The name of a decorator. A dotted name may be used. + The name enclosed in this markup can include a module name and/or a class name. For example, ``:func:`filter``` could refer to a function named ``filter`` in the current module, or the built-in function of that name. In contrast, From ebd81192fcd2a1f379e764711998a76ade8f4320 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Wed, 12 Nov 2025 10:39:23 -0800 Subject: [PATCH 077/103] Update target triple for WASI (#1683) --- getting-started/setup-building.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 20ca9e4128..c6cf6c9fa1 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -424,7 +424,7 @@ Python you have installed on your machine): python3 Tools/wasm/wasi.py build --quiet -- --config-cache --with-pydebug That single command will configure and build both the build Python and the -WASI build in ``cross-build/build`` and ``cross-build/wasm32-wasi``, +WASI build in ``cross-build/build`` and ``cross-build/wasm32-wasip1``, respectively. You can also do each configuration and build step separately; the command above From 3b7d515de02865bd0b06d3e92a2a2b9b25184d53 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Thu, 13 Nov 2025 19:35:59 +0000 Subject: [PATCH 078/103] Update translation dashboard URL (#1688) --- documentation/translations/coordinating.rst | 2 +- documentation/translations/translating.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/translations/coordinating.rst b/documentation/translations/coordinating.rst index 13cf617b83..6db4c5cb08 100644 --- a/documentation/translations/coordinating.rst +++ b/documentation/translations/coordinating.rst @@ -213,7 +213,7 @@ linting with :pypi:`sphinx-lint`. See `this documentation `_ for sample workflows with usage guides. -The `dashboard `_ +The `dashboard `_ also tests translations and uploads error logs. diff --git a/documentation/translations/translating.rst b/documentation/translations/translating.rst index 17fe000b49..6252add5af 100644 --- a/documentation/translations/translating.rst +++ b/documentation/translations/translating.rst @@ -13,8 +13,8 @@ generally the ``README`` file, and this page. If your language isn’t listed below, feel free to start the translation! See :doc:`coordination ` to get started. -For more details about translations and their progress, see `the dashboard -`__. +For more details about translations and their progress, see +`translations.python.org `__. .. _translation-coordinators: From 1c3273ab0a89cc30fab2ecfadb4271b9f327022d Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 17 Nov 2025 13:36:27 +0200 Subject: [PATCH 079/103] Make no-force-push advice linkable (#1687) --- getting-started/pull-request-lifecycle.rst | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index 3d74e84406..c401187593 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -54,10 +54,13 @@ Here is a quick overview of how you can contribute to CPython: .. [*] If an issue is trivial (for example, typo fixes), or if an issue already exists, you can skip this step. -.. note:: - In order to keep the commit history intact, please avoid squashing or amending - history and then force-pushing to the PR. Reviewers often want to look at - individual commits. +Don't force-push +---------------- + +In order to keep the commit history intact, please avoid squashing or amending +history and then force-pushing to the PR. Reviewers often want to look at +individual commits. +When the PR is merged, everything will be squashed into a single commit. .. _Clear communication: https://opensource.guide/how-to-contribute/#how-to-submit-a-contribution .. _Open Source: https://opensource.guide/ From 7599baaea67976b6c840a942d231ff4641d9ab64 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 17 Nov 2025 17:46:36 +0000 Subject: [PATCH 080/103] Add GitHub Actions to things Dependabot keeps track of (#1691) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- .github/dependabot.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c990752808..21189f2be1 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,7 +1,19 @@ version: 2 updates: +- package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: monthly + groups: + actions: + patterns: + - "*" + - package-ecosystem: pip directory: "/" schedule: interval: monthly - open-pull-requests-limit: 10 + groups: + pip: + patterns: + - "*" From 25b44963d1d5d574ace7be0a9b3d0cb3133f57fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Nov 2025 19:54:43 +0200 Subject: [PATCH 081/103] Bump the actions group with 3 updates (#1692) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/lint.yml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 22ad254ebf..6479277afe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,8 +12,8 @@ jobs: timeout-minutes: 10 steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v5 + - uses: actions/setup-python@v6 with: python-version: "3" - name: Install uv diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 5c9caf026f..c1554eb5e6 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -8,8 +8,8 @@ jobs: timeout-minutes: 10 steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v5 + - uses: actions/setup-python@v6 with: python-version: "3.x" - - uses: pre-commit/action@v3.0.0 + - uses: pre-commit/action@v3.0.1 From 677a0798c0e9e5e8c1a072962c7d4809ff659cff Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Tue, 18 Nov 2025 16:26:12 +0800 Subject: [PATCH 082/103] Add Ezio as assignee for Dependabot PRs (#1693) --- .github/dependabot.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 21189f2be1..23f03616cf 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,6 +4,8 @@ updates: directory: "/" schedule: interval: monthly + assignees: + - "ezio-melotti" groups: actions: patterns: @@ -13,6 +15,8 @@ updates: directory: "/" schedule: interval: monthly + assignees: + - "ezio-melotti" groups: pip: patterns: From 4512cedb59604129445b884572fc427212319b82 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan Date: Thu, 20 Nov 2025 00:51:16 +1100 Subject: [PATCH 083/103] Update affiliation for Alyssa Coghlan (#1695) --- core-team/motivations.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core-team/motivations.rst b/core-team/motivations.rst index d5a87e22c9..6d539b7c3b 100644 --- a/core-team/motivations.rst +++ b/core-team/motivations.rst @@ -106,11 +106,11 @@ participating in the CPython core development process: * Personal site: `Curious Efficiency `_ * `Extended bio `__ * Python Software Foundation (Fellow, Packaging Working Group) - * Element Labs/LM Studio (Python deployment engineer) + * Westpac (Principal Python Engineer) 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. + for Boeing Defence Australia, and now works for Westpac, supporting their + use of Python for a range of purposes. 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, From 1cfdb000f391c1150d3da10ab2800dc1b40c29ff Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 24 Nov 2025 19:21:35 +0000 Subject: [PATCH 084/103] Bump to ``sphinxext-opengraph`` v0.13.0 (#1698) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 9d124749aa..cb6b2cd5cf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,6 +5,6 @@ sphinx-inline-tabs>=2023.4.21 sphinx-lint==1.0.1 sphinx-notfound-page>=1.0.0 sphinx_copybutton>=0.3.3 -sphinxext-opengraph>=0.7.1 +sphinxext-opengraph>=0.13.0 sphinxext-rediraffe Sphinx~=8.2.3 From 40019d09bd087eb5ec48f84bb488796bb8a560a4 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 24 Nov 2025 20:27:02 +0000 Subject: [PATCH 085/103] Resolve two reference warnings in the Clinic HOWTO (#1699) --- development-tools/clinic/howto.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/development-tools/clinic/howto.rst b/development-tools/clinic/howto.rst index 364cf20bed..359c53e903 100644 --- a/development-tools/clinic/howto.rst +++ b/development-tools/clinic/howto.rst @@ -742,7 +742,7 @@ See also :pep:`573`. How to write a custom converter ------------------------------- -A converter is a Python class that inherits from :py:class:`CConverter`. +A converter is a Python class that inherits from :py:class:`~clinic.CConverter`. The main purpose of a custom converter, is for parameters parsed with the ``O&`` format unit --- parsing such a parameter means calling a :c:func:`PyArg_ParseTuple` "converter function". @@ -758,8 +758,8 @@ write a :py:meth:`!converter_init` method. After *self*, all additional parameters **must** be keyword-only. Any arguments passed to the converter in Argument Clinic will be passed along to your :py:meth:`!converter_init` method. -See :py:class:`CConverter` for a list of members you may wish to specify in -your subclass. +See :py:class:`~clinic.CConverter` for a list of members you may wish to specify +in your subclass. Here's the simplest example of a custom converter, from :cpy-file:`Modules/zlibmodule.c`:: From bf44e3da65027432a9e4b3c466aaf960dfdabc6d Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 24 Nov 2025 20:52:27 +0000 Subject: [PATCH 086/103] Remove unused images (#1701) --- _static/python-cyclic-gc-1-new-page.png | Bin 4415 -> 0 bytes _static/python-cyclic-gc-2-new-page.png | Bin 4337 -> 0 bytes _static/python-cyclic-gc-3-new-page.png | Bin 4876 -> 0 bytes _static/python-cyclic-gc-4-new-page.png | Bin 4863 -> 0 bytes _static/python-cyclic-gc-5-new-page.png | Bin 5712 -> 0 bytes 5 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 _static/python-cyclic-gc-1-new-page.png delete mode 100644 _static/python-cyclic-gc-2-new-page.png delete mode 100644 _static/python-cyclic-gc-3-new-page.png delete mode 100644 _static/python-cyclic-gc-4-new-page.png delete mode 100644 _static/python-cyclic-gc-5-new-page.png diff --git a/_static/python-cyclic-gc-1-new-page.png b/_static/python-cyclic-gc-1-new-page.png deleted file mode 100644 index 2ddac50f4b5575888d8d19cd9b6f2e3863132776..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4415 zcmZ`-cUV)~vfn9?Pz*(Sks?SF4DHY{v_R-ZsUjdq5iyj2R83TRQ>ubMBya=-k*@S2 z3Mdj0L~1}mA_z$D@Zve|-FwgdzW2whS$p=LHM3{dH*0Xq9R2J5_h(<=`5s@q#(=Bn-Jf z-S2tM!qOTyM=GQ_F{MtvGeD=0kzPv=j*Bz!5MIOG|JTF)DzhYW(esjJ z8f05Ovk=8t?*$Q51LL3qw;pW~)XD##-`3zt|49Z~^5l;x(40MO)Z%!tAv7mko!A0n zmG#6YS#c$AIH392w1k_$~Q!)rSP0RDWQ!sH=4h`Nb>*26BS5k7PBYnJF~ zbT4h4YeC+M?a%Iny|4wBj~)hRJUqkjTZ&4xuGN!2BhK(*%O4{t+91coptKo@;$BTd z8tby(2ExM#R#22;W_ASN3no4_?B;Et>+u|1uR`eH#BUM!{+2a9O!2SDGaL z+x{Le<&h{En)7esAe?j22{GF+P z8UCG4tAF_PcUmjyag17G>?K%Ygo#Mdu;kiXRH~!owO1KUka-VjL$^T~iu-|^u@FXV z*t)x+@Ra1!*_1hMv}rjUt#m~jP)}G?nl@feRtmFl^L;= z$w$i9gtOE2uM7y16@5beh=!|xal#WO^1>CK3c3wRQPDQmnCt>Q7sNH$b#l;) zb)+(&o){N*nz=H6uIKq_vQ?(XgJ1~pri#cb=ka%tsO0yaD6c9ES|SKSB*m4xoHb>m z$_9BqP2~1b(B(d}1jpSZTH$@p%HrR&7YP!UPvAn@1#CgiS#>w|7F~|cuC?9XU99#x z$Ghr;dli0#a>^~k9QBm<6${xGj~lH05#tcZbhGmK?PS*qcRgf-H#pL+UL?|%V(#{G z2t*ZTug-}8@;so^DG_%kkv4?~h09NmYa(`53@k#7>4#RGi|03&*kkMp#~^v#%ugi8 zVN|f|WyD79+FkpDyJhG7UTz1r=5@BeD6gcRA-165an3iQxUae=c-m{u@q88<9TY1d zVULl6)!4o>M8jSY;fHcTREPMUfU3z8isR+49X@S`b$x;2*nBH&sw~D3yFabBtx!&T z+E|`(IYttvd@BxUOacm%qfsZRSw2l^cFZ~a`1)#@SN?VQEc|w^)J*8LlYu5Lv^VlP zD=zu+Q#4av36X_j0`^}w(C@vtH|w!vEkl%u@A=ABGz3vElJN@3$n|>t$FF`S#v{ia z(KvSA2ym1#Gm*+KapVLNWJVh6T%OAQw)M!2x74+-Nzuug{(c4)v7ziD;r_=Ur9o2p zZ93zl?Pq4T;F-FG znp{`A*bDVz|?V`}Lei!y3+2TSH}ph&!A zqox-2Aik@nulVg@6stEGr=~R$?}brw=3a8WNqbPFO#abgyQu-3IQMDXl5LMrx2?>w z)?K8J3+ExnBJ%-ipr2LO2uOYI@cit($04`Xa2K(v*0-i}Pt7t3V{@BE7$I|S@&<2& zd3&{qlKEddrbr;%za?J$9saHoq;8Wr-4UulLT9nhTbY z9SN)Jx0p)gW9q~zR1dP;uG321FcX!EgNsl#2wYVGTmi;w*G;8S@_jPOULQ%ByN90T zt9Rem1pENF0O;*+?-P1v^bW21RVGh8NssFpsG8X7E>Aj{EEzI%ZF}l-r}W7r-L!yw z%9fH7%f{C(EZ-YX;q zyHp$UHq+e_sIbgZM)L_y^y8AW%r(cWs&mP= zVDI9!p>wm5%dMV>s5WdZ`n@cLWuBbf>QJh4_KdtaFUl7?q=9jqn8{tN$VwNCSn8Ln zltHvz0N@b_Ua7XLt zzuuy7V$k}qZN^HneP)UTI&xm_ht zoVnB^x#18saQk(B+R-HN+#ek^h&34t(t)<>88N$x}nsZE#MGvQXeL9`VO$Vv~|fgxZUxG(+O(b+i^Jc6irFph_OD& zd5tV7qf*%xa&Q@f(S5)cdK_qf5sA_H*fm-&^kEp}TZ~mE+U?bY8x46b;`4`*QnFEw zgo?@Lqp?+|#0Ke!Pi@Ot(`BCypCHD?uhaYHVYUA6^WbU$H4*;p$GIae8b=*K&ArG* zzuLN{vNw|*EfNDmmePc}z6MdUOq3I7@^q51Pg9KnWuP|fuI`fmx^2fv>X|_XHTKLlue~_{KBZ$4PXp$#_#s+x*UPa zwMM%4Ar|Wf!v}}16|3E($eVS;^&qlVXGwajZC^~edaw{D+i3G!azPsw71~7cTNguU-QSiIGhDAhI#41P8wN=Z;8Jr4N3QG@%5e zw&Ao_myO|hIm%$EP}6Zdnq#vbKKmlFw;r|_9Vx^~+XpqF^JuLQ&{(2<$>%zO6NMT{P!G%_z@~aqz z3x2?YHLXaGd`21UD+LSO~EC;)9T#smRQaXX?+8EXbl_n_`chHawo* zh`N#(Wmj6bLNPy8zn9OV?$`Otm}3mGgnKGwXcTtr>t8!<{yDh&!1A~;V(01A0b6ZS z%8L5%dPPL@JPl8E6>p&odBe@s0;PdMm+Q7y>9pQ#l!xNmCyxQ$zj_0}aj;22_vQ!)t#z_Gs7bqTm{2b&`T*6Y zNj@A55xJ+s;$|r~0#kRv9SD;v;Tw^yLI!$7$|sdlZE_QTej6*58y4Ocn~ZSoGh93r zxI~>_MtOq!+0=_w1qQU8o=a`$(Hi2Z%9yCq*MfwjS@FiVqN7E$2FY>(vb2pl79&H$ zRp^$04WfI8rg1q-ZEN*_5aE^^G0%quH=3@ggc+|Z|0+&)VWzSdcZrU^T+!6V+<@Y4 ziRaf)y;OshyGpX>?w`s_cZ6uQ+R7Tf9P4S>FMY;~rXy}EUzBnDu7vDU$vR2C;%eK diff --git a/_static/python-cyclic-gc-2-new-page.png b/_static/python-cyclic-gc-2-new-page.png deleted file mode 100644 index 159aeeb05024a3247381e1c3aec2b986035b5e44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4337 zcmai2c|26z|GzV1UlU^N*_SX`LzplkQPwOGiO9~_w~?}rl$3;wY$aRPjEpP|m2?rJ zmR-!@|}8q%k%v4d;R`+pL1U4-uLI6d*1h+^LgL&^H!%h*@V~t0N^w?GqC{x zC`fM)v(O8`)bGhCG@A?yWf?=9IGv3e#VmmljFh{G#RiPKn)u5jej&5;;o z8)=E~t&T2Aeq=+&9f}n5;8Aw~cqzZYcC67;rB*^zaJuDiizk4>< zkypd{HI5{l{iu!+E4ww&`yu@rH~L6v^a0C;#QkF4Q8Ax;&#ka-P(%4D9neZqraj+Q zW0Mc($GG5_SwfG4WBmty56JNFpLpyhNPcn$X?uy;M@}@U!ax)}3Z!MI`Sv4OtRaBY zOKGTOycVtl^4GCKM=8d^Gzh@KG{)<**a#`QVs!s_I|OBVLg&h$_bYccI@^USK;QI@ zd{wgimy)Z7W=4co$(u;qI_4%JwEkb%D*3{KgJxcywn!H<+|zNG?mKzNDcLe!&^$%3 zbh=Gh8vM8f$r==tNaG%SfCeTlAm_1i;K!>l-8AMisw(HkL@@@pmpSR<2!nOo1qx70 z+&{qM^LrWpi3}vK&;R20O0#ItLBWci>v~K$1fHzCy<>yikak+MfMlIAIU;)cV0?G3 zGt+ILk?>Rwl2sis&_T?*$^N%$e`5WP_upD2$%1@;@LN!8 zhKD=e$kgd(u-nvjv3b;Ra-v<;yJVMx>~rI>Lw_%G@U(d2njA8A!S?RSB!#}b^UJRd zf3|QVVi~X-D9gN{&PI`YNZWBW@4cPOY(y*vc0X#E$`9_Wh1x+aUHzim88=Qp&}Sl2 zsHhN5G=1r+%8V%x+}yN#n$&;ILl*qE)_-*8CC@|kpH^L?Gx7j@@#hD*bnzkNP^t5D zrKjPOR`iJ*Ay4PAXxQ_Ut*4u9$6?M@-@vJmd`QUlH1gbR(e^NlHgt+iK;Qd}fq z9}=u|!6ri)!vvINzVwvCZEWfy7Gt4Pk&OLTA3l^+Go!@{!%P(iz`jB$p43%N^n>FA z0p31Wb)V-AtuRsw!*(S&Ng`x_Ql6gTSc&IhlM67i&OF(?C$cV7;%f>r`!>`?>f3`b zE-`KkT+nSNPeVD1J{?tNo-}`|-Vmup+Y2PrbjxRUe|lgn>{p|& zdgvus6?CDdb7E-AtLGC7dU%jaxk}`<9G_<3Bq#X+4=JZXq#$YYTihij><63F6`3xJ z$Tq`YvN%)-K0-hC2ieB5KHLA+_WO=OL*#H1yA+gUvcE|XQvEl7bHk2Wz#AGf$lz~X(ebpht!FA-G%PP zXCf`aP1-Z;K-S5tVb&c{S?^!z?r^DH3@9BTY72*W&Of>rD$?Vqb~mnE7Y)PlTw%bi zYKc7K80#80cq7o(N}R8R#B*s{t`>R>~q{WFM91BD}6(_0CSe9 zQY!U@qJi_r==;?s#;T%t05$IUI=AQ6aY}5Nh}UrV=LFXuK^yXp+}rmnx81a-S7GP^ zgqDL&sL4v)-3HgiExZE9?8+_wlW>7ZSBVJAxI4AK6qI({mfPW2I{^UCn0ytq6HI#AuHG>9V2f&L`;r@dQn?sE zpXpv^A)kEDU{Gp7q)<4^IxS7F0U_gRF`V(P4o>vO$t`@Yc03h4TiEXWv7X6ih_9Tz zNcx2_Z*qZde$IB;;dAb7=3durk>_Yxo#eXRr95HM+4cDuvH3cO}C9oW9>YXC# zlHO`24BX0H2FbT_+41q4NYjWFUs~9}tGafYN`A@wh(-!}Tp$?|dMwaQZp}0&KVGF; z3=%W*?E9dEd9opOC^T^YgH!u}UOn+yO>zQTQ`)Z1ewa4t zH8Qh5D5h^~+n5hSUT9A+#N}N~7)8{##WyVpm5XqHNg}`|#ShO!oArG8xT1_1{Gj@R z^S<`TX3)N)9&H+kNnTw`tYOZ$Avry@O!p@?O64_ie#YxpdJV)(Thh8M9!N{R zV_33YhC8ZART#JVcFW?#DN`Jja#h*%^1CNLVI^cNkU8o(DWTW)oln~w2zkV{G)zU{ zGI^CMUdn`Be*O5wLN7nZuu~+|;@oJ;zH8+=vqE3z9;L1*ExpI9}&va*iwfp#1wAGRCS@cn6sruI%E+egyACipOqeFPO&jPVT)Wk{Our zU-~AT_fmgT~-chP>VgCCMMsy~E3Yp9#qXJ&cnyM4) z{yYkENC_`0h-jr^dW6WBX!boNI_7+{L%2Y_1I<|{(OQpmAjne|-gqqm^6U zN8qP3HeHJOOy?Wr-}?Lr*5R4&a=e5Kb*4si>|Zvf`DdwKUr>Mamy2DX!O(n_59y}a1%DtW@5GEg!`_iv3d{*&|RO_WoiAM3A(Rjn~R#&T3 zed;2t2z3-A%Bqo6%hdERe9PCxn>>9);S?MF+!)1J5zifewCZ~?M9-Cn2TnhJ&>e96 z!l3!x6s#t4UKdu-JG=$MDc!td$mLlqqB~f{g+6n_v8dR7`}xH7t8(Q+1!#OC8@d@` zN8GW$1sfhsidbpt@@fUE)3({}qCz9RGgiOHGNQ{74FU?INh&SYZ$q?>Tvu|<;(?4EBJIyTKq;GWM4jJ}#1Lo-yg*&Xha^Jsk} zfsRiqQ4;lF4=ibuB)zj+%?0wke>0yp1?z@-=j{YB|EVMiN3Y*Bg^;*{#~M zkQBDPRjUD;q{3O09OCPSf&|_LvQQ!!V;Y8a=AAXYx&-IKfH|-mX}qZyd0^_T7)r7z8UaBAyYKJ-@ss0Wt`kSe~+jlY17oB%%{>_Vx!- z2O~jt-yO#?+W6k?vUw~6=#1mU6U`?)Wki`RiF-+pI=u+?qk&FJ-kT+#)vlvO?V^e}-zAd-rILnC+_S|gFq8e+tJ&n|HZU>X)^NSG6c*b}kTvC~@ zxOxV%6AHHH(_PfR%<8}W?B?wXx`o+gAnO&SGd#rK@4Wc2$xPgXD(E>AAhq$V=vbBl z!$W6vO@sO?e@P99c~-}|P=Yt9r)(WWo1%pV$T7c diff --git a/_static/python-cyclic-gc-3-new-page.png b/_static/python-cyclic-gc-3-new-page.png deleted file mode 100644 index 29fab0498e5b106f813e08aa2799602269cd74d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4876 zcma)AcT`i$w?1hgARUw{9f{J5KxmO50qIqw$(14qh(JsbDTxXJq)U?;L_n&b6afQr z0YPa&q)JgiiPEkRq)6li@9)05)_d!%_5L{Lo3-cLduH~WS!ebaZ*7TYXBA=v0D#@p z#K;x^z!XON?GeTcF!q0ZnE@=I1^lB3#Xj=55SyDZAlKN{sm-} zJ!`}HQU+LYVz}2x);DtOQ-JVC`l|Pn?_Z53u?fOgU7U=cA}lNEgk!9c(^U93WCfNv zx5BQ@1(V>Y2c^0vdAZ%QVT=KDCOE<=jBo@;lEdFo`Ft5eAy5C)cWR6mQXmbdR6c>I z-?t+no<$G6!9ftS7>WN=Nm21(6Aj*m6v zG2hDuqamMe-%5tDQD8b8dg`&H6ie9asgw+x+5!_BlEW}_gTQl;hm;}s%kGopIO?=# zF@vj5VuK~bsY{3vhSbY47T^5G_%RVAx!d<@5$0>fkJNDgJ$jn1HS;Ici|%-LlOM*v zEyFvn|JUOFULzy9Bz|8;a*bH>u~!>IB84v;#f9V zNQ%3rHTl<*-On9WbJe)WsuNK4gh_|ykptC^{lKxjz{d#lN+Lk+sa14+%!tlN>;K5^ z;nw{-kAJpx{wVd-3!z6;5{PvYSHck}5l`TR43srigzkDc_A5_*TL^<{I$?Oy`Zcr&|kzYj#A( zNYIw8U}&K&?%gcy@XecV)vS0>1ox_js6DRptTcsb*YtCYN%1pw{{I8*!c-w9pD#8H zZU>Z-R?SFdv?z&q7R3SEV*}~cgJ(h1l|Fvh9te3{#}ZyTGq=8WUF4$}kqR zh=Ll1VI$~A(QqJyoiUcrzmk6tg{p#$F+T=e;)eff_YqI;$IA7vaTK85e-adGoA);q^dHQ|Y~0^jk8QZk|`$x&Eo zg;gSU-CnNQsgP?f5(*4XyO^(+IBw&Xcy7A_MJ7DIdKyk?0|t-Q%|5NSb#zpu(|q_f?BK_{umQ}r1r-xiD$by9ao*7+s?1p9L5{XI8wJk zOP(zk%r;AGf==55*XTzT$mwePpJkTOQ{)@5P5DQ5y|{`->u+f+*v5}!q3h&TMwvR) z#`HxMv#+ExIQ+g6XmjBv53%vig52PWZr^_5pYpnQpZ2V$+m6n zVCrIA-#H9c9(XxjfJ(N?m5|j3Q5;kKz};tlv_Y8IiUW3%?&;xw`Qm+gzfr9qDh>CaRVzuCj?JGXjg)+ zQE?gCedj;DHk)Rr-kD7^PHS7ypFq%v9LG>1A_k`xwbVTaGqyDF#*gqQg6tG0wWpT+ zel1cbrUHwVf8&v)#0lA>Br37dME9IqL>|Ls{4`P9%O7~vQG}={QV$pR)I;PtJBA~j zpZW!vC-MAxE3_854r-8*yxQFQ2&ps*&GfRa29wn&ycWo(X9?GIQKP{5&oGgnJ@^y4 zfKe4vlPQ-aqLp6E@S^4Sd=w6doG@+5q*qq3P&6lNZdHdEAzfcWL~a#^%`;I82YoME zX3xmYT)qM4xwLv6F}vjzGAK86+o;QH(wGcze#ZR*&VYTW=WT*Wm z*`k=Y-13EYW$S>D{f(Xbmts4jb{EmPzg#2eKRaBe^qBW}+bptH$M1^7Q;9|67%twV z5o>ni4J10fubgm7uK300>Hwy2a?wxq5<$w>RFv8r0tG37sK%6b@p`|r?*^0?xT}w* z;;kl4%3QyW%{(_ifuaI^a7BXQai3Hu7&+#ha}&*Jomd6uAW0LzX0b@ag32gf+Aam`T{eZkZZ zK_R7gh{t&V>E8K0Eb__s&?27(*UwH{{b4M=9ne2RtrqhA*A#%ICCvzqEX~o~lb0N& z+KK?Wbn9eiS9A^YsU9PixDNma6xU-ec^`^z&VVz1^x1-{li%RKU4eP8-H z?~rbODeZoA-Qx3U<%mA}cCL{9eyf83uM6Xofn2BymRjV*ueN>PyL$aatIe}?pK4?o zzf4=e*-43IAK!@}r#^AioBgn)I2a~GT4J7-w1a)(;hs<)jFtydQ5LtQH}m|@6USm( zILul(Xelj*Gf$FM$~3Spx_q|AD)tuudikP;sL_K_$x+ueY(gBj%8;8PTrBJOr<*at z?ao`6dqua@OZ@6zZCoq^gth$5}!nij!AJ@`(Hq0S#r z$Ic#l9XD9Vm}D7hpWdi_ZEAr}*5XqOgZH*agrrwoPWOhjs!-+81RK(eso{s4_GS;#ngx?sTjvB1d}_M zpnJf?>gBqgi&55BzMTCQg&ba9X?C;}LVGB(_DAhT`}myjEa>M`**rqpuob*2G}YT` zFRr7I62VF7?@j6x$vQy$_&fj-LvgZY(m2M*JG@{9mVjMx4PznqWshGgr&~jnDNv6``*I|Iul@n~?MxN9aV^=i(&%0_wtzmuYk@qT`;WTj;JF}j&zcd? zy{d`QNi~<9VW)Y;N>SqY=0F90Je5FRPopTok}nzAC8qWW1kJ5FrqtXsP8_5l&wFd@ zg)&nN`3ca)w3PTjbHNxxi_n_w&5^4B?O2=PPO9Q4udl?Bz&2nblw?PO4x8}VvKoEn z3h{dB!p9mU4ifJl2tWWyo%T)y>+`SgN3v-HPAMjWU)>6HdI$Ca(o+BOZaeW$0>Lod zikCVGA{ceIS|Wq$PctDWIeq!WlbUN$9n3-jRez=TF7kYlb9_X~cOa9FJM=`Q#+KZ3J$p-~2#B_2$*`y`1PX&zkmIi}m3f*%3A`Fr@6Ot?Hy51)D z#)zl_X72l|$P}g=6A$pW?|mQgZF2~Thm*~N7tH$29jAK5WvS|GYMrs})ctM?z8fnO zYuRs;e{sAtBmH|Qy$X>Y#7^@7c_o-Y@iq5RD_O}4PJQJWlIIf3fSBy=gI<8VwXruG zfc``^QO@~5g~|&gN5y+DH9EvOoqh|YT3{8((RK$nd>69SlA5)e(gl00a|yLs9Go$Q z8y}a@S+4q4{8_GbUU^FIExhiWw7Wu5BkS=wyKqXNGj>fo5niY}0zxOWP#64j*k@Z% zd6UO^-g&HsA-J!AmoLG z>sl(Gvt8hF!0Y?MW}B&y`<92S&obG&NeIW8G(aJXOjezuXW`(E(Olo_b(d zF$;pZjt-W#q&!IADK;bCeHX~!nMWD64y0`uVwCzK=P|OmuvqxgiwfkE2sshViRpSJxM!2BN33vB1Ghrxmfy7kFsq{_ZVu*~ z*}I?DtL6eOtPrak+Ds=_=W_c0Xc~vltxR?_e*J*X`4MEi?8;$^RIH-6O9VWOyD(8B zK@4DSoq99iE;d#vXn|v8e>TPSEpQ~r=vNz9FZJS(DV%Z(yc*bZ@lB*!#}&!F?`{P5 z%V=2m6_R(m&`s*c?X)<#XgiXDFbvjeKpC?vm30ZQ_h~QbUubCoLb^=80+QJ#Mt5DJsz~qyZn7m+C#ZWkHH&RY`Hg2ikKXapFy2~KYn6zhDBSgSmsi22X& zG1HeqSiPTROyGM{Y`T2Z6N^Ke1@``O^)hY5y;)ZDd{-x!bU|BW%lY7dHT;chvQpWX zWy(2vEi#&gG!j&9&8R)azzutD|JJKxd548NL%2AEs0;sAvkv~Gg1yMbPsd0lh#$wM zbO>MWjj6s{zcO^*e?E7seEpSJ=SO|gLJy~PN5=$4@U30Ty}znFqaPB=e&S;#)XIwD z=^lbK1_hOXduZ1m6yPup(-*PFjO9{;S{?(mC5IWarm}j=>y)|Xr zBRmxB_gC4T?QcQhw_5X$ymF`tRQxRt90EgZAV2>l*7sDPT7U=so}n|zV9q&Vy#By= zBRoUA833p%tEej|YbvNJ+p8)gG?Wo4XHF|CBb1ei4-yVltA8B=gS`BFZvNj6Ke|;L Q7!H8xIZLBjLyz141yIB0(EtDd diff --git a/_static/python-cyclic-gc-4-new-page.png b/_static/python-cyclic-gc-4-new-page.png deleted file mode 100644 index 51a2b1065ea64eaf009a96ce6fecd3132424ea0f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4863 zcma)AXIN8Nw?0WE)W8S|NY{Xl^r8ZRK$LC)DN+R-YA{j_C}1ENg@{5B5k^!X6k+HJ z0Y+jdA{`}y6oCY000}}2NNACA<9Fw4KkoC~ALqRL+2^di)_T|8d+oJTF526`MC3#O z0D#%qS~>v$n9gqx3h`fnHRg9eJ_twHdR*tD?LQvt9*h~k0rop*V+rgL)B9ThK=QPm z82#6q+FnvrGKR}ilyOU0y zY+V+9bjatnv44;l36k}t$h^E*-KqRb^RdToT1q``4)%zjQR5@b*weiPHH>@Y2F`{^8;(ZxEGL1ZeRPC@)!%C-*AK#zFskKZ|H-ou3>c?44}EH&+LWMIAxb5(i}$3dChM z?u`r63*AJGT^zoUyxq_U-b}OlaGjeKUYaILw>LQa;PyuE-~eVFB5Cj|pcSV_hC9{R zrZX|;%nd_<=}yW;yfjjo{*e~b&$5dKBMQ>>c#A`4_{#5~Hbhbm1z|;gfsPkE(Cp=_ zk%1sAGMBPQpRPc8s9I+*h1G#i=+wBs56x%t-%kFgum5!NKYc~<1%B}QzjWli$aH>T z=_`abF1^Toj?c~vu<{jUk%78dBc8c~a^hud4DDfEv(XjQ_CW@946;K;FMHEb+L=q}txm9*+-at9*R-lvs|Z zDHpH4%Qk@THrX_p3Q|K`Wiyuc^EP;cUcKBv zYl`&7?`qmp-_L}Sch=%nQNFutI?RL5YVxx*P>D)qbAkjCm>VU(6tzwRaOtku0sHy! z{xKK+KY#%gOV>#JS+b*s*S`1zqw(V9w%vzOi3R&TMd>iSwxY`c@&?e^fknEfqf{;LTXW)tP| zTBuxr1;d+}9+pp~U+>quWkWXE_t46k#U`xF0WJ`-gq{tLgi05AI5#H1N_{_WKPOGv z695vnvpvMKRZtu-_M(EO#nhV>Bwi=Nv~sq(#DvU|YoY^v+Kr~?mI{`z%PvF3x} zV^$V9tY3NK>V`e}l7l6Js(>bHv;C%}6PkVeDC+c#;?esytg)++)_>&HGAkJIgqU&_ zr=$+l{K@F}3b{Yh@@ukWs}5P1$X2{COfY{af$)mG3r?l;$jSzYV zn2x(ZHa|)CcJTiwVQj{-e!D4#k{>kEABM^$L89KGNhuW<@VjL1!Bi7~ou%BB&>>nu zg;88#@?CTe)e+lu3_!GbrQTY-SPf9r;C^@7j)C0ZWOH<*d!0?TMf}61%YkHbUApHV zRfL4mG@svsfhUU7BJtcbyjgr;-En$pOy;RT2{H|Crzj7?t!Q8SV^_cUF#WorB!Ux( zeE0H#5+eBFF9C4!fKt;_Fz%XR#n(2ko8j4z+>OpzYm_pK(xB@*y>+_ioihqSeETWDiZgv{QiSDCMe+=L>a_6u_$7ps2}+1dF<>5_VTb)u6hXuVi{iu^ z@$wKH+Rc3YtADtNa~PD{);cJU&7gvE?bBOzgt-u&AI4bLUtuwg4ueg$$b-475Tw1p zEo)F5hJ1aw2=G>9y-yYLrpai4xo60wB3ORcA@sq!mbn6~P=a=EaLIcidKRIf$=$cf z9?z6!k?r)|yq>9|@~gk-_$CU`y@1>YTkFMHCInK#bB(i=V6GxN8&<2Jcl`ve48UR_ z8yxF*vg7D^lQ|^`WBq@yo(k#WQXX`KYokM;nWqpQzol1LxDrL5Ae*1}@ zqY5$OEo>=k_I%yWnM}GLr?Nj{QfE%{vcp|0~DGD^%qpU zm(TGTya+dzeXL7Eek0p_WT8R*_&WrJchMD-A>YI5V}@iKf$`&w0bTcu!}7=Z3u5PT zoiPH-kU#zA2=Bn%n}>t2 zb{fGm9K1NuZ$a>!#2)rZapaw2j4r6j$>vwzqKB_;(2DXc*iLaBx9{v16g6KPz~i+8CD(>WRG04|)W1HoEBY9_yaJ=C<~f~q4z|GK6d zk48(2LcGS>(ee6Y`9W=riL73?GbCl|a(?~zn&@~{1~CS*0G3HsV9*C!2f}Y8%k{b@ zBqWe6RC@I9obQ}zW49Y2d-d%~3M|cc9F#r$o&~pYL|)#4QWPbp&bumw7;2*%JBxpU zgy?Dmy!nJ{*RH&dG9j|JUklUKYQ_GvCs%x_*<1eFyFSI+3U1k5-Mcm#CP1!I^Y~ch zJ;nNL$*tMjY_x{@Py?j{HO#~JQ5sI*abR-G*i~xC=tdpK{pHQ%Fc;)VXsRr4ZvKD> zy$>%Q!Sp%+it{2D6<+EeRzD_8uZx3W`wZ=c=+Sul7ZFR2`&hlG%p`?EfEFo+RL{K` zTb&GeLs&~R&S5?72+AOHoAZYx8dDW*rhNAESQ)gT(OESQIswZO%T~?2pgO}9FKZn6 zo)KUks!ZEllSXX>Kd*6~?+ZdXloox$9;0U_{+b*78_s;ITq4O-L3J!sb6r%!QuVq1KM1U=m5FS>Wb9}noiWkq~c-baijNv(*p@K z7=5{Gq1vJpJE__C;o$5qvFof0hD$5WS9%Y4SsQU+2Noh#k1H^jjDKgo=|3o?V}t`( zX-$q2Xw0Mfk@8_w{6i39YwsH&3d}+uA7mO~0vNT&v6Qh^Ky8fizv(71LMD{S@OO@jO$IB3FA`v@1IO znTTKbi8B?~sOY9Hg3_fMM^gTzoX81y!*aB(_#A>Z_%ZYsQdSmmR2d(mM-pjQFt`&^ zQ2DaBeW7B+6Z4ZDTlRr%MdhXJa0^m|GJQW>O0(*CumHpq>O{Rf+_<8JWB*JO9}bzOTiQ}Y7t=6%Ev4DBm(@i&h!DtSmhr3Owd;4 z%_iao)5Ov`wK$3&g&Qw|QTeCTs|4c!yU;RTU$}HhJ0|V^UG#2RXsyC?-HjXb1p{`4 z!yR7M06wM89~b1fGrKvY5#!FGjl%F@V`)#|6#W2K%#F&{Oyry9>n%PpM+6zKD(%L|6(d26|LCG|-`)5adrs-6C+dNE&?gAwXDFrvLfw!J?xy+E7}mlV~c zk`%TDKFfCBiga>3^Gy8FCn&3sVDvcN7bnsE>~e~29F{nJQmNstLW$PVPT8!PyBV5D ze(p5<(wRpb&A%XGvl;s{*W<>}960{>W=N+LJ;77G5LUI`ET~^)mP#i2wurLC6f0{L z=+q%&xRR;~a??UgQ5~qm7#cQr0{_V{hbH(7{_#~qYmlI2RdpVzjY3Z59;z@Er zbb9?zjC^#_`k!mz_K&?pPMFNzbeG$m03Bpxe8R9h>okcC#Q0~LS1Qk~4(`Yf#Mn({ z%yqv%>fduEt4{{?+vy5zy}YXP!56)mOC9&tEoXP?*-kZC^07vdI!bm=z7-H@_0DY- zcL=HCB?I*qB>u{XMp8J}d^xFEf)pjzU+ojQ4Z{<(7I*mmvV2+tL*~}ng=WUF?+A>s z0yo6WB;R^l0VQZ;1n;vk6pW+1II(h)@Oj!l&Yrvgd!(t%P(nleLq6UIGn#*#_i_T? zWjf%iv*v7>uBNYj@OgF~uEuuwYBBEJ4-*!rJn_{+6gOO|UJxj5=7EKLFcdDjU6D@D zl3*Sn%YYS60GY0U;`o@?iEmO3@jCS5o%L|;i`xWcfYCkhdN8digsRYY&s|5Wr3JHx zSImFGAc`|DL$IA|5YmL~rZ_7ofy5e9Kr634Taxip*QFOxlxd59fNbzuO z+f#zHRHdas%p)1B2%{38=M)X||NouRD08~fs7FgmDk5z2UoYP`HR`qa3;?wz!G=EmDUuNZx%pi$CZIprNv1WZM zCJrK@$M^$aB^X5e!=r+6k7v5MIKuk}6h;GTad*3@eCGDXuFmH0_iY#aFe4>U%`A{$0@ko)B3wL z`e#ayX0qka>ACrcM#OG}z3vxcpx@0mym2_!vc=gPt&llWuU50>WOKW@(d!`95t-~- zyC8I+rUK`*P2O#)ju=CxP=0qxM|x%Z$lPOR5FjL6g*{N)SNp0ANMvs zUV9RccxLc;?>f@1$~0rl&0%X|UA&dT1h`plJI{|Ce<0u%rM diff --git a/_static/python-cyclic-gc-5-new-page.png b/_static/python-cyclic-gc-5-new-page.png deleted file mode 100644 index fe67a6896fe4b07c03291ca8b21781fde8785757..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5712 zcmZ{oc|25W{Ksd(U>H&MeTi&kD-6RRYgw`{4T`ZO6oaB+CgB#@ibBH?ne3G1rjSZx zJ@y(GNf>)HBujpC@9*CG+g`sv&iOp&`99z0oaghL=e(ZtzHMh?&dn*p34uVkEiF#l zLm)7aSsr9(o*-sHPcJfsUr3MiX71YkS z46$;&&OfOq;KkV&VAeD?n6jEu#b}*Z-deqM^y;-f+eey7Npi>dh~_sRV&$;Or(ty# ze+x-XsESiz@uTdi-t6t>$w z?tqJflHqqz=fsXi>wp3X)|aM<0RvPBaoE)TL;G*cej%#ZWR?J^yBrn?$}oiwFoo4I zy9ZeRiDl4llWn9qz{hKd0HiE7*%L(=Sj$wrCK|Z07epI#mLCA%?Z=F3hX(xC6KHE1K*+6MMs3EA3G_fVf7p{ zopk@Yk-5&Z$QnEt$r3I1N%5~5!x`=WJ}!~~(=Vv|pTcyOB=FBD|Ic8VvHxrm^6`VB z>*F={09~pb0|!-A_;9C18CZZ;pi_TQx8`}uCsq83$p#z&*?isjtt#SQ%+;dOS2DFwE<5o-+B=AxsXVWaCp= z>uK#VnD~V+CSO=Mbe)xQgOOnL!)eyumioLPa)XO4*Ac+bNI0^4{AAaeT%wP*3ye}- zu%LvEOXTVjINl_9aZWghyCAVQ9Ky+Tg86L7f8;NFnA85JOaBU; z3P&d$GPYng-N!*D8fBhJF*BxE!KQM)Fm`Z?2Rv@YrHYL+$Bs2d)WaA^C{EQ;0PqJ^ zE~qmCol;&$OM%Xa&AH|HYAynoIbQdDM=wRGiIpCOaaFHzy;dTF?JvXqF(rm)X%ciz zgEvW~FY~8$IW&86O?U)tO3w-Tq^i_N2!#o8$t9#;n*$E5wE5IP{+%ZV(AxBoaIc&mHr&Em0-=x)oWFQeB*m-=|q-OvgM*1<0eb6?4 zo|Rro&R?#a!o&L4s&*?Zc0X^bD&|M-^Ohj}i)YTpY4%7q!E^6MNCKLquTHwJ z}eWu5d}US28D?~qLlHJ)ZF6RE|R!%`wp#f%FnG3piiS#QU56_MC1|Hs1uSEH`7QG~=s;SL4?8@2ZHAE9Y(MErPitJDJ_t(^F24pmdi^G*yy>7k1HP;Lg|#G zVmRiSK8T4nqks2UP3j@n9P8yy{;_pR5?NPY7rFXnZ}Mw!r#Y08E)d)+_Ye=^UyG;8;o%muPF(SRyRID8m(z8 z$%=%a6D$|Jc`{WN-=Ab=TF6BYj*Iv5@|h?aoC^P%ZYh6Q5<*BxDNStAkgiQ6%jsn; z43n`B?5w;uN}-rrR$(N6#|amW_a{5G)2(_Kz?|{Ot-H~veS;#3@d$0tIAkJ{~2Vz3@gi9(ZmU^{1ER9l+K3i-@yi%yla|zcZc~=i&FwoAB+n4 zw=6qr%{$K})dX_{S;s&rZ_Jc&!v|9c!fg-B)~5$kLG4x-Lbs0D(3ab}cMjH;3f10B zYMJN8IIQ3!w?hDA&&o(*a!JmKMX5D7t@LE~mf*qaiLPe_!R=ilJQ~L*`S|lu^z%92 z&4)G;UL7-{c%J|D>%;7EDio*hWlQ7%pXlDq%k8U?WNAtl+{DTS5yvlio_D8i@?z(0 zh&M{U;dnf0wV7WpioWyAnTONlGo2;^QLcDl?qzIpgZ$B;r{v}FR|kP_6axu$5P9wQ z`C>iR;W`CV^$90M&WaN%E`-g~O1`Iuz%Y$3>zs{~?BWx<^(jeT$yFM9PtFIP(Lcn# zR+z*hb#`jfC58ob-sM+z?s=86m5mVQKkK(Cg8QP+K~v^ue{ECAqpL3p4k$fex407? zF7=h=F!#pqdryz)32_M@M-=BM>9KItk-5T&$$H)SzZlP>^4{{udc^H@9C);>vKb?i zV%-($3Kx*T!Cv+Zf2PZ%kUv))BI>LEGtjJQ&Ut4(V@72b4u#h871(rK!uSlidkFxLm` zXMOZoW>>!>o^Sd_oMg%K+>Rf;1F4kVHvbL7KC=KPUEtYbh{jT4$y5p$cfA!Ss(cW3 z$`~6CcR;emUYMGkr@mp6K8NE(||!$-fpFm?WiRI|*PvIber#KT}&&dSB8 zNAulb_tW(4rOsBZnT4m|>KgWa&dqEjmi@X|UaX9TZ?_#R34@Vk*X$kgL~}inTBOx} ze=PO(-B?)DzNLk)F&Zi^0V8m>DL2Y|)p45L|9G(2grFL-%kgGMxKu+J9r+o&7XI0j zcY-}6sFosQliv)SRyST*#Dr_UMgkoT^3SV6cT_=_2q@$JVG*y;1GhsTphp2p{gxEq zlAV_QUBYwoGoyf(!CxEkQyD6L?qQQwZjlTqjj~V?dMaM-X@~E2MDkC)i_Ie+|4jw= zsHdrEfd{s77Qfb|m^gY=*?Pzc{r0yvu^a?n-J{Jb3Qty!H;Ohd8lfykfNMCRb4VFY z0qm~3?YP*D2Ur&*x05Zekd{_?0=bf*M(cA-&>aDrguolooRGx)7u3e(HxR60B!Zb6$wJIiCd_@55hyfgfL zdQ4m2RaHyuxwA;VmRh8`@wjgHg{c&ceh7i6iEo6`1zu#SIclVys@w-XRpfGZb72kv zp;e03rHPH>MSH-#X%VxIB`W4i>#Nw9)AqQ$C2qPdiZelwCt>Y+`jeG+8MLaGCcY^twGpkw`gmPh zEp7G%$wmp!+B_be#6zcgy&C%?E%w=K$%BPB)TN*O2kDaydcoBjW331M@wpRINIq1#+HfGkO z<_?VTl5I%ZMRm651X8Ox5j{m`D8nh-J?%%5Ap7pvdkM?;AQ(S38QtZ^=@*dwD?m8= z^kUl$FHXAi_VWm+ZNsSh)L27dYW?UvU+qzZLMX1H_=lXZs^wOslx5J%LmHOjVl{i) zXrQuwG(p2NUR>di4&%u`#;Z;^(ss2+C{*#^skD##>VjSof4q8~;(PpGfzqD0YB`F=+QB)vGaF0-SA9(v2m zD7)v%!zd0)X~7LYu?QzickxFz^{mHK4O-X&%1yp;=HD{l4fM9qP!_7@rE*x@id4Pr zi~S}No$u&z;|BF)LW@*PTqxH>%LjLPsqjbfoYKb##ZC%a7=~koIYM zmop%$v>&!H6j>ts>Fro#j5h2piQNFh+hXu41F>}BO1;FV0y1*BV+8w|&LD6jir zy*q@`a7%17vnRQ1U@I=&Qi)>W?v#xcrA~ZoyOiM%yzP@lu-zQ~IfD(-gHFUg!K=F% z=G4B$4$2xTfDWBTlW@W#^wjFh-*^+2-S65>^U?bpXLYksU(;ZeEF51c&PZ-IGU?cP z*hJAvNswxe(}6Tl-j-=WEfvohUnv}&Wv8gK4D$vIt?K}H%dTk4JC8ysU_W-Kmw)h4 zuTDO{+s_JYsKKjPmL}U$#KsX#-$7+(mM~BM;Sg7m%9PI1^+dhVqsL8BUqJ&N3<997 zy2<4P@O>ugy9e`?kjkLdd!;*#Ds^|K%T}?{itlqZDf)f$HMOl)nkTMwteuvk_!&)A zoi2|S4%^-*tvcO-L<$vtDzy?9O1BRKsp;_wnkDT9QI*yGY=kLPwPXW~8zNuZ?je0Y z5|S}gY@jM$kG^$CrIXZ^@=?Y+z6KIqg>dE2f;`oEzb-BJY^d_$<;ms-Vx`H&H{kK! z#Y5Rv%1V)4VfVY1hfwNT z<%(24Jfird_~p8}*k?aLcISR( zfzGM#J5P2=RWy~~xPcaud|-@NBe2KYrVfhtTwezL=fu_epP{7nBmfqLFxC36^5HbD9{^+0UkD5UyMIH=sPI4l(<6B?wq-}UIHOP zz%^XE3oF_^2M<+yRIVcz-16yE!62_qYSrLwN zA{pp^6;dgKOq`t_{xbXrhFmoz0-hro7$hD~PcqIdzPZ?A3cNfF&X|dNDPR2&$diC( z2jvi4a^)@v2u3{hhc%N8(CaRU#;*y}*Dq&1D|{Wd|0L&FU4NowN}Xq4nq06 zh0RUVXHjD^m8I-Nd4Ss49k~m)mT)cIE`IidI$@YSt2QR^A@(&gNXfW>gTCd41;HmdEn~#_NihACS>I&lmmz4Qi;myqczM4#*1lG3RG~EIHVNI_Y z_;0ig=AO_+DVApk+=!PYw~QeXDwlQ8!DFJ3uGtwTOM`>epL+F3@@EWRrRp*P)Q$jn z0+0Ha_56+h{u6%vONICVFL=NStYO~X7=$JXW!#ln`Zt>VTmFWl{Y3|ef%~pM z3N_a7Ojdi8VCqWny+FXDeZufefoQ0yYpJSft7Ulni@p(`R@Nn d2oCiP^t=B5CtNi{nllq1mZmnRtBk#G{s-d0T~Yu5 From 8090ffc21e85b440eb0b5bd45422f6fbde01e04b Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Tue, 25 Nov 2025 18:58:26 +0000 Subject: [PATCH 087/103] Remove references to ``Misc/ACKS`` in the devguide (#1702) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- .github/CONTRIBUTING.md | 11 +++++------ getting-started/git-boot-camp.rst | 2 +- getting-started/pull-request-lifecycle.rst | 6 ++---- triage/triaging.rst | 1 - 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 0287153194..c4a7d25457 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -18,13 +18,12 @@ Please be aware that our workflow does deviate slightly from the typical GitHub project. Details on how to properly submit a pull request are covered in [Lifecycle of a Pull Request](https://devguide.python.org/pullrequest/). We utilize various bots and status checks to help with this, so do follow the -comments they leave and their "Details" links, respectively. The key points of -our workflow that are not covered by a bot or status check are: +comments they leave and their "Details" links, respectively. -- All discussions that are not directly related to the code in the pull request - 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) +The final key part of our workflow is that all discussions that are not +directly related to the code in the pull request should happen on the +[issue tracker](https://devguide.python.org/tracker/), generally in the +pull request's parent issue. ## Setting Expectations diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index 87177840cb..2ecaa62f0e 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -611,7 +611,7 @@ When a pull request submitter has enabled the `Allow edits from maintainers`_ option, Python Core Developers may decide to make any remaining edits needed prior to merging themselves, rather than asking the submitter to do them. This can be particularly appropriate when the remaining changes are bookkeeping -items like updating ``Misc/ACKS``. +items like updating a news entry. .. _Allow edits from maintainers: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index c401187593..46975b7f73 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -629,10 +629,8 @@ it is warranted. Crediting ========= -Non-trivial contributions are credited in the ``Misc/ACKS`` file (and, most -often, in a contribution's news entry as well). You may be -asked to make these edits on the behalf of the core team member who -accepts your pull request. +Non-trivial contributions are often credited in What's New in Python +and a contributions's news entry as well. .. _issue tracker: https://github.com/python/cpython/issues .. _Core Development Discourse category: https://discuss.python.org/c/core-dev/23 diff --git a/triage/triaging.rst b/triage/triaging.rst index c560d8c1d5..207c59082f 100644 --- a/triage/triaging.rst +++ b/triage/triaging.rst @@ -92,7 +92,6 @@ you can help by making sure the pull request: * includes proper tests * includes proper documentation changes * includes a :ref:`NEWS entry ` (if needed) -* includes the author in ``Misc/ACKS``, either already or the pull request adds them * doesn't have conflicts with the ``main`` branch * :ref:`doesn't have failing CI checks ` From 1ea4acaec22a6e46fa265a41a0b56d5e967d6600 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Tue, 25 Nov 2025 19:31:09 +0000 Subject: [PATCH 088/103] Fix reference link (#1703) --- documentation/translations/coordinating.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/translations/coordinating.rst b/documentation/translations/coordinating.rst index 6db4c5cb08..066237e5d9 100644 --- a/documentation/translations/coordinating.rst +++ b/documentation/translations/coordinating.rst @@ -35,7 +35,7 @@ Announcement ------------ Post an announcement introducing yourself and the translation you're -starting on `Discourse `_. Also join the other communication +starting on `Discourse `_. Also join the other communication channels, if possible. From 098351234d6beba22faf43612512d5476fea9981 Mon Sep 17 00:00:00 2001 From: David Hills <20931105+DJHills@users.noreply.github.com> Date: Fri, 28 Nov 2025 13:32:24 +0000 Subject: [PATCH 089/103] Fix typo in "Getting Started" guide (#1707) --- getting-started/setup-building.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index c6cf6c9fa1..a6ba77959a 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -823,7 +823,7 @@ some of CPython's modules (for example, ``zlib``). package. You can safely remove it from the install list above and the Python build will use a bundled version. But we recommend using the system `libmpdec `_ library. - Either built it from sources or install this package from + Either build it from sources or install this package from https://deb.sury.org. .. tab:: macOS From 7a8438290bf69c6f6ed20a74fb8a5c8d24028844 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 29 Nov 2025 18:30:39 +0200 Subject: [PATCH 090/103] RST markup: recommend anonymous hyperlinks (#1709) --- contrib/intro/index.rst | 6 +- core-team/committing.rst | 6 +- core-team/experts.rst | 2 +- core-team/join-team.rst | 10 ++-- core-team/memorialization.rst | 24 ++++---- core-team/motivations.rst | 58 +++++++++---------- core-team/responsibilities.rst | 4 +- developer-workflow/c-api.rst | 4 +- developer-workflow/communication-channels.rst | 22 +++---- developer-workflow/development-cycle.rst | 44 +++++++------- developer-workflow/extension-modules.rst | 6 +- developer-workflow/grammar.rst | 2 +- developer-workflow/sbom.rst | 12 ++-- development-tools/clang.rst | 8 +-- development-tools/gdb.rst | 2 +- documentation/devguide.rst | 2 +- documentation/help-documenting.rst | 4 +- documentation/markup.rst | 13 +++-- documentation/style-guide.rst | 8 +-- documentation/translations/coordinating.rst | 18 +++--- documentation/translations/translating.rst | 16 ++--- getting-started/git-boot-camp.rst | 26 ++++----- getting-started/pull-request-lifecycle.rst | 10 ++-- getting-started/setup-building.rst | 36 ++++++------ index.rst | 20 +++---- internals/compiler.rst | 2 +- internals/garbage-collector.rst | 2 +- internals/interpreter.rst | 2 +- internals/parser.rst | 2 +- testing/buildbots.rst | 2 +- testing/coverage.rst | 2 +- testing/new-buildbot-worker.rst | 26 ++++----- testing/run-write-tests.rst | 4 +- triage/github-bpo-faq.rst | 8 +-- triage/labels.rst | 6 +- triage/triage-team.rst | 6 +- versions.rst | 4 +- 37 files changed, 216 insertions(+), 213 deletions(-) diff --git a/contrib/intro/index.rst b/contrib/intro/index.rst index c5ba303dfd..98fa30fc38 100644 --- a/contrib/intro/index.rst +++ b/contrib/intro/index.rst @@ -24,12 +24,12 @@ 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 `_ +* `How to Contribute to Open Source `__ +* `Building Welcoming Communities `__ Healthy collaboration diff --git a/core-team/committing.rst b/core-team/committing.rst index 41cf672542..a88ff12053 100644 --- a/core-team/committing.rst +++ b/core-team/committing.rst @@ -59,11 +59,11 @@ to enter the public source tree. Ask yourself the following questions: * **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 `_ + 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. @@ -125,7 +125,7 @@ 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 `_, +``NEWS`` entry can be created by using `blurb-it `__, 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 diff --git a/core-team/experts.rst b/core-team/experts.rst index 2fb37cb3f9..01935106ba 100644 --- a/core-team/experts.rst +++ b/core-team/experts.rst @@ -365,6 +365,6 @@ Documentation translations ========================== Translations are within the charter of -`Editorial Board `_. +`Editorial Board `__. For a list of translations and their coordinators, see :ref:`this table of translations `. diff --git a/core-team/join-team.rst b/core-team/join-team.rst index d7996cd424..20ce9e4c98 100644 --- a/core-team/join-team.rst +++ b/core-team/join-team.rst @@ -40,14 +40,14 @@ are granted through these steps: (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 `_. + 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 `_. + `🔒 python/voters `__. - A reminder about the `Code of Conduct`_ and guidance on reporting issues to the PSF Conduct WG. @@ -55,12 +55,12 @@ are granted through these steps: - Enable the various new privileges. - Remove the new committer from the triage team, if applicable. - - Add their details to `🔒 python/voters `_. + - Add their details to `🔒 python/voters `__. - Once the python/voters update is merged, regenerate the public team membership list at :ref:`developers`. See "Public list of members" in the ``voters`` README. - Post an announcement in the `Committers Discourse category - `_. The past few announcements + `__. The past few announcements were in the form of a separate post on the already open topic with the poll. @@ -69,7 +69,7 @@ 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 diff --git a/core-team/memorialization.rst b/core-team/memorialization.rst index 7ab0fab02b..3d893a3029 100644 --- a/core-team/memorialization.rst +++ b/core-team/memorialization.rst @@ -31,11 +31,11 @@ certain content when the legacy contact or family members request it. GitHub ------ -* The user is removed from the `python/ `_ +* The user is removed from the `python/ `__ organization on GitHub; -* The user is removed from the `psf/ `_ +* The user is removed from the `psf/ `__ organization on GitHub; -* The user is removed from the `pypa/ `_ +* The user is removed from the `pypa/ `__ organization on GitHub. The PSF staff does not follow up with GitHub with regards to GitHub account @@ -43,7 +43,7 @@ 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 `_ +`Deceased User Policy `__ page. Repositories in the organization @@ -51,9 +51,9 @@ Repositories in the organization * The user's GitHub handle is removed from ``/.github/CODEOWNERS``. To see all that need action, perform - `this query `_. + `this query `__. * The user is marked as deceased in the private - `voters/python-core.toml `_ + `voters/python-core.toml `__ file with the ``left=`` field set to the day of passing, if known. discuss.python.org @@ -80,7 +80,7 @@ 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 `_ +`Best practices for deceased community members `__ page. python.org email account @@ -116,8 +116,8 @@ python.org admin devguide.python.org ------------------- -* The user is marked as deceased in `core-team.csv `_; -* The user is removed from the `experts index `_. +* The user is marked as deceased in `core-team.csv `__; +* The user is removed from the `experts index `__. bugs.python.org --------------- @@ -139,16 +139,16 @@ Other PSF-related infrastructure 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 `_ + is available on their `Deceased or Incapacitated Users `__ page. * The user is removed from Salt configuration for the PSF infrastructure - in `/pillar/base/users `_ + 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 `_ + `buildmaster-config `__ repository. PyPI diff --git a/core-team/motivations.rst b/core-team/motivations.rst index 6d539b7c3b..d0e5a0cc18 100644 --- a/core-team/motivations.rst +++ b/core-team/motivations.rst @@ -97,13 +97,13 @@ participating in the CPython core development process: .. topic:: Brett Cannon (Canada) - * Personal site: `snarky.ca `_ + * Personal site: `snarky.ca `__ * Microsoft (Software Developer) * Python Software Foundation (Fellow) .. topic:: Alyssa Coghlan (Australia) - * Personal site: `Curious Efficiency `_ + * Personal site: `Curious Efficiency `__ * `Extended bio `__ * Python Software Foundation (Fellow, Packaging Working Group) * Westpac (Principal Python Engineer) @@ -123,9 +123,9 @@ participating in the CPython core development process: .. topic:: Steve Dower (United States/Australia) * Microsoft (Software Developer) - * Personal site: `stevedower.id.au `_ - * Speaking: `stevedower.id.au/speaking `_ - * Work blog: `devblogs.microsoft.com/python/ `_ + * Personal site: `stevedower.id.au `__ + * Speaking: `stevedower.id.au/speaking `__ + * Work blog: `devblogs.microsoft.com/python/ `__ * Email address: steve.dower@python.org Steve started with Python while automating a test harness for medical @@ -143,25 +143,25 @@ participating in the CPython core development process: .. topic:: Mariatta (Canada) - * Personal site: `mariatta.ca `_ - * Works as a `Software Engineer `_ + * Personal site: `mariatta.ca `__ + * Works as a `Software Engineer `__ in Vancouver, helps organize `Vancouver PyLadies - `_ meetup on the side, and - sometimes `speaks `_ + `__ meetup on the side, and + sometimes `speaks `__ at conferences. * Email address: mariatta@python.org - * `Sponsor Mariatta on GitHub `_ - * `Patreon `_ + * `Sponsor Mariatta on GitHub `__ + * `Patreon `__ - Support Mariatta by `becoming a sponsor `_, - sending her a `happiness packet `_, - or `paypal `_. + Support Mariatta by `becoming a sponsor `__, + sending her a `happiness packet `__, + 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 @@ -177,7 +177,7 @@ participating in the CPython core development process: 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 interested corporations (additional development work on email funded by @@ -187,7 +187,7 @@ participating in the CPython core development process: .. topic:: Antoine Pitrou (France) - * LinkedIn: ``_ (Senior Software Engineer) + * LinkedIn: ``__ (Senior Software Engineer) * QuantStack * Python Software Foundation (Fellow) * Email address: antoine@python.org @@ -213,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) @@ -224,21 +224,21 @@ participating in the CPython core development process: .. topic:: Barry Warsaw (United States) * NVIDIA, Principal System Software Engineer, Open Source Python Ecosystem - * Personal site: `barry.warsaw.us `_ - * Blog: `We Fear Change `_ - * `LinkedIn `_ - * `Bluesky `_ + * 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 `NIST `_ in Gaithersburg, + 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, + `__. 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 + `__ project leader, `GNU Mailman + `__ project leader, and Python Steering Council member in 2019, 2020, 2021, 2024, and 2025. .. topic:: Eric Snow (United States) @@ -256,13 +256,13 @@ participating in the CPython core development process: 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 - `Cinder `_ improving Python + `Cinder `__ improving Python performance for Instagram. .. topic:: Carol Willing (United States) * Noteable (VP Engineering) - * Personal site: `Willing Consulting `_ + * Personal site: `Willing Consulting `__ * `Extended bio `__ * Project Jupyter (Software Council, Core Team for JupyterHub/Binder) * Python Software Foundation (Fellow) diff --git a/core-team/responsibilities.rst b/core-team/responsibilities.rst index 3b2137d6b0..9f5c62b728 100644 --- a/core-team/responsibilities.rst +++ b/core-team/responsibilities.rst @@ -48,12 +48,12 @@ Communication channels and bug notifications ============================================ Mailing lists have generally been replaced by the -`Discourse forum `_ (``discuss.python.org``). +`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 — +settings for the `python/cpython `__ repository — follow the link and click on the :guilabel:`Watch` button to set your notification options. diff --git a/developer-workflow/c-api.rst b/developer-workflow/c-api.rst index 90c1d12e4e..c65e88ce1c 100644 --- a/developer-workflow/c-api.rst +++ b/developer-workflow/c-api.rst @@ -38,7 +38,7 @@ 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 `_ +`C API Discourse category `__ or an issue so we can try to find a supported way to serve them. @@ -218,7 +218,7 @@ use this API reliably: (: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 `_ + 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 diff --git a/developer-workflow/communication-channels.rst b/developer-workflow/communication-channels.rst index 9b088b350e..43c00b9e1b 100644 --- a/developer-workflow/communication-channels.rst +++ b/developer-workflow/communication-channels.rst @@ -64,7 +64,7 @@ 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 +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 @@ -84,7 +84,7 @@ 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. +`__ core team. The Committers category is often used for announcements and notifications. It is also the designated venue for the core team promotion votes. @@ -97,8 +97,8 @@ 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 +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. @@ -114,13 +114,13 @@ Greetings!" received under Notifications and Messages in your user account. * 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 `_. +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. +`@staff `__, +`@moderators `__, or +`@admins `__ groups in a message. @@ -164,7 +164,7 @@ 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 `_. +go to `Preferences of your account `__. This allows you to make adjustments according to categories, users, and tags. Enabling mailing list mode @@ -174,7 +174,7 @@ 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 +`__, check "Enable mailing list mode" and save changes. .. _Discourse: https://discuss.python.org/ @@ -243,7 +243,7 @@ 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 `_ +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. diff --git a/developer-workflow/development-cycle.rst b/developer-workflow/development-cycle.rst index 7f82ea42f0..d39fd2cfc5 100644 --- a/developer-workflow/development-cycle.rst +++ b/developer-workflow/development-cycle.rst @@ -134,7 +134,7 @@ 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 -`_. +`__. .. _stages: @@ -212,27 +212,27 @@ Repository administration ------------------------- The source code is currently hosted on `GitHub -`_ in the `Python organization `_. +`__ in the `Python organization `__. Organization repository policy ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Within the `GitHub Python organization `_, +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 `_. +* 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 `_ +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, @@ -241,18 +241,18 @@ 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 `_, +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 +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 `_). +`typeshed `__, +`tzdata `__, or +`pythoncapi-compat `__). Organization owner policy @@ -264,7 +264,7 @@ 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. @@ -315,7 +315,7 @@ 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 workflow tooling, Release Managers for all :ref:`in-development `, :ref:`maintenance `, and :ref:`security mode ` diff --git a/developer-workflow/extension-modules.rst b/developer-workflow/extension-modules.rst index 7131cfdf86..fa4c11868f 100644 --- a/developer-workflow/extension-modules.rst +++ b/developer-workflow/extension-modules.rst @@ -562,7 +562,7 @@ Now that the configuration is in place, it remains to compile the project: .. tip:: - We recommend installing `Podman `_ + 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. @@ -609,8 +609,8 @@ by executing :cpy-file:`Tools/build/regen-configure.sh`: 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 `_. +`__. Alternatively, you may try +using `Podman `__. Missing ``Py_BUILD_CORE`` define when using internal headers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/developer-workflow/grammar.rst b/developer-workflow/grammar.rst index d574dfed7d..bd314c61e3 100644 --- a/developer-workflow/grammar.rst +++ b/developer-workflow/grammar.rst @@ -5,4 +5,4 @@ Changing CPython's grammar ========================== This document is now part of the -`CPython Internals Docs `_. +`CPython Internals Docs `__. diff --git a/developer-workflow/sbom.rst b/developer-workflow/sbom.rst index 756c175708..c8a2facd14 100644 --- a/developer-workflow/sbom.rst +++ b/developer-workflow/sbom.rst @@ -5,15 +5,15 @@ 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 `_ +`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 `_ +`python/cpython-source-deps `__ repository. Whenever adding or updating a third-party dependency, an update will likely @@ -51,10 +51,10 @@ 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 `_ +* License of the project as an `SPDX License Expression `__ * Software identifiers that match values in vulnerability databases - (`CPE `_ and - `Package URLs `_ + (`CPE `__ and + `Package URLs `__ or "PURLs") * Paths to include and exclude in the CPython source tree corresponding to this dependency diff --git a/development-tools/clang.rst b/development-tools/clang.rst index b353d82f00..149fb7adcf 100644 --- a/development-tools/clang.rst +++ b/development-tools/clang.rst @@ -11,7 +11,7 @@ libraries. This document does not cover interpreting the findings. For a discussion of interpreting results, see Marshall Clow's `Testing libc++ with --fsanitize=undefined `_. The +-fsanitize=undefined `__. The blog posting is a detailed examinations of issues uncovered by Clang in ``libc++``. @@ -45,7 +45,7 @@ flags are passed through ``CFLAGS`` and ``CXXFLAGS``, and sometimes through ``CC`` and ``CXX`` (in addition to the compiler). A complete list of sanitizers can be found at `Controlling Code Generation -`_. +`__. .. note:: @@ -70,7 +70,7 @@ Pre-built Clang builds are available for most platforms: includes the "C++ clang tools for windows" feature. You can also build ``clang`` from source; refer to -`the clang documentation `_ for details. +`the clang documentation `__ for details. 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 @@ -284,6 +284,6 @@ Or, you could ignore the entire file with:: 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/gdb.rst b/development-tools/gdb.rst index 8f89ea1360..835b2dbc70 100644 --- a/development-tools/gdb.rst +++ b/development-tools/gdb.rst @@ -29,7 +29,7 @@ this approach is less helpful when debugging the runtime virtual machine, since the main interpreter loop function, ``_PyEval_EvalFrameDefault``, is well over 4,000 lines long as of Python 3.12. Fortunately, among the `many ways to set breakpoints -`_, +`__, you can break at C labels, such as those generated for computed gotos. If you are debugging an interpreter compiled with computed goto support (generally true, certainly when using GCC), each instruction will be diff --git a/documentation/devguide.rst b/documentation/devguide.rst index 7c53d054e1..9f2ada23c1 100644 --- a/documentation/devguide.rst +++ b/documentation/devguide.rst @@ -23,7 +23,7 @@ Changes to the Developer's Guide are published when pull requests are merged. Changes to the Python documentation are published regularly, ususally within 48 hours of the change being committed. -The documentation is also `published for each release `_, +The documentation is also `published for each release `__, which may also be used by redistributors. diff --git a/documentation/help-documenting.rst b/documentation/help-documenting.rst index 1c64b4832c..23520375cb 100644 --- a/documentation/help-documenting.rst +++ b/documentation/help-documenting.rst @@ -37,8 +37,8 @@ The in-development and recent maintenance branches are rebuilt once per day. If you would like to be more involved with documentation, consider subscribing to the `Documentation category on the Python Discourse -`_ and the -`docs@python.org `_ mailing list +`__ and the +`docs@python.org `__ mailing list where user issues are raised and documentation toolchain, projects, and standards are discussed. diff --git a/documentation/markup.rst b/documentation/markup.rst index cad0b4d9c3..f9291a335b 100644 --- a/documentation/markup.rst +++ b/documentation/markup.rst @@ -28,7 +28,7 @@ attribute definitions ``.. attribute: `attr-name``` :ref:`inform attribute references ``:attr:`attr-name``` :ref:`roles` reference labels ``.. _label-name:`` :ref:`doc-ref-role` internal references ``:ref:`label-name``` :ref:`doc-ref-role` -external links ```Link text `_`` :ref:`hyperlinks` +external links ```Link text `__`` :ref:`hyperlinks` roles w/ custom text ``:role:`custom text ``` :ref:`roles` roles w/ only last part ``:role:`~hidden.hidden.visible``` :ref:`roles` roles w/o link ``:role:`!target``` :ref:`roles` @@ -51,7 +51,7 @@ language, this will not take too long. .. seealso:: The authoritative `reStructuredText User - Documentation `_. + Documentation `__. Use of whitespace @@ -185,9 +185,12 @@ Hyperlinks External links ^^^^^^^^^^^^^^ -Use ```Link text `_`` for inline web links. If the link text +Use ```Link text `__`` for inline web links. If the link text should be the web address, you don't need special markup at all, the parser -finds links and mail addresses in ordinary text. +finds links and mail addresses in ordinary text. Prefer anonymous hyperlinks +(with a double underscore) over named hyperlinks (with a single underscore) +to avoid target name clashes. + Internal links ^^^^^^^^^^^^^^ @@ -343,7 +346,7 @@ they are used in the Python documentation. This is just an overview of Sphinx' extended markup capabilities; full coverage can be found in `its own documentation - `_. + `__. Meta-information markup diff --git a/documentation/style-guide.rst b/documentation/style-guide.rst index 68350c4017..d90a14ce90 100644 --- a/documentation/style-guide.rst +++ b/documentation/style-guide.rst @@ -73,7 +73,7 @@ boolean abbreviated name with appropriate markup (for example, ``:type:`bool```). C API - Python's `API `_ used by C programmers + Python's `API `__ used by C programmers to write extension modules. All caps and unhyphenated. CPU @@ -122,7 +122,7 @@ such as "for example" or "that is." Diátaxis ======== -Python's documentation strives to follow the `Diátaxis `_ +Python's documentation strives to follow the `Diátaxis `__ framework. This means adapting the writing style according to the nature of the documentation that is being written. The framework splits documentation into four distinct types: tutorials, how-to guides, reference, and @@ -135,7 +135,7 @@ explanation. and abstract concepts should be avoided. Please consult the Diátaxis guide on :ref:`diataxis:tutorials` for more detail. -* `Python how-to guides `_ are +* `Python how-to guides `__ are designed to guide a user through a problem-field. Both tutorials and how-to guides are instructional rather than explanatory and should provide logical steps on how to complete a task. However, @@ -158,7 +158,7 @@ explanation. found throughout Python's documentation, for example the :ref:`python:unicode-howto`. -Please consult the `Diátaxis `_ guide for more +Please consult the `Diátaxis `__ guide for more detail. diff --git a/documentation/translations/coordinating.rst b/documentation/translations/coordinating.rst index 066237e5d9..a7872b6aec 100644 --- a/documentation/translations/coordinating.rst +++ b/documentation/translations/coordinating.rst @@ -12,7 +12,7 @@ Communication/help channels =========================== Discussions about translations occur on the Python Docs Discord -`#translations channel `_ and the +`#translations channel `__ and the `translations category `_ of the Python Discourse. For administrative issues, ping ``@python/editorial-board``. @@ -72,16 +72,16 @@ account, with the correct Git hierarchy and folder structure. This can be done in several ways, and depends on what translation process you plan to use. Each translation is assigned an appropriate lowercase -`IETF language tag `_. +`IETF language tag `__. The tag may have an optional subtag, joined with a dash. For example, ``pt`` (Portuguese) or ``pt-br`` (Brazilian Portuguese). The repository name is then: ``python-docs-TAG`` The name of each branch should be the Python version it holds translations for, for example, ``3.14``. The files should be structured like the source files -in `CPython/Doc `_. +in `CPython/Doc `__. A correctly set up repository looks like this: -`python-docs-pl `_ +`python-docs-pl `__ Below, the recommended ways for starting your repository are described. You can choose another way if you like; it’s up to you. @@ -100,7 +100,7 @@ Translation platform ~~~~~~~~~~~~~~~~~~~~ You can also start your translation using -`Transifex `_. +`Transifex `__. This will allow you to translate via the web interface, and to use shared automatically updated source files. @@ -155,7 +155,7 @@ PEP 545 summary Here are the essential points of :PEP:`545`: - Each translation is assigned an appropriate lowercase - `IETF language tag `_. + `IETF language tag `__. The tag may have an optional region subtag, joined with a dash. For example, ``pt`` (Portuguese) or ``pt-br`` (Brazilian Portuguese). @@ -210,10 +210,10 @@ Testing should ideally be set up in your repository, and will help catch errors early and ensure translation quality. Testing generally consists of building, and linting with :pypi:`sphinx-lint`. -See `this documentation `_ +See `this documentation `__ for sample workflows with usage guides. -The `dashboard `_ +The `dashboard `__ also tests translations and uploads error logs. @@ -289,7 +289,7 @@ Is there a Weblate instance we can translate on? ------------------------------------------------ There is currently no Weblate instance for Python translations. -See this `Discourse thread `_ +See this `Discourse thread `__ for updates. diff --git a/documentation/translations/translating.rst b/documentation/translations/translating.rst index 6252add5af..2e4f6cf91c 100644 --- a/documentation/translations/translating.rst +++ b/documentation/translations/translating.rst @@ -32,7 +32,7 @@ For more details about translations and their progress, see - :github:`GitHub ` * - `French (fr) `__ - Julien Palard (:github-user:`JulienPalard`) - - `AFPy/python-docs-fr `_, + - `AFPy/python-docs-fr `__, :github:`mirror ` * - `Greek (el) `__ - | Lysandros Nikolaou (:github-user:`lysnikolaou`), @@ -122,7 +122,7 @@ If there is already a repository for your language team (there may be links to Telegrams/Discords in the ``README``), join and introduce yourself. Your fellow translators will be more than happy to help! General discussions about translations occur on the Python Docs Discord -`#translations channel `_ and the +`#translations channel `__ and the `translations category `_ of the Python Discourse. .. _translation-style-guide: @@ -215,7 +215,7 @@ Code examples Translate values in code examples, that is string literals, and comments. Don't translate keywords or names, including variable, function, class, argument, -and attribute names. An example of a translated codeblock from the `tutorial `_ +and attribute names. An example of a translated codeblock from the `tutorial `__ is provided below: .. code-block:: python @@ -259,7 +259,7 @@ through the following resources from the Transifex documentation: Within the organization, a project for translating the :github:`Python Docs Sphinx Theme ` can also be found. -For further information about Transifex see our `documentation `_. +For further information about Transifex see our `documentation `__. Resources @@ -270,10 +270,10 @@ Some useful resources: - :ref:`git-boot-camp`: Several translations accept contributions by pull requests. Most have their own guide for how to do this, but this can provide useful tips. -- `Translation issues & improvements `_ GitHub project: +- `Translation issues & improvements `__ GitHub project: This project contains issues and pull requests that aim to improve the Python documentation for translations. -- `Python Pootle archive `_: +- `Python Pootle archive `__: Pootle is no longer used for translation. Contains translations for old Python versions. @@ -322,7 +322,7 @@ How do I translate the Python Docs Sphinx Theme? The Sphinx theme for the Python documentation supports localization. You can translate either on -`Transifex `_ +`Transifex `__ (see :ref:`translating on Transifex ` for more information) or locally by following the steps outlined below. @@ -357,7 +357,7 @@ The coordination team for my language is inactive, what do I do? ---------------------------------------------------------------- If you would like to coordinate, open a pull request in the -`devguide `_ adding yourself to the table +`devguide `__ adding yourself to the table at the top of this page, and ping ``@python/editorial-board``. diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index 2ecaa62f0e..b845e00aa6 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -33,7 +33,7 @@ relevant to CPython's workflow. .. note:: Setting up Git aliases for common tasks can be useful to you. You can get more information about that in - `Git documentation `_ + `Git documentation `__ .. _fork-cpython: @@ -280,7 +280,7 @@ Compare to the ``main`` branch:: $ git diff main Exclude generated files from diff using an ``attr`` -`pathspec `_ (note the +`pathspec `__ (note the single quotes):: $ git diff main ':(attr:!generated)' @@ -289,7 +289,7 @@ Exclude generated files from diff by default:: $ git config diff.generated.binary true -The ``generated`` `attribute `_ is +The ``generated`` `attribute `__ is defined in :cpy-file:`.gitattributes`, found in the repository root. .. _push-changes: @@ -389,8 +389,8 @@ you run ``git merge upstream/main``. When it happens, you need to resolve conflict. See these articles about resolving conflicts: -- `About merge conflicts `_ -- `Resolving a merge conflict using the command line `_ +- `About merge conflicts `__ +- `Resolving a merge conflict using the command line `__ .. _git_from_patch: @@ -443,8 +443,8 @@ Scenario: - A contributor made a pull request to CPython. - Before merging it, you want to be able to test their changes locally. -If you've got `GitHub CLI `_ or -`hub `_ installed, you can do:: +If you've got `GitHub CLI `__ or +`hub `__ installed, you can do:: $ gh co # GitHub CLI $ hub pr checkout # hub @@ -523,7 +523,7 @@ The bad example contains bullet points that are a direct effect of the PR life cycle, while being irrelevant to the final change. .. note:: - `How to Write a Git Commit Message `_ + `How to Write a Git Commit Message `__ is a nice article describing how to write a good commit message. Finally, press the :guilabel:`Confirm squash and merge` button. @@ -557,7 +557,7 @@ after it has been accepted and merged into ``main``. It is usually indicated by the label ``needs backport to X.Y`` on the pull request itself. Use the utility script -`cherry_picker.py `_ +`cherry_picker.py `__ to backport the commit. The commit hash for backporting is the squashed commit that was merged to @@ -649,12 +649,12 @@ To edit an open pull request that targets ``main``: GitHub CLI ---------- -`GitHub CLI `_ is a command-line +`GitHub CLI `__ is a command-line interface that allows you to create, update, and check GitHub issues and pull requests. You can install GitHub CLI `by following these instructions -`_. After installing, +`__. After installing, you need to authenticate:: $ gh auth login @@ -740,6 +740,6 @@ Change into a directory to work from that branch. For example:: .. seealso:: - * `Git Reference Manual `_ + * `Git Reference Manual `__ * `"Experiment on your code freely with Git worktree" - `_ + `__ diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index 46975b7f73..d1f7e26a52 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -183,7 +183,7 @@ resolved as follows: When running the final command, Git may open an editor for writing a commit message. It is usually okay to leave that as-is and close the editor. -See `the merge command's documentation `_ +See `the merge command's documentation `__ for a detailed technical explanation. @@ -283,7 +283,7 @@ The automated checklist runs through: * Has the documentation been updated? * Has the test suite been updated? * Has an entry under ``Misc/NEWS.d/next`` been added? - (using `blurb-it `_, + (using `blurb-it `__, or the :pypi:`blurb` tool) * Has ``Misc/ACKS`` been updated? * Has ``configure`` been regenerated, if necessary? @@ -329,7 +329,7 @@ instructions on how the commit message should look like when merging a pull request. .. note:: - `How to Write a Git Commit Message `_ + `How to Write a Git Commit Message `__ is a nice article that describes how to write a good commit message. @@ -417,7 +417,7 @@ This will get your changes up to GitHub. Now you want to `create a pull request from your fork -`_. +`__. If this is a pull request in response to a pre-existing issue on the `issue tracker`_, please make sure to reference the issue number using ``gh-NNNNN:`` prefix in the pull request title and ``#NNNNN`` in the description. @@ -452,7 +452,7 @@ existing patch. In this case, both parties should sign the :ref:`CLA `. When creating a pull request based on another person's patch, provide attribution to the original patch author by adding "Co-authored-by: Author Name ." to the pull request description and commit message. -See `the GitHub article `_ +See `the GitHub article `__ on how to properly add the co-author info. See also :ref:`Applying a Patch to Git `. diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index a6ba77959a..df208f28cf 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -20,9 +20,9 @@ compiled version of the CPython interpreter (CPython is the version of Python available from https://www.python.org/). It also gives an overview of the directory structure of the CPython source code. -Alternatively, if you have `Docker `_ installed you +Alternatively, if you have `Docker `__ installed you might want to use `our official images -`_. These +`__. These contain the latest releases of several Python versions, along with Git head, and are provided for development and testing purposes only. @@ -38,23 +38,23 @@ Install Git .. c_install_git_start -CPython is developed using `Git `_ for version control. The Git +CPython is developed using `Git `__ for version control. The Git command line program is named ``git``; this is also used to refer to Git itself. Git is easily available for all common operating systems. - **Install** As the CPython repo is hosted on GitHub, please refer to either the - `GitHub setup instructions `_ - or the `Git project instructions `_ for step-by-step + `GitHub setup instructions `__ + or the `Git project instructions `__ for step-by-step installation directions. You may also want to consider a graphical client - such as `TortoiseGit `_ or - `GitHub Desktop `_. + such as `TortoiseGit `__ or + `GitHub Desktop `__. - **Configure** Configure :ref:`your name and email ` and create - `an SSH key `_ + `an SSH key `__ as this will allow you to interact with GitHub without typing a username and password each time you execute a command, such as ``git pull``, ``git push``, or ``git fetch``. On Windows, you should also @@ -141,7 +141,7 @@ Install pre-commit as a Git hook -------------------------------- To make sure your code is linted correctly, we recommend setting up -`pre-commit `_ as a Git hook:: +`pre-commit `__ as a Git hook:: $ pre-commit install --allow-missing-config pre-commit installed at .git/hooks/pre-commit @@ -170,7 +170,7 @@ working only on pure Python code the pydebug build provides several useful checks that one should not skip. .. seealso:: The effects of various configure and build flags are documented in - the `Python configure docs `_. + the `Python configure docs `__. .. _unix-compiling: @@ -822,7 +822,7 @@ some of CPython's modules (for example, ``zlib``). Note that Debian 12 and Ubuntu 24.04 do not have the ``libmpdec-dev`` package. You can safely remove it from the install list above and the Python build will use a bundled version. But we recommend using the system - `libmpdec `_ library. + `libmpdec `__ library. Either build it from sources or install this package from https://deb.sury.org. @@ -889,7 +889,7 @@ some of CPython's modules (for example, ``zlib``). --with-dbmliborder=gdbm:ndbm (``--with-dbmliborder`` is a workaround for a Homebrew-specific change - to ``gdbm``; see `#89452 `_ + to ``gdbm``; see `#89452 `__ for details.) .. tab:: MacPorts @@ -928,7 +928,7 @@ some of CPython's modules (for example, ``zlib``). For more details on various options and considerations for building, refer to the `macOS README - `_. + `__. .. note:: While you need a C compiler to build CPython, you don't need any knowledge of the C language to contribute! Vast areas of CPython are @@ -981,7 +981,7 @@ If a change is made to Python which relies on some POSIX system-specific functionality (such as using a new system call), it is necessary to update the :cpy-file:`configure` script to test for availability of the functionality. Python's :file:`configure` script is generated from :cpy-file:`configure.ac` -using `GNU Autoconf `_. +using `GNU Autoconf `__. After editing :file:`configure.ac`, run ``make regen-configure`` to generate :file:`configure`, :cpy-file:`pyconfig.h.in`, and :cpy-file:`aclocal.m4`. @@ -1185,13 +1185,13 @@ What is GitHub Codespaces? If you'd like to start contributing to CPython without needing to set up a local developer environment, you can use -`GitHub Codespaces `_. +`GitHub Codespaces `__. Codespaces is a cloud-based development environment offered by GitHub that allows developers to write, build, test, and debug code directly within their web browser or in Visual Studio Code (VS Code). To help you get started, CPython contains a -`devcontainer folder `_ +`devcontainer folder `__ with a JSON configuration file that provides consistent and versioned codespace configurations for all users of the project. It also contains a Dockerfile that allows you to set up the same environment but locally in a Docker container if @@ -1204,7 +1204,7 @@ Create a CPython codespace Here are the basic steps needed to contribute a pull request using Codespaces. You first need to navigate to the -`CPython repo `_ hosted on GitHub. +`CPython repo `__ hosted on GitHub. Then you will need to: @@ -1229,7 +1229,7 @@ Then you will need to: 2. A screen should appear that lets you know your codespace is being set up. (Note: Since the CPython devcontainer is provided, codespaces will use the configuration it specifies.) -3. A `web version of VS Code `_ will open inside your web +3. A `web version of VS Code `__ will open inside your web browser, already linked up with your code and a terminal to the remote codespace where CPython and its documentation have already been built. 4. Use the terminal with the usual Git commands to create a new branch, commit diff --git a/index.rst b/index.rst index e19bb88263..0af90e295e 100644 --- a/index.rst +++ b/index.rst @@ -31,7 +31,7 @@ instructions please see the :ref:`setup guide `. 1. Install and set up :ref:`Git ` and other dependencies (see the :ref:`Git Setup ` page for detailed information). -2. Fork `the CPython repository `_ +2. Fork `the CPython repository `__ to your GitHub account and :ref:`get the source code ` using:: git clone https://github.com//cpython @@ -91,7 +91,7 @@ instructions please see the :ref:`setup guide `. git checkout -b fix-issue-12345 main If an issue does not already exist, please `create it - `_. Trivial issues (for example, typo fixes) do + `__. Trivial issues (for example, typo fixes) do not require any issue to be created. 6. Once you fixed the issue, run the tests, and the patchcheck: @@ -125,10 +125,10 @@ instructions please see the :ref:`setup guide `. gh-12345: Fix some bug in spam module 8. Add a News entry into the ``Misc/NEWS.d`` directory as individual file. The - news entry can be created by using `blurb-it `_, + news entry can be created by using `blurb-it `__, or the :pypi:`blurb` tool and its ``blurb add`` command. Please read more about ``blurb`` in its - `repository `_. + `repository `__. .. note:: @@ -159,12 +159,12 @@ this guide, then the `Core Python Mentorship`_ group is available to help guide contributors through the process. A number of individuals from the Python community have contributed to a series -of excellent guides at `Open Source Guides `_. +of excellent guides at `Open Source Guides `__. Core developers and contributors alike will find the following guides useful: -* `How to Contribute to Open Source `_ -* `Building Welcoming Communities `_ +* `How to Contribute to Open Source `__ +* `Building Welcoming Communities `__ Guide for contributing to Python: @@ -251,8 +251,8 @@ Key resources * `Buildbot status`_ * Source code - * `Browse online `_ - * `Snapshot of the *main* branch `_ + * `Browse online `__ + * `Snapshot of the *main* branch `__ * PEPs_ (Python Enhancement Proposals) * :ref:`help` @@ -279,7 +279,7 @@ Additional resources * :ref:`clang` * Various tools with configuration files as found in the `Misc directory`_ * Information about editors and their configurations can be found in the - `wiki `_ + `wiki `__ * `python.org maintenance`_ * :ref:`Search this guide ` diff --git a/internals/compiler.rst b/internals/compiler.rst index 5b43e1e6dc..f22039c649 100644 --- a/internals/compiler.rst +++ b/internals/compiler.rst @@ -7,4 +7,4 @@ Compiler design .. highlight:: none This document is now part of the -`CPython Internals Docs `_. +`CPython Internals Docs `__. diff --git a/internals/garbage-collector.rst b/internals/garbage-collector.rst index acbcedf0e8..d86bbf8a18 100644 --- a/internals/garbage-collector.rst +++ b/internals/garbage-collector.rst @@ -9,4 +9,4 @@ Garbage collector design .. highlight:: none This document is now part of the -`CPython Internals Docs `_. +`CPython Internals Docs `__. diff --git a/internals/interpreter.rst b/internals/interpreter.rst index a7ae39c120..52c1509441 100644 --- a/internals/interpreter.rst +++ b/internals/interpreter.rst @@ -5,4 +5,4 @@ The bytecode interpreter ======================== This document is now part of the -`CPython Internals Docs `_. +`CPython Internals Docs `__. diff --git a/internals/parser.rst b/internals/parser.rst index 688ad61e77..9700c25b05 100644 --- a/internals/parser.rst +++ b/internals/parser.rst @@ -7,4 +7,4 @@ Guide to the parser .. highlight:: none This document is now part of the -`CPython Internals Docs `_. +`CPython Internals Docs `__. diff --git a/testing/buildbots.rst b/testing/buildbots.rst index e038499354..1e711ab6bb 100644 --- a/testing/buildbots.rst +++ b/testing/buildbots.rst @@ -11,7 +11,7 @@ branches `, Python has a set of dedicated machines (called *buildbots* or *build workers*) used for continuous integration. They span a number of hardware/operating system combinations. Furthermore, each machine hosts several *builders*, one per active branch: when a new change is pushed -to this branch on the public `GitHub repository `_, all corresponding builders +to this branch on the public `GitHub repository `__, all corresponding builders will schedule a new build to be run as soon as possible. The build steps run by the buildbots are the following: diff --git a/testing/coverage.rst b/testing/coverage.rst index d01141a7dc..c34bb5235a 100644 --- a/testing/coverage.rst +++ b/testing/coverage.rst @@ -127,7 +127,7 @@ to install coverage. You can now use python without the ./ for the rest of these instructions, as long as your venv is activated. For more info on venv see `Virtual Environment -`_ documentation. +`__ documentation. If this does not work for you for some reason, you should try using the in-development version of coverage.py to see if it has been updated as needed. diff --git a/testing/new-buildbot-worker.rst b/testing/new-buildbot-worker.rst index cac7bb63d5..a0fbf9681a 100644 --- a/testing/new-buildbot-worker.rst +++ b/testing/new-buildbot-worker.rst @@ -20,12 +20,12 @@ to go about setting up a buildbot worker, getting it added, and some hints about buildbot maintenance. Anyone running a buildbot that is part of the fleet should subscribe to the -`python-buildbots `_ +`python-buildbots `__ mailing list. This mailing list is also the place to contact if you want to contribute a buildbot but have questions. As for what kind of buildbot to run...take a look at our `current fleet -`_. Pretty much anything that isn't +`__. Pretty much anything that isn't on that list would be interesting: different Linux/Unix distributions, different versions of the various OSes, other OSes if you or someone are prepared to make the test suite actually pass on that new OS. Even if you only @@ -47,7 +47,7 @@ compiled python. In order to set up the buildbot software, you will need to obtain an identifier and password for your worker so it can join the fleet. Open an issue in the -`configuration repository `_ +`configuration repository `__ to discuss adding your worker and to obtain the needed workername and password. You can do some of the steps that follow before having the credentials, but it is easiest to have them before @@ -60,7 +60,7 @@ Setting up the buildbot worker Conventional always-on machines ------------------------------- -You need a recent version of the `buildbot `_ software, +You need a recent version of the `buildbot `__ software, and you will probably want a separate 'buildbot' user to run the buildbot software. You may also want to set the buildbot up using a virtual environment, depending on how you manage your system. We won't cover how to that @@ -103,7 +103,7 @@ can put the ``buildarea`` wherever you want to):: :file:`Scripts` directory of your Python installation.) On Windows, `the maximum length for a path is limited -`_. +`__. This might cause some tests to fail, unless long paths support is enabled. Use this PowerShell command to check whether long paths are enabled:: @@ -254,7 +254,7 @@ For Windows: * Alternatively (note: don't do both!), set up the worker service as described in the `buildbot documentation - `_. + `__. To start the worker running for your initial testing, you can do:: @@ -262,7 +262,7 @@ To start the worker running for your initial testing, you can do:: Then you can either wait for someone to make a commit, or you can pick a builder associated with your worker from the `list of builders -`_ and force a build. +`__ and force a build. In any case you should initially monitor builds on your builders to make sure the tests are passing and to resolve any platform issues that may be revealed @@ -273,7 +273,7 @@ idea. .. note:: If your buildbot worker is disconnecting regularly, it may be a symptom of the default ``keepalive`` value (``600`` for 10 minutes) being `set - `_ + `__ too high. You can change it to a lower value (for example, ``180`` for 3 minutes) in the ``buildbot.tac`` file found in your build area. @@ -282,7 +282,7 @@ Latent workers -------------- We also support running `latent workers -`_ +`__ on the AWS EC2 service. To set up such a worker: * Start an instance of your chosen base AMI and set it up as a @@ -305,7 +305,7 @@ instance(s), so it is recommended to periodically check and make sure there are no "zombie" instances running on your account, created by the buildbot master. Also, if you notice that your worker seems to have been down for an unexpectedly long time, please ping the `python-buildbots -`_ list to +`__ list to request that the master be restarted. Latent workers should also be updated periodically to include operating system @@ -390,7 +390,7 @@ Required resources ================== Based on the last time we did a `survey -`_ on +`__ on buildbot requirements, the recommended resource allocations for a python buildbot are at least: @@ -408,7 +408,7 @@ Security considerations ======================= We only allow builds to be triggered against commits to the -`CPython repository on GitHub `_. +`CPython repository on GitHub `__. This means that the code your buildbot will run will have been vetted by a committer. However, mistakes and bugs happen, as could a compromise, so keep this in mind when siting your buildbot on your network and establishing the security around it. @@ -427,7 +427,7 @@ VM setup. But if you are confident in your setup, we'd love to have a buildbot that runs python as root. Note that the above is a summary of a `discussion -`_ on +`__ on python-dev about buildbot security that includes examples of the tests for which privilege matters. There was no final consensus, but the information is useful as a point of reference. diff --git a/testing/run-write-tests.rst b/testing/run-write-tests.rst index 83a4a28610..34101bd2d2 100644 --- a/testing/run-write-tests.rst +++ b/testing/run-write-tests.rst @@ -286,7 +286,7 @@ Benchmarks Benchmarking is useful to test that a change does not degrade performance. -`The Python Benchmark Suite `_ +`The Python Benchmark Suite `__ has a collection of benchmarks for all Python implementations. Documentation about running the benchmarks is in the `README.txt -`_ of the repo. +`__ of the repo. diff --git a/triage/github-bpo-faq.rst b/triage/github-bpo-faq.rst index 8c21a17fea..f4f8b16dd4 100644 --- a/triage/github-bpo-faq.rst +++ b/triage/github-bpo-faq.rst @@ -16,7 +16,7 @@ How to format my comments nicely? ================================= There is a wonderful `beginner guide to writing and formatting on GitHub -`_. +`__. Highly recommended. One pro-tip we can sell you right here is that if you want to paste @@ -43,7 +43,7 @@ Use Markdown links. If you link to the default GitHub path, the file will link to the latest current version on the given branch. You can get a permanent link to a given revision of a given file by -`pressing "y" `_. +`pressing "y" `__. How to do advanced searches? ============================ @@ -80,7 +80,7 @@ Add a checkbox list like this in the issue description:: then those will become sub-tasks on the given issue. Moreover, GitHub will automatically mark a task as complete if the other referenced issue is closed. More details in the `official GitHub documentation -`_. +`__. What on earth is a "mannequin"? =============================== @@ -88,7 +88,7 @@ What on earth is a "mannequin"? For issues migrated to GitHub from `bpo`_ where the authors or commenters are not core developers, we opted not to link to their GitHub accounts directly. Users not in the `python organization on GitHub -`_ might not like comments to +`__ might not like comments to appear under their name from an automated import. Others never linked GitHub on `bpo`_ in the first place so linking their account, if any, would be impossible. diff --git a/triage/labels.rst b/triage/labels.rst index 34c7dc26c9..96e0d8f58e 100644 --- a/triage/labels.rst +++ b/triage/labels.rst @@ -9,7 +9,7 @@ Triagers, core developers and bots can add labels on GitHub to categorize issues and pull requests. Many labels are shared for both use cases, while some are dedicated only to one. Below is a possibly inexhaustive list, but it should get -you going. For a full list, see `here `_. +you going. For a full list, see `here `__. .. _general-purpose-labels: @@ -73,7 +73,7 @@ we don't have a dedicated Unix label. Use the :gh-label:`OS-unsupported` label for issues on platforms outside the support tiers defined in :pep:`11`. Applying this label adds the issue to -`a GitHub project `_ where +`a GitHub project `__ where it can be categorized further. See also the :ref:`Platform experts list `. @@ -92,7 +92,7 @@ they are encouraged to subscribe to them. Depending on the label, this might also automatically add the issue to a GitHub project. You can see the `full list of topic labels on GitHub -`_. +`__. .. _Version labels: diff --git a/triage/triage-team.rst b/triage/triage-team.rst index 68a88457e4..7acebc130c 100644 --- a/triage/triage-team.rst +++ b/triage/triage-team.rst @@ -86,14 +86,14 @@ Any existing active contributor to the Python repository on GitHub can transition into becoming a Python triager. They can request this to any core developer, either confidentially via a DM in Discourse, or publicly by opening an `issue in the core-workflow repository -`_. +`__. If the core developer decides you are ready to gain the extra privileges on the tracker, they will ask a :ref:`Python organization admin ` to invite you to the Python organisation, and then act as a mentor to you until you are ready to do things entirely on your own. For every new triager, it would be great to announce them in the -`Committers category `_ -on the `Python Discourse `_ +`Committers category `__ +on the `Python Discourse `__ (`example announcement `__). diff --git a/versions.rst b/versions.rst index 0a52829c2f..d0f8379915 100644 --- a/versions.rst +++ b/versions.rst @@ -7,14 +7,14 @@ Status of Python versions The ``main`` branch is currently the future Python |main_version|, and is the only branch that accepts new features. The latest release for each Python -version can be found on the `download page `_. +version can be found on the `download page `__. .. raw:: html :file: include/release-cycle.svg (See :ref:`below ` for a chart with older versions. -Another useful visualization is `endoflife.date/python `_.) +Another useful visualization is `endoflife.date/python `__.) Supported versions From 0e9faabf8519c49ae3070ee95707f7dc706c1b17 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 10:23:54 +0800 Subject: [PATCH 091/103] Bump actions/checkout from 5 to 6 in the actions group (#1711) Bumps the actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 5 to 6 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- .github/workflows/lint.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6479277afe..b85a45c1bb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: timeout-minutes: 10 steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: python-version: "3" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index c1554eb5e6..4622f995aa 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -8,7 +8,7 @@ jobs: timeout-minutes: 10 steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: python-version: "3.x" From 4732570b2e2ecaaa83804e07c6c42d2b07209f04 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 11:02:33 +0000 Subject: [PATCH 092/103] Bump the pip group with 2 updates (#1710) --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index cb6b2cd5cf..7c2bbd806e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,9 +2,9 @@ furo>=2022.6.4 jinja2 sphinx-autobuild>=2024.9.19 sphinx-inline-tabs>=2023.4.21 -sphinx-lint==1.0.1 +sphinx-lint==1.0.2 sphinx-notfound-page>=1.0.0 sphinx_copybutton>=0.3.3 sphinxext-opengraph>=0.13.0 sphinxext-rediraffe -Sphinx~=8.2.3 +Sphinx>=8.2.3 From 1830dddf03451b7bb2bf31b7c553a9789ed44bdf Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Fri, 19 Dec 2025 11:41:00 +0000 Subject: [PATCH 093/103] Remove empty InternalDoc pages (GH-1712) The info is now in the CPython repo; the devguide has links to that and other guides. --- conf.py | 12 ++++-- developer-workflow/c-api.rst | 2 +- index.rst | 7 +--- internals/exploring.rst => internals.rst | 50 ++---------------------- internals/compiler.rst | 10 ----- internals/garbage-collector.rst | 12 ------ internals/index.rst | 20 ---------- internals/interpreter.rst | 8 ---- internals/parser.rst | 10 ----- 9 files changed, 15 insertions(+), 116 deletions(-) rename internals/exploring.rst => internals.rst (67%) delete mode 100644 internals/compiler.rst delete mode 100644 internals/garbage-collector.rst delete mode 100644 internals/index.rst delete mode 100644 internals/interpreter.rst delete mode 100644 internals/parser.rst diff --git a/conf.py b/conf.py index 0f6a820d88..02f9c74771 100644 --- a/conf.py +++ b/conf.py @@ -149,10 +149,14 @@ "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", + "compiler.rst": "internals.rst", + "exploring.rst": "internals.rst", + "garbage_collector.rst": "internals.rst", + "parser.rst": "internals.rst", + "internals/compiler.rst": "internals.rst", + "internals/exploring.rst": "internals.rst", + "internals/garbage_collector.rst": "internals.rst", + "internals/parser.rst": "internals.rst", # Testing and Buildbots "buildbots.rst": "testing/buildbots.rst", "coverage.rst": "testing/coverage.rst", diff --git a/developer-workflow/c-api.rst b/developer-workflow/c-api.rst index c65e88ce1c..a6523a9094 100644 --- a/developer-workflow/c-api.rst +++ b/developer-workflow/c-api.rst @@ -387,7 +387,7 @@ Guidelines for adding to the Limited API details involve: - The GIL - - :ref:`Garbage collection ` + - Garbage collection - Memory layout of PyObject, lists/tuples and other structures If following these guidelines would hurt performance, add a fast function diff --git a/index.rst b/index.rst index 0af90e295e..997f599327 100644 --- a/index.rst +++ b/index.rst @@ -267,11 +267,8 @@ Additional resources * Anyone can clone the sources for this guide. See :ref:`devguide`. * Help with ... - * :ref:`exploring` + * :ref:`internals` * :ref:`grammar` - * :ref:`parser` - * :ref:`compiler` - * :ref:`garbage_collector` * Tool support @@ -317,7 +314,7 @@ Full table of contents testing/index development-tools/index core-team/index - internals/index + internals versions contrib/index diff --git a/internals/exploring.rst b/internals.rst similarity index 67% rename from internals/exploring.rst rename to internals.rst index 0ae8337e8c..89897eb19c 100644 --- a/internals/exploring.rst +++ b/internals.rst @@ -1,53 +1,9 @@ -.. _exploring: +.. _internals: =================== -CPython source code +CPython's internals =================== -This section gives an overview of CPython's code structure and provides -a summary of file locations for modules and built-ins. - - -Source code layout -================== - -For a Python :term:`module`, the typical layout is: - -* :file:`Lib/{}.py` -* :file:`Modules/_{}.c` (if there's also a C accelerator module) -* :file:`Lib/test/test_{}.py` -* :file:`Doc/library/{}.rst` - -For an :term:`extension module`, the typical layout is: - -* :file:`Modules/{}module.c` -* :file:`Lib/test/test_{}.py` -* :file:`Doc/library/{}.rst` - -For :ref:`bltin-types`, the typical layout is: - -* :file:`Objects/{}object.c` -* :file:`Lib/test/test_{}.py` -* :cpy-file:`Doc/library/stdtypes.rst` - -For :ref:`built-in-funcs`, the typical layout is: - -* :cpy-file:`Python/bltinmodule.c` -* :cpy-file:`Lib/test/test_builtin.py` -* :cpy-file:`Doc/library/functions.rst` - -Some exceptions to these layouts are: - -* built-in type ``int`` is at :cpy-file:`Objects/longobject.c` -* built-in type ``str`` is at :cpy-file:`Objects/unicodeobject.c` -* built-in module ``sys`` is at :cpy-file:`Python/sysmodule.c` -* built-in module ``marshal`` is at :cpy-file:`Python/marshal.c` -* Windows-only module ``winreg`` is at :cpy-file:`PC/winreg.c` - - -Additional references -===================== - The CPython code base is constantly changing and evolving. Here's a sample of references about CPython's architecture aimed at building your understanding of CPython internals and its evolution: @@ -56,6 +12,7 @@ building your understanding of CPython internals and its evolution: :header: "Title", "Brief", "Author", "Version" :widths: 50, 50, 20, 5 + "`CPython's InternalDocs`_", "Docs on CPython internals maintained in the source tree", "", "" "`A guide from parser to objects, observed using GDB`_", "Code walk from Parser, AST, Sym Table and Objects", Louie Lu, 3.7.a0 "`Green Tree Snakes`_", "The missing Python AST docs", Thomas Kluyver, 3.6 "`Yet another guided tour of CPython`_", "A guide for how CPython REPL works", Guido van Rossum, 3.5 @@ -72,6 +29,7 @@ building your understanding of CPython internals and its evolution: "`A guide from parser to objects, observed using Eclipse`_", "Code walk from Parser, AST, Sym Table and Objects", Prashanth Raghu, 2.7.12 "`CPython internals: A ten-hour codewalk through the Python interpreter source code`_", "Code walk from source code to generators", Philip Guo, 2.7.8 +.. _CPython's InternalDocs: https://github.com/python/cpython/blob/main/InternalDocs/README.md .. _A guide from parser to objects, observed using GDB: https://hackmd.io/s/ByMHBMjFe diff --git a/internals/compiler.rst b/internals/compiler.rst deleted file mode 100644 index f22039c649..0000000000 --- a/internals/compiler.rst +++ /dev/null @@ -1,10 +0,0 @@ -.. _compiler: - -=============== -Compiler design -=============== - -.. highlight:: none - -This document is now part of the -`CPython Internals Docs `__. diff --git a/internals/garbage-collector.rst b/internals/garbage-collector.rst deleted file mode 100644 index d86bbf8a18..0000000000 --- a/internals/garbage-collector.rst +++ /dev/null @@ -1,12 +0,0 @@ -.. _garbage-collector: -.. _gc: -.. _garbage_collector: - -======================== -Garbage collector design -======================== - -.. highlight:: none - -This document is now part of the -`CPython Internals Docs `__. diff --git a/internals/index.rst b/internals/index.rst deleted file mode 100644 index 05723f4824..0000000000 --- a/internals/index.rst +++ /dev/null @@ -1,20 +0,0 @@ -.. _internals: - -=================== -CPython's internals -=================== - -This guide describes the basics of CPython's internals. -It explains the layout of CPython's source code. -It also explains how the parser, compiler, and interpreter -work together to run your Python code. -Finally, it covers the garbage collector and how it manages memory. - -.. toctree:: - :maxdepth: 3 - - exploring - parser - compiler - interpreter - garbage-collector diff --git a/internals/interpreter.rst b/internals/interpreter.rst deleted file mode 100644 index 52c1509441..0000000000 --- a/internals/interpreter.rst +++ /dev/null @@ -1,8 +0,0 @@ -.. _interpreter: - -======================== -The bytecode interpreter -======================== - -This document is now part of the -`CPython Internals Docs `__. diff --git a/internals/parser.rst b/internals/parser.rst deleted file mode 100644 index 9700c25b05..0000000000 --- a/internals/parser.rst +++ /dev/null @@ -1,10 +0,0 @@ -.. _parser: - -=================== -Guide to the parser -=================== - -.. highlight:: none - -This document is now part of the -`CPython Internals Docs `__. From ec0447ad318b673ec6a640c5af31d9cfe0ebb2a1 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Sun, 21 Dec 2025 08:50:04 +0000 Subject: [PATCH 094/103] Pin to Sphinx 8.2.3 (#1716) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7c2bbd806e..359d282681 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,4 @@ sphinx-notfound-page>=1.0.0 sphinx_copybutton>=0.3.3 sphinxext-opengraph>=0.13.0 sphinxext-rediraffe -Sphinx>=8.2.3 +Sphinx~=8.2.3 From b24ed5025bb9efa6df0c638cdec81121f03ed8b3 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 21 Dec 2025 11:06:59 +0200 Subject: [PATCH 095/103] Clarify development cycle (#1681) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- developer-workflow/development-cycle.rst | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/developer-workflow/development-cycle.rst b/developer-workflow/development-cycle.rst index d39fd2cfc5..2f1cadbbd9 100644 --- a/developer-workflow/development-cycle.rst +++ b/developer-workflow/development-cycle.rst @@ -68,8 +68,8 @@ Maintenance branches A branch for a previous feature release, currently being maintained for bug fixes, or for the next feature release in its :ref:`beta ` or :ref:`release candidate ` stages. -There is usually either one or two maintenance branches at any given time for -Python 3.x. After the final release of a new minor version (3.x.0), releases +There are usually either one or two maintenance branches at any given time. +After the final release of a new minor version (3.x.0), releases produced from a maintenance branch are called **bugfix** or **maintenance** releases; the terms are used interchangeably. These releases have a **micro version** number greater than zero. @@ -190,7 +190,7 @@ severe enough (for example, crashes) that they deserve fixing before the final r All other issues should be deferred to the next development cycle, since stability is the strongest concern at this point. -While the goal is to have no code changes between a RC and a final release, +While the goal is to have no code changes between an RC and a final release, there may be a need for final documentation or test fixes. Any such proposed changes should be discussed first with the release manager. @@ -204,8 +204,7 @@ 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. +changes to the branch. Repository administration From 43b50c317669a4ecbeb11ce2be8ba784fbbe3af8 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 21 Dec 2025 11:13:41 +0200 Subject: [PATCH 096/103] Replace local release-cycle.json with PEPs repo version (#1685) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- .pre-commit-config.yaml | 2 - Makefile | 17 ++-- _tools/generate_release_cycle.py | 14 ++- conf.py | 5 +- include/release-cycle.json | 146 ------------------------------- 5 files changed, 26 insertions(+), 158 deletions(-) delete mode 100644 include/release-cycle.json diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ae27fd1f23..c5beee4a37 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,14 +7,12 @@ repos: 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 diff --git a/Makefile b/Makefile index 3d485ae2da..a3e1764382 100644 --- a/Makefile +++ b/Makefile @@ -103,15 +103,20 @@ _ensure-pre-commit: 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 +# Generate all release cycle files together with a single script invocation +# Use branches.csv as the primary target, others depend on it +include/branches.csv: $(VENVDIR)/bin/python3 _tools/generate_release_cycle.py @echo Release cycle data generated. +# Other files are generated together with branches.csv +include/end-of-life.csv: include/branches.csv + @: +include/release-cycle-all.svg: include/branches.csv + @: +include/release-cycle.svg: include/branches.csv + @: + # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. .PHONY: Makefile diff --git a/_tools/generate_release_cycle.py b/_tools/generate_release_cycle.py index dd0a3a7c65..00373036df 100644 --- a/_tools/generate_release_cycle.py +++ b/_tools/generate_release_cycle.py @@ -7,6 +7,9 @@ import csv import datetime as dt import json +from functools import cache +from pathlib import Path +from urllib.request import urlopen import jinja2 @@ -37,12 +40,17 @@ def parse_version(ver: str) -> list[int]: return [int(i) for i in ver["key"].split(".")] +@cache +def get_versions() -> dict[str, dict[str, str | int]]: + with urlopen("https://peps.python.org/api/release-cycle.json") as in_file: + return json.loads(in_file.read().decode("utf-8")) + + 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) + self.versions = get_versions() # Generate a few additional fields for key, version in self.versions.items(): @@ -197,6 +205,8 @@ def main() -> None: versions = Versions() assert len(versions.versions) > 10 + Path("include").mkdir(exist_ok=True) + versions.write_csv() versions.write_svg(args.today, "include/release-cycle-all.svg") diff --git a/conf.py b/conf.py index 02f9c74771..c38e33dd85 100644 --- a/conf.py +++ b/conf.py @@ -1,4 +1,5 @@ import json +from urllib.request import urlopen extensions = [ 'notfound.extension', @@ -182,8 +183,8 @@ # 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) +with urlopen("https://peps.python.org/api/release-cycle.json") as _f: + _cycle = json.loads(_f.read().decode("utf-8")) _main_version = next( version for version, data in _cycle.items() if data.get("branch") == "main" diff --git a/include/release-cycle.json b/include/release-cycle.json deleted file mode 100644 index 26436bf003..0000000000 --- a/include/release-cycle.json +++ /dev/null @@ -1,146 +0,0 @@ -{ - "3.15": { - "branch": "main", - "pep": 790, - "status": "feature", - "first_release": "2026-10-01", - "end_of_life": "2031-10", - "release_manager": "Hugo van Kemenade" - }, - "3.14": { - "branch": "3.14", - "pep": 745, - "status": "bugfix", - "first_release": "2025-10-07", - "end_of_life": "2030-10", - "release_manager": "Hugo van Kemenade" - }, - "3.13": { - "branch": "3.13", - "pep": 719, - "status": "bugfix", - "first_release": "2024-10-07", - "end_of_life": "2029-10", - "release_manager": "Thomas Wouters" - }, - "3.12": { - "branch": "3.12", - "pep": 693, - "status": "security", - "first_release": "2023-10-02", - "end_of_life": "2028-10", - "release_manager": "Thomas Wouters" - }, - "3.11": { - "branch": "3.11", - "pep": 664, - "status": "security", - "first_release": "2022-10-24", - "end_of_life": "2027-10", - "release_manager": "Pablo Galindo Salgado" - }, - "3.10": { - "branch": "3.10", - "pep": 619, - "status": "security", - "first_release": "2021-10-04", - "end_of_life": "2026-10", - "release_manager": "Pablo Galindo Salgado" - }, - "3.9": { - "branch": "3.9", - "pep": 596, - "status": "end-of-life", - "first_release": "2020-10-05", - "end_of_life": "2025-10-31", - "release_manager": "Łukasz Langa" - }, - "3.8": { - "branch": "3.8", - "pep": 569, - "status": "end-of-life", - "first_release": "2019-10-14", - "end_of_life": "2024-10-07", - "release_manager": "Łukasz Langa" - }, - "3.7": { - "branch": "3.7", - "pep": 537, - "status": "end-of-life", - "first_release": "2018-06-27", - "end_of_life": "2023-06-27", - "release_manager": "Ned Deily" - }, - "3.6": { - "branch": "3.6", - "pep": 494, - "status": "end-of-life", - "first_release": "2016-12-23", - "end_of_life": "2021-12-23", - "release_manager": "Ned Deily" - }, - "3.5": { - "branch": "3.5", - "pep": 478, - "status": "end-of-life", - "first_release": "2015-09-13", - "end_of_life": "2020-09-30", - "release_manager": "Larry Hastings" - }, - "3.4": { - "branch": "3.4", - "pep": 429, - "status": "end-of-life", - "first_release": "2014-03-16", - "end_of_life": "2019-03-18", - "release_manager": "Larry Hastings" - }, - "3.3": { - "branch": "3.3", - "pep": 398, - "status": "end-of-life", - "first_release": "2012-09-29", - "end_of_life": "2017-09-29", - "release_manager": "Georg Brandl, Ned Deily (3.3.7+)" - }, - "3.2": { - "branch": "3.2", - "pep": 392, - "status": "end-of-life", - "first_release": "2011-02-20", - "end_of_life": "2016-02-20", - "release_manager": "Georg Brandl" - }, - "2.7": { - "branch": "2.7", - "pep": 373, - "status": "end-of-life", - "first_release": "2010-07-03", - "end_of_life": "2020-01-01", - "release_manager": "Benjamin Peterson" - }, - "3.1": { - "branch": "3.1", - "pep": 375, - "status": "end-of-life", - "first_release": "2009-06-27", - "end_of_life": "2012-04-09", - "release_manager": "Benjamin Peterson" - }, - "3.0": { - "branch": "3.0", - "pep": 361, - "status": "end-of-life", - "first_release": "2008-12-03", - "end_of_life": "2009-06-27", - "release_manager": "Barry Warsaw" - }, - "2.6": { - "branch": "2.6", - "pep": 361, - "status": "end-of-life", - "first_release": "2008-10-01", - "end_of_life": "2013-10-29", - "release_manager": "Barry Warsaw" - } -} From 7e6a146b4fc8c4e2bc274f7bb3ac62f03c4a16f1 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 21 Dec 2025 11:20:39 +0200 Subject: [PATCH 097/103] Replace deprecated workflow with RTD app (#1713) --- .github/workflows/documentation-links.yml | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 .github/workflows/documentation-links.yml diff --git a/.github/workflows/documentation-links.yml b/.github/workflows/documentation-links.yml deleted file mode 100644 index bacb37d07c..0000000000 --- a/.github/workflows/documentation-links.yml +++ /dev/null @@ -1,18 +0,0 @@ -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" From e583bd3f9407d5edacd94e6e2799e1d8032fda78 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 29 Dec 2025 11:53:23 +0200 Subject: [PATCH 098/103] Fix typos (#1714) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- developer-workflow/c-api.rst | 2 +- developer-workflow/extension-modules.rst | 2 +- documentation/devguide.rst | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/developer-workflow/c-api.rst b/developer-workflow/c-api.rst index a6523a9094..e7f129a27d 100644 --- a/developer-workflow/c-api.rst +++ b/developer-workflow/c-api.rst @@ -104,7 +104,7 @@ 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. +we only introduce C11 features individually as needed. .. _decisions repo: https://github.com/capi-workgroup/decisions/issues diff --git a/developer-workflow/extension-modules.rst b/developer-workflow/extension-modules.rst index fa4c11868f..4d8c0ffca1 100644 --- a/developer-workflow/extension-modules.rst +++ b/developer-workflow/extension-modules.rst @@ -574,7 +574,7 @@ Now that the configuration is in place, it remains to compile the project: :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 + invocations may completely rebuild the project, but it could be needed in some specific cases. Troubleshooting diff --git a/documentation/devguide.rst b/documentation/devguide.rst index 9f2ada23c1..fc12c369f9 100644 --- a/documentation/devguide.rst +++ b/documentation/devguide.rst @@ -22,7 +22,7 @@ lives in a `separate repository`_ and bug reports should be submitted to the Changes to the Developer's Guide are published when pull requests are merged. Changes to the Python documentation are published regularly, -ususally within 48 hours of the change being committed. +usually within 48 hours of the change being committed. The documentation is also `published for each release `__, which may also be used by redistributors. From 3e65c0c96150433530b74c9dc46210e2f4d4d027 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 30 Dec 2025 15:51:16 +0200 Subject: [PATCH 099/103] Make release cycle charts reusable (#1708) Co-authored-by: Petr Viktorin --- .gitignore | 4 +- Makefile | 4 +- _static/devguide_overrides.css | 96 ------------ _tools/generate_release_cycle.py | 4 +- _tools/release_cycle_template.svg.jinja | 186 +++++++++++++++++++----- make.ps1 | 2 +- versions.rst | 6 +- 7 files changed, 160 insertions(+), 142 deletions(-) diff --git a/.gitignore b/.gitignore index b712492014..f61a108300 100644 --- a/.gitignore +++ b/.gitignore @@ -90,5 +90,5 @@ celerybeat-schedule # Generated CSV and SVG files include/branches.csv include/end-of-life.csv -include/release-cycle.svg -include/release-cycle-all.svg +_static/release-cycle.svg +_static/release-cycle-all.svg diff --git a/Makefile b/Makefile index a3e1764382..2f8e086148 100644 --- a/Makefile +++ b/Makefile @@ -22,8 +22,8 @@ REQUIREMENTS = requirements.txt _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 + _static/release-cycle-all.svg \ + _static/release-cycle.svg .PHONY: help help: diff --git a/_static/devguide_overrides.css b/_static/devguide_overrides.css index 5b6d67b093..625a9dda2d 100644 --- a/_static/devguide_overrides.css +++ b/_static/devguide_overrides.css @@ -6,102 +6,6 @@ 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); } diff --git a/_tools/generate_release_cycle.py b/_tools/generate_release_cycle.py index 00373036df..24dfa03e74 100644 --- a/_tools/generate_release_cycle.py +++ b/_tools/generate_release_cycle.py @@ -208,10 +208,10 @@ def main() -> None: Path("include").mkdir(exist_ok=True) versions.write_csv() - versions.write_svg(args.today, "include/release-cycle-all.svg") + versions.write_svg(args.today, "_static/release-cycle-all.svg") versions = Versions(limit_to_active=True, special_py27=True) - versions.write_svg(args.today, "include/release-cycle.svg") + versions.write_svg(args.today, "_static/release-cycle.svg") if __name__ == "__main__": diff --git a/_tools/release_cycle_template.svg.jinja b/_tools/release_cycle_template.svg.jinja index d3d5866a06..9f23814a9e 100644 --- a/_tools/release_cycle_template.svg.jinja +++ b/_tools/release_cycle_template.svg.jinja @@ -4,6 +4,104 @@ class="release-cycle-chart" viewBox="0 0 {{ diagram_width }} {{ diagram_height }}" > + @@ -11,9 +109,16 @@ + + {% for version in versions %} {% set y = version.y * line_height %} - {% if version.y % 2 %} {% for version in versions %} - + {% set top_y = version.y * line_height - 1 * SCALE %} {% set height = 1.25 * SCALE %} @@ -82,8 +187,6 @@ {% set end_x = date_to_x(version.end_of_life_date) %} {% set radius = 0.25 * SCALE %} - {% set small_text_y = version.y * line_height - 0.1 * SCALE %} - + + + {% for version in versions %} + + + {% set start_x = date_to_x(version.first_release_date) %} + {% set end_x = date_to_x(version.end_of_life_date) %} + {% set middle_x = ([end_x, date_to_x(version.start_security_date)]|min) %} + {% set small_text_y = version.y * line_height - 0.1 * SCALE %} - - {{ version.status }} - + {% for cls in ('text-outline', 'text-main') %} + + {{ version.status }} + + {% endfor %} {% endfor %} - - - diff --git a/make.ps1 b/make.ps1 index ffda672698..c8ad842c9b 100644 --- a/make.ps1 +++ b/make.ps1 @@ -65,7 +65,7 @@ if ($target -Eq "clean") { $BUILDDIR, $_VENV_DIR, "include/branches.csv", "include/end-of-life.csv", - "include/release-cycle.svg", "include/release-cycle-all.svg" + "_static/release-cycle.svg", "_static/release-cycle-all.svg" ) foreach ($item in $ToClean) { if (Test-Path -Path $item) { diff --git a/versions.rst b/versions.rst index d0f8379915..3d5fdced91 100644 --- a/versions.rst +++ b/versions.rst @@ -11,7 +11,7 @@ version can be found on the `download page `_ .. raw:: html - :file: include/release-cycle.svg + :file: _static/release-cycle.svg (See :ref:`below ` for a chart with older versions. Another useful visualization is `endoflife.date/python `__.) @@ -36,7 +36,7 @@ Unsupported versions .. csv-table:: :header-rows: 1 :width: 100% - :file: include/end-of-life.csv + :file: _static/end-of-life.csv .. _full-chart: @@ -45,7 +45,7 @@ Full chart ========== .. raw:: html - :file: include/release-cycle-all.svg + :file: _static/release-cycle-all.svg Status key From 521dacefce4e4cad0c42704e4dc07f48e6f02a35 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 30 Dec 2025 16:45:01 +0200 Subject: [PATCH 100/103] Fix paths in Makefile (#1719) --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 2f8e086148..a26ad48e00 100644 --- a/Makefile +++ b/Makefile @@ -112,9 +112,9 @@ include/branches.csv: # Other files are generated together with branches.csv include/end-of-life.csv: include/branches.csv @: -include/release-cycle-all.svg: include/branches.csv +_static/release-cycle-all.svg: include/branches.csv @: -include/release-cycle.svg: include/branches.csv +_static/release-cycle.svg: include/branches.csv @: # Catch-all target: route all unknown targets to Sphinx using the new From 5d02e79675aeaf80fbf821a8d4af9d1977958a9b Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Thu, 1 Jan 2026 12:48:21 +0200 Subject: [PATCH 101/103] Revert "Pin to Sphinx 8.2.3 (#1716)" (#1717) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 359d282681..7c2bbd806e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,4 @@ sphinx-notfound-page>=1.0.0 sphinx_copybutton>=0.3.3 sphinxext-opengraph>=0.13.0 sphinxext-rediraffe -Sphinx~=8.2.3 +Sphinx>=8.2.3 From f657b399c31fef3682249e65835772bee1ae2a4b Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Tue, 6 Jan 2026 17:05:22 +0000 Subject: [PATCH 102/103] Add section on terminology to avoid to style guide (#1715) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- documentation/style-guide.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/documentation/style-guide.rst b/documentation/style-guide.rst index d90a14ce90..d263fb8f17 100644 --- a/documentation/style-guide.rst +++ b/documentation/style-guide.rst @@ -116,6 +116,24 @@ Don't use Latin abbreviations like "e.g." or "i.e." where English words will do, such as "for example" or "that is." +Charged terminology to avoid +============================ + +Avoid terminology that may be considered insensitive or exclusionary. + +.. list-table:: + :header-rows: 1 + + * - Avoid + - Instead + * - whitelist + - allowlist + * - blacklist + - blocklist, denylist + * - master/slave + - main, parent/child, server/client, primary/secondary + + .. index:: diataxis .. _diataxis: From d5ca1b4aea6281aa66ce4b25b9889e6f89c0d2fe Mon Sep 17 00:00:00 2001 From: Rafael Weingartner-Ortner <38643099+RafaelWO@users.noreply.github.com> Date: Sun, 25 Jan 2026 14:52:04 +0100 Subject: [PATCH 103/103] Merge macOS "Python 3.13+" and "Python 3.11-3.12" tabs (#1726) --- getting-started/setup-building.rst | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index df208f28cf..110d718e95 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -858,18 +858,9 @@ some of CPython's modules (for example, ``zlib``). $ brew install pkg-config openssl@3 xz gdbm tcl-tk mpdecimal zstd - .. tab:: Python 3.13+ - - For Python 3.13 and newer:: + .. tab:: Python 3.11+ - $ GDBM_CFLAGS="-I$(brew --prefix gdbm)/include" \ - GDBM_LIBS="-L$(brew --prefix gdbm)/lib -lgdbm" \ - ./configure --with-pydebug \ - --with-openssl="$(brew --prefix openssl@3)" - - .. tab:: Python 3.11-3.12 - - For Python 3.11 and 3.12:: + For Python 3.11 and newer:: $ GDBM_CFLAGS="-I$(brew --prefix gdbm)/include" \ GDBM_LIBS="-L$(brew --prefix gdbm)/lib -lgdbm" \